NOGDUS

Articles, Tutorials, and other things. => General Game Programming => Topic started by: Richard Marks on December 30, 2008, 03:09:24 PM



Title: Basics of using OpenGL / GLUT with Pascal
Post by: Richard Marks on December 30, 2008, 03:09:24 PM
Basics of using OpenGL / GLUT with Pascal

I bet you think I'm insane. ;D Well, maybe I am, maybe not.
Pascal is really cool once you get to know it.

First lets create the main program:
Code:
program FirstGlutPrg;
uses gl, glut, glu;
const WIN_WIDTH = 640; WIN_HEIGHT = 480;
var screenWidth, screenHeight : integer;
begin
Initialize_GLUT(true);
glutInitDisplayMode(GLUT_DOUBLE or GLUT_RGB or GLUT_DEPTH);
glutInitWindowSize(WIN_WIDTH, WIN_HEIGHT);
screenWidth  := GlutGet(GLUT_SCREEN_WIDTH);
screenHeight := GlutGet(GLUT_SCREEN_HEIGHT);
glutInitWindowPosition((screenWidth - WIN_WIDTH) div 2, (screenHeight - WIN_HEIGHT) div 2);
glutCreateWindow('GLUT in Pascal #1');
Initialize_GL;
glutDisplayFunc(@GLHandler_DrawScene);
glutReshapeFunc(@GLHandler_ResizeScene);
glutKeyboardFunc(@GLHandler_Keyboard);
glutMainLoop;
end.

Now, we need to implement the procedures we are using here.

We have to copy the program command line arguments into a C-style array so that GLUT can be initialized.
Its painless once you know how.
Code:
procedure Initialize_GLUT(parse : boolean);
var
argv  : array of pchar;
argc  : integer;
index : integer;
begin
if parse then
argc := ParamCount + 1
else
argc := 1;
SetLength(argv, argc);
for index := 0 to argc - 1 do
argv[index] := pchar(ParamStr(index));
glutInit(@argc, @argv);
end;

We will clear the screen to a nice blue/green color.
Code:
procedure Initialize_GL;
begin
glClearColor(0.10, 0.66, 0.20, 0);
end;

Our scene gets drawn in this procedure.
Code:
procedure GLHandler_DrawScene; cdecl;
begin
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
glutSwapBuffers;
end;

When the window gets resized, this procedure gets activated.
Code:
procedure GLHandler_ResizeScene(width, height : longint); cdecl;
begin
if height = 0 then height := 1;
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity;
gluPerspective(45, width / height, 0.1, 1000);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity;
end;

We need a way to close the window, ESC will halt the program.
Don't close the window via the X button! Your program will just hide itself and keep running!
Code:
procedure GLHandler_Keyboard(key : byte; x, y : longint); cdecl;
begin
if key = 27 then halt(0);
end;

Well that was one hell of a crash course wasn't it?

Full source:
Code:
(*
first.pas

basics of using OpenGL / GLUT with Pascal

to compile with fpc on linux: $ fpc -Sd first.pas

Written by Richard Marks <ccpsceo@gmail.com>
*)
program FirstGlutPrg;
uses gl, glut, glu;

const
WIN_WIDTH = 640;
WIN_HEIGHT = 480;

(* wrap the initialization of GLUT because it expects the commandline args in C style *)
procedure Initialize_GLUT(parse : boolean);
var
argv  : array of pchar;
argc  : integer;
index : integer;
begin
if parse then
argc := ParamCount + 1
else
argc := 1;
SetLength(argv, argc);
for index := 0 to argc - 1 do
argv[index] := pchar(ParamStr(index));
glutInit(@argc, @argv);
end;

procedure Initialize_GL;
begin
glClearColor(0.18, 0.20, 0.66, 0);
end;

procedure GLHandler_DrawScene; cdecl;
begin
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
glutSwapBuffers;
end;

procedure GLHandler_ResizeScene(width, height : longint); cdecl;
begin
if height = 0 then height := 1;
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity;
gluPerspective(45, width / height, 0.1, 1000);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity;
end;

procedure GLHandler_Keyboard(key : byte; x, y : longint); cdecl;
begin
if key = 27 then halt(0);
end;

(* variables *)
var
screenWidth, screenHeight : integer;

(* main code *)
begin
Initialize_GLUT(true);

glutInitDisplayMode(GLUT_DOUBLE or GLUT_RGB or GLUT_DEPTH);

glutInitWindowSize(WIN_WIDTH, WIN_HEIGHT);

screenWidth  := GlutGet(GLUT_SCREEN_WIDTH);
screenHeight := GlutGet(GLUT_SCREEN_HEIGHT);

glutInitWindowPosition((screenWidth - WIN_WIDTH) div 2, (screenHeight - WIN_HEIGHT) div 2);

glutCreateWindow('GLUT in Pascal #1');

Initialize_GL;

glutDisplayFunc(@GLHandler_DrawScene);
glutReshapeFunc(@GLHandler_ResizeScene);
glutKeyboardFunc(@GLHandler_Keyboard);

glutMainLoop;
end.


Title: Re: Basics of using OpenGL / GLUT with Pascal
Post by: Richard Marks on December 30, 2008, 03:17:17 PM
Lets draw something on that window now!

We will just add code to the GLHandler_DrawScene procedure, so I'm not going to bother posting the full source again.

Code:
procedure GLHandler_DrawScene; cdecl;
begin
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);

glLoadIdentity;
glTranslatef(0, 0, -6);

glBegin(GL_TRIANGLES);
glColor3f(0, 0, 1); glVertex3f(-1, -1, 0); (* blue corner *)
glColor3f(0, 1, 0); glVertex3f( 1, -1, 0); (* green corner *)
glColor3f(1, 0, 0); glVertex3f( 0,  1, 0); (* red corner *)
glEnd;

glutSwapBuffers;
end;

Isn't that easy? I think it is.

Stay tuned as I'll have more interesting things, and screen-shots to go along with them later. 8)