rendered paste body; 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