Display List III (Many Cubes)

Category: Graphics - OpenGL

Date: 03-28-2012

Return to Index


 
'This example displays 20 rotating cubes, each drawn using a single
'display list.  The cubes also spin in place.
 
'OpenGL provides a "display list" as a means of storing a sequence of drawing
'commands, Once the list of commands is saved, it can be called with a single
'statement.  Also, the list can be used over and over again in the OpenGL application.
 
'Primary Code:
'First, the glNewList/glEndList commands are used to create the list.
'Between the two commands glNewList and glEndList, place drawing commands.
'Note that the display list is assigned a simple integer identifier.
 
'Then, where glBegin/glEnd would have gone in the DrawScene procedure, use the
'glCallList function to call the display list by its numberical identifier.
 
Sub BuildDisplayList(ListNumber As Long)
   glNewList iNumber, %gl_compile
      glBegin %GL_QUADS
         glColor3f   0.0,  1.0,  0.0
         glVertex3f  1.0,  1.0, -1.0
         glVertex3f -1.0,  1.0, -1.0
         glVertex3f -1.0,  1.0,  1.0
         glVertex3f  1.0,  1.0,  1.0
      glEnd
   glEndList
End Sub
 
Sub DrawScene (dx As Single, dy As Single, dz As Single)
   ... usual..commands...
   glCallList 1           'call the display list
   glTranslatef 2,0,0     'move to a new location
   glCallList 1           'call the display list a 2nd time
 
   SwapBuffers hDC        'display the buffer (image)
End Sub
 
'Compilable Example:
#Compiler PBWin 9, PBWin 10
#Compile EXE
#Dim All
#Include "win32api.inc"
#Include "gl.inc"
#Include "glu.inc"
 
Type BlockCenter
   x as Long
   y as Long
   z as Long
   ang as Single   'absolute angle
   rate as Single  'incremental spin rate
End Type
 
   %ID_Timer = 1000
 
   Global hDlg, hDC, hRC As DWord
   Global scalefactor As Single
   Global Cubes() As BlockCenter
 
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
   BuildDisplayList 1
   BuildBlocks
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
   Local i As Long
 
   glClear %gl_color_buffer_bit Or %gl_depth_buffer_bit  'clear buffers
   glLoadIdentity               'clear the modelview matrix
 
   gluLookAt 0,0,70,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
 
   For i = 1 to UBound(Cubes)
      glPushMatrix
      Cubes(i).ang = Cubes(i).ang + Cubes(i).rate
      glTranslatef Cubes(i).x, Cubes(i).y, Cubes(i).z
      glRotatef Cubes(i).ang, 1,1,1
      glCallList 1
      glPopMatrix
   Next
 
   SwapBuffers hDC              'display the buffer (image)
End Sub
 
Sub BuildBlocks
   Local i as Long
   ReDim Cubes(20)
   Randomize Timer
   For i = 1 to UBound(Cubes)
      Cubes(i).x = Rnd(-20,20)
      Cubes(i).y = Rnd(-20,20)
      Cubes(i).z = Rnd(-20,20)
      Cubes(i).ang = Rnd(0,360)
      Cubes(i).rate = Rnd(-15,15)
   Next i
End Sub
 
Sub BuildDisplayList(ListNumber As Long)
   glNewList ListNumber, %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_00595
'Date: 03-10-2012


created by gbSnippets
http://www.garybeene.com/sw/gbsnippets.htm