; ------------------------------------------
; 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
|