Date: 02-16-2022
Return to Index
created by gbSnippets
'Transformations (translate, rotate, scale) are cumulative. This can make it
'difficult to know where a primitive is being placed. For example, if you want
'an object at z=-4 and z=+4, then with simple translation you move -4 to place
'the first object and +8 to place the next object. After a dozen translations
'you can see that keeping the current position can be an inconvenience.
'the glPushMatrix and glPopMatrix solve the problem by capturing a scene state
'and restoring it on demands. In the discussion above, you would us glPushMatrix
'to save the state, move -4 to place the first object, use glPopMatrix to be back
'the original (untranslated) state, then move +4 to place the second object.
'Primary Code:
'This example follows the approach just discussed.
glPushMatrix 'save state
glTranslatef 0,0,-4 'move -4
glvertex3f 1,2,3 'draw 1st vertex
glPopMatrix 'restore un-moved state
glTranslatef 0,0,+4 'move +4
glvertex3f -2,-3,-7 'draw 2nd vertex
glCallList 1 'draw using same display list
'By using glPushMatrix and glPopMatrix, the user does not need to track
'cumulative translations (moves).
'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
Global hDlg, hDC, hRC As DWord
Global scalefactor As Single
Function PBMain() As Long
Dialog New Pixels, 0, "OpenGL Example",,, 320, 240,%WS_OverlappedWindow To hDlg
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 : GetRenderContext
InitializeScene
SetTimer(hDlg, %ID_Timer, 50, %NULL)
ScaleFactor = 1
Case %WM_Timer : DrawScene 1,2,0 'redraw with rotation
Case %WM_Paint : DrawScene 0,0,0 'redraw with no rotation
Case %WM_Size : ResizeScene Lo(Word, CB.lParam), Hi(Word, CB.lParam)
DrawScene 0,0,0 'redraw with no rotation
Case %WM_Close : wglmakecurrent %null, %null 'unselect rendering context
wgldeletecontext hRC 'delete the rendering context
releasedc hDlg, hDC 'release device context
Case %WM_MouseWheel
Select Case Hi(Integer,CB.wParam)
Case > 0 : ScaleFactor = ScaleFactor + 0.1 : DrawScene 0,0,0
Case < 0 : ScaleFactor = ScaleFactor - 0.1 : DrawScene 0,0,0
End Select
Case %WM_SetCursor
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
DrawScene -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 GetRenderContext
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
hDC = GetDC(hDlg) 'DC for dialog
SetPixelFormat(hDC, ChoosePixelFormat(hDC, pfd), pfd) 'set properties of device context
hRC = wglCreateContext (hDC) 'get rendering context
wglMakeCurrent hDC, hRC 'make the RC current
End Sub
Sub InitializeScene
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
BuildCubeDisplayList 1
End Sub
Sub ResizeScene (w As Long, h As Long)
glViewport 0, 0, w, h 'resize viewport to match window size
glMatrixMode %gl_projection 'select the projection matrix
glLoadIdentity 'reset the projection matrix
gluPerspective 45, w/h, 0.1, 100 'set frustum using viewport aspect ratio
glMatrixMode %gl_modelview 'select the modelview matrix
End Sub
Sub DrawScene (dx As Single, dy As Single, dz As Single)
Static anglex, angley, anglez As Single
glClear %gl_color_buffer_bit Or %gl_depth_buffer_bit 'clear buffers
glLoadIdentity 'clear the modelview matrix
gluLookAt 0,0,10,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
glPushMatrix 'with PushPop
glCallList 1
glPushMatrix
glTranslatef -3,0,0
glCallList 1
glPopMatrix
glTranslatef 3,0,0 'do not have to use accumulated translate value
glCallList 1
SwapBuffers hDC 'display the buffer (image)
End Sub
Sub BuildCubeDisplayList(iCube As Long)
glNewList iCube, %gl_compile
glBegin %GL_QUADS
glColor3f 0.0, 1.0, 0.0 ' Set the color to green
glVertex3f 1.0, 1.0, -1.0 ' Top right of the quad (Top)
glVertex3f -1.0, 1.0, -1.0 ' Top left of the quad (Top)
glVertex3f -1.0, 1.0, 1.0 ' Bottom left of the quad (Top)
glVertex3f 1.0, 1.0, 1.0 ' Bottom right of the quad (Top)
glColor3f 1.0, 0.5, 0.0 ' Set the color to orange
glVertex3f 1.0, -1.0, 1.0 ' Top right of the quad (Bottom)
glVertex3f -1.0, -1.0, 1.0 ' Top left of the quad (Bottom)
glVertex3f -1.0, -1.0, -1.0 ' Bottom left of the quad (Bottom)
glVertex3f 1.0, -1.0, -1.0 ' Bottom right of the quad (Bottom)
glColor3f 1.0, 0.0, 0.0 ' Set the color to red
glVertex3f 1.0, 1.0, 1.0 ' Top right of the quad (Front)
glVertex3f -1.0, 1.0, 1.0 ' Top left of the quad (Front)
glVertex3f -1.0, -1.0, 1.0 ' Bottom left of the quad (Front)
glVertex3f 1.0, -1.0, 1.0 ' Bottom right of the quad (Front)
glColor3f 1.0, 1.0, 0.0 ' Set the color to yellow
glVertex3f 1.0, -1.0, -1.0 ' Top right of the quad (Back)
glVertex3f -1.0, -1.0, -1.0 ' Top left of the quad (Back)
glVertex3f -1.0, 1.0, -1.0 ' Bottom left of the quad (Back)
glVertex3f 1.0, 1.0, -1.0 ' Bottom right of the quad (Back)
glColor3f 0.0, 0.0, 1.0 ' Set the color to blue
glVertex3f -1.0, 1.0, 1.0 ' Top right of the quad (Left)
glVertex3f -1.0, 1.0, -1.0 ' Top left of the quad (Left)
glVertex3f -1.0, -1.0, -1.0 ' Bottom left of the quad (Left)
glVertex3f -1.0, -1.0, 1.0 ' Bottom right of the quad (Left)
glColor3f 1.0, 0.0, 1.0 ' Set the color to violet
glVertex3f 1.0, 1.0, -1.0 ' Top right of the quad (Right)
glVertex3f 1.0, 1.0, 1.0 ' Top left of the quad (Right)
glVertex3f 1.0, -1.0, 1.0 ' Bottom left of the quad (Right)
glVertex3f 1.0, -1.0, -1.0 ' Bottom right of the quad (Right)
glEnd
glEndList
End Sub
'gbs_00601
'Date: 03-10-2012
http://www.garybeene.com/sw/gbsnippets.htm