.586p
.MODEL FLAT,STDCALL      ;__SGI__=1 ; Enable this if you want to use SGI's version of OpenGL
OPTION SCOPED        
OPTION CASEMAP:NONE  
ScrWIDTH  = 640  
ScrHEIGHT = 480
ScrBPP    = 24
.XLIST
include windows.inc
.LIST
include \masm32\include\gl.def
include \masm32\include\glu.def
IFDEF __SGI__
includelib \masm32\lib\opengl.lib
includelib \masm32\lib\glu.lib
ELSE
includelib \masm32\lib\opengl32.lib
includelib \masm32\lib\glu32.lib
ENDIF
include \masm32\include\kernel32.inc
include \masm32\include\user32.inc
include \masm32\include\gdi32.inc
include \masm32\include\winextra.def
include \masm32\include\ddraw.def
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib
includelib \masm32\lib\gdi32.lib
includelib \masm32\lib\ddraw.lib

.DATA
defstring DD_libname,'ddraw.dll'
defstring DD_create,'DirectDrawCreate'
defstring MyClassName,'W32AsmClass'
IFDEF __SGI__
defstring WinTitleString,'OpenGL fullscreen in Assembly (SGI)'
ELSE
defstring WinTitleString,'OpenGL fullscreen in Assembly (MS)'
ENDIF
ALIGN DWORD
Roll GLfloat 0.0
rotstep GLfloat 0.5
lpDD LPDIRECTDRAW NULL
.DATA?
ALIGN DWORD
hdc HDC ?   ; GDI device context
hrc HGLRC ? ; OGL rendering context
hWindow HWND ?
hInstance HANDLE ?
Activity DWORD ?
FullScreen BOOLEAN ?

.CODE 
SetFullscreen PROC hWnd:HWND,screenwidth:DWORD,screenheight:DWORD,bpp:DWORD
LOCAL devmode:DEVMODE  ;  ======  ustawienia monitora ========
LOCAL modnum:DWORD
 invoke LoadLibrary,ADDR DD_libname
 test eax,eax
 jnz ddLoaded
LetsTryAnotherWay:
 mov modnum,0
SearchVideoMode:
 invoke EnumDisplaySettings,NULL,modnum,ADDR devmode
 test eax,eax
 jz Error
 mov eax,screenwidth
 mov edx,screenheight
 mov ecx,bpp
 .if (eax==devmode.dmPelsWidth)&&\
      (edx==devmode.dmPelsHeight)&&\
        (ecx==devmode.dmBitsPerPel)
   invoke ChangeDisplaySettings,ADDR devmode,CDS_FULLSCREEN
   .if eax==DISP_CHANGE_SUCCESSFUL
     jmp Done
   .endif
   mov devmode.dmFields,DM_BITSPERPEL or DM_PELSWIDTH or DM_PELSHEIGHT
   invoke ChangeDisplaySettings,ADDR devmode,CDS_FULLSCREEN
   .if eax==DISP_CHANGE_SUCCESSFUL
     jmp Done
   .endif
    mov devmode.dmFields,DM_BITSPERPEL
   invoke ChangeDisplaySettings,ADDR devmode,CDS_FULLSCREEN
   .if eax==DISP_CHANGE_SUCCESSFUL
      mov devmode.dmFields,DM_PELSWIDTH or DM_PELSHEIGHT
      invoke ChangeDisplaySettings,ADDR devmode,CDS_FULLSCREEN
      .if eax==DISP_CHANGE_SUCCESSFUL
        jmp Done
      .endif
   .endif
 .else
  inc modnum
  jmp SearchVideoMode
 .endif
Error:
 stc
 ret
Done:
 clc
 ret
ddLoaded:
 invoke GetProcAddress,eax,ADDR DD_create
 test eax,eax
 jz LetsTryAnotherWay
 push NULL
 push OFFSET lpDD
 push NULL
 call eax
 clc
 ret
SetFullscreen ENDP  ;====== koniec ustawienia monitora 

SetGLViewport PROC w:DWORD,h:DWORD  ;=====
 invoke glViewport,0,0,w,h
 ret
SetGLViewport ENDP                  ;=====

SetupOpenGL PROC hWnd;============== OpenGL initialization
LOCAL pfd:PIXELFORMATDESCRIPTOR
LOCAL pixformat:DWORD
 mov FullScreen,FALSE
 invoke SetFullscreen,hWnd,ScrWIDTH,ScrHEIGHT,ScrBPP
 .if CARRY?
  GenericErrMsg hWnd,'Unable to switch to fullscreen'
  return FALSE
 .endif
  mov FullScreen,TRUE

 invoke GetDC,hWnd
 mov hdc,eax
 mov pfd.nSize,sizeof(PIXELFORMATDESCRIPTOR)
 mov pfd.nVersion,1
 mov pfd.dwFlags,PFD_SUPPORT_OPENGL OR PFD_DOUBLEBUFFER
 mov pfd.dwLayerMask,PFD_MAIN_PLANE
 mov pfd.iPixelType,PFD_TYPE_RGBA
 mov pfd.cColorBits,16
 mov pfd.cDepthBits,16
 mov pfd.cAccumBits,0
 mov pfd.cStencilBits,0
 invoke ChoosePixelFormat,hdc,ADDR pfd
 mov pixformat,eax
 
 invoke SetPixelFormat,hdc,pixformat,ADDR pfd
 invoke wglCreateContext,hdc
 mov hrc,eax
 invoke wglMakeCurrent,hdc,hrc

 _glMatrixMode GL_PROJECTION
 _glFrustum    -0.5f,  0.5f, -0.5f, 0.5f,  0.3f,  4.0f
 _glMatrixMode GL_MODELVIEW   ;* position viewer
 _glTranslatef 0.0f,0.0f,-2.0f
 _glShadeModel GL_SMOOTH
 _glEnable   GL_DEPTH_TEST  ; GL_LIGHT0      
 _glEnable   GL_LIGHTING    ;GL_CULL_FACE ; okresla swiatlo przenikanie
                            ;_glEnable  GL_SPOT_DIRECTION   

 return TRUE
SetupOpenGL ENDP

KillOpenGL PROC    ; ===============wycofanie open gl
 invoke wglMakeCurrent,NULL,NULL
 invoke wglDeleteContext,hrc
 invoke ReleaseDC,hWindow,hdc
 ret
KillOpenGL ENDP    ; koniec===========wycofanie open gl

GL_Paint PROC      ;            rysowanie ====
 .if hrc
 invoke glPushMatrix
 invoke glMatrixMode,GL_MODELVIEW

invoke glClear,GL_COLOR_BUFFER_BIT OR GL_DEPTH_BUFFER_BIT
invoke glDisable,GL_LIGHTING    ;===wylaczenie swiatla


 
invoke glBegin,GL_TRIANGLES ; trujkat =====================
                       _glColor3f 1.0f,0.0f,0.0f
  _glVertex3f  -1.0f,-1.0f,-1.0f
  _glVertex3f  -1.0f,-1.0f,1.0f
  _glVertex3f  -1.0f,1.0f,1.0f
invoke glEnd

invoke glBegin,GL_POINTS    ; punkt   =====================   
                       _glColor3f 1.0f,1.0f,1.0f 
  _glVertex3f  0.5f,0.0f,-0.5f  
invoke glEnd

invoke glBegin,GL_LINES 
  _glColor3f   0.0f,1.0f, 0.0f 
  _glVertex3f  -1.0f,0.0f,0.0f  
  _glVertex3f  1.0f,0.0f,0.0f 

  _glVertex3f  0.0f,1.0f,0.0f  
  _glVertex3f  0.0f,-1.0f,0.0f 

  _glVertex3f  0.0f,0.0f,1.0f  
  _glVertex3f  0.0f,0.0f,-1.0f 


invoke glEnd


 _glRotatef Roll,   0.0f,1.0f,0.0f   ; obroty =============
 _glRotatef 30.of,  0.0f,0.0f,1.0f
 _glRotatef Roll,   1.0f,0.0f,0.0f
 fld Roll
 fadd rotstep
 fstp Roll                           ; koniec obroty ========  
 

invoke glBegin,GL_TRIANGLES ; trujkat =====================
      _glColor3f 0.0f,1.0f,1.0f
  _glVertex3f  0.4f,0.0f,0.0f
  _glVertex3f  0.0f,0.4f,0.0f
  _glVertex3f  0.0f,0.0f,0.0f
                       _glColor3f 1.0f,1.0f,0.0f
  _glVertex3f  0.4f,0.0f,0.0f
  _glVertex3f  0.0f,0.0f,0.0f
  _glVertex3f  0.0f,0.0f,0.4f
                       _glColor3f 1.0f,0.0f,1.0f
  _glVertex3f  0.0f,0.0f,0.0f        
  _glVertex3f  0.0f,0.4f,0.0f
  _glVertex3f  0.0f,0.0f,0.4f
                       _glColor3f 1.0f,0.5f,0.4f 
  _glVertex3f  0.4f,0.0f,0.0f        
  _glVertex3f  0.0f,0.4f,0.0f
  _glVertex3f  0.0f,0.0f,0.4f
invoke glEnd

 invoke glPopMatrix
 invoke glFinish
 invoke glFlush
 invoke SwapBuffers,hdc
 .endif
 ret
GL_Paint ENDP






ALIGN 4

MainWinProc PROC hWnd:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM
LOCAL ps:PAINTSTRUCT
LOCAL crect:RECT
 mov eax,uMsg
  .if eax==WM_CREATE
    sub eax,eax
  .elseif eax==WM_KEYDOWN
    .if wParam==VK_ESCAPE
      invoke PostMessage,hWnd,WM_CLOSE,NULL,NULL
    .endif
    sub eax,eax
  .elseif eax==WM_DESTROY
    .if FullScreen
     call KillOpenGL
     .if lpDD
     .else
      invoke ChangeDisplaySettings,NULL,0
     .endif
    .endif
    invoke PostQuitMessage,0
  .elseif eax==WM_ACTIVATEAPP
    push wParam
    pop Activity
    xor eax,eax
 .elseif eax==WM_PAINT
    invoke BeginPaint,hWnd,ADDR ps
    call GL_Paint                   ; skok do rysowania
    
    invoke EndPaint,hWnd,ADDR ps
    sub eax,eax
 .else
    invoke DefWindowProc,hWnd,uMsg,wParam,lParam
 .endif
 ret
MainWinProc ENDP



ALIGN 4

WinMain PROC hInst:DWORD,prevInstance:DWORD,cmdlinePtr:DWORD,cmdShow:DWORD
LOCAL wc:WNDCLASSEX
LOCAL msg:MSG
 lea edi,wc
 sub eax,eax
 mov ecx,(sizeof WNDCLASSEX)/4
 rep stosd
 mov eax,hInst
 mov hInstance,eax
 mov wc.hInstance,eax
 mov wc.cbSize,sizeof(WNDCLASSEX)
 mov wc.style,CS_OWNDC or CS_HREDRAW or CS_VREDRAW
 mov wc.lpszClassName,offset MyClassName
 mov wc.lpfnWndProc,offset MainWinProc
 invoke LoadCursor,NULL,IDC_ARROW
 mov wc.hCursor,eax
 mov wc.hbrBackground,COLOR_GRAYTEXT

 invoke RegisterClassEx,ADDR wc

 sub eax,eax
 invoke CreateWindowEx,NULL,ADDR MyClassName,ADDR WinTitleString,WS_POPUP or WS_MAXIMIZE or WS_CLIPSIBLINGS or WS_CLIPCHILDREN,0,0,ScrWIDTH,ScrHEIGHT,eax,eax,hInst,eax
 mov hWindow,eax
 invoke ShowWindow,eax,SW_SHOWDEFAULT
 invoke UpdateWindow,hWindow  ; send WM_PAINT to the window proc
 invoke SetupOpenGL,hWindow
 test eax,eax
 jz Abort
 invoke SetGLViewport,ScrWIDTH,ScrHEIGHT

@@winmainmsgloop:
 invoke InvalidateRect,hWindow,NULL,FALSE ; forse WM_PAINT
 sub eax,eax
 lea edi,msg
 invoke GetMessage,edi,eax,eax,eax
 test eax,eax
 jz @@quitmsgposted
 push edi
 push edi
 call TranslateMessage
 call DispatchMessage
 jmp @@winmainmsgloop
 EVEN
@@quitmsgposted:
 mov eax,msg.wParam
Abort::
 invoke ExitProcess,eax
 ret
WinMain ENDP


Start:
 invoke GetModuleHandle,NULL ; Get hInstance
 sub edx,edx
 invoke WinMain,eax,edx,edx,edx

END Start
