luis and the snippet from d.j.peters demonstrating how to render OpenGL
on a window in Linux I decided to strip down a bare bones code example
which works in Windows, Linux and even MacOS. This example simply
displays a triangle with a color gradient.
I tested it successfully on these operating systems with PB 4.61:
Windows
- Windows 98 SE
- Windows XP SP3
- Windows 7 x86
- Windows 7 SP1 x86
- Windows 7 x64
Linux
- Kubuntu 10.04 x86
- Kubuntu 11.10 x86
- Kubuntu 12.04 x86
- Kubuntu 12.04 x64
- Linux Mint 11 x86
- Linux Mint 12 x86
- Linux Mint 13 Cinnamon x86
- OpenSuSE 11.4 x86
- OpenSuSE 12.1 x86
- Ubuntu 10.04 x86
- Ubuntu 11.04 x86
- Ubuntu 12.04 Gnome 2 x86
- Ubuntu 12.04 Gnome 2 x64
- Ubuntu 12.04 Unity x86
- Ubuntu 12.04 Unity x64
- Xubuntu 10.04 x86
- Xubuntu 11.10 x86
- Xubuntu 12.04 x86
MacOS
- MacOS X 10.6.8 (Snow Leopard)
- MacOS X 10.7.4 (Lion)
- MacOS X 10.8.0 (Mountain Lion)
Code: Select all
EnableExplicit
#AGL_RGBA = 4
#AGL_DOUBLEBUFFER = 5
#AGL_DEPTH_SIZE = 12
#AGL_PIXEL_SIZE = 50
#GL_COLOR_BUFFER_BIT = $00004000
#GL_DEPTH_BUFFER_BIT = $00000100
#GL_MODELVIEW = $1700
#GL_PROJECTION = $1701
#GL_TRIANGLES = 4
Define RenderingContext.I
OpenWindow(0, 270, 100, 640, 480, "Cross-platform OpenGL demo", #PB_Window_SystemMenu | #PB_Window_Invisible)
SetWindowColor(0, 0)
CompilerSelect #PB_Compiler_OS
CompilerCase #PB_OS_Linux
ImportC "-lGL"
glBegin_(PrimitiveID.I) As "glBegin"
glClear_(BuffersToClear.I) As "glClear"
glColor3f_(Red.F, Green.F, Blue.F) As "glColor3f"
glEnd_() As "glEnd"
glLoadIdentity_() As "glLoadIdentity"
glMatrixMode_(Target.I) As "glMatrixMode"
glTranslatef_(x.F, y.F, z.F) As "glTranslatef"
glVertex3f_(x.F, y.F, z.F) As "glVertex3f"
glViewport_(x.I, y.I, Width.I, Height.I) As "glViewport"
glXChooseVisual(*Display, ScreenNumber.I, *AttributeArray)
glXCreateContext(*Display, *XVisualInfo, GLXContext.I, DirectGraphicsConnection.I)
glXDestroyContext(*Display, GLXContext.I)
glXMakeCurrent(*Display, GLXDrawable.I, GLXContext.I)
glXSwapBuffers(*Display, GLXDrawable.I)
EndImport
ImportC "-lGLU"
gluPerspective_(FieldOfViewAngle.D, AspectRatioWidthToHeight.D, DistanceFromViewerToNearPlane.D, DistanceFromViewerToFarPlane.D) As "gluPerspective"
EndImport
Define *Widget.GtkWidget
Define *Window
Define *X11Display
Define X11Window.I
Define *XVisualInfo
Dim Attributes.L(4)
Attributes(0) = #AGL_DEPTH_SIZE
Attributes(1) = 16
Attributes(2) = #AGL_DOUBLEBUFFER
Attributes(3) = #AGL_RGBA
Attributes(4) = 0
*X11Display = gdk_x11_get_default_xdisplay_()
Repeat
Delay(20)
Until IsWindow(0) <> 0
*Widget.GtkWidget = WindowID(0)
*Window = *Widget\Window
X11Window = gdk_x11_drawable_get_xid_(*Window)
If X11Window
*XVisualInfo = glXChooseVisual(*X11Display, 0, @Attributes())
If *XVisualInfo
RenderingContext = glXCreateContext(*X11Display, *XVisualInfo, 0, #False)
If RenderingContext
glXMakeCurrent(*X11Display, X11Window, RenderingContext)
EndIf
EndIf
EndIf
CompilerCase #PB_OS_MacOS
ImportC "/System/Library/Frameworks/AGL.framework/AGL"
aglChoosePixelFormat(*AGLDevice, DeviceCount.L, *AttributeArray)
aglCreateContext(PixelFormatObject.L, RenderingContext.L)
aglDestroyContext(AGLContext.L)
aglDestroyPixelFormat(PixelFormatObject.L)
aglSetCurrentContext(AGLContext.L)
aglSetWindowRef(AGLContext.L, WindowRef.L)
aglSwapBuffers(AGLContext.L)
EndImport
ImportC "/System/Library/Frameworks/OpenGL.framework/OpenGL"
glBegin_(PrimitiveID.I) As "_glBegin"
glClear_(BuffersToClear.I) As "_glClear"
glColor3f_(Red.F, Green.F, Blue.F) As "_glColor3f"
glEnd_() As "_glEnd"
glLoadIdentity_() As "_glLoadIdentity"
glMatrixMode_(Target.I) As "_glMatrixMode"
glTranslatef_(x.F, y.F, z.F) As "_glTranslatef"
gluPerspective_(FieldOfViewAngle.D, WidthToHeightRatio.D, DistanceToNearPlane.D, DistanceToFarPlane.D) As "_gluPerspective"
glVertex3f_(x.F, y.F, z.F) As "_glVertex3f"
glViewport_(x.I, y.I, Width.I, Height.I) As "_glViewport"
EndImport
Define PixelFormatObject.I
Dim Attributes.L(4)
Attributes(0) = #AGL_DEPTH_SIZE
Attributes(1) = 16
Attributes(2) = #AGL_DOUBLEBUFFER
Attributes(3) = #AGL_RGBA
Attributes(4) = 0
PixelFormatObject = aglChoosePixelFormat(0, 0, @Attributes())
If PixelFormatObject
RenderingContext = aglCreateContext(PixelFormatObject, 0)
If RenderingContext
aglSetWindowRef(RenderingContext, WindowID(0))
aglSetCurrentContext(RenderingContext)
EndIf
EndIf
CompilerCase #PB_OS_Windows
Define DeviceContext.I
Define PFD.PIXELFORMATDESCRIPTOR
Define PixelFormat.I
DeviceContext = GetDC_(WindowID(0))
PFD\nSize = SizeOf(PIXELFORMATDESCRIPTOR)
PFD\nVersion = 1
PFD\dwFlags = #PFD_SUPPORT_OPENGL | #PFD_DOUBLEBUFFER | #PFD_DRAW_TO_WINDOW
PFD\dwLayerMask = #PFD_MAIN_PLANE
PFD\iPixelType = #PFD_TYPE_RGBA
PFD\cColorBits = 24
PFD\cDepthBits = 16
PixelFormat = ChoosePixelFormat_(DeviceContext, PFD)
If PixelFormat
If SetPixelFormat_(DeviceContext, PixelFormat, PFD)
RenderingContext = wglCreateContext_(DeviceContext)
If RenderingContext
wglMakeCurrent_(DeviceContext, RenderingContext)
EndIf
EndIf
EndIf
CompilerEndSelect
If RenderingContext = 0
MessageRequester("Error", "Unable to obtain OpenGL context")
End
EndIf
HideWindow(0, #False)
Repeat
glViewport_(0, 0, WindowWidth(0), WindowHeight(0))
glMatrixMode_(#GL_PROJECTION)
glLoadIdentity_()
gluPerspective_(30.0, Abs(WindowWidth(0) / WindowHeight(0)), 0.1, 500.0)
glMatrixMode_(#GL_MODELVIEW)
glLoadIdentity_()
glClear_(#GL_COLOR_BUFFER_BIT | #GL_DEPTH_BUFFER_BIT)
glLoadIdentity_()
glTranslatef_(0.0, 0.0, -8.0)
glColor3f_(1.0, 1.0, 1.0)
glBegin_(#GL_TRIANGLES) ; Start drawing a triangle
glColor3f_ ( 1.0, 0.0, 0.0) ; Set top point of triangle to Red
glVertex3f_( 0.0, 1.0, 0.0) ; First point of the triangle
glColor3f_ ( 0.0, 1.0, 0.0) ; Set left point of triangle to Green
glVertex3f_(-1.0, -1.0, 0.0) ; Second point of the triangle
glColor3f_ ( 0.0, 0.0, 1.0) ; Set right point of triangle to Blue
glVertex3f_( 1.0, -1.0, 0.0) ; Third point of the triangle
glEnd_() ; Done drawing the triangle
; Swap buffers (double buffering)
CompilerSelect #PB_Compiler_OS
CompilerCase #PB_OS_Linux
glxSwapBuffers(*X11Display, X11Window)
CompilerCase #PB_OS_MacOS
aglSwapBuffers(RenderingContext)
CompilerCase #PB_OS_Windows
SwapBuffers_(DeviceContext)
CompilerEndSelect
Until WaitWindowEvent() = #PB_Event_CloseWindow
; ---- Delete rendering context
CompilerSelect #PB_Compiler_OS
CompilerCase #PB_OS_Linux
glXDestroyContext(*X11Display, RenderingContext)
CompilerCase #PB_OS_MacOS
aglDestroyPixelFormat(PixelFormatObject)
aglDestroyContext(RenderingContext)
CompilerCase #PB_OS_Windows
wglDeleteContext_(RenderingContext)
ReleaseDC_(WindowID(0), DeviceContext)
CompilerEndSelect
the subsystem OpenGL. Thank you for your hint, luis!
Update 2: I tested the code example even successfully in Windows 98 SE...

Update 3: For Linux I changed #True in the line
Code: Select all
RenderingContext = glXCreateContext(*X11Display, *XVisualInfo, 0, #True)
direct connection to the graphics system (#True) or through the X server
(#False). With this option changed to #False the code example even runs
without problems in OpenSuSE 12.1...

Update 4: I tested the code example successfully in Ubuntu 12.04 LTS and
MacOS X 10.7.4 (Lion)
Update 5: In order to run successfully on 64 bit Linux distributions the following
modification was necessary:
Code: Select all
Dim Attributes.I(4)
Code: Select all
Dim Attributes.L(4)
paths to libGL and libGLU like this:
Code: Select all
CompilerIf #UbuntuFamilyDistro_newer_than_11_04
#LibGLUPath = "/usr/lib/i386-linux-gnu/libGLU.so"
CompilerElse
#LibGLUPath = "/usr/lib/libGLU.so"
CompilerEndIf
Code: Select all
ImportC "-lGL"
Code: Select all
ImportC "-lGLU"

I have modified the above example accordingly.
At last I have tested the example successfully under several further 32 bit and 64 bit
Linux distributions.
Update 6: I tested the code example successfully on OS X 10.8.0 (Mountain Lion).