$TYPECHECK ON
$include <WINDOWS.Inc>
$include <RapidQ2.inc>
$include <gl.inc>
$include <glwgl.inc>
$include <glu.inc>



DECLARE SUB ChangeToFullScreen()
DECLARE SUB Display()
DECLARE SUB Init()
DECLARE SUB SetLighting(LightType AS DWORD, x AS SINGLE, y AS SINGLE, z AS SINGLE, a AS SINGLE)
DECLARE SUB SizeglScreen(width AS INTEGER, height AS INTEGER)      '// Init GL Window size, also use to adjusts the viewport onResize
DECLARE SUB TimerOver
DECLARE SUB glInit(bpp As BYTE, zbuffer As BYTE, stencil As BYTE, hDC As LONG)
DECLARE SUB glQuit()


CONST Null	AS STRING = ""

DIM hDC 			AS LONG			'the windows handle to device context (DC)
DIM	glhDC			AS LONG			'my open GL handle to the DC

DIM InitItDone		as integer: InitItDone = 0
DIM fps 			as Integer
DIM FrameTime 		as Integer
DIM Frames 			as Integer
DIM rot_y 			as integer
DIM rot_Speed		as integer: rot_Speed = 3
DIM glFullScreen	as integer
DIM glTimer 		as QDXTimer


CREATE MainForm 	AS QFORM
	Caption = "OpenGL Demo"
	Width = 640
	Height = 480
	BorderStyle = bsSizeable'bsSingle
	Center
END CREATE



'initalize the interface to windows, bits/pix , windows DC handle
SUB glInit(bpp As BYTE, zbuffer As BYTE, stencil As BYTE, hDC As LONG)
    DIM pf 			AS PIXELFORMATDESCRIPTOR
	DIM Hresult		AS LONG

    pf.nSize = Len(pf)
    pf.nVersion = 1							'should always be 1 ??
    pf.dwFlags = PFD_DRAW_TO_WINDOW OR PFD_SUPPORT_OPENGL Or PFD_DOUBLEBUFFER OR PFD_GENERIC_ACCELERATED OR PFD_STEREO 'last two may not be supported-	
    pf.iPixelType = PFD_TYPE_RGBA			'32 bit or use PFD_TYPE_COLORINDEX for palette based
    pf.cColorBits = bpp						'8,16,24, 32
    pf.cDepthBits = zbuffer					'same for z-buffer
    pf.cStencilBits = stencil				'depth of the stencil buffer which does pen styles

    Hresult = ChoosePixelFormat(hDC, pf)
    IF Hresult = 0 THEN ShowMessage "ChoosePixelFormat failed":	Exit SUB
		'now let open GL know the pixel format for the render window
    IF SetPixelFormat(hDC, Hresult, pf) = 0 THEN ShowMessage "SetPixelFormat Failed": EXIT SUB
    glhDC = wglCreateContext(hDC)			'let open gl know which window device context
    wglMakeCurrent hDC, glhDC				'set up a GDI handle to the screen for openGL
	INC InitItDone
END SUB



'**************************************************************************
' Set the width and height of the OpenGL screen, and set its viewport
'**************************************************************************

SUB SizeglScreen(width AS INTEGER, height AS INTEGER)      '// Init GL Window size, also use to adjusts the viewport onResize
        IF (height=0) THEN height=1                        '// Prevent A Divide By Zero error
        glViewport(0,0,width,height)                '// whole window the viewport but could make the view smaller inside
                                                                                '// The glViewport takes (x, y, width, height) -- our drawing boundries
        glMatrixMode(GL_PROJECTION)                        '// GL_ORTHO = all objects are same size try (GL_PROJECTION) for distant = smaller
        glLoadIdentity                                                '// Reset The Projection Matrix

'// *********   Calculate The Aspect Ratio Of The Window  ****************
'//  The parameters are (view angle, aspect ration of the width to the height,closest camera distance before clipping
'                  // FOV deg in y-direction /Aspect Ratio =FOV in x-direction/ dist to Near clipping plane/ dist to far clipping Plane
'        gluPerspective(45.0, (width/height), 0.5 , 20.0)                                        '//sets up a perspective projection matrix.
END SUB




'**************************************************************************
'   Properly exit from the program and release device context (DC)
'**************************************************************************

SUB glQuit()
        IF glFullScreen THEN ChangeDisplaySettings(Null,0)
        IF glhDC THEN wglMakeCurrent 0, 0: wglDeleteContext glhDC
        IF hDC THEN ReleaseDC(MainForm.Handle, hDC)
END SUB



Public Sub glFlip()
    SwapBuffers hDC
End Sub





'**************************************************************************
'   OpenGL lighting, tons of room to play here
'**************************************************************************

SUB SetLighting(LightType AS DWORD, x AS SINGLE, y AS SINGLE, z AS SINGLE, a AS SINGLE)
        DIM params(3)                AS SINGLE
        '// LightType = GL_AMBIENT, GL_SPECULAR, GL_POSITION, GL_SPOT_DIRECTION, etc
        '// turn on lighting
        glEnable GL_LIGHTING:        glEnable GL_LIGHT0                '//light numbers from 0 to 7
        params(0) = x: params(1) =  y: params(2) = z :params(3) = a         '// light RGBA intensities range from -1.0 to 1.0
                                                                                                                                        '//, integers converted
        glLightfv GL_LIGHT0, LightType, VARPTR(params(0))
END SUB





SUB TimerOver
  IF InitItDone < 2 THEN Init()				'need to re-CALL this initialization for it to run, why???
	Display()
	FrameTime = glTimer.framerate
	MainForm.Caption = "OpenGL Demo -- Frame rate = "+ STR$(FrameTime)
End SUB

SUB FormResize
	SizeglScreen(MainForm.Width, MainForm.Height)
	MainForm.Caption = "(" + STR$(MainForm.Width) + " x " + STR$(MainForm.Height) + ")"
END SUB


SUB Init()
	hDC = GetDC(MainForm.Handle)
	glInit(24, 8, 0, hDC)		'bits/pix, z-buffer bits, stencil bits, form DC
	glEnable(GL_TEXTURE_2D)
	'glDisable(GL_DEPTH_TEST)
	glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE)
	glShadeModel(GL_SMOOTH)				'	// Set the shading model

	glMatrixMode(GL_PROJECTION)
	glLoadIdentity						'// Set the modelview matrix to be the identity matrix
	LoadTexture("gl.tga")     
'	SizeglScreen(60,60)				'set viewport
	glTimer.Enabled = 1
End Sub




SUB Display()

	glClear(GL_COLOR_BUFFER_BIT OR GL_DEPTH_BUFFER_BIT)	'clear the RGB and depth back buffer
	glPushMatrix						'store matrix of rotation, scaling, translation
	glTranslatef(0.0,0.0,0.0)			'DEFAULT center of view is at x,y,z = 0,0,0
	glRotatef(rot_y, 0.5, 1.0, 0.0)		'rotate the plane

  ' ----------------------------------------------------------------------
  glBegin GL_QUADS
    ' ----------------+ vertex code from hot basic example +------------------
    '  cube model has 6 faces with 12 points joined at the same place. 
    ' each face of the cube plotted using 4 points boundry (quad base) similar like
    ' you draw a retangle or square shape over a drawing paper. in this demo, I
    ' draw each quad is half size (0.5) of GL viewer(viewport) which is form
    ' client area size.
    '
    ' next, we color half of each faces with a unique color which is would
    ' produce blending color effect when they meet together. to examine it,
    ' try change value of glColor3f below. color parameter is (Red,Green,Blue).
    '--------------------------------------------------------------------------
    ' 1st Face
    glColor3f 1.0,1.0,0.0: glVertex3f  0.5, 0.5, 0.5: glVertex3f -0.5, 0.5, 0.5
    glColor3f 0.0,0.0,1.0: glVertex3f -0.5,-0.5, 0.5: glVertex3f  0.5,-0.5, 0.5
    ' 2nd Face

    glColor3f 0.0,1.0,0.0: glVertex3f -0.5,-0.5,-0.5: glVertex3f -0.5, 0.5,-0.5
    glColor3f 0.5,0.0,1.0: glVertex3f  0.5, 0.5,-0.5: glVertex3f  0.5,-0.5,-0.5
    ' 3rd Face

    glColor3f 1.0,0.0,1.0: glVertex3f  0.5, 0.5, 0.5: glVertex3f  0.5, 0.5,-0.5
    glColor3f 0.0,0.0,1.0: glVertex3f -0.5, 0.5,-0.5: glVertex3f -0.5, 0.5, 0.5
    ' 4th Face

    glColor3f 0.0,1.0,1.0: glVertex3f -0.5,-0.5,-0.5: glVertex3f  0.5,-0.5,-0.5
    glColor3f 0.0,0.0,1.0: glVertex3f  0.5,-0.5, 0.5: glVertex3f -0.5,-0.5, 0.5
    ' 5th Face

    glColor3f 1.0,0.0,0.0: glVertex3f  0.5, 0.5, 0.5: glVertex3f  0.5,-0.5, 0.5
    glColor3f 1.0,0.0,1.0: glVertex3f  0.5,-0.5,-0.5: glVertex3f  0.5, 0.5,-0.5
    ' 6th Face

    glColor3f 1.0,0.0,0.0: glVertex3f -0.5,-0.5,-0.5: glVertex3f -0.5,-0.5, 0.5
    glColor3f 1.0,1.0,0.0: glVertex3f -0.5, 0.5, 0.5: glVertex3f -0.5, 0.5,-0.5
	glEnd

	glPopMatrix										'if you push the matrix then pop it
'	glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)        '// Render the triangles in wire frame mode
	INC (rot_y, rot_Speed)
	glFlip()                                         'bring back buffer to screen
END SUB





'**************************************************************************
'   Set graphics mode to full screen, can't use QDXSCREEN because we need a DC (device context) 
'**************************************************************************

SUB ChangeToFullScreen()
        DIM hRESULT AS LONG
        DIM dmSettings AS DEVMODE                                                         '// Device Mode variable in WIN32AP.INC

        memset(dmSettings,0,sizeof(dmSettings))                                '// Makes Sure Memory's Cleared
        '// Get current settings -- makes sure NT and Win98 machines change correctly
        hRESULT = EnumDisplaySettings(Null, ENUM_CURRENT_SETTINGS, dmSettings)                ' Null for current display(or \DisplayX), caches the current settings if 0
        IF hRESULT = DISP_CHANGE_FAILED THEN
                ShowMessage "Enum Display Settings failed, program will run in window mode"
                glFullScreen = False
                EXIT SUB
        END IF

        dmSettings.dmSize = sizeof(dmSettings)                                '//must initalize size
        dmSettings.dmPelsWidth		= SCREEN.WIDTH                                '// Selected Screen Width
        dmSettings.dmPelsHeight		= SCREEN.HEIGHT                                '// Selected Screen Height
        dmSettings.dmFields			= DM_PELSWIDTH OR DM_PELSHEIGHT' OR DM_BITSPERPEL

        '// CDS_FULLSCREEN - flag will also gets Rid Of Start Bar.-- always check if function failed
        hRESULT = ChangeDisplaySettings(dmSettings, CDS_FULLSCREEN)
        IF(hRESULT<> DISP_CHANGE_SUCCESSFUL) THEN ShowMessage "Display Mode Not Compatible with Fullscreen"
END SUB



glTimer.Interval = 1
glTimer.Enabled = 0
glTimer.OnTimer = TimerOver 

MainForm.OnShow = Init			'these must be last lines
MainForm.OnResize = FormResize
MainForm.ShowModal
