Working with Glut |
Delphi Glut Headers | http://home.get2net.dk/mithrandir |
SGI Glut Downloads | http://reality.sgi.com/opengl/glut3/glut3.html |
SGI Glut FAQ | http://reality.sgi.com/mjk/glut3/glut-faq.html |
Charlie's example programs on source forge. | http://sourceforge.net/projects/elvenware |
Glut is pronounced like the first syllable in gluttony.
Glut has two primary goals:
Glut allows you to simply and easily create windows, add simple controls such as menus, and handle basic user input. it is not, however, intended to be a cross platform library such as Qt. It is much simpler than a full blown GUI library. It is just a hand full of calls for creating simple applications
You have more power using a set of native APIs
The classic book on OpenGL, the OpenGL Programmer's Guide, uses Glut almost exclusively throughout. There is nothing rinkydink about using Glut, it's a good way to get some jobs done. It only fails you if you need to dig in deeply.
You need to be sure the Glut DLL is on your system. C++ developers need Glut.h, which ships with C++Builder in the ../include/gl/ directory. Delphi programers need a translation of the Glut header file. The link at the top of this article shows how to get that file.
Glut programs can be very short and simple.
#include#include #include #pragma hdrstop void Display(void) { glClearColor(0,0,0,1); glClear(GL_COLOR_BUFFER_BIT); glBegin(GL_TRIANGLES); glVertex3f(-1.0,0.0,0.0); glVertex3f(0.0,1.0,0.0); glVertex3f(1.0,0.0,0.0); glEnd(); glFlush (); } #pragma argsused int main(int argc, char* argv[]) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_SINGLE || GLUT_RGB); glutCreateWindow("Simple GLUT Application"); glutDisplayFunc(Display); glutMainLoop(); return 0; }
The same code in Object Pascal:
program GlutBasics; uses Windows, SysUtils, OpenGL, ElfGlut; procedure Display; cdecl; begin glClearColor(0.0,0.0,0.0,1.0); glClear(GL_COLOR_BUFFER_BIT); glBegin(GL_TRIANGLES); glVertex3f(-1.0,0.0,0.0); glVertex3f(0.0,1.0,0.0); glVertex3f(1.0,0.0,0.0); glEnd; glFlush (); end; begin if glutInit(MS_LIB) then begin glutInitDisplayMode(GLUT_SINGLE); glutCreateWindow('A very simple Glut application'); glutDisplayFunc(Display); glutMainLoop; end; end.
In C, you pass in the parameters to main when you call glutInit:
glutInit(&argc, argv);
In Pascal, you pass in either MS_LIB or SGI_LIB:
if glutInit(MS_LIB) then begin
If you are working in Linux, then you definitely should pass in SGI_LIB. I have done some work in Kylix with Glut, and it has gone fairly well.
Once you have initialized the system, you need to create your main window:
glutInitDisplayMode(GLUT_SINGLE); glutCreateWindow('A very simple Glut application');
The parameter you pass into glutCreateWindow ends up as the caption to your window.
The next step is to declare your call back proceding for handling painting chores, and then to enter the main loop:
glutDisplayFunc(Display); glutMainLoop;
Here is the C++Builder source:
#ifdef _WIN32 #include#endif #include #include #include void ErrorCheck(char* s) { GLenum errorCode; errorCode = glGetError(); if (errorCode != GL_NO_ERROR) printf("Error in %s %s", s, gluErrorString(errorCode)); } void Reshape(int w, int h) { glViewport(0, 0, w, h); /* Establish viewing area to cover entire window. */ glOrtho(-1, 1, -1, 1, -1, 1); } void Display(void) { glClearColor(0.8,0.8,0.9,1.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glBegin(GL_TRIANGLES); ErrorCheck("Display middle"); glColor3f(1.0,0.0,0.0); glVertex3f(-1.0, -1.0, 0.0); glColor3f(0.0,1.0,0.0); glVertex3f(0.0, 1.0, 0.0); glColor3f(0.0,0.0,1.0); glVertex3f(1.0, -1.0, 0.0); glEnd(); glFlush(); ErrorCheck("Display End"); } #pragma argsused int main(int argc, char* argv[]) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); glutInitWindowSize(640, 480); glutInitWindowPosition(250, 250); glutCreateWindow("Try resizing this window"); glutDisplayFunc(Display); glutReshapeFunc(Reshape); ErrorCheck("About to start loop"); glutMainLoop(); return 0; }
Here is the Pascal source:
program GlutReshape; uses Windows, SysUtils, OpenGL, ElfGlut; procedure Display; cdecl; begin glClearColor(0.0,0.0,0.0,1.0); glClear(GL_COLOR_BUFFER_BIT); glBegin(GL_TRIANGLES); glColor3f(1.0,0.0,0.0); glVertex3f(-1.0,0.0,0.0); glColor3f(0.0,1.0,0.0); glVertex3f(0.0,1.0,0.0); glColor3f(0.0,0.0,1.0); glVertex3f(1.0,0.0,0.0); glEnd; glFlush (); end; procedure Reshape(w, h: Integer); cdecl; begin glViewport(0, 0, w, h); glOrtho(-1, 1, -1, 1, -1, 1); end; begin if glutInit(MS_LIB) then begin glutInitDisplayMode(GLUT_SINGLE); glutCreateWindow('A very simple Glut application'); glutDisplayFunc(Display); glutReshapeFunc(Reshape); glutMainLoop; end; end.
The major difference in this code from the earlier versions comes in the main code block, where there is a call to glutReshapeFunc:
glutReshapeFunc(Reshape);
This function tells glut what function of yours to call when there is a resize event. It is very much like setting up an OnResize event in C++Builder or Delphi. The method you create will be passed the current width and height of the window that was resized. In Delphi, you must explicitly the function to use the cdecl calling convention
Here is the Reshape method itself:
procedure Reshape(Width, Height: Integer); cdecl; begin glViewport(0, 0, Width, Height); glOrtho(-1, 1, -1, 1, -1, 1); end;