; OpenGL example in x86 Linux assembler / NASM using Glut ; Author: Wesley Stessens (wesley@ubuntu.com) ; ; OpenGL calls to create pyramid and cube are from Jeff Molofee's OpenGL tutorial ; See: http://nehe.gamedev.net/data/lessons/lesson.asp?lesson=05 ; ; Features: ; - Calling C functions by cdecl conventions ; - Using GLUT and OpenGL calls to perform 3D graphics ; - Low-level framerate control ; ; Sample compile instructions: ; nasm -felf ogl.asm && ld -lglut -s -I/lib/ld-linux.so.2 -o ogl ogl.o ; ; This code is released as sample code in the public domain. Use it for whatever you want. ; Feel free to let me know if you found this code useful in any way. ; Glut extern glutInit, glutInitDisplayMode, glutInitWindowSize, glutInitWindowPosition extern glutCreateWindow, glutMainLoop extern glutDisplayFunc, glutIdleFunc, glutReshapeFunc, glutKeyboardFunc extern glutSwapBuffers ; Glu extern gluPerspective ; OpenGL extern glClearColor, glClearDepth, glDepthFunc, glEnable, glShadeModel extern glClear, glLoadIdentity, glMatrixMode, glViewport extern glTranslatef, glRotatef, glBegin, glEnd, glVertex3f, glColor3f ; Needed for framerate control extern usleep ; Macros %macro _3call 4 push dword %4 push dword %3 push dword %2 call %1 add esp, 12 %endmacro %macro _4call 5 push dword %5 push dword %4 push dword %3 push dword %2 call %1 add esp, 16 %endmacro section .data title: db 'OpenGL in x86 Linux assembler / NASM using Glut', 0 ; Data for FP math with 4 bytes n7: dd -7.0 n6: dd -6.0 n1p5: dd -1.5 n1: dd -1.0 p0p4: dd 0.4 p0p5: dd 0.5 p1: dd 1.0 p1p5: dd 1.5 p3: dd 3.0 rottrm: dd 4.5 rotsqm: dd -3.0 ; Data for FP math with 8 bytes q0p1: dq 0.1 q1: dq 1.0 q45: dq 45.0 q100: dq 100.0 ; Data for framerate control mspf: dd 20000 ; ms per frame section .bss ; Vars for rotation rottr: resd 1 rotsq: resd 1 ; Var for aspect ratio aspr: resq 1 ; Vars for framerate control time: resd 2 usecs: resd 1 oldslp: resd 1 section .text global _start fpsmanager: push eax push ebx push ecx push edx mov eax, 78 ; sys_gettimeofday mov ebx, time mov ecx, 0 int 80h mov eax, [time + 4] sub eax, [usecs] mov ebx, [mspf] sub ebx, eax test eax, eax js keep_sleep test ebx, ebx js keep_sleep push ebx call usleep add esp, 4 mov dword [oldslp], ebx jmp done_sleep keep_sleep: push dword [oldslp] call usleep add esp, 4 done_sleep: mov eax, [time + 4] mov dword [usecs], eax pop edx pop ecx pop ebx pop eax ret display: ; Prepare for drawing push dword 4100h ; GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT call glClear add esp, 4 call glLoadIdentity ; Draw pyramid on the left of the screen _3call glTranslatef, [n1p5], 0, [n6] _4call glRotatef, [rottr], 0, [p1], 0 push dword 9h ; GL_POLYGON call glBegin add esp, 4 _3call glColor3f, [p1], 0, 0 ; Start drawing front face _3call glVertex3f, 0, [p1], 0 _3call glColor3f, 0, [p1], 0 _3call glVertex3f, [n1], [n1], [p1] _3call glColor3f, 0, 0, [p1] _3call glVertex3f, [p1], [n1], [p1] _3call glColor3f, [p1], 0, 0 ; Start drawing right face _3call glVertex3f, 0, [p1], 0 _3call glColor3f, 0, 0, [p1] _3call glVertex3f, [p1], [n1], [p1] _3call glColor3f, 0, [p1], 0 _3call glVertex3f, [p1], [n1], [n1] _3call glColor3f, [p1], 0, 0 ; Start drawing back face _3call glVertex3f, 0, [p1], 0 _3call glColor3f, 0, [p1], 0 _3call glVertex3f, [p1], [n1], [n1] _3call glColor3f, 0, 0, [p1] _3call glVertex3f, [n1], [n1], [n1] _3call glColor3f, [p1], 0, 0 ; Start drawing right face _3call glVertex3f, 0, [p1], 0 _3call glColor3f, 0, 0, [p1] _3call glVertex3f, [n1], [n1], [n1] _3call glColor3f, 0, [p1], 0 _3call glVertex3f, [n1], [n1], [p1] call glEnd ; Draw cube on the right of the screen call glLoadIdentity _3call glTranslatef, [p1p5], 0, [n7] _4call glRotatef, [rotsq], [p1], [p0p4], [p0p5] push dword 7h ; GL_QUADS call glBegin add esp, 4 _3call glColor3f, 0, [p1], 0 ; Start drawing top face _3call glVertex3f, [p1], [p1], [n1] _3call glVertex3f, [n1], [p1], [n1] _3call glVertex3f, [n1], [p1], [p1] _3call glVertex3f, [p1], [p1], [p1] _3call glColor3f, [p1], [p0p5], 0 ; Start drawing bottom face _3call glVertex3f, [p1], [n1], [p1] _3call glVertex3f, [n1], [n1], [p1] _3call glVertex3f, [n1], [n1], [n1] _3call glVertex3f, [p1], [n1], [n1] _3call glColor3f, [p1], 0, 0 ; Start drawing front face _3call glVertex3f, [p1], [p1], [p1] _3call glVertex3f, [n1], [p1], [p1] _3call glVertex3f, [n1], [n1], [p1] _3call glVertex3f, [p1], [n1], [p1] _3call glColor3f, [p1], [p1], 0 ; Start drawing back face _3call glVertex3f, [p1], [n1], [n1] _3call glVertex3f, [n1], [n1], [n1] _3call glVertex3f, [n1], [p1], [n1] _3call glVertex3f, [p1], [p1], [n1] _3call glColor3f, 0, 0, [p1] ; Start drawing left face _3call glVertex3f, [n1], [p1], [p1] _3call glVertex3f, [n1], [p1], [n1] _3call glVertex3f, [n1], [n1], [n1] _3call glVertex3f, [n1], [n1], [p1] _3call glColor3f, [p1], 0, [p1] ; Start drawing right face _3call glVertex3f, [p1], [p1], [n1] _3call glVertex3f, [p1], [p1], [p1] _3call glVertex3f, [p1], [n1], [p1] _3call glVertex3f, [p1], [n1], [n1] call glEnd ; Update rotation fld dword [rottr] fadd dword [rottrm] fstp dword [rottr] fld dword [rotsq] fadd dword [rotsqm] fstp dword [rotsq] call glutSwapBuffers ; Swap buffers and display call fpsmanager ; Cap framerate if necessary ret reshape: push ebp mov ebp, esp ; Prevent division by zero cmp dword [ebp+8], 0 jne reshape_2 inc dword [ebp+8] reshape_2: fild dword [ebp+8] fidiv dword [ebp+12] fstp qword [aspr] push dword [ebp+12] push dword [ebp+8] push dword 0 push dword 0 call glViewport add esp, 16 push dword 1701h; GL_PROJECTION call glMatrixMode add esp, 4 call glLoadIdentity push dword [q100+4] push dword [q100] push dword [q0p1+4] push dword [q0p1] push dword [aspr+4] push dword [aspr] push dword [q45+4] push dword [q45] call gluPerspective add esp, 32 push dword 1700h; GL_MODELVIEW call glMatrixMode add esp, 4 pop ebp ret keyhandler: ret _start: ; Initialize glut push dword [esp+8] lea eax, [esp+8] push eax call glutInit add esp, 8 push dword 1ah ; GLUT_RGBA|GLUT_DOUBLE|GLUT_ALPHA|GLUT_DEPTH call glutInitDisplayMode add esp, 4 push dword 480 push dword 640 call glutInitWindowSize add esp, 8 push dword 0 push dword 0 call glutInitWindowPosition add esp, 8 ; Create window push title call glutCreateWindow add esp, 4 ; Register functions push display call glutDisplayFunc call glutIdleFunc add esp, 4 push reshape call glutReshapeFunc add esp, 4 push keyhandler call glutKeyboardFunc add esp, 4 ; Initialize OpenGL push dword 0 push dword 0 push dword 0 push dword 0 call glClearColor add esp, 16 push dword [q1+4] push dword [q1] call glClearDepth add esp, 8 push dword 203h; GL_LEQUAL call glDepthFunc add esp, 4 push dword 0b71h; GL_DEPTH_TEST call glEnable add esp, 4 push dword 1d01h; GL_SMOOTH call glShadeModel add esp, 4 ; Frame rate cap initialization mov dword [oldslp], 0 ; Enter main loop call glutMainLoop ; Exit (return with error code 0) mov eax, 1 ; sys_exit mov ebx, 0 int 80h