Ik ben een beetje met x86 Linux assembler / NASM aan het spelen.
Na wat zoeken heb ik de nodige zaken bij elkaar gepuzzeld om de GLUT-bibliotheek via assembler aan te roepen.
Nu heb ik dus - na porten van voorbeeldcode van NeHe.gamedev.net - enkele ronddraaiende objecten.
Nu is mijn vraag echter.. heeft iemand een idee hoe ik de framerate hiervan zou kunnen cappen naar bv. ~30fps?
Ik heb niet meteen bruikbare kernelfuncties hiervoor kunnen vinden.
Misschien kan ik wel ergens de microseconden sinds opstart vinden.. iemand hier ervaring mee?
Ik vind mijn data section trouwens ook niet zo netjes.
Is het echt niet mogelijk om floating points in NASM te gebruiken zonder deze vooraf te moeten declareren?
Als iemand hier in geslaagd is, let me know please
Voor de geïnteresseerden, een port van de eerste lessenreeks naar assembler/GLUT:
; OpenGL example in x86 Linux assembler / NASM using Glut
; Author: Wesley Stessens [wesley@ubuntu.com]
; Original sample code for C/Windows by Jeff Molofee (NeHe)
;
; This code is released as sample code in the public domain
; Use it for whatever you want...
; 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
; 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
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 0.3
rotsqm: dd -0.2
q0p1: dq 0.1
q1: dq 1.0
q45: dq 45.0
q100: dq 100.0
section .bss
rottr: resd 1
rotsq: resd 1
aspr: resq 1
section .text
global _start
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]
; Swap buffers and display
call glutSwapBuffers
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
; Enter main loop
call glutMainLoop
; Exit (return with error code 0)
mov eax, 1
mov ebx, 0
int 80h
Compileren en linken kan met: nasm -felf filename.asm && ld -lglut -s -I/lib/ld-linux.so.2 -o filename filename.o
Het was toch wel een karwij om alles bij elkaar te puzzelen. Er is verrassend weinig informatie te vinden wat betreft NASM / Linux.
Men verwacht meestal dat je vroeger al met assembler in DOS hebt gewerkt...