'//+--------------------------------------------------------------------------+
'//|                                                                          |
'//|                                 Sydney                                   |
'//|                              Version 1.00                                |
'//|                                                                          |
'//|      OpenGL project using the GDImage flat API to create on the fly      |
'//|             MD2 object with smooth shading and ambient light.            |
'//|                                                                          |
'//|          The GDImage.dll unregistered version has no limitation,         |
'//|             and all features of the API are fully functional.            |
'//|                                                                          |
'//|       Buying a commercial license removes the copyright nag screen.      |
'//|                                                                          |
'//+--------------------------------------------------------------------------+
'//|                                                                          |
'//|                         Author Patrice TERRIER                           |
'//|                           copyright (c) 2010                             |
'//|                                                                          |
'//|                        pterrier@zapsolution.com                          |
'//|                                                                          |
'//|                          www.zapsolution.com                             |
'//|                                                                          |
'//+--------------------------------------------------------------------------+
'//|                  Project started on : 08-16-2010 (MM-DD-YYYY)            |
'//|                        Last revised : 08-17-2010 (MM-DD-YYYY)            |
'//+--------------------------------------------------------------------------+

#COMPILE EXE "Sydney.exe"

%WINAPI                                         = 1
%FW_BOLD                                        = 700
%TRUE                                           = 1
%FALSE                                          = 0
%NULL                                           = 0
%ERROR_ALREADY_EXISTS                           = 183
%ANSI_VAR_FONT                                  = 12
%SW_RESTORE                                     = 9
%VK_PGUP                                        = &H21
%VK_PGDN                                        = &H22
%VK_LEFT                                        = &H25
%VK_UP                                          = &H26
%VK_RIGHT                                       = &H27
%VK_DOWN                                        = &H28
%GWL_WNDPROC                                    = -4
%GCL_HCURSOR                                    = -12
%WM_DESTROY                                     = &H2
%WM_SIZE                                        = &H5
%WM_ACTIVATE                                    = &H6
%WM_PAINT                                       = &HF
%WM_QUIT                                        = &H12
%WM_SETFONT                                     = &H30
%WM_KEYDOWN                                     = &H100
%WM_COMMAND                                     = &H111
%WM_MOUSEMOVE                                   = &H200
%WM_LBUTTONDOWN                                 = &H201
%WM_LBUTTONUP                                   = &H202
%WM_RBUTTONDOWN                                 = &H204
%WM_RBUTTONUP                                   = &H205
%WS_OVERLAPPED                                  = &H0
%WS_CHILD                                       = &H40000000
%WS_VISIBLE                                     = &H10000000
%WS_CLIPSIBLINGS                                = &H04000000
%WS_CLIPCHILDREN                                = &H02000000
%WS_CAPTION                                     = &H00C00000  ' WS_BORDER OR WS_DLGFRAME
%WS_SYSMENU                                     = &H00080000
%WS_THICKFRAME                                  = &H00040000
%WS_TABSTOP                                     = &H00010000
%WS_MINIMIZEBOX                                 = &H00020000
%WS_MAXIMIZEBOX                                 = &H00010000
%WS_OVERLAPPEDWINDOW                            = %WS_OVERLAPPED OR %WS_CAPTION OR %WS_SYSMENU OR %WS_THICKFRAME OR %WS_MINIMIZEBOX OR %WS_MAXIMIZEBOX
%WS_EX_WINDOWEDGE                               = &H00000100
%WS_EX_STATICEDGE                               = &H00020000
%WS_EX_APPWINDOW                                = &H00040000
%CS_VREDRAW                                     = &H1
%CS_HREDRAW                                     = &H2
%PM_REMOVE                                      = &H0001
%SM_CXSCREEN                                    = 0
%SM_CYSCREEN                                    = 1
%MB_ICONHAND                                    = &H00000010&
%IDC_ARROW                                      = 32512&
%IDC_SIZEALL                                    = 32646&
%IDC_HAND                                       = 32649&
%SS_CENTER                                      = &H00000001
%SS_SUNKEN                                      = &H00001000
%WM_HSCROLL                                     = &H114
%WM_VSCROLL                                     = &H115
%BST_CHECKED                                    = &H01
%BM_GETCHECK                                    = &HF0
%HWND_TOPMOST                                   = &HFFFFFFFF???

%TBS_AUTOTICKS                                  = &H0001
%TBS_VERT                                       = &H0002
%TBS_HORZ                                       = &H0000
%TBS_BOTTOM                                     = &H0000
%TBM_GETPOS                                     = %WM_USER
%TBM_SETPOS                                     = %WM_USER + 5
%TBM_SETRANGE                                   = %WM_USER + 6
%TBM_SETTICFREQ                                 = %WM_USER + 20
%TBM_SETPAGESIZE                                = %WM_USER + 21
%TBM_SETLINESIZE                                = %WM_USER + 23

%GL_LESS                                        = &H0201
%GL_DEPTH_BUFFER_BIT                            = &H00000100
%GL_COLOR_BUFFER_BIT                            = &H00004000
%GL_LINES                                       = &H0001
%GL_LINE_STRIP                                  = &H0003
%GL_QUADS                                       = &H0007
%GL_SRC_ALPHA                                   = &H0302
%GL_ONE_MINUS_SRC_ALPHA                         = &H0303
%GL_SPECULAR                                    = &H1202
%GL_EMISSION                                    = &H1600
%GL_SHININESS                                   = &H1601
%GL_UNSIGNED_BYTE                               = &H1401
%GL_FRONT                                       = &H0404
%GL_LINE_SMOOTH                                 = &H0B20
%GL_LIGHTING                                    = &H0B50
%GL_COLOR_MATERIAL                              = &H0B57
%GL_DEPTH_TEST                                  = &H0B71
%GL_BLEND                                       = &H0BE2
%GL_PERSPECTIVE_CORRECTION_HINT                 = &H0C50
%GL_TEXTURE_2D                                  = &H0DE1
%GL_NICEST                                      = &H1102
%GL_LIGHT0                                      = &H4000
%GL_LIGHT1                                      = &H4001
%GL_AMBIENT                                     = &H1200
%GL_DIFFUSE                                     = &H1201
%GL_POSITION                                    = &H1203
%GL_COMPILE                                     = &H1300
%GL_AMBIENT_AND_DIFFUSE                         = &H1602
%GL_RGB                                         = &H1907
%GL_SMOOTH                                      = &H1D01
%GL_LINEAR                                      = &H2601
%GL_TEXTURE_MAG_FILTER                          = &H2800
%GL_TEXTURE_MIN_FILTER                          = &H2801
%GLU_SMOOTH                                     = 100000
%GL_RGBA                                        = &H00001908

TYPE RECT
  nLeft AS LONG
  nTop AS LONG
  nRight AS LONG
  nBottom AS LONG
END TYPE

TYPE POINTAPI
  x AS LONG
  y AS LONG
END TYPE

TYPE tagMSG
  hwnd AS DWORD
  message AS DWORD
  wParam AS LONG
  lParam AS LONG
  time AS DWORD
  pt AS POINTAPI
END TYPE

TYPE SECURITY_ATTRIBUTES
  nLength AS DWORD
  lpSecurityDescriptor AS LONG
  bInheritHandle AS LONG
END TYPE

TYPE WNDCLASSEX
    cbSize AS DWORD
    STYLE AS DWORD
    lpfnWndProc AS LONG
    cbClsExtra AS LONG
    cbWndExtra AS LONG
    hInstance AS DWORD
    hIcon AS DWORD
    hCursor AS DWORD
    hbrBackground AS DWORD
    lpszMenuName AS ASCIIZ PTR
    lpszClassName AS ASCIIZ PTR
    hIconSm AS DWORD
END TYPE

TYPE PAINTSTRUCT
  hDC AS DWORD
  fErase AS LONG
  rcPaint AS RECT
  fRestore AS LONG
  fIncUpdate AS LONG
  rgbReserved(0 TO 31) AS BYTE
END TYPE

DECLARE FUNCTION GetWindowRect LIB "USER32.DLL" ALIAS "GetWindowRect" (BYVAL hWnd AS DWORD, lpRect AS RECT) AS LONG
DECLARE FUNCTION GetMessage LIB "USER32.DLL" ALIAS "GetMessageA" (lpMsg AS tagMSG, BYVAL hWnd AS DWORD, BYVAL uMsgFilterMin AS DWORD, BYVAL uMsgFilterMax AS DWORD) AS LONG
DECLARE FUNCTION SetWindowLong LIB "USER32.DLL" ALIAS "SetWindowLongA" (BYVAL hWnd AS DWORD, BYVAL nIndex AS LONG, BYVAL lNewLong AS LONG) AS LONG
DECLARE FUNCTION CallWindowProc LIB "USER32.DLL" ALIAS "CallWindowProcA" (BYVAL lpPrevWndFunc AS DWORD, BYVAL hWnd AS DWORD, BYVAL uMsg AS DWORD, BYVAL wParam AS DWORD, BYVAL lParam AS LONG) AS LONG
DECLARE FUNCTION AdjustWindowRectEx LIB "USER32.DLL" ALIAS "AdjustWindowRectEx" (lpRect AS RECT, BYVAL dsStyle AS LONG, BYVAL bMenu AS LONG, BYVAL dwEsStyle AS DWORD) AS LONG
DECLARE FUNCTION BeginPaint LIB "USER32.DLL" ALIAS "BeginPaint" (BYVAL hWnd AS DWORD, lpPaint AS PAINTSTRUCT) AS LONG
DECLARE FUNCTION CloseHandle LIB "KERNEL32.DLL" ALIAS "CloseHandle" (BYVAL hObject AS DWORD) AS LONG
DECLARE FUNCTION CreateMutex LIB "KERNEL32.DLL" ALIAS "CreateMutexA" (lpMutexAttributes AS SECURITY_ATTRIBUTES, BYVAL bInitialOwner AS LONG, lpName AS ASCIIZ) AS LONG
DECLARE FUNCTION CreateWindowEx LIB "USER32.DLL" ALIAS "CreateWindowExA" (BYVAL dwExStyle AS DWORD, lpClassName AS ASCIIZ, lpWindowName AS ASCIIZ, BYVAL dwStyle AS DWORD, BYVAL x AS LONG, BYVAL y AS LONG, _
    BYVAL nWidth AS LONG, BYVAL nHeight AS LONG, BYVAL hWndParent AS DWORD, BYVAL hMenu AS DWORD, BYVAL hInstance AS DWORD, lpParam AS ANY) AS DWORD
DECLARE FUNCTION DefWindowProc LIB "USER32.DLL" ALIAS "DefWindowProcA" (BYVAL hWnd AS DWORD, BYVAL uMsg AS DWORD, BYVAL wParam AS DWORD, BYVAL lParam AS LONG) AS LONG
DECLARE FUNCTION DispatchMessage LIB "USER32.DLL" ALIAS "DispatchMessageA" (lpMsg AS tagMSG) AS LONG
DECLARE FUNCTION EndPaint LIB "USER32.DLL" ALIAS "EndPaint" (BYVAL hWnd AS DWORD, lpPaint AS PAINTSTRUCT) AS LONG
DECLARE FUNCTION FindWindow LIB "USER32.DLL" ALIAS "FindWindowA" (lpClassName AS ASCIIZ, lpWindowName AS ASCIIZ) AS LONG
DECLARE FUNCTION FreeLibrary LIB "KERNEL32.DLL" ALIAS "FreeLibrary" (BYVAL hLibModule AS DWORD) AS LONG
DECLARE FUNCTION GetClassInfoEx LIB "USER32.DLL" ALIAS "GetClassInfoExA" (BYVAL hInst AS DWORD, lpszClass AS ASCIIZ, lpWndClass AS WNDCLASSEX) AS LONG
DECLARE FUNCTION GetClientRect LIB "USER32.DLL" ALIAS "GetClientRect" (BYVAL hwnd AS DWORD, lpRect AS RECT) AS LONG
DECLARE FUNCTION GetDlgItem LIB "USER32.DLL" ALIAS "GetDlgItem" (BYVAL hDlg AS DWORD, BYVAL nIDDlgItem AS LONG) AS DWORD
DECLARE FUNCTION GetFocus LIB "USER32.DLL" ALIAS "GetFocus" () AS DWORD
DECLARE FUNCTION GetForegroundWindow LIB "USER32.DLL" ALIAS "GetForegroundWindow" () AS DWORD
DECLARE FUNCTION GetLastError LIB "KERNEL32.DLL" ALIAS "GetLastError" () AS LONG
DECLARE FUNCTION GetProcAddress LIB "KERNEL32.DLL" ALIAS "GetProcAddress" (BYVAL hModule AS DWORD, lpProcName AS ASCIIZ) AS LONG
DECLARE FUNCTION GetStockObject LIB "GDI32.DLL" ALIAS "GetStockObject" (BYVAL nIndex AS LONG) AS DWORD
DECLARE FUNCTION GetSystemMetrics LIB "USER32.DLL" ALIAS "GetSystemMetrics" (BYVAL nIndex AS LONG) AS LONG
DECLARE FUNCTION GetWindowText LIB "USER32.DLL" ALIAS "GetWindowTextA" (BYVAL hWnd AS DWORD, lpString AS ASCIIZ, BYVAL cch AS LONG) AS LONG
DECLARE FUNCTION glGenLists LIB "opengl32.dll" ALIAS "glGenLists" (BYVAL range&) AS DWORD
DECLARE FUNCTION glGetError LIB "opengl32.dll" ALIAS "glGetError" () AS DWORD
DECLARE FUNCTION gluNewQuadric  LIB "glu32.dll" ALIAS "gluNewQuadric"  () AS LONG
DECLARE FUNCTION IsIconic LIB "USER32.DLL" ALIAS "IsIconic" (BYVAL hWnd AS DWORD) AS LONG
DECLARE FUNCTION LoadCursor LIB "USER32.DLL" ALIAS "LoadCursorA" (BYVAL hInstance AS DWORD, lpCursorName AS ASCIIZ) AS DWORD
DECLARE FUNCTION LoadIcon LIB "USER32.DLL" ALIAS "LoadIconA" (BYVAL hInstance AS DWORD, lpIconName AS ASCIIZ) AS DWORD
DECLARE FUNCTION LoadLibrary LIB "KERNEL32.DLL" ALIAS "LoadLibraryA" (lpLibFileName AS ASCIIZ) AS LONG
DECLARE FUNCTION MessageBox LIB "USER32.DLL" ALIAS "MessageBoxA" (BYVAL hWnd AS DWORD, lpText AS ASCIIZ, lpCaption AS ASCIIZ, BYVAL dwType AS DWORD) AS LONG
DECLARE FUNCTION PeekMessage LIB "USER32.DLL" ALIAS "PeekMessageA" (lpMsg AS tagMSG, BYVAL hWnd AS DWORD, BYVAL dwMsgFilterMin AS DWORD, BYVAL dwMsgFilterMax AS DWORD, BYVAL dwRemoveMsg AS DWORD) AS LONG
DECLARE FUNCTION RegisterClassEx LIB "USER32.DLL" ALIAS "RegisterClassExA" (pcWndClassEx AS WNDCLASSEX) AS WORD
DECLARE FUNCTION ScreenToClient LIB "USER32.DLL" ALIAS "ScreenToClient" (BYVAL hWnd AS DWORD, lpPoint AS POINTAPI) AS LONG
DECLARE FUNCTION SendMessage LIB "USER32.DLL" ALIAS "SendMessageA" (BYVAL hWnd AS DWORD, BYVAL dwMsg AS DWORD, BYVAL wParam AS DWORD, BYVAL lParam AS LONG) AS LONG
DECLARE FUNCTION SetClassLong LIB "USER32.DLL" ALIAS "SetClassLongA" (BYVAL hWnd AS DWORD, BYVAL nIndex AS LONG, BYVAL dwNewLong AS DWORD) AS LONG
DECLARE FUNCTION SetFocus LIB "USER32.DLL" ALIAS "SetFocus" (BYVAL hWnd AS DWORD) AS LONG
DECLARE FUNCTION SetForegroundWindow LIB "USER32.DLL" ALIAS "SetForegroundWindow" (BYVAL hWnd AS DWORD) AS LONG
DECLARE FUNCTION SetRect LIB "USER32.DLL" ALIAS "SetRect" (lpRect AS RECT, BYVAL X1 AS LONG, BYVAL Y1 AS LONG, BYVAL X2 AS LONG, BYVAL Y2 AS LONG) AS LONG
DECLARE FUNCTION ShowWindow LIB "USER32.DLL" ALIAS "ShowWindow" (BYVAL hWnd AS DWORD, BYVAL nCmdShow AS LONG) AS LONG
DECLARE FUNCTION TranslateMessage LIB "USER32.DLL" ALIAS "TranslateMessage" (lpMsg AS tagMSG) AS LONG
DECLARE FUNCTION WindowFromPoint LIB "USER32.DLL" ALIAS "WindowFromPoint" (BYVAL xPoint AS LONG, BYVAL yPoint AS LONG) AS LONG
DECLARE FUNCTION GetDlgCtrlID LIB "USER32.DLL" ALIAS "GetDlgCtrlID" (BYVAL hWnd AS DWORD) AS LONG

DECLARE SUB glBegin LIB "opengl32.dll" ALIAS "glBegin" (BYVAL mode AS DWORD)
DECLARE SUB glBindTexture LIB "opengl32.dll" ALIAS "glBindTexture" (BYVAL ntarget AS DWORD, BYVAL texture AS DWORD)
DECLARE SUB glBlendFunc LIB "opengl32.dll" ALIAS "glBlendFunc" (BYVAL sfactor AS DWORD, BYVAL dfactor AS DWORD)
DECLARE SUB glCallList LIB "opengl32.dll" ALIAS "glCallList" (BYVAL list AS DWORD)
DECLARE SUB glClear LIB "opengl32.dll" ALIAS "glClear" (BYVAL mask AS DWORD)
DECLARE SUB glClearColor LIB "opengl32.dll" ALIAS "glClearColor" (BYVAL red AS SINGLE, BYVAL green AS SINGLE, BYVAL blue AS SINGLE, BYVAL alpha AS SINGLE)
DECLARE SUB glClearDepth LIB "opengl32.dll" ALIAS "glClearDepth" (BYVAL depth AS DOUBLE)
DECLARE SUB glColor4fv LIB "opengl32.dll" ALIAS "glColor4fv" (v AS ANY)
DECLARE SUB glColorMaterial LIB "opengl32.dll" ALIAS "glColorMaterial" (BYVAL face AS DWORD, BYVAL mode AS DWORD)
DECLARE SUB glDepthFunc LIB "opengl32.dll" ALIAS "glDepthFunc" (BYVAL func AS DWORD)
DECLARE SUB glEnable LIB "opengl32.dll" ALIAS "glEnable" (BYVAL cap AS DWORD)
DECLARE SUB glDisable LIB "opengl32.dll" ALIAS "glDisable" (BYVAL cap AS DWORD)
DECLARE SUB glEnd LIB "opengl32.dll" ALIAS "glEnd" ()
DECLARE SUB glEndList LIB "opengl32.dll" ALIAS "glEndList" ()
DECLARE SUB glGenTextures LIB "opengl32.dll" ALIAS "glGenTextures" (BYVAL n&, textures AS ANY)
DECLARE SUB glHint LIB "opengl32.dll" ALIAS "glHint" (BYVAL ntarget AS DWORD, BYVAL mode AS DWORD)
DECLARE SUB glLightfv LIB "opengl32.dll" ALIAS "glLightfv" (BYVAL light AS DWORD, BYVAL pname AS DWORD, params AS ANY)
DECLARE SUB glLineWidth LIB "opengl32.dll" ALIAS "glLineWidth" (BYVAL nwidth AS SINGLE)
DECLARE SUB glLoadIdentity LIB "opengl32.dll" ALIAS "glLoadIdentity" ()
DECLARE SUB glNewList LIB "opengl32.dll" ALIAS "glNewList" (BYVAL list AS DWORD, BYVAL mode AS DWORD)
DECLARE SUB glRotatef LIB "opengl32.dll" ALIAS "glRotatef" (BYVAL angle AS SINGLE, BYVAL x AS SINGLE, BYVAL y AS SINGLE, BYVAL z AS SINGLE)
DECLARE SUB glShadeModel LIB "opengl32.dll" ALIAS "glShadeModel" (BYVAL mode AS DWORD)
DECLARE SUB glTexCoord2f LIB "opengl32.dll" ALIAS "glTexCoord2f" (BYVAL s AS SINGLE, BYVAL t AS SINGLE)
DECLARE SUB glTexImage2D LIB "opengl32.dll" ALIAS "glTexImage2D" (BYVAL ntarget AS DWORD, BYVAL level&, BYVAL internalformat&, BYVAL nwidth&, BYVAL height&, BYVAL border&, BYVAL format AS DWORD, BYVAL ntype AS DWORD, npixels AS ANY)
DECLARE SUB glTexParameteri LIB "opengl32.dll" ALIAS "glTexParameteri" (BYVAL ntarget AS DWORD, BYVAL pname AS DWORD, BYVAL param&)
DECLARE SUB glTranslatef LIB "opengl32.dll" ALIAS "glTranslatef" (BYVAL x AS SINGLE, BYVAL y AS SINGLE, BYVAL z AS SINGLE)
DECLARE SUB gluCylinder    LIB "glu32.dll" ALIAS "gluCylinder"    (BYVAL qobj AS DWORD, BYVAL baseRadius#, BYVAL topRadius#, BYVAL nheight#, BYVAL slices&, BYVAL stacks AS LONG)
DECLARE SUB gluDeleteQuadric    LIB "glu32.dll" ALIAS "gluDeleteQuadric"   (BYVAL state AS DWORD)
DECLARE SUB gluDisk   LIB "glu32.dll" ALIAS "gluDisk"   (BYVAL qobj AS DWORD, BYVAL innerRadius#, BYVAL outerRadius#, BYVAL slices&, BYVAL loops AS LONG)
DECLARE SUB gluQuadricNormals   LIB "glu32.dll" ALIAS "gluQuadricNormals"  (BYVAL quadObject AS DWORD, BYVAL normals AS DWORD)
DECLARE SUB gluQuadricTexture   LIB "glu32.dll" ALIAS "gluQuadricTexture"  (BYVAL quadObject AS DWORD, BYVAL textureCoords AS DWORD)' ANY)
DECLARE SUB glVertex3f LIB "opengl32.dll" ALIAS "glVertex3f" (BYVAL x AS SINGLE, BYVAL y AS SINGLE, BYVAL z AS SINGLE)
DECLARE SUB glColor4f LIB "opengl32.dll" ALIAS "glColor4f" (BYVAL red AS SINGLE, BYVAL green AS SINGLE, BYVAL blue AS SINGLE, BYVAL alpha AS SINGLE)
DECLARE SUB InitCommonControls LIB "COMCTL32.DLL" ALIAS "InitCommonControls" ()
DECLARE SUB PostQuitMessage LIB "USER32.DLL" ALIAS "PostQuitMessage" (BYVAL nExitCode AS LONG)
DECLARE SUB glMaterialfv LIB "OPENGL32.DLL" ALIAS "glMaterialfv" (BYVAL face AS DWORD, BYVAL pname AS DWORD, BYREF params AS SINGLE)
DECLARE SUB glColor3f LIB "OPENGL32.DLL" ALIAS "glColor3f" (BYVAL nRed AS SINGLE, BYVAL nGreen AS SINGLE, BYVAL nBlue AS SINGLE)
DECLARE SUB glPopMatrix LIB "OPENGL32.DLL" ALIAS "glPopMatrix" ()
DECLARE SUB glPushMatrix LIB "OPENGL32.DLL" ALIAS "glPushMatrix" ()
DECLARE SUB glColor4ub LIB "OPENGL32.DLL" ALIAS "glColor4ub" (BYVAL nRed AS BYTE, BYVAL nGreen AS BYTE, BYVAL nBlue AS BYTE, BYVAL alpha AS BYTE)
DECLARE SUB glScalef LIB "OPENGL32.DLL" ALIAS "glScalef" ( BYVAL x AS SINGLE, BYVAL y AS SINGLE, BYVAL z AS SINGLE)
DECLARE SUB glDeleteTextures LIB "opengl32.dll" ALIAS "glDeleteTextures" (BYVAL n&, textures AS ANY)

'------------------------------------------------------------------------------------------
#RESOURCE "Sydney.pbr"
'------------------------------------------------------------------------------------------
#INCLUDE "WINLIFT.INC"
#INCLUDE "gdimage.inc"

DECLARE FUNCTION MD2_Load LIB "MD2ex.DLL" ALIAS "MD2_Load" (BYVAL index AS LONG, BYVAL s AS STRING, BYVAL n AS LONG, BYVAL w AS LONG, BYVAL h AS LONG) AS LONG
DECLARE FUNCTION MD2_Draw LIB "MD2ex.DLL" ALIAS "MD2_Draw" (BYVAL index AS LONG, BYVAL n AS SINGLE) AS LONG
DECLARE FUNCTION MD2_Delete LIB "MD2ex.DLL" ALIAS "MD2_Delete" (BYVAL index AS LONG) AS LONG
DECLARE FUNCTION MD2_DeleteAll LIB "MD2ex.DLL" ALIAS "MD2_DeleteAll" () AS LONG

'------------------------------------------------------------------------------------------
DECLARE FUNCTION zTrace LIB "zTrace.DLL" ALIAS "zTrace" (zMessage AS ASCIIZ) AS LONG


%ID_CTRL       = -1

%IDC_STATIC    = -101
%IDC_LABEL     = -102
%IDC_ZOOM      = -103
%IDC_CLOCK     = -104
%IDC_LOGO      = -105
%IDC_CHECKBOX  = -106

' WinXP Theme support declares (if applicable)
DECLARE FUNCTION EnableDialogTheme(BYVAL hDlg AS DWORD, BYVAL dwStyle AS DWORD) AS LONG
DECLARE FUNCTION IsThemeActive() AS LONG

'/* OpenGL globals, defines, and prototypes */
'GLOBAL latitude AS SINGLE', longitude AS SINGLE', gYincr AS SINGLE, gXincr AS SINGLE

TYPE THISOBJECT
    radius      AS SINGLE
    barsize     AS SINGLE
    xoff        AS SINGLE
    yoff        AS SINGLE
    zoff        AS SINGLE
    xrot        AS SINGLE
    yrot        AS SINGLE
    xcpy        AS SINGLE
    ycpy        AS SINGLE
    move        AS LONG
    xdown       AS LONG
    ydown       AS LONG
    mouseDown   AS LONG
    listIndex   AS LONG
END TYPE

TYPE ZGLTEXTURE_EX
    ID       AS LONG
    FullName AS ASCIIZ * 260
    Texture  AS LONG
    Square   AS LONG            '// boolean TRUE or FALSE value
    nWidth   AS LONG
    nHeight  AS LONG
END TYPE

GLOBAL glObj AS THISOBJECT
GLOBAL quadObj AS LONG
GLOBAL mt() AS ZGLTEXTURE_EX
GLOBAL g_hMain, g_hGLcontrol, g_hGLproc AS DWORD
GLOBAL g_UseFont AS ZGLFONT
GLOBAL g_sResource AS STRING

FUNCTION WINMAIN (BYVAL hInstance     AS LONG, _
                  BYVAL hPrevInstance AS LONG, _
                  BYVAL lpCmdLine     AS ASCIIZ PTR, _
                  BYVAL iCmdShow      AS LONG) AS LONG

    LOCAL Msg         AS tagMsg
    LOCAL wc          AS WndClassEx
    LOCAL zClass      AS ASCIIZ * 16
    LOCAL zMessage    AS ASCIIZ * 260
    LOCAL dwExStyle, dwStyle, hMutex, hFound, hCtrl AS DWORD
    LOCAL rc          AS RECT
    LOCAL K, x, y     AS LONG
    LOCAL p           AS POINTAPI

    zClass = "ZCYLINDER"

    hMutex = CreateMutex(BYVAL %Null, 0, zClass)
    IF hMutex THEN
       IF GetLastError = %ERROR_ALREADY_EXISTS THEN
          DO
             hFound = FindWindow(zClass, ""): IF hFound THEN EXIT DO
             WHILE PeekMessage(Msg, %NULL, %NULL, %NULL, %PM_REMOVE): WEND
          LOOP
          IF IsIconic(hFound) THEN ShowWindow(hFound, %SW_RESTORE)
          SetForeGroundWindow(hFound)
          FUNCTION = 0
          EXIT FUNCTION
       END IF
    END IF

    wc.cbSize = SIZEOF(wc)
    IsInitialized& = GetClassInfoEx(zInstance, zClass, wc)
    IF IsInitialized&   = 0 THEN
       wc.cbSize        = SIZEOF(wc)
       wc.style         = %CS_HREDRAW OR %CS_VREDRAW
       wc.lpfnWndProc   = CODEPTR(WndProc)
       wc.cbClsExtra    = 0
       wc.cbWndExtra    = 0
       wc.hInstance     = hInstance
       wc.hIcon         = LoadIcon(wc.hInstance, "PROGRAM")
       wc.hCursor       = LoadCursor(%NULL, BYVAL %IDC_ARROW)
       wc.hbrBackground = %NULL
       wc.lpszMenuName  = %NULL
       wc.lpszClassName = VARPTR(zClass)
       wc.hIconSm       = wc.hIcon
       IF RegisterClassEx(wc) THEN IsInitialized& = %TRUE
    END IF
'
    IF IsInitialized& THEN

     '************************************************************************************
     ' Load the GDImage.dll
       IF RegisterGDImageClass() = 0 THEN
          FUNCTION = 99:  EXIT FUNCTION ' If it fails to register then return ERROR = 99
       ELSE
          ZI_LoadDLL("")
       END IF
     '************************************************************************************

'
     ' Window Extended Style
       dwExStyle = %WS_EX_APPWINDOW OR %WS_EX_WINDOWEDGE
     ' Windows Style
       dwStyle = %WS_OVERLAPPEDWINDOW
       SetRect(rc, 0, 0, 668, 532)
       AdjustWindowRectEx(rc, dwStyle, %FALSE, dwExStyle)  ' Adjust Window To True Requested Size
'
       x = MAX&((GetSystemMetrics(%SM_CXSCREEN) - rc.nRight - rc.nLeft) \ 2, 0)
       y = MAX&((GetSystemMetrics(%SM_CYSCREEN) - rc.nBottom - rc.nTop) \ 2, 0)
'
     ' Create The Window
       zMessage = "GDImage control " + ZI_Version + " - ""3D lighting"" demo"
       g_hMain = CreateWindowEx(dwExStyle, _           ' Extended Style For The Window
                             zClass, _               ' Class Name
                             zMessage, _             ' Window Title
                             dwStyle OR _            ' Defined Window Style
                             %WS_CLIPSIBLINGS OR _   ' Required Window Style
                             %WS_CLIPCHILDREN, _     ' Required Window Style
                             x, y, _                 ' Window Position
                             rc.nRight - rc.nLeft, _ ' Calculate Window Width
                             rc.nBottom - rc.nTop, _ ' Calculate Window Height
                             %NULL, _                ' No Parent Window
                             %NULL, _                ' No Menu
                             hInstance, _            ' Instance
                             BYVAL %NULL)            ' Dont Pass Anything To WM_CREATE

       IF g_hMain THEN

        ' *******************************************************************************
        ' Alternate methode to create a GDImage OpenGL control
        ' Note: when GDImage is active the OpenGL $GLImageClassName is already registered
        ' -------------------------------------------------------------------------------
          g_hGLcontrol = CreateWindowEx(0, _
                                 $GLImageClassName, _         ' Make it an OpenGL control
                                 "", _                        ' Currently not used
                                 %WS_CHILD OR %WS_VISIBLE, _  ' window style
                                 10, _                        ' initial x position
                                 10, _                        ' initial y position
                                 512, _                       ' Calculate Window Width
                                 512, _                       ' Calculate Window Height
                                 g_hMain, _                   ' parent window handle
                                 %ID_CTRL, _                  ' ControlID
                                 hInstance, _                 ' program instance handle
                                 BYVAL %NULL)                 ' creation parameters
'         // Subclass the OpenGL control
          IF g_hGLcontrol THEN
             g_hGLproc = SetWindowLong(g_hGLcontrol, %GWL_WNDPROC, CODEPTR(glWndProc))
          END IF

          ZI_SetAnchorMode(g_hGLcontrol, %ANCHOR_HEIGHT_WIDTH)  ' Anchor the control (make it a resizable)

'         // Add checkbox
          'hCtrl =    CreateWindowEx( 0, _
          '                          "BUTTON", _
          '                          "Darker mode", _
          '                          %WS_CHILD OR %WS_VISIBLE OR %WS_TABSTOP OR %BS_AUTOCHECKBOX, _
          '                          554, 490, 120, 16, _
          '                          g_hMain, %IDC_CHECKBOX, _
          '                          hInstance, _
          '                          BYVAL %NULL)
          'ZI_SetAnchorMode(hCtrl, %ANCHOR_BOTTOM_RIGHT)

'         // Add trackbar
          hCtrl = CreateWindowEx( 0, _
                                 "MSCTLS_TRACKBAR32", _
                                 "", _
                                 %WS_CHILD OR %WS_VISIBLE OR %WS_TABSTOP OR %TBS_HORZ OR %TBS_BOTTOM OR %TBS_AUTOTICKS, _
                                 537, 457, 120, 16, _
                                 g_hMain, %IDC_ZOOM, _
                                 hInstance, _
                                 BYVAL %NULL)
          ZI_SetAnchorMode(hCtrl, %ANCHOR_BOTTOM_RIGHT)
'         // Setup the trackbar parameters.
          SendMessage(hCtrl, %TBM_SETPAGESIZE, 0, 1)
          SendMessage(hCtrl, %TBM_SETLINESIZE, 0, 1)
          SendMessage(hCtrl, %TBM_SETTICFREQ, 0, 1)
          SendMessage(hCtrl, %TBM_SETRANGE, 1, MAK(LONG, 1, 100)) '// Set the zoom range
          SendMessage(hCtrl, %TBM_SETPOS, 1, 50)


          g_sResource = EXE.Path$ + "Resource\"

        ' OpenGL section
        ' ----------------------------------------
        ' Load any of the supported GDImage graphic format to create a texture

          DIM mt(1) AS ZGLTEXTURE_EX
          mt(0).FullName = g_sResource + "Background.jpg": mt(0).ID = 1: mt(0).Square = 0
          mt(1).FullName = g_sResource + "Sydney.png":     mt(1).ID = 2: mt(1).Square = 0
          MakeMultipleTextureEx(BYVAL VARPTR(mt(LBOUND(mt))), UBOUND(mt) - LBOUND(mt) + 1)
          FOR K = 1 TO UBOUND(mt()): REPLACE ".png" WITH ".md2" IN mt(K).FullName: NEXT

          InitializeGL()

          g_UseFont.fontName = "Arial"
          g_UseFont.fontHeight = 10
          g_UseFont.fontWeight = %FW_BOLD
          ZI_BuildGLfont(ZI_GetGLDC(g_hGLcontrol), g_UseFont) ' Build OpenGL font for our OpenGL window

          IF skInitEngine("Scarlet.sks", "") THEN

             skSkinWindow(g_hMain, "Dock|Undock|Minimize|Maximize|Restore|Close")

'            // Add a skinned border around the GDImage control.
             GetWindowRect(g_hGLcontrol, rc)
             p.X = rc.nLeft: p.Y = rc.nTop
             ScreenToClient(g_hMain, p)
             skBorder(g_hGLcontrol, p.X - 1, p.Y - 1, rc.nRight - rc.nLeft + 2, rc.nBottom - rc.nTop + 2, 0, 1)

'            // Add a WinLIFT clock
             hCtrl = skClockCtrl(g_hMain, g_sResource + "Clock_09_92.png", p.X + rc.nRight - rc.nLeft + 28, p.Y, 0, 0, %IDC_CLOCK, &H7FCB0000, &H7F8F8F8F, 0)
             skSetAnchorCtrl(hCtrl, %ANCHOR_RIGHT)
             skCreateToolTip(hCtrl, "WinLIFT clock widget")

'            // Add a static control to display the help text.
             GetClientRect(g_hMain, rc)
             zMessage = "Mouse buttons" + $CRLF + $CRLF + "Left: rotation, and view angle." + $CRLF + _
                        $CRLF + "Right: new X,Y location."
             hCtrl = CreateWindowEx(0, "STATIC", zMessage, %WS_CHILD OR %WS_VISIBLE OR %SS_CENTER OR %WS_BORDER, _
                                    rc.nRight - (129 + 8), 10 + (22 + 5) * 5 + 5, 129, 135, g_hMain, %IDC_LABEL, hInstance, BYVAL %NULL)
'            // Skin the static control on the fly.
             skSkinChildCtrl(hCtrl, 0)
             ZI_SetAnchorMode(hCtrl, %ANCHOR_RIGHT)
'            // Use a custom font with the static control.
             skSetLabelFont(hCtrl, "TREBUCHET MS", 15, skARGB(200, 255,255,255), %FontStyleBold)


'            // Diplay the GDImage logo.
             hCtrl = skStaticImage(g_hMain, g_sResource + "GDImage.png", rc.nRight - (129 + 6), 350, 124, 45, %IDC_LOGO)
             ZI_SetAnchorMode(hCtrl, %ANCHOR_BOTTOM_RIGHT)

'            // All is done, it is time to show the main window.
             ShowWindow(g_hMain, iCmdShow)
             SetForegroundWindow(g_hMain)                ' Slightly Higher Priority
             SetFocus(g_hMain)                           ' Sets Keyboard Focus To The Window

'            // Main message pump.
             WHILE GetMessage(Msg, 0, 0, 0)
                TranslateMessage(Msg)
                DispatchMessage(Msg)
             WEND

          END IF

'         // Free OpenGL resources.
          IF quadObj THEN gluDeleteQuadric(quadObj)  ' OpenGL quadric onject
          FOR K = 1 TO UBOUND(mt()): MD2_Delete(K): NEXT
          ZI_DestroyTexture (BYVAL VARPTR(mt(LBOUND(mt))), UBOUND(mt) - LBOUND(mt) + 1)

          FUNCTION = msg.wParam
       END IF

    END IF

    IF hMutex THEN CloseHandle(hMutex)
'
END FUNCTION

SUB InitObject()

    glObj.xoff = 0.0 ' Initial x location.
    glObj.yoff = -0.25   ' Initial y location.
    glObj.zoff = -2  ' Initial zoom factor.

    glObj.xrot = 5
    glObj.yrot = -30.0

    glObj.radius = 2.0
END SUB

' Set up our OpenGL scene
SUB InitializeGL()

    LOCAL Value AS SINGLE

    InitObject()
    glEnable(%GL_TEXTURE_2D)
    glDepthFunc(%GL_LESS)
    glEnable(%GL_DEPTH_TEST)
    glShadeModel(%GL_SMOOTH)
    glHint(%GL_PERSPECTIVE_CORRECTION_HINT, %GL_NICEST)

    quadObj = gluNewQuadric()
    glBlendFunc(%GL_SRC_ALPHA, %GL_ONE_MINUS_SRC_ALPHA)
    glEnable(%GL_BLEND)
    glEnable(%GL_LINE_SMOOTH)
    gluQuadricNormals(quadObj, %GLU_SMOOTH)

    DIM LightDiffuse(3) AS SINGLE:  ARRAY ASSIGN LightDiffuse()  = 1.0, 1.0, 0.8, 1.0
    DIM LightAmbient(3) AS SINGLE:  ARRAY ASSIGN LightAmbient()  = 0.3, 0.3, 0.3, 1.0
    DIM LightPosition(3) AS SINGLE: ARRAY ASSIGN LightPosition() = -50.0, 150.0, -100.0, 1.0

    glLightfv(%GL_LIGHT1, %GL_DIFFUSE, LightDiffuse(0))     ' Setup the Diffuse Light
    glLightfv(%GL_LIGHT1, %GL_AMBIENT, LightAmbient(0))     ' Setup the Ambient Light
    glLightfv(%GL_LIGHT1, %GL_POSITION,  LightPosition(0))  ' Position the Light

    glMaterialfv(%GL_FRONT, %GL_SPECULAR, LightDiffuse(0))


    glMaterialfv(%GL_FRONT, %GL_EMISSION, 0.0)
    glMaterialfv(%GL_FRONT, %GL_SHININESS, 5.0)

    glEnable(%GL_LIGHT1)                                    ' Enable Light ONE

    glEnable(%GL_LIGHTING)                                  ' Enable Lighting
    glColorMaterial(%GL_FRONT, %GL_AMBIENT_AND_DIFFUSE)
    glEnable(%GL_COLOR_MATERIAL)                            ' Enable Coloring Of Material

    MD2_Load(1, mt(1).FullName, mt(1).Texture, mt(1).nWidth, mt(1).nHeight)

END SUB

DECLARE SUB glTexCoord2f LIB "opengl32.dll" ALIAS "glTexCoord2f" (BYVAL s AS SINGLE, BYVAL t AS SINGLE)

SUB DrawBackground()
    glBindTexture(%GL_TEXTURE_2D, mt(0).Texture)
    glBegin(%GL_QUADS)
       glTexCoord2f(0.0, 0.0): glVertex3f(-80,-40,-80.0) ' Bottom Left Of The Texture And Quad
       glTexCoord2f(1.0, 0.0): glVertex3f( 80,-40,-80.0) ' Bottom Right Of The Texture And Quad
       glTexCoord2f(1.0, 1.0): glVertex3f( 80, 40,-80.0) ' Top Right Of The Texture And Quad
       glTexCoord2f(0.0, 1.0): glVertex3f(-80, 40,-80.0) ' Top Left Of The Texture And Quad
    glEnd()
END SUB

SUB SetZoom(BYVAL zoom AS LONG)
    ZI_SetGLzoom(g_hGLcontrol, zoom)
    ZI_ResizeGLWindow(g_hGLcontrol)
END SUB

SUB RenderOpenGL()
    LOCAL k, i, j, ZoomIs AS LONG
    STATIC TextColor AS LONG

'   // Save current zoom, then switch to a fixed zoom for the background.
    ZoomIs = ZI_GetGLzoom(g_hGLcontrol)
    SetZoom(50)

    glClear(%GL_COLOR_BUFFER_BIT OR %GL_DEPTH_BUFFER_BIT)
    glLoadIdentity()

'   // Draw fixed background image
    DrawBackground()

'   // Restore the previously saved zoom.
    SetZoom(ZoomIs)

    glTranslatef(glObj.xoff, glObj.yoff, glObj.zoff)

    glRotatef(glObj.xrot, 1.0, 0.0, 0.0)
    glRotatef(glObj.yrot, 0.0, 1.0, 0.0)


    glPushMatrix
        glScalef 0.025, 0.025, 0.025
        FOR K = 1 TO UBOUND(mt())
            MD2_Draw(K, 1)
        NEXT
    glPopMatrix

    glTranslatef(2.0 * glObj.radius, 0.0, 0.0)
    glTranslatef(-2.0 * glObj.radius, 0.0, 2.0 * glObj.radius + 0.5)



'   // Display the x,y location, and the current zoom value
    IF TextColor = 0 THEN TextColor = ZD_ColorARGB(255, RGB(247, 225, 125))
    LOCAL zString AS ASCIIZ * 64
    zString = "Horizontal " + USING$("##.##", glObj.xoff)
    ZI_DrawGLText(g_hGLcontrol, g_UseFont, 9, 10, zString, TextColor)
    zString = "Vertical " + USING$("##.##", glObj.yoff + 12)
    ZI_DrawGLText(g_hGLcontrol, g_UseFont, 25, 10 + g_UseFont.fontHeight, zString, TextColor)
    zString = "Zoom" + STR$(100 - ZoomIs)
    ZI_DrawGLText(g_hGLcontrol, g_UseFont, 39, 10 + g_UseFont.fontHeight * 2, zString, TextColor)

'   // Update the display
    ZI_UpdateGLWindow(g_hGLcontrol)

END SUB

SUB GradientPaint(BYVAL hWin&, BYVAL TopRGB&, BYVAL BottomRGB&)
    LOCAL ps AS PAINTSTRUCT
    LOCAL rc AS RECT
  ' Tile the background
    CALL GetClientRect (hWin&, rc)
    hDC& = BeginPaint(hWin&, ps)
'    CALL ZI_GradientPaintDC(hDC&, 0, 0, rc.nRight, rc.nBottom, TopRGB&, BottomRGB&)
    CALL EndPaint(hWin&, ps)

RenderOpenGL()

END SUB

FUNCTION WndProc(BYVAL hWin AS DWORD, BYVAL Msg AS LONG, BYVAL wParam AS DWORD, BYVAL lParam AS DWORD) AS LONG

    SELECT CASE LONG Msg

    CASE %WM_SIZE
         ZI_ResizeGLWindow(g_hGLcontrol)
         RenderOpenGL()

    CASE %WM_HSCROLL
         IF GetDlgCtrlId(lParam) = %IDC_ZOOM THEN
            '// Do not use nPosition, because it could be NULL.
            SetZoom(101 - SendMessage(lParam, %TBM_GetPos, 0, 0))
            RenderOpenGL()
         END IF

    CASE %WM_COMMAND

'         IF LO(INTEGER, wParam) = %IDC_CHECKBOX THEN
'            IF SendMessage(GetDlgItem(hWin, %IDC_CHECKBOX), %BM_GETCHECK, 0, 0) = %BST_CHECKED THEN
'
'            ELSE
'
'            END IF
'            CALL SetFocus(g_hGLcontrol)
'            RenderOpenGL()
'         END IF

    CASE %WM_PAINT
         CALL GradientPaint(hWin, RGB(228,227,227), RGB(168,167,191))
         FUNCTION = 0: EXIT FUNCTION

    CASE %WM_DESTROY
         ZI_DeleteGLFont(g_UseFont)
         PostQuitMessage(0)
         FUNCTION = 0: EXIT FUNCTION
    END SELECT

    FUNCTION = DefWindowProc(hWin, Msg, wParam, lParam)

END FUNCTION

SUB MakeMultipleTextureEx (BYVAL tp AS ZGLTEXTURE_EX PTR, BYVAL N AS LONG)
    LOCAL mtCount, K, nRet, xSize, ySize, OkDelete AS LONG
    DIM t(1 TO N) AS ZGLTEXTURE_EX AT tp
    mtCount = UBOUND(t()) - LBOUND(t()) + 1
    IF mtCount THEN
       DIM Texture(1 TO mtCount) AS LONG
       FOR K = 1 TO mtCount
           Texture(K) = t(k).Texture: IF Texture(K) THEN OkDelete = -1
       NEXT
       IF OkDelete THEN CALL glDeleteTextures(mtCount, Texture(1))
       CALL glGenTextures(mtCount, Texture(1)): nRet = glGetError()
       IF nRet = 0 THEN
          FOR K = 1 TO mtCount
              REDIM PixelArray(0) AS BYTE
              IF ZI_CreateGLTextureFromFileEX(t(K).FullName, xSize, ySize, PixelArray(), t(K).Square) THEN
                 t(k).Texture = Texture(K)
                 t(k).nWidth = xSize
                 t(k).nHeight = ySize
                 CALL glBindTexture(%GL_TEXTURE_2D, Texture(K)): nRet = glGetError
                 IF nRet = 0 THEN
                    CALL glTexParameteri(%GL_TEXTURE_2D, %GL_TEXTURE_MAG_FILTER, %GL_LINEAR)
                    CALL glTexParameteri(%GL_TEXTURE_2D, %GL_TEXTURE_MIN_FILTER, %GL_LINEAR)
                    CALL glTexImage2D(%GL_TEXTURE_2D, 0, 4, xSize, ySize, 0, %GL_RGBA, %GL_UNSIGNED_BYTE, PixelArray(0))
                 END IF
              END IF
          NEXT
       END IF
    END IF
END SUB

FUNCTION glWndProc(BYVAL hWnd AS DWORD, BYVAL Msg AS LONG, BYVAL wParam AS DWORD, BYVAL lParam AS DWORD) AS LONG

    LOCAL rc AS RECT
    STATIC LeftMousing, RightMousing, wasLX, wasLY, wasRX, wasRY AS LONG

    LOCAL x, y, dx, dy AS LONG

    SELECT CASE LONG Msg

    CASE %WM_PAINT
        RenderOpenGL()

    CASE %WM_LBUTTONDOWN
        IF (LeftMousing = %FALSE) THEN
            x = LO(INTEGER, lParam): y = HI(INTEGER, lParam)
            glObj.xcpy = glObj.xrot
            glObj.ycpy = glObj.yrot

            glObj.xdown = x
            glObj.ydown = y
            LeftMousing = %TRUE
        END IF
        IF (GetFocus() <> hWnd) THEN SetFocus(hWnd)

    CASE %WM_LBUTTONUP
        LeftMousing = %FALSE

    CASE %WM_RBUTTONDOWN
        IF (RightMousing = %FALSE) THEN
            x = LO(INTEGER, lParam): y = HI(INTEGER, lParam)
            glObj.xcpy = glObj.xoff
            glObj.ycpy = glObj.yoff

            glObj.xdown = x
            glObj.ydown = y
            RightMousing = %TRUE
        END IF
        IF (GetFocus() <> hWnd) THEN SetFocus(hWnd)

    CASE %WM_RBUTTONUP
        RightMousing = %FALSE

    CASE %WM_MOUSEMOVE
        x = LO(INTEGER, lParam): y = HI(INTEGER, lParam)

        IF (NOT ZI_IsLButtonDown()) THEN
            LeftMousing = %FALSE
        ELSE
            IF ((wasLX <> x) OR (wasLY <> y)) THEN
                IF (LeftMousing) THEN
                   dx = x - glObj.xdown: glObj.yrot = glObj.ycpy + dx / 2.0
                   dy = y - glObj.ydown: glObj.xrot = glObj.xcpy + dy / 2.0
                END IF
            END IF
            wasLX = x: wasLY = y
            RenderOpenGL()
        END IF

        IF (NOT ZI_IsRButtonDown()) THEN
            RightMousing = %FALSE
        ELSE
            IF ((wasLX <> x) OR (wasLY <> y)) THEN
                IF (RightMousing) THEN
                    GetClientRect(g_hGLcontrol, rc)
                    dx = x - glObj.xdown: glObj.xoff = glObj.xcpy - (-45 * dx) / (12.0 * rc.nRight)  ' Use 12.0 instead of 2.0 to reduce sensitivity
                    dy = y - glObj.ydown: glObj.yoff = glObj.ycpy + (-45 * dy) / (12.0 * rc.nBottom) ' Use 12.0 instead of 2.0 to reduce sensitivity
                END IF
                RenderOpenGL()
            END IF
            wasRX = x: wasRY = y
        END IF
        RenderOpenGL()

    END SELECT

    FUNCTION = CallWindowProc(g_hGLproc, hWnd, Msg, wParam, lParam)

END FUNCTION

