Orthographic vs Perspective Projection

Category: Graphics - OpenGL

Date: 03-28-2012

Return to Index


 
'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:
#Compiler PBWin 9, PBWin 10
#Compile EXE
#Dim All
#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


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