Wybiral
January 11th, 2007, 05:49 AM
To demonstrate the similarity between a few common languages...
C++
//
//
//
#include <GL/glut.h>
int angle = 0;
void InitGL(int width, int height) {
//
glMatrixMode(GL_PROJECTION);
gluPerspective(45.0, (float)width/height, 0.1, 100.0);
glMatrixMode(GL_MODELVIEW);
glEnable(GL_DEPTH_TEST);
}
void DrawGLScene() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glTranslatef(0.0, 0.0, -6.0);
glRotatef(angle, 1.0, 1.0, 0.0);
glRotatef(angle, 0.0, 1.0, 0.0);
glBegin(GL_QUADS);
glColor3f(1,0,0); glVertex2f( 1.0,-1.0);
glColor3f(1,1,0); glVertex2f(-1.0,-1.0);
glColor3f(1,1,1); glVertex2f(-1.0, 1.0);
glColor3f(0,0,1); glVertex2f( 1.0, 1.0);
glEnd();
angle += 1;
glutSwapBuffers();
}
int main(int argc, char** argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
glutInitWindowSize(640, 480);
glutCreateWindow("OpenGL in C++");
glutIdleFunc(&DrawGLScene);
InitGL(640, 480);
glutMainLoop();
}
//
Perl
#
#
#
use OpenGL qw(:all);
my $angle = 0;
sub InitGL {
my ($width, $height) = @_;
glMatrixMode(GL_PROJECTION);
gluPerspective(45.0, $width/$height, 0.1, 100.0);
glMatrixMode(GL_MODELVIEW);
glEnable(GL_DEPTH_TEST);
}
sub DrawGLScene {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity;
glTranslatef(0.0, 0.0, -6.0);
glRotatef($angle, 1.0, 1.0, 0.0);
glRotatef($angle, 0.0, 1.0, 0.0);
glBegin(GL_QUADS);
glColor3f(1,0,0); glVertex2f( 1.0,-1.0);
glColor3f(1,1,0); glVertex2f(-1.0,-1.0);
glColor3f(1,1,1); glVertex2f(-1.0, 1.0);
glColor3f(0,0,1); glVertex2f( 1.0, 1.0);
glEnd;
$angle += 1;
glutSwapBuffers;
}
sub main {
glutInit;
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
glutInitWindowSize(640, 480);
glutCreateWindow("OpenGL in Perl");
glutIdleFunc(\&DrawGLScene);
InitGL(640, 480);
glutMainLoop;
}
main();
Python
import sys
from OpenGL.GL import *
from OpenGL.GLUT import *
from OpenGL.GLU import *
angle = 0
def InitGL(width, height):
#
glMatrixMode(GL_PROJECTION)
gluPerspective(45.0, float(width)/height, 0.1, 100.0)
glMatrixMode(GL_MODELVIEW)
glEnable(GL_DEPTH_TEST)
def DrawGLScene():
global angle
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glLoadIdentity()
glTranslatef(0.0, 0.0, -6.0)
glRotatef(angle, 1.0, 1.0, 0.0)
glRotatef(angle, 0.0, 1.0, 0.0)
glBegin(GL_QUADS)
glColor3f(1,0,0); glVertex2f( 1.0,-1.0)
glColor3f(1,1,0); glVertex2f(-1.0,-1.0)
glColor3f(1,1,1); glVertex2f(-1.0, 1.0)
glColor3f(0,0,1); glVertex2f( 1.0, 1.0)
glEnd()
angle += 1
glutSwapBuffers()
def main():
glutInit(sys.argv)
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH)
glutInitWindowSize(640, 480)
glutCreateWindow("OpenGL in Python")
glutIdleFunc(DrawGLScene)
InitGL(640, 480)
glutMainLoop()
main()
And just for fun, I disassembled the C version, optimized it a little, added some comments...
Gas Assembly
### Constants ###
.constTitle:
.string "OpenGL in GAS Assembly"
.constOneTenth:
.long -1717986918
.long 1069128089
.constAspectRatio:
.long 343597384
.long 1073039278
.constFOV:
.long 0
.long 1078362112
### Variables ###
.globl angle
.bss
.size angle, 4
angle:
.text
### Functions ###
.globl DrawGLScene
.globl main
DrawGLScene:
pushl %ebp
movl %esp, %ebp
subl $24, %esp
movl $16640, (%esp) #\__glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT)
call glClear #/
call glLoadIdentity #\__glLoadIdentity()
movl $0xc0c00000, 8(%esp) #\
movl $0x00000000, 4(%esp) # \__glTranslatef(0, 0, -6)
movl $0x00000000, (%esp) # /
call glTranslatef #/
pushl angle #\
fildl (%esp) # \
leal 4(%esp), %esp # \
movl $0x00000000, 12(%esp) # \__glRotatef(angle, 1, 1, 0)
movl $0x3f800000, 8(%esp) # /
movl $0x3f800000, 4(%esp) # /
fstps (%esp) # /
call glRotatef #/
pushl angle #\
fildl (%esp) # \
leal 4(%esp), %esp # \
movl $0x00000000, 12(%esp) # \__glRotatef(angle, 0, 1, 0)
movl $0x3f800000, 8(%esp) # /
movl $0x00000000, 4(%esp) # /
fstps (%esp) # /
call glRotatef #/
movl $7, (%esp) #\__glBegin(GL_QUADS)
call glBegin #/
movl $0, 8(%esp) #\
movl $0, 4(%esp) # \__glColor3b(127, 0, 0)
movl $127, (%esp) # /
call glColor3b #/
movl $-1, 4(%esp) #\
movl $1, (%esp) # \__glVertex2i(1, -1)
call glVertex2i #/
movl $0, 8(%esp) #\
movl $127, 4(%esp) # \__glColor3b(127, 127, 0)
movl $127, (%esp) # /
call glColor3b #/
movl $-1, 4(%esp) #\
movl $-1, (%esp) # \__glVertex2i(-1,-1)
call glVertex2i #/
movl $127, 8(%esp) #\
movl $127, 4(%esp) # \__glColor3b(127,127,127)
movl $127, (%esp) # /
call glColor3b #/
movl $1, 4(%esp) #\
movl $-1, (%esp) # \__glVertex2i(-1, 1)
call glVertex2i #/
movl $127, 8(%esp) #\
movl $0, 4(%esp) # \__glColor3b(0, 0, 127)
movl $0, (%esp) # /
call glColor3b #/
movl $1, 4(%esp) #\
movl $1, (%esp) # \__glVertex2i(1, 1)
call glVertex2i #/
call glEnd #\__glEnd()
incl angle #\__angle+=1
call glutSwapBuffers #\__glutSwapBuffers()
leave
ret
main:
leal 4(%esp), %ecx
andl $-16, %esp
pushl -4(%ecx)
pushl %ebp
movl %esp, %ebp
pushl %ecx
subl $36, %esp
movl 4(%ecx), %eax
movl %eax, 4(%esp) #\
movl %ecx, (%esp) # \__glutInit(&argc, argv)
call glutInit #/
movl $18, (%esp) #\__glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH)
call glutInitDisplayMode #/
movl $480, 4(%esp) #\
movl $640, (%esp) # \__glutInitWindowSize(640, 480)
call glutInitWindowSize #/
movl $.constTitle, (%esp) #\__glutCreateWindow(constTitle)
call glutCreateWindow #/
movl $DrawGLScene, (%esp) #\__glutIdleFunc(DrawGLScene)
call glutIdleFunc #/
movl $5889, (%esp) #\__glMatrixMode(GL_PROJECTION)
call glMatrixMode #/
movl $100, 24(%esp) #\
fldl .constOneTenth # \
fstpl 16(%esp) # \
fldl .constAspectRatio # \__gluPerspective(45, 1.33, 0.1, 100)
fstpl 8(%esp) # /
fldl .constFOV # /
fstpl (%esp) # /
call gluPerspective #/
movl $5888, (%esp) #\__glMatrixMode(GL_MODELVIEW)
call glMatrixMode #/
movl $2929, (%esp) #\__glEnable(GL_DEPTH_TEST)
call glEnable #/
call glutMainLoop #\__glutMainLoop()
To compile the C++ one, "g++ program.cpp -lglut"
To run the perl one "perl program.pl"
To run the python one "python program.py"
To assembly the GAS one "gcc program.s -lglut -s"
You will need the appropriate OpenGL modules/libraries for those languages (but, the assembly one uses the C libraries)
These examples use GLUT as well, so you will need freeGLUT installed.
You can also cut a few bytes off of the assembly one with a hex editor, but for simplicity just assembly that code above.
With the C, perl, and python examples I preserved the spacing to show how they line up so well.
C++
//
//
//
#include <GL/glut.h>
int angle = 0;
void InitGL(int width, int height) {
//
glMatrixMode(GL_PROJECTION);
gluPerspective(45.0, (float)width/height, 0.1, 100.0);
glMatrixMode(GL_MODELVIEW);
glEnable(GL_DEPTH_TEST);
}
void DrawGLScene() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glTranslatef(0.0, 0.0, -6.0);
glRotatef(angle, 1.0, 1.0, 0.0);
glRotatef(angle, 0.0, 1.0, 0.0);
glBegin(GL_QUADS);
glColor3f(1,0,0); glVertex2f( 1.0,-1.0);
glColor3f(1,1,0); glVertex2f(-1.0,-1.0);
glColor3f(1,1,1); glVertex2f(-1.0, 1.0);
glColor3f(0,0,1); glVertex2f( 1.0, 1.0);
glEnd();
angle += 1;
glutSwapBuffers();
}
int main(int argc, char** argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
glutInitWindowSize(640, 480);
glutCreateWindow("OpenGL in C++");
glutIdleFunc(&DrawGLScene);
InitGL(640, 480);
glutMainLoop();
}
//
Perl
#
#
#
use OpenGL qw(:all);
my $angle = 0;
sub InitGL {
my ($width, $height) = @_;
glMatrixMode(GL_PROJECTION);
gluPerspective(45.0, $width/$height, 0.1, 100.0);
glMatrixMode(GL_MODELVIEW);
glEnable(GL_DEPTH_TEST);
}
sub DrawGLScene {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity;
glTranslatef(0.0, 0.0, -6.0);
glRotatef($angle, 1.0, 1.0, 0.0);
glRotatef($angle, 0.0, 1.0, 0.0);
glBegin(GL_QUADS);
glColor3f(1,0,0); glVertex2f( 1.0,-1.0);
glColor3f(1,1,0); glVertex2f(-1.0,-1.0);
glColor3f(1,1,1); glVertex2f(-1.0, 1.0);
glColor3f(0,0,1); glVertex2f( 1.0, 1.0);
glEnd;
$angle += 1;
glutSwapBuffers;
}
sub main {
glutInit;
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
glutInitWindowSize(640, 480);
glutCreateWindow("OpenGL in Perl");
glutIdleFunc(\&DrawGLScene);
InitGL(640, 480);
glutMainLoop;
}
main();
Python
import sys
from OpenGL.GL import *
from OpenGL.GLUT import *
from OpenGL.GLU import *
angle = 0
def InitGL(width, height):
#
glMatrixMode(GL_PROJECTION)
gluPerspective(45.0, float(width)/height, 0.1, 100.0)
glMatrixMode(GL_MODELVIEW)
glEnable(GL_DEPTH_TEST)
def DrawGLScene():
global angle
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glLoadIdentity()
glTranslatef(0.0, 0.0, -6.0)
glRotatef(angle, 1.0, 1.0, 0.0)
glRotatef(angle, 0.0, 1.0, 0.0)
glBegin(GL_QUADS)
glColor3f(1,0,0); glVertex2f( 1.0,-1.0)
glColor3f(1,1,0); glVertex2f(-1.0,-1.0)
glColor3f(1,1,1); glVertex2f(-1.0, 1.0)
glColor3f(0,0,1); glVertex2f( 1.0, 1.0)
glEnd()
angle += 1
glutSwapBuffers()
def main():
glutInit(sys.argv)
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH)
glutInitWindowSize(640, 480)
glutCreateWindow("OpenGL in Python")
glutIdleFunc(DrawGLScene)
InitGL(640, 480)
glutMainLoop()
main()
And just for fun, I disassembled the C version, optimized it a little, added some comments...
Gas Assembly
### Constants ###
.constTitle:
.string "OpenGL in GAS Assembly"
.constOneTenth:
.long -1717986918
.long 1069128089
.constAspectRatio:
.long 343597384
.long 1073039278
.constFOV:
.long 0
.long 1078362112
### Variables ###
.globl angle
.bss
.size angle, 4
angle:
.text
### Functions ###
.globl DrawGLScene
.globl main
DrawGLScene:
pushl %ebp
movl %esp, %ebp
subl $24, %esp
movl $16640, (%esp) #\__glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT)
call glClear #/
call glLoadIdentity #\__glLoadIdentity()
movl $0xc0c00000, 8(%esp) #\
movl $0x00000000, 4(%esp) # \__glTranslatef(0, 0, -6)
movl $0x00000000, (%esp) # /
call glTranslatef #/
pushl angle #\
fildl (%esp) # \
leal 4(%esp), %esp # \
movl $0x00000000, 12(%esp) # \__glRotatef(angle, 1, 1, 0)
movl $0x3f800000, 8(%esp) # /
movl $0x3f800000, 4(%esp) # /
fstps (%esp) # /
call glRotatef #/
pushl angle #\
fildl (%esp) # \
leal 4(%esp), %esp # \
movl $0x00000000, 12(%esp) # \__glRotatef(angle, 0, 1, 0)
movl $0x3f800000, 8(%esp) # /
movl $0x00000000, 4(%esp) # /
fstps (%esp) # /
call glRotatef #/
movl $7, (%esp) #\__glBegin(GL_QUADS)
call glBegin #/
movl $0, 8(%esp) #\
movl $0, 4(%esp) # \__glColor3b(127, 0, 0)
movl $127, (%esp) # /
call glColor3b #/
movl $-1, 4(%esp) #\
movl $1, (%esp) # \__glVertex2i(1, -1)
call glVertex2i #/
movl $0, 8(%esp) #\
movl $127, 4(%esp) # \__glColor3b(127, 127, 0)
movl $127, (%esp) # /
call glColor3b #/
movl $-1, 4(%esp) #\
movl $-1, (%esp) # \__glVertex2i(-1,-1)
call glVertex2i #/
movl $127, 8(%esp) #\
movl $127, 4(%esp) # \__glColor3b(127,127,127)
movl $127, (%esp) # /
call glColor3b #/
movl $1, 4(%esp) #\
movl $-1, (%esp) # \__glVertex2i(-1, 1)
call glVertex2i #/
movl $127, 8(%esp) #\
movl $0, 4(%esp) # \__glColor3b(0, 0, 127)
movl $0, (%esp) # /
call glColor3b #/
movl $1, 4(%esp) #\
movl $1, (%esp) # \__glVertex2i(1, 1)
call glVertex2i #/
call glEnd #\__glEnd()
incl angle #\__angle+=1
call glutSwapBuffers #\__glutSwapBuffers()
leave
ret
main:
leal 4(%esp), %ecx
andl $-16, %esp
pushl -4(%ecx)
pushl %ebp
movl %esp, %ebp
pushl %ecx
subl $36, %esp
movl 4(%ecx), %eax
movl %eax, 4(%esp) #\
movl %ecx, (%esp) # \__glutInit(&argc, argv)
call glutInit #/
movl $18, (%esp) #\__glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH)
call glutInitDisplayMode #/
movl $480, 4(%esp) #\
movl $640, (%esp) # \__glutInitWindowSize(640, 480)
call glutInitWindowSize #/
movl $.constTitle, (%esp) #\__glutCreateWindow(constTitle)
call glutCreateWindow #/
movl $DrawGLScene, (%esp) #\__glutIdleFunc(DrawGLScene)
call glutIdleFunc #/
movl $5889, (%esp) #\__glMatrixMode(GL_PROJECTION)
call glMatrixMode #/
movl $100, 24(%esp) #\
fldl .constOneTenth # \
fstpl 16(%esp) # \
fldl .constAspectRatio # \__gluPerspective(45, 1.33, 0.1, 100)
fstpl 8(%esp) # /
fldl .constFOV # /
fstpl (%esp) # /
call gluPerspective #/
movl $5888, (%esp) #\__glMatrixMode(GL_MODELVIEW)
call glMatrixMode #/
movl $2929, (%esp) #\__glEnable(GL_DEPTH_TEST)
call glEnable #/
call glutMainLoop #\__glutMainLoop()
To compile the C++ one, "g++ program.cpp -lglut"
To run the perl one "perl program.pl"
To run the python one "python program.py"
To assembly the GAS one "gcc program.s -lglut -s"
You will need the appropriate OpenGL modules/libraries for those languages (but, the assembly one uses the C libraries)
These examples use GLUT as well, so you will need freeGLUT installed.
You can also cut a few bytes off of the assembly one with a hex editor, but for simplicity just assembly that code above.
With the C, perl, and python examples I preserved the spacing to show how they line up so well.