Date: 02-16-2022
Return to Index
created by gbSnippets
'OpenGL has functions for setting the type of projection (i.e., type of viewing
'volume) used to convert the 3D images to a 2D screen.
' - glOrthographic - rectangular volume (parallelepiped)
' - gluPerspective - symmetrical frustum
' - glFrustum - non-symmetrical frustum
'Both glPerspective and glFrustum are considered "perspective" types of projection.
'Setting the projection method is done during initilization of the rendering
'context. In this case, the code if found in the Sub Resize procedure which
'is re-initializes the rendering context each time the dialog size is changed.
'Compiler Comments:
'This code was written to compilete in PBWin10. To compile with PBWin9, split pt
'into pt.x and pt.y as arguments wherever the ChildWindowFromPoint() API is used (4 places).
'Primary Code:
'Two viewports are provided in this snippet (two label controsl). On the left, the
'glOrtho command is used to set the projection method and in on the right the
'glPerspective command is used.
'Orthographic (sometimes called parallel) viewing. It sets the viewing volume
'to a rectangular volume (box). Perspective viewing results in distance objects
'appearing smaller to the eye.
'Parallel viewing is typical of CAD drawings, where the dimensions of objects
'in the 3D scene must be preserved when projected to the 2D screen.
glMatrixMode %gl_projection 'select the projection matrix
glLoadIdentity 'reset the projection matrix
glOrtho -5,5,5,-5,0.1,50 'set orthographic viewing volume
'Notice that when rotating the left viewport, the base/top of the cube appear
'not to be the same size (perspective viewing), whereas on the right viewport they
'do appear to be the same size (parallel viewing).
'Compilable Example: (Jose Includes)
#Compiler PBWin 9, PBWin 10
#Compile EXE
#Dim All
%Unicode=1
#Include "win32api.inc"
#Include "gl.inc"
#Include "glu.inc"
%ID_Timer = 1000 : %ID_LabelA = 1002 : %ID_LabelB = 1003
Global hDlg, hDCA, hDCB, hDCX, hRCA, hRCB, hLabelA, hLabelB As DWord
Global anglex, angley, anglez, scalefactor As Single
Function PBMain() As Long
Dialog New Pixels, 0, "OpenGL Example",,, 320, 240,%WS_OverlappedWindow To hDlg
Control Add Label, hdlg, %ID_LabelA,"",10,10,100,100, %WS_Child Or %WS_Visible Or %SS_Sunken Or %SS_Notify
Control Add Label, hdlg, %ID_LabelB,"",10,10,100,100, %WS_Child Or %WS_Visible Or %SS_Sunken Or %SS_Notify
Dialog Show Modal hdlg Call dlgproc
End Function
CallBack Function dlgproc()
Local pt As Point
Local XDelta, YDelta as Single
Static SpinInWork,XLast,YLast As Long
Select Case CB.Msg
Case %WM_InitDialog : GetRenderContextA : GetRenderContextB
InitializeSceneA : InitializeSceneB
SetTimer(hDlg, %ID_Timer, 50, %NULL)
ScaleFactor = 1
Case %WM_Timer : DrawSceneA 1,1,0 : DrawSceneB 1,1,1 'redraw with rotation on all 3 axes
Case %WM_Paint : DrawSceneA 0,0,0 : DrawSceneB 0,0,0 'redraw with no rotation
Case %WM_Size : Control Set Size hDlg, %ID_LabelA, Lo(Word, CB.lParam)/2-15, Hi(Word, CB.lParam)-20
Control Set Size hDlg, %ID_LabelB, Lo(Word, CB.lParam)/2-15, Hi(Word, CB.lParam)-20
Control Set Loc hDlg, %ID_LabelB, Lo(Word, CB.lParam)/2+5, 10
ResizeSceneA Lo(Word, CB.lParam)/2-15, Hi(Word, CB.lParam)-20
ResizeSceneB Lo(Word, CB.lParam)/2-15, Hi(Word, CB.lParam)-20
DrawSceneA 0,0,0 'redraw with no rotation
DrawSceneB 0,0,0 'redraw with no rotation
Case %WM_Close : wglmakecurrent %null, %null 'unselect rendering context
wgldeletecontext hRCA 'delete the rendering context
releasedc hDlg, hDCA 'release device context
wgldeletecontext hRCB 'delete the rendering context
releasedc hDlg, hDCB 'release device context
Case %WM_MouseWheel
Select Case Hi(Integer,CB.wParam)
Case > 0 : ScaleFactor = ScaleFactor + 0.1 : DrawSceneA 0,0,0 : DrawSceneB 0,0,0
Case < 0 : ScaleFactor = ScaleFactor - 0.1 : DrawSceneA 0,0,0 : DrawSceneB 0,0,0
End Select
Case %WM_SetCursor
GetCursorPos pt 'p.x and p.y are in screen coordinates
ScreenToClient hDlg, pt 'p.x and p.y are now dialog client coordinates
If (GetDlgCtrlID(ChildWindowFromPoint( hDlg, pt )) <> %ID_LabelA) AND _
(GetDlgCtrlID(ChildWindowFromPoint( hDlg, pt )) <> %ID_LabelB) Then Exit Function
If GetDlgCtrlID(ChildWindowFromPoint( hDlg, pt )) = %ID_LabelA Then hDCX = hDCA
If GetDlgCtrlID(ChildWindowFromPoint( hDlg, pt )) = %ID_LabelA Then hDCX = hDCB
Select Case Hi(Word, CB.lParam)
Case %WM_LButtonDown
GetCursorPos pt 'pt has xy screen coordinates
ScreenToClient hDlg, pt 'pt now has dialog client coordinates
If pt.y < 0 Then Exit Select
KillTimer CB.Hndl, %ID_Timer
SpinInWork = 1
XLast = Pt.x
YLast = Pt.y
Case %WM_MouseMove
If SpinInWork Then
GetCursorPos pt 'pt has xy screen coordinates
ScreenToClient hDlg, pt 'pt now has dialog client coordinates
If pt.y < 0 Then Exit Select
XDelta = XLast - Pt.x
YDelta = YLast - Pt.y
DrawSceneA -YDelta, -XDelta, 0
DrawSceneB -YDelta, -XDelta, 0
XLast = pt.x
YLast = pt.y
End If
Case %WM_LButtonUp
SetTimer(hDlg, %ID_Timer, 50, %NULL)
SpinInWork = 0
End Select
End Select
End Function
Sub GetRenderContextA
Local pfd As PIXELFORMATDESCRIPTOR 'pixel format properties for device context
pfd.nSize = SizeOf(PIXELFORMATDESCRIPTOR)
pfd.nVersion = 1
pfd.dwFlags = %pfd_draw_to_window Or %pfd_support_opengl Or %pfd_doublebuffer
pfd.dwlayermask = %pfd_main_plane
pfd.iPixelType = %pfd_type_rgba
pfd.ccolorbits = 24
pfd.cdepthbits = 24
Control Handle hdlg, %ID_LabelA To hLabelA
hDCA = GetDC(hLabelA)
SetPixelFormat(hDCA, ChoosePixelFormat(hDCA, pfd), pfd) 'set properties of device context
hRCA = wglCreateContext (hDCA) 'get rendering context
End Sub
Sub GetRenderContextB
Local pfd As PIXELFORMATDESCRIPTOR 'pixel format properties for device context
pfd.nSize = SizeOf(PIXELFORMATDESCRIPTOR)
pfd.nVersion = 1
pfd.dwFlags = %pfd_draw_to_window Or %pfd_support_opengl Or %pfd_doublebuffer
pfd.dwlayermask = %pfd_main_plane
pfd.iPixelType = %pfd_type_rgba
pfd.ccolorbits = 24
pfd.cdepthbits = 24
Control Handle hdlg, %ID_LabelB To hLabelB
hDCB = GetDC(hLabelB)
SetPixelFormat(hDCB, ChoosePixelFormat(hDCA, pfd), pfd) 'set properties of device context
hRCB = wglCreateContext (hDCB) 'get rendering context
End Sub
Sub InitializeSceneA
wglMakeCurrent hDCA, hRCA 'make the RC current
glClearColor 0,0,0,0 'sets color to be used with glClear
glClearDepth 1 'sets zvalue to be used with glClear
glEnable %gl_depth_test 'enable depth testing
glHint %gl_perspective_correction_hint, %gl_nicest 'best quality rendering
BuildDisplayList 1
End Sub
Sub InitializeSceneB
wglMakeCurrent hDCB, hRCB 'make the RC current
glClearColor 0,0,0,0 'sets color to be used with glClear
glClearDepth 1 'sets zvalue to be used with glClear
glEnable %gl_depth_test 'enable depth testing
glHint %gl_perspective_correction_hint, %gl_nicest 'best quality rendering
BuildDisplayList 1
End Sub
Sub ResizeSceneA (w As Long, h As Long)
wglMakeCurrent hDCA, hRCA 'make the RC current
glViewport 0, 0, w, h 'resize viewport to match window size
glMatrixMode %gl_projection 'select the projection matrix
glLoadIdentity 'reset the projection matrix
gluPerspective 25, w/h, 0.1, 100 'set frustum using viewport aspect ratio
glMatrixMode %gl_modelview 'select the modelview matrix
End Sub
Sub ResizeSceneB (w As Long, h As Long)
wglMakeCurrent hDCB, hRCB 'make the RC current
glViewport 0, 0, w, h 'resize viewport to match window size
glMatrixMode %gl_projection 'select the projection matrix
glLoadIdentity 'reset the projection matrix
glOrtho -1.2,1.2,-1.2,1.2,0.1,50 'set orthographic viewing volume
'gluPerspective 45, w/h, 0.1, 100 'set frustum using viewport aspect ratio
glMatrixMode %gl_modelview 'select the modelview matrix
End Sub
Sub DrawSceneA (dx As Single, dy As Single, dz As Single)
wglMakeCurrent hDCA, hRCA 'make the RC current
glClear %gl_color_buffer_bit Or %gl_depth_buffer_bit 'clear buffers
glLoadIdentity 'clear the modelview matrix
gluLookAt 0,0,6,0,0,0,0,1,0
glScalef scalefactor, scalefactor, scalefactor
anglex = anglex + dx : glRotatef anglex, 1,0,0
angley = angley + dy : glRotatef angley, 0,1,0
anglez = anglez + dz : glRotatef anglez, 0,0,1
glCallList 1
SwapBuffers hDCA 'display the buffer (image)
End Sub
Sub DrawSceneB (dx As Single, dy As Single, dz As Single)
wglMakeCurrent hDCB, hRCB 'make the RC current
glClear %gl_color_buffer_bit Or %gl_depth_buffer_bit 'clear buffers
glLoadIdentity 'clear the modelview matrix
gluLookAt 0,0,6,0,0,0,0,1,0
glScalef scalefactor, scalefactor, scalefactor
glRotatef anglex, 1,0,0
glRotatef angley, 0,1,0
glRotatef anglez, 0,0,1
glCallList 1
SwapBuffers hDCB 'display the buffer (image)
End Sub
Sub BuildDisplayList (ListNumber As Long)
glNewList ListNumber, %gl_compile
glBegin %gl_line_loop
glVertex3f -0.5, -0.5, -0.5 '1234
glVertex3f -0.5, 0.5, -0.5
glVertex3f 0.5, 0.5, -0.5
glVertex3f 0.5, -0.5, -0.5
glEnd
glBegin %gl_line_loop
glVertex3f -0.5, -0.5, 0.5 '5678
glVertex3f -0.5, 0.5, 0.5
glVertex3f 0.5, 0.5, 0.5
glVertex3f 0.5, -0.5, 0.5
glEnd
glBegin %gl_lines
glVertex3f -0.5, -0.5, -0.5 '15
glVertex3f -0.5, -0.5, 0.5
glVertex3f -0.5, 0.5, -0.5 '26
glVertex3f -0.5, 0.5, 0.5
glVertex3f 0.5, 0.5, -0.5 '37
glVertex3f 0.5, 0.5, 0.5
glVertex3f 0.5, -0.5, -0.5 '48
glVertex3f 0.5, -0.5, 0.5
glEnd
glEndList
End Sub
'gbs_00602
'Date: 03-10-2012
http://www.garybeene.com/sw/gbsnippets.htm