'====================================================================
' OpenGL demo, modeless dialog as main.
' NeHe Lesson 4, adapted for OxygenBasic
' Comments from MichaelW and NeHe
'====================================================================

$ filename "OpenGl.exe"
'uses rtl32
'uses rtl64

'% review

uses dialogs

uses glWinUtil


declare sub DrawGLScene ()
declare sub ReSizeGLScene (GLsizei width, GLsizei height)

sys dlgHDC

function DialogProc( sys hDlg, uint uMsg, sys wParam, lParam ) as int callback

  select case uMsg

    case WM_INITDIALOG

      PIXELFORMATDESCRIPTOR pfd
      int pixelFormatIndex
      sys hglrc
      RECT rc

      dlgHDC = GetDC( hDlg )
      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 = 8
      pfd.cDepthBits = 16

      pixelFormatIndex = ChoosePixelFormat( dlgHDC, @pfd )

      if SetPixelFormat( dlgHDC, pixelFormatIndex, @pfd ) = 0 then
        MessageBox( hDlg, "SetPixelFormat failed", 0, 0 )
        DestroyWindow( hDlg )
      end if

      hglrc = wglCreateContext( dlgHDC )
      if hglrc = 0 then
        MessageBox( hDlg, "wglCreateContext failed", 0, 0 )
        DestroyWindow( hDlg )
      end if

      if wglMakeCurrent( dlgHDC, hglrc ) = 0 then
        MessageBox( hDlg, "wglMakeCurrent failed", 0, 0 )
        DestroyWindow( hDlg )
      end if

      GetClientRect( hDlg, @rc )

      glViewport 0, 0, rc.right, rc.bottom

      glMatrixMode GL_PROJECTION
      glLoadIdentity
      gluPerspective 45.0, rc.right/rc.bottom, 0.1, 100.0
      glMatrixMode GL_MODELVIEW
      glLoadIdentity

      glShadeModel GL_SMOOTH
      glClearColor 0.0, 0.0, 0.0, 1.0
      glClearDepth 1.0
      glEnable GL_DEPTH_TEST
      glDepthFunc GL_LEQUAL
      glHint GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST

    case WM_COMMAND

      if loword(wParam) = IDCANCEL then
        DestroyWindow( hDlg )
      end if

    case WM_SIZE                   ' Resize The OpenGL Window    
      ReSizeGLScene(loword(lParam),hiword(lParam))  ' LoWord=Width, HiWord=Height
      return 0                     ' Jump Back

    case WM_CLOSE
      DestroyWindow( hDlg )

    case WM_DESTROY
      PostQuitMessage( null )

  end select

  return 0

end function

'====================================================================

sys hDlg
MSG wMsg

GLfloat	rtri				' Angle For The Triangle ( NEW )
GLfloat	rquad				' Angle For The Quad ( NEW )

Dialog( 0, 0, 160, 120, "NeHe's Rotation Tutorial in a Dialog",
        WS_OVERLAPPEDWINDOW  or WS_VISIBLE or DS_CENTER )

hDlg = CreateModelessDialog( 0, @DialogProc, 0 )

' This special message loop is useful when some action needs to
' be repeated at a very high rate. Where the minimum effective
' period for a normal timer is about 10ms, the effective period
' for this message loop running on the typical system is well
' under one microsecond. PM_REMOVE indicates that we want the
' messages removed from the message queue as we process them.
'
do
  if PeekMessage( @wMsg, null, 0, 0, PM_REMOVE ) <> 0 then

    ' PeekMessage returned non-zero, indicating that a
    ' message is available. If the message was WM_QUIT,
    ' then it's time to exit.
    '
    if wMsg.message = WM_QUIT then exit do

    if IsDialogMessage( hDlg,  @wMsg ) = 0 then
      TranslateMessage( @wMsg )
      DispatchMessage( @wMsg )
    end if

  else

    DrawGLScene
    SwapBuffers( dlgHDC )

  end if

end do

'====================================================================

sub DrawGLScene ()                                   ' Here's Where We Do All The Drawing
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) ' Clear Screen And Depth Buffer
  glLoadIdentity()                                   ' Reset The Current Modelview Matrix

  glTranslatef(-1.5f,0.0f,-6.0f)                     ' Move Left 1.5 Units And Into The Screen 6.0
  glRotatef(rtri,0.0f,1.0f,0.0f)                     ' Rotate The Triangle On The Y axis ( NEW )
  glBegin(GL_TRIANGLES)                              ' Start Drawing A Triangle
      glColor3f(1.0f,0.0f,0.0f)                      ' Set Top Point Of Triangle To Red
      glVertex3f( 0.0f, 1.0f, 0.0f)                  ' First Point Of The Triangle
      glColor3f(0.0f,1.0f,0.0f)                      ' Set Left Point Of Triangle To Green
      glVertex3f(-1.0f,-1.0f, 0.0f)                  ' Second Point Of The Triangle
      glColor3f(0.0f,0.0f,1.0f)                      ' Set Right Point Of Triangle To Blue
      glVertex3f( 1.0f,-1.0f, 0.0f)                  ' Third Point Of The Triangle
  glEnd()                                            ' Done Drawing The Triangle
  glLoadIdentity()                                   ' Reset The Current Modelview Matrix
  glTranslatef(1.5f,0.0f,-6.0f)                      ' Move Right 1.5 Units And Into The Screen 6.0
  glRotatef(rquad,1.0f,0.0f,0.0f)                    ' Rotate The Quad On The X axis ( NEW )
  glColor3f(0.5f,0.5f,1.0f)                          ' Set The Color To Blue One Time Only
  glBegin(GL_QUADS)                                  ' Draw A Quad
      glVertex3f(-1.0f, 1.0f, 0.0f)                  ' Top Left
      glVertex3f( 1.0f, 1.0f, 0.0f)                  ' Top Right
      glVertex3f( 1.0f,-1.0f, 0.0f)                  ' Bottom Right
      glVertex3f(-1.0f,-1.0f, 0.0f)                  ' Bottom Left
  glEnd()      
                                                     ' Done Drawing The Quad
  rtri+=0.5f                                         ' Increase The Rotation Variable For The Triangle ( NEW )
  rquad-=0.4f                                       ' Decrease The Rotation Variable For The Quad ( NEW )

end sub

sub ReSizeGLScene (GLsizei width, GLsizei height)    ' Resize And Initialize The GL Window
  if height=0 then              ' Prevent A Divide By Zero By
    height=1                    ' Making Height Equal One
  end if

  glViewport(0,0,width,height)  ' Reset The Current Viewport

  glMatrixMode(GL_PROJECTION)   ' Select The Projection Matrix
  glLoadIdentity()              ' Reset The Projection Matrix

  ' Calculate The Aspect Ratio Of The Window
  gluPerspective(45.0f, width/ height,0.1f,100.0f)

  glMatrixMode(GL_MODELVIEW)        ' Select The Modelview Matrix
  glLoadIdentity()                  ' Reset The Modelview Matrix
end sub
