WinInc OpenGL Sample Source Code

OPENGL1.ASM
; ------------------------------------------
; Title: OpenGL test
; 
; Author: Franck Charlet.
;
; Notes: Just a little example on how to use OpenGL.
;    Needs OpenGl32.dll and Glu32.dll (should be no problem).
;    Object have 2112 faces / 3 (weird) moving light sources
;    and it's f***ing slow on my cyrix 133.
;
; ------------------------------------------

; --- slightly modified for wininc includes by japheth

; --------------- Assembler directives
        .386
        .model  flat,stdcall
        option  casemap:none  

; --------------- External includes
WIN32_LEAN_AND_MEAN equ 1
        include windows.inc
        include GL\GL.inc
        include GL\GLU.inc

        includelib kernel32.lib
        includelib user32.lib
        includelib gdi32.lib
        includelib opengl32.lib
        includelib glu32.lib

; --------------- Macros Section
szText  MACRO   Name,Text:VARARG
        LOCAL   lbl
        jmp lbl
Name    db  Text,0
lbl:
        ENDM

m2m     MACRO   M1, M2
        push    M2
        pop M1
        ENDM

return  MACRO   arg
        mov eax,arg
        ret
        ENDM

; --------------- These constants are not defined in windows.inc
PFD_MAIN_PLANE      equ 0
PFD_TYPE_COLORINDEX equ 1
PFD_TYPE_RGBA       equ 0
PFD_DOUBLEBUFFER    equ 1
PFD_DRAW_TO_WINDOW  equ 4
PFD_SUPPORT_OPENGL  equ 020h

; --------------- Data Section
        .data
        
szDisplayName       db  "TestOpenGL - Written by Franck 'hitchhikr' Charlet.",0
            even
PixFrm      PIXELFORMATDESCRIPTOR <>

CommandLine     dd  0
hWnd            dd  0
MainHDC         dd  0
OpenDC          dd  0
hInstance       dd  0

; Some values
Value0Flt       dd  0.0
Value1Flt       dd  1.0
Value1Dbl       dq  1.0
Value45Dbl      dq  45.0
Value3Dbl       dq  3.0
Value7Dbl       dq  7.0

; Light position
LightSourcePosition dd  -2.0,-2.0,-4.0,0.0
LightSource2Position    dd  2.0,2.0,4.0,0.0
LightSource3Position    dd  -2.0,2.0,4.0,0.0
LightAmbient        dd  0.2,0.0,0.0,1.0
Light2Ambient       dd  0.0,0.2,0.0,1.0
Light3Ambient       dd  0.0,0.0,0.2,1.0
LightDiffuse        dd  1.0,1.0,1.0,1.0
LightSpecular       dd  1.0,1.0,1.0,1.0
SpotCut             dd  -1.0
SpotExp             dd  0.0
SpotDir             dd  -1.0,-1.0,-1.0
LightConstAtt       dd  1.0
LightLinAtt         dd  1.0
LightQuadAtt        dd  1.0

; --- Sphere 1
; Angles
Sphere1AnglesFlt    dd  0.0,0.0,0.0
; Rotations speed
Sphere1AnglesSpeedFlt   dd  -1.0,-1.2,-1.4
; Objects datas
Sphere1Color        dd  0.6,0.4,0.2,0.0
Sphere1Radius       dq  1.0
sphere1Parts        dd  24
Sphere1Position     dd  0.0,0.0,-5.0
GlSphere1           dd  0

; --- Sphere 2
; Angles
Sphere2AnglesFlt    dd  0.0,0.0,0.0
; Rotations speed
Sphere2AnglesSpeedFlt   dd  -1.0,0.8,-0.4
; Objects datas
Sphere2Color        dd  0.4,0.6,0.2,0.0
Sphere2Radius       dq  0.3
sphere2Parts        dd  16
Sphere2Position     dd  0.0,0.0,-1.5
GlSphere2           dd  0

; --- Sphere 3
; Angles
Sphere3AnglesFlt    dd  0.0,0.0,0.0
; Rotations speed
Sphere3AnglesSpeedFlt   dd  -1.0,-0.8,1.4
; Objects datas
Sphere3Color        dd  0.2,0.4,0.6,0.0
Sphere3Radius       dq  0.3
sphere3Parts        dd  16
Sphere3Position     dd  0.0,0.0,1.5
GlSphere3           dd  0

; --- Sphere 4
; Angles
Sphere4AnglesFlt    dd  0.0,0.0,0.0
; Rotations speed
Sphere4AnglesSpeedFlt   dd  -1.0,1.4,-0.8
; Objects datas
Sphere4Color        dd  0.4,0.2,0.6,0.0
Sphere4Radius       dq  0.3
sphere4Parts        dd  16
Sphere4Position     dd  0.0,1.5,0.0
GlSphere4           dd  0

; --- Sphere 5
; Angles
Sphere5AnglesFlt    dd  0.0,0.0,0.0
; Rotations speed
Sphere5AnglesSpeedFlt   dd  1.0,1.8,0.8
; Objects datas
Sphere5Color        dd  0.6,0.2,0.4,0.0
Sphere5Radius       dq  0.3
sphere5Parts        dd  16
Sphere5Position     dd  1.5,0.0,0.0
GlSphere5           dd  0

; --- Sphere 6
; Angles
Sphere6AnglesFlt    dd  0.0,0.0,0.0
; Rotations speed
Sphere6AnglesSpeedFlt   dd  1.0,-1.8,2.0
; Objects datas
Sphere6Color        dd  0.2,0.6,0.4,0.0
Sphere6Radius       dq  0.3
sphere6Parts        dd  16
Sphere6Position     dd  -1.5,0.0,0.0
GlSphere6           dd  0

; --- Sphere 7
; Angles
Sphere7AnglesFlt    dd  0.0,0.0,0.0
; Rotations speed
Sphere7AnglesSpeedFlt   dd  -2.1,-1.8,2.0
; Objects datas
Sphere7Color        dd  0.6,0.6,0.6,0.0
Sphere7Radius       dq  0.3
sphere7Parts        dd  16
Sphere7Position     dd  0.0,-1.5,0.0
GlSphere7           dd  0

; --------------- Procedures Declarations
        .code

MainInit        PROTO   :DWORD,:DWORD,:DWORD,:DWORD
MainLoop        PROTO   :DWORD,:DWORD,:DWORD,:DWORD
TopXY           PROTO   :DWORD,:DWORD
DrawScene       PROTO
GlInit          PROTO   :DWORD,:DWORD
ResizeObject    PROTO   :DWORD,:DWORD
CreateSphere    PROTO   :DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD
SetLightSource  PROTO   :DWORD,:DWORD,:DWORD
RotateObject    PROTO   :DWORD,:DWORD,:DWORD,:DWORD
DeleteSpheres   PROTO

; --------------- Procedures Section
CenterForm  PROC    wDim:DWORD, sDim:DWORD
        shr sDim,1
        shr wDim,1
        mov eax,wDim
        sub sDim,eax
        return  sDim
CenterForm  ENDP

DoEvents    PROC
        LOCAL   msg:MSG
StartLoop:      ; Check for waiting messages
        invoke  PeekMessage,ADDR msg,0,0,0,PM_NOREMOVE
        or  eax,eax
        jz  NoMsg
        invoke  GetMessage,ADDR msg,NULL,0,0
        or  eax,eax
        jz  ExitLoop
        invoke  TranslateMessage,ADDR msg
        invoke  DispatchMessage,ADDR msg
        jmp StartLoop
NoMsg:          ; No pending messages: draw the scene
        invoke  DrawScene
        jmp StartLoop
ExitLoop:
        mov eax,msg.wParam
        ret
DoEvents    ENDP

; --------------- Program start
start:  
        invoke  GetModuleHandle,NULL
        mov hInstance, eax
        invoke  GetCommandLine
        mov CommandLine,eax
        invoke  MainInit,hInstance,NULL,CommandLine,SW_SHOWDEFAULT
        invoke  ExitProcess,eax

; --------------- Program main inits
MainInit        PROC    hInst:DWORD,hPrevInst:DWORD,CmdLine:DWORD,CmdShow:DWORD
        LOCAL   wc:WNDCLASSEX
        LOCAL   Wwd:DWORD
        LOCAL   Wht:DWORD
        LOCAL   Wtx:DWORD
        LOCAL   Wty:DWORD
        szText  szClassName,"Win32SDI_Class"
        mov wc.cbSize,sizeof WNDCLASSEX
        mov wc.style,0
        mov wc.lpfnWndProc,offset MainLoop
        mov wc.cbClsExtra,NULL
        mov wc.cbWndExtra,NULL
        m2m wc.hInstance,hInst
        mov wc.hbrBackground,COLOR_WINDOWTEXT+1
        mov wc.lpszMenuName,NULL
        mov wc.lpszClassName,offset szClassName
        invoke  LoadCursor,NULL,IDC_ARROW
        mov wc.hCursor,eax
        mov wc.hIcon,0
        mov wc.hIconSm,0
        invoke  RegisterClassEx, ADDR wc
        mov Wwd,400
        mov Wht,420
        invoke  GetSystemMetrics,SM_CXSCREEN
        invoke  CenterForm,Wwd,eax
        mov Wtx,eax
        invoke  GetSystemMetrics,SM_CYSCREEN
        invoke  CenterForm,Wht,eax
        mov Wty,eax
        invoke  CreateWindowEx,0,ADDR szClassName,
                ADDR szDisplayName,
                WS_OVERLAPPEDWINDOW or WS_CLIPSIBLINGS or WS_CLIPCHILDREN,
                Wtx,Wty,Wwd,Wht,
                NULL,NULL,
                hInst,NULL
        mov hWnd,eax
        invoke  ShowWindow,hWnd,SW_SHOWNORMAL
        call    DoEvents
        ret
MainInit    ENDP

; --------------- Program main loop
MainLoop    PROC    hWin:DWORD,uMsg:DWORD,wParam:DWORD,lParam:DWORD
        LOCAL   WINRect:RECT
        LOCAL   PixFormat:DWORD
        .if uMsg == WM_KEYDOWN
            .if wParam == VK_ESCAPE
                invoke  SendMessage,hWin,WM_SYSCOMMAND,SC_CLOSE,NULL
            .endif
            return  0
        .elseif uMsg == WM_CREATE
            invoke  GetDC,hWin
            mov MainHDC,eax
            mov ax,SIZEOF PixFrm
            mov PixFrm.nSize,ax
            mov PixFrm.nVersion,1
            mov PixFrm.dwFlags,PFD_DRAW_TO_WINDOW or PFD_SUPPORT_OPENGL or PFD_DOUBLEBUFFER
            mov PixFrm.dwLayerMask,PFD_MAIN_PLANE
            mov PixFrm.iPixelType,PFD_TYPE_RGBA
            mov PixFrm.cColorBits,8
            mov PixFrm.cDepthBits,16
            mov PixFrm.cAccumBits,0
            mov PixFrm.cStencilBits,0
            invoke  ChoosePixelFormat,MainHDC,ADDR PixFrm
            mov PixFormat,eax
            invoke  SetPixelFormat,MainHDC,PixFormat,ADDR PixFrm
            or  eax,eax
            jz  NoPixelFmt
            invoke  wglCreateContext,MainHDC
            mov OpenDC,eax
            invoke  wglMakeCurrent,MainHDC,OpenDC
            invoke  GetClientRect,hWin,ADDR WINRect
            invoke  GlInit,WINRect.right,WINRect.bottom
NoPixelFmt:     
            return  0
        .elseif uMsg == WM_SIZE
            invoke  GetClientRect,hWin,ADDR WINRect
            invoke  ResizeObject,WINRect.right,WINRect.bottom
            return  0
                
        .elseif uMsg == WM_CLOSE
if 0        
            szText TheText,"Are you sure ?"
            invoke  MessageBox,hWin,ADDR TheText,ADDR szDisplayName,MB_YESNO+MB_ICONQUESTION
            .if eax == IDNO
                return  0
            .endif
endif            
            mov eax,OpenDC
            or  eax,eax
            jz  NoGlDC
            ; Delete our objects
            invoke  DeleteSpheres
            invoke  wglDeleteContext,OpenDC
NoGlDC:
            invoke  ReleaseDC,hWin,MainHDC
            invoke  DestroyWindow,hWin
            return  0
        .elseif uMsg == WM_DESTROY
            invoke  PostQuitMessage,NULL
            return  0 
        .endif
        invoke  DefWindowProc,hWin,uMsg,wParam,lParam
        ret
MainLoop    ENDP

; ------------------------------
; OpenGl related stuff
; ------------------------------

; --------------- Init the scene
GlInit  PROC    ParentW:DWORD,ParentH:DWORD
        invoke  SetLightSource,GL_LIGHT0,ADDR LightSourcePosition,ADDR LightAmbient
        invoke  SetLightSource,GL_LIGHT1,ADDR LightSource2Position,ADDR Light2Ambient
        invoke  SetLightSource,GL_LIGHT2,ADDR LightSource3Position,ADDR Light3Ambient
        invoke  CreateSphere,1,GLU_FILL,GLU_SMOOTH,ADDR Sphere1Color,ADDR Sphere1Radius,sphere1Parts
        mov GlSphere1,eax
        invoke  CreateSphere,2,GLU_FILL,GLU_SMOOTH,ADDR Sphere2Color,ADDR Sphere2Radius,sphere2Parts
        mov GlSphere2,eax
        invoke  CreateSphere,3,GLU_FILL,GLU_SMOOTH,ADDR Sphere3Color,ADDR Sphere3Radius,sphere3Parts
        mov GlSphere3,eax
        invoke  CreateSphere,4,GLU_FILL,GLU_SMOOTH,ADDR Sphere4Color,ADDR Sphere4Radius,sphere4Parts
        mov GlSphere4,eax
        invoke  CreateSphere,5,GLU_FILL,GLU_SMOOTH,ADDR Sphere5Color,ADDR Sphere5Radius,sphere5Parts
        mov GlSphere5,eax
        invoke  CreateSphere,6,GLU_FILL,GLU_SMOOTH,ADDR Sphere6Color,ADDR Sphere6Radius,sphere6Parts
        mov GlSphere6,eax
        invoke  CreateSphere,7,GLU_FILL,GLU_SMOOTH,ADDR Sphere7Color,ADDR Sphere7Radius,sphere7Parts
        mov GlSphere7,eax
        ; Set global flags
        invoke  glEnable,GL_DEPTH_TEST
        invoke  glEnable,GL_LIGHTING
        invoke  glEnable,GL_CULL_FACE       ; Don't render back faces
        invoke  glShadeModel,GL_SMOOTH
        invoke  glEnable,GL_NORMALIZE
        ret
GlInit  ENDP

; --------------- Display the scene
DrawScene   PROC
        invoke  glClear,GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT
        invoke  glPushMatrix
        invoke  RotateObject,1,ADDR Sphere1Position,ADDR Sphere1AnglesSpeedFlt,ADDR Sphere1AnglesFlt
        invoke  glPushMatrix
        invoke  RotateObject,2,ADDR Sphere2Position,ADDR Sphere2AnglesSpeedFlt,ADDR Sphere2AnglesFlt
        invoke  glLightfv,GL_LIGHT0,GL_POSITION,ADDR LightSourcePosition
        invoke  glPopMatrix
        invoke  glPushMatrix
        invoke  RotateObject,3,ADDR Sphere3Position,ADDR Sphere3AnglesSpeedFlt,ADDR Sphere3AnglesFlt
        invoke  glLightfv,GL_LIGHT1,GL_POSITION,ADDR LightSource2Position
        invoke  glPopMatrix
        invoke  glPushMatrix
        invoke  RotateObject,4,ADDR Sphere4Position,ADDR Sphere4AnglesSpeedFlt,ADDR Sphere4AnglesFlt
        invoke  glLightfv,GL_LIGHT2,GL_POSITION,ADDR LightSource3Position
        invoke  glPopMatrix
        invoke  glPushMatrix
        invoke  RotateObject,5,ADDR Sphere5Position,ADDR Sphere5AnglesSpeedFlt,ADDR Sphere5AnglesFlt
        invoke  glPopMatrix
        invoke  glPushMatrix
        invoke  RotateObject,6,ADDR Sphere6Position,ADDR Sphere6AnglesSpeedFlt,ADDR Sphere6AnglesFlt
        invoke  glPopMatrix
        invoke  glPushMatrix
        invoke  RotateObject,7,ADDR Sphere7Position,ADDR Sphere7AnglesSpeedFlt,ADDR Sphere7AnglesFlt
        invoke  glPopMatrix
        invoke  glPopMatrix
        invoke  SwapBuffers,MainHDC
        ret
DrawScene   ENDP

; --------------- Resize the scene
ResizeObject    PROC    ParentW:DWORD,ParentH:DWORD
        invoke  glViewport,0,0,ParentW,ParentH
        invoke  glMatrixMode,GL_PROJECTION
        invoke  glLoadIdentity
        invoke  gluPerspective, Value45Dbl, Value1Dbl, Value3Dbl, Value7Dbl 
        invoke  glMatrixMode,GL_MODELVIEW
        invoke  glLoadIdentity
        ret
ResizeObject    ENDP

; --------------- Free the memory allocated for the spheres
DeleteSpheres   PROC
        invoke  gluDeleteQuadric,GlSphere1
        invoke  gluDeleteQuadric,GlSphere2
        invoke  gluDeleteQuadric,GlSphere3
        invoke  gluDeleteQuadric,GlSphere4
        invoke  gluDeleteQuadric,GlSphere5
        invoke  gluDeleteQuadric,GlSphere6
        invoke  gluDeleteQuadric,GlSphere7
        ret
DeleteSpheres   ENDP

; --------------- Create a sphere with glu object
CreateSphere    PROC    ListNumber:DWORD,FillType:DWORD,NormalsType:DWORD,
			Color:DWORD,Radius:DWORD,Parts:DWORD
        LOCAL   GlSphere:DWORD
        invoke  glNewList,ListNumber,GL_COMPILE
        ; Create a template
        invoke  gluNewQuadric
        mov GlSphere,eax
        ; Set object draw style
        invoke  gluQuadricDrawStyle,GlSphere,FillType
        ; Set normals style
        invoke  gluQuadricNormals,GlSphere,NormalsType
        ; Set object color
        invoke  glMaterialfv,GL_FRONT,GL_AMBIENT_AND_DIFFUSE,Color
        mov eax,Radius
        ; Create a sphere primitive
        invoke  gluSphere, GlSphere,[eax], Parts, Parts
        invoke  glEndList
        mov eax,GlSphere
        ret
CreateSphere    ENDP

; --------------- Set a light source
SetLightSource  PROC    LtNumber:DWORD,LtPosition:DWORD,LtAmbient:DWORD
        invoke  glLightfv,LtNumber,GL_POSITION,LtPosition
        invoke  glLightfv,LtNumber,GL_DIFFUSE,ADDR LightDiffuse
        invoke  glLightfv,LtNumber,GL_SPECULAR,ADDR LightSpecular
        invoke  glLightfv,LtNumber,GL_AMBIENT,LtAmbient
        invoke  glLightfv,LtNumber,GL_CONSTANT_ATTENUATION,ADDR LightConstAtt
        invoke  glLightfv,LtNumber,GL_LINEAR_ATTENUATION,ADDR LightLinAtt
        invoke  glLightfv,LtNumber,GL_QUADRATIC_ATTENUATION,ADDR LightQuadAtt
        invoke  glLightfv,LtNumber,GL_SPOT_CUTOFF,ADDR SpotCut
        invoke  glLightfv,LtNumber,GL_SPOT_EXPONENT,ADDR SpotExp
        invoke  glLightfv,LtNumber,GL_SPOT_DIRECTION,ADDR SpotDir
        invoke  glEnable,LtNumber
        ret 
SetLightSource  ENDP

; --------------- Position and rotate an object
RotateObject    PROC    ListNumber:DWORD,XYZPosition:DWORD,XYZRotations:DWORD,XYZAngles:DWORD
        LOCAL   LocXSpd:DWORD
        LOCAL   LocYSpd:DWORD
        LOCAL   LocZSpd:DWORD
        LOCAL   LocXAngle:DWORD
        LOCAL   LocYAngle:DWORD
        LOCAL   LocZAngle:DWORD
        mov eax,XYZPosition
        mov ecx,[eax]
        mov ebx,[eax+4]
        mov eax,[eax+8]
        invoke  glTranslatef,ecx,ebx,eax
        mov eax,XYZAngles           ; Rotate X
        mov ebx,XYZRotations
        fld DWORD PTR [eax]
        fadd    DWORD PTR [ebx]
        fstp    DWORD PTR [eax]
        invoke  glRotatef,[eax],Value0Flt,Value1Flt,Value0Flt
        mov eax,XYZAngles           ; Rotate Y
        mov ebx,XYZRotations
        fld DWORD PTR [eax+4]
        fadd    DWORD PTR [ebx+4]
        fstp    DWORD PTR [eax+4]
        invoke  glRotatef,[eax+4],Value1Flt,Value0Flt,Value0Flt
        mov eax,XYZAngles           ; Rotate Z
        mov ebx,XYZRotations
        fld DWORD PTR [eax+8]
        fadd    DWORD PTR [ebx+8]
        fstp    DWORD PTR [eax+8]
        invoke  glRotatef,DWORD PTR [eax+8],Value0Flt,Value0Flt,Value1Flt
        invoke  glCallList,ListNumber
        ret
RotateObject    ENDP

; --------------- Program end
end start