§ Справка

Существует справочный материал по OpenGL 1.2 от IBM.

§ Структура программы

  • Инициализация приложения Windows
  • Создание окна и назначение процедуры обработки сообщений
  • Бесконечный цикл ожидания новых системных сообщений
  • Процедура обработки сообщений
Процедура состоит из обработки следующих соообщений.
  • WM_CREATE: Вызывается при создании окна. Инициализация OpenGL
  • WM_SIZE: Изменение размеров окна
  • WM_PAINT: Перерисовка окна
  • WM_KEYDOWN: Нажатие на клавишу
  • WM_DESTROY: Закрытие окна
Инициализация OpenGL
  • Получение Drawing Canvas окна через GetDC
  • Заполнение структуры PIXELFORMATDESCRIPTOR
  • Выбор формата пикселей через ChoosePixelFormat и SetPixelFormat, создание контекста wglCreateContext, назначение его текущим wglMakeCurrent
  • Получение размера окна GetClientRect и назначение области рисования glViewport

§ Программный код

Программа, которая рисует вращающийся текстурированный квадрат.
format  PE GUI 4.0
entry   start

include 'include/win32a.inc'
include 'opengl.inc'

section '.text' code readable executable

start:

    invoke      GetModuleHandle,0
    mov         [wc.hInstance], eax
    invoke      LoadIcon, 0, IDI_APPLICATION
    mov         [wc.hIcon], eax
    invoke      LoadCursor, 0, IDC_ARROW
    mov         [wc.hCursor], eax
    invoke      RegisterClass,wc
    invoke      CreateWindowEx,0,_class,_title,\
                WS_VISIBLE+WS_OVERLAPPEDWINDOW+WS_CLIPCHILDREN+WS_CLIPSIBLINGS,\
                16,16,432,432,NULL,NULL,[wc.hInstance],NULL
[wc.hInstance], NULL
    mov         [hwnd], eax

msg_loop:

    invoke      GetMessage,msg,NULL,0,0
    or          eax, eax
    jz          end_loop
    invoke      TranslateMessage,msg
    invoke      DispatchMessage,msg
    jmp         msg_loop

end_loop:

    invoke      ExitProcess,[msg.wParam]

; Основной обработчик окна
; ----------------------------------------------------------------------
proc WindowProc hwnd,wmsg,wparam,lparam

    push        ebx esi edi
    cmp         [wmsg], WM_CREATE
    je          .wmcreate
    cmp         [wmsg], WM_SIZE
    je          .wmsize
    cmp         [wmsg], WM_PAINT
    je          .wmpaint
    cmp         [wmsg], WM_KEYDOWN
    je          .wmkeydown
    cmp         [wmsg], WM_DESTROY
    je          .wmdestroy

.defwndproc:

    invoke      DefWindowProc,[hwnd],[wmsg],[wparam],[lparam]
    jmp         .finish

.wmcreate:

    invoke      GetDC,[hwnd]
    mov         [hdc],eax
    mov         edi, pfd
    mov         ecx, sizeof.PIXELFORMATDESCRIPTOR shr 2
    xor         eax,eax
    rep         stosd
    mov         [pfd.nSize],sizeof.PIXELFORMATDESCRIPTOR
    mov         [pfd.nVersion],1
    mov         [pfd.dwFlags], PFD_SUPPORT_OPENGL+PFD_DOUBLEBUFFER+PFD_DRAW_TO_WINDOW
    mov         [pfd.iLayerType], 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],pfd
    invoke      SetPixelFormat,[hdc],eax,pfd
    invoke      wglCreateContext,[hdc]
    mov         [hrc], eax
    invoke      wglMakeCurrent,[hdc],[hrc]
    invoke      GetClientRect,[hwnd],rc
    invoke      glViewport,0,0,[rc.right],[rc.bottom]

; Загрузка простой текстуры
; ----------------------------------------------------------------------

    mov         esi, pTexture
    xor         eax, eax
    mov         ecx, 256*256
@@: mov         ah, cl
    xor         ah, ch
    stosd
    loop        @b

    invoke      glEnable, GL_TEXTURE_2D
    invoke      glGenTextures, 1, aTextures
    invoke      glBindTexture, GL_TEXTURE_2D, [aTextures]
    invoke      glTexImage2D, GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, pTexture
    invoke      glTexParameteri, GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT
    invoke      glTexParameteri, GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT
    invoke      glTexParameteri, GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR
    invoke      glTexParameteri, GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR

    invoke      GetTickCount
    mov         [clock], eax
    xor         eax, eax
    jmp         .finish

.wmsize:

    invoke      GetClientRect,[hwnd],rc
    invoke      glViewport,0,0,[rc.right],[rc.bottom]
    xor         eax, eax
    jmp         .finish

.wmpaint:

    invoke      GetTickCount
    sub         eax, [clock]
    cmp         eax, 10
    jb          .animation_ok
    add         [clock], eax

    invoke      glRotatef,[theta],0.0,0.0,1.0

.animation_ok:

    invoke      glClear,GL_COLOR_BUFFER_BIT
    invoke      glBegin,GL_QUADS
    invoke      glBindTexture,GL_TEXTURE_2D,[aTextures]

    invoke      glVertex3f,-0.6,-0.6,0.0
    invoke      glTexCoord2f,0.0,0.0

    invoke      glVertex3f,0.6,-0.6,0.0
    invoke      glTexCoord2f,1.0,0.0

    invoke      glVertex3f,0.6,0.6,0.0
    invoke      glTexCoord2f,1.0,1.0

    invoke      glVertex3f,-0.6,0.6,0.0
    invoke      glTexCoord2f,0.0,1.0

    invoke      glEnd
    invoke      SwapBuffers,[hdc]
    xor         eax, eax
    jmp         .finish

.wmkeydown:

    cmp         [wparam],VK_ESCAPE
    jne         .defwndproc

.wmdestroy:

    invoke      wglMakeCurrent,0,0
    invoke      wglDeleteContext,[hrc]
    invoke      ReleaseDC,[hwnd],[hdc]
    invoke      PostQuitMessage,0
    xor         eax, eax

.finish:

    pop         edi esi ebx
    ret

endp

; ----------------------------------------------------------------------
section '.data' data readable writeable

_title      db 'Windows XP OpenGL Assembly',0
_class      db 'FASMOPENGL32',0
theta       GLfloat 0.6
wc          WNDCLASS 0,WindowProc,0,0,NULL,NULL,NULL,NULL,NULL,_class
hwnd        dd ?
hdc         dd ?
hrc         dd ?
clock       dd ?
aTextures   dd ?
rc          RECT
msg         MSG
pfd         PIXELFORMATDESCRIPTOR
dd          ?
; Данные от PDF слегка выходят за пределы
pTexture:   times (4*65536) db ?

include "idata.asm"
И конечно, куда же без makefile:
all:
	fasm opengl.asm
	rem ollydbg opengl.exe

§ Библиотеки

Для ассемблера fasm потребуются некоторые файлы.