Back to Title Page

←Previous Entry

Next Entry→

July 3

 

Megan came around yesterday and we ground some steak in the Cuisinart and grilled burgers.  This, despite the discovery of a beef cow in Texas with mad cow disease.  Foxy is having her first visit and she and Bella get along fine, except Foxy never learned to play because Nin was such a morose hound.

 

Dabbling back into getting an handle on OpenGL application development environment.  In the GLADE, if you will.  In DEC++, you can open a project under “multimedia” or some such, called OpenGL, which I then named simpleOpenGL.  It has these includes:

#include <Windows.h>

#include <gl/gl.h>

 

and is generally much more complicated than I would like to begin with.

 

So I googled for one of the linker errors I was getting and tried inserting parameters under project/options and found my way to http://www.cprogramming.com/tutorial/gl1.html and compiled/executed the little Hello World

#include <windows.h>

int APIENTRY WinMain(HINSTANCE hInstance,

                     HINSTANCE hPrevInstance,

                     LPSTR     lpCmdLine,

                     int       nCmdShow)

{

     

      MessageBox(NULL, "\tHello World!", "My first windows app", NULL);

      return 0;

}

 with DEC++ and it worked…with a few error messages, such as “In function int WinMain(HINSTANCE_*, HINSTANCE_*, CHAR*,int) [Warning] passing NULL used for non-pointer argument passing 4 of ‘int MessageBoxA(HWND_*,const CHAR*, const CHAR*, unsigned int) [Warning] argument to non-pointer type ‘unsigned int’ from NULL. 

 

VisualC++ can’t find the file. Hmmm.  This is just the sort of bugaboo that causes me fits. 

 

After hours of uncertainty I remembered that it’s not enough to be just editing the document with your project (solution) open, you actually have to “add existing item” to your “source files.”   What a pain.  Ok.  Having done this, it then takes significantly longer to compile and…fails!  Here’re the error messages:

 

LIBCD.lib(crt0.obj) : error LNK2019: unresolved external symbol _main referenced in function _mainCRTStartup

Debug/simpleopenGL.exe : fatal error LNK1120: 1 unresolved externals

 

Do I need to also include the window.h file in the header section?  Let’s see.  I find such a file located in c:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\PlatformSDK\Include
Nope.  No difference at all.  So I google this error and get a message board where someone has said they have the same problem and ask why.  The answer come: “This means the linker cannot find your main().”  Wow.  Now we’re making some progress…Not!

Ok.  Progress.  I went back to the code in Angel’s Primer:

 

#include <GL/glut.h>

 

void display()

{

      glClear(GL_COLOR_BUFFER_BIT);

 

      glBegin(GL_POLYGON);

        glVertex2f(-0.5, -0.5);

        glVertex2f(-0.5, 0.5);

        glVertex2f(0.5, 0.5);

        glVertex2f(0.5, -0.5);

      glEnd();

 

      glFlush();

}

 

int main(int argc, char** argv)

{

      glutInit(&argc, argv);

      glutCreateWindow("simple");

      glutDisplayFunc(display);

      glutMainLoop();

} 

 

and made sure I had the source file, header (glut.h) and the library glut32.lib, which turned out to be locked away in a zip file so that the solution explorer is as shown at right:
 

Then I get a window with a white rectangle centered on a black background! Hooray!  Actually, I first get a command window that’s blank.  And I get a bunch of compiler messages that say things similar to “'simple01.exe': Loaded 'C:\WINDOWS\system32\glut32.dll', No symbols loaded.”

 

 

So I’m ready to get back to Angel’s primer and advance. 

 

In section 2.2 of the primer, we’re informed that

 void glutInit(int *argc, char **argv)

initializes GLUT and should be called  before other GLUT and OpenGL functions. glutInit() takes arguments from main() and the program can use them in an implementation-dependent manner.”

 

This is certainly consistent with that tiny little program I just compiled/linked/ran.  Next, glutCreateWindow("simple") puts a window on the screen at the default (upper left) position and default size 300X300 pixels.  The string argument “simple” puts an optional title on the top. 

 

What about some interaction?  We’d like our picture to react to mouse/keyboard events, no?   To handle this sort of thing, operating systems like Windows employ a data structure called the event queue.   Programmers use callback functions to define reactions to events.  GLUT provides reactions to most events you might want, excluding perhaps the emergency pause per involuntary bodily function/sneeze, etc.  The simple program above contained a single callback glutDisplayFunc(display)  which is invoked whenever OpenGL redraws the window, or, as in this case, on first display.

 

Interestingly, our display is a function without arguments. In fact the display is an argument registered this way: void glutDisplayFunc(void (*func)(void)) and func() is called each time the window needs to be redrawn.  One way to pass values to the display callback function is to use globals.

 

After callbacks have been registered, glutMainLoop() invokes the event loop.  The only way to get out of the loop once entered is some kill switch like alt+ctrl+del. As such, this should be the last statement in the main() function.  

 

Gaby’s making pesto with real pine nuts and fresh basil.  I wonder if it’s ready and I’ve missed the call back to dinner.  Box Car Willie is ending his Orange Blossom Special and Hendrix is launching If 6 Was 9.  Time to investigate….later…apparently we need to wait for Garrett and Esme to set the table, which may be a long wait.

 

Let’s focus a little on the display function itself.  Since we’ve included (#include <GL/glut.h>) which in turn include gl.h and glu.h with the lines

#include <GL/gl.h>

#include <GL/glu.h>

this is kind of a catch-all include. 

 

Now the fundamental geometrical entity is the vertex, which, ideally is a a unique, indivisible location in space, but on the computer corresponds to entire area defined by the resolution of a pixel, say.  In OpenGL, a vertex can have 2,3 or 4 dimensions through the various forms of glVertex*() functions. 

 

Hey, thou shalt crank on Sundays, eh?  I’ve graded some summer college algebra papers today, most very disappointing.  I put the papers I expect to be better first, so, well, aside from Angel Paz and Christine Brooker, things are looking pretty sorry.

 

So here is the general forms the declaration of a vertex function in OpenGL:

void glVertex{234}{sifd}{TYPE xcoordinate, TYPE ycoordinate, … )

void glVertex{234}v{TYPE *coordinates)

 Typically, say, a 2D vertex with float coordinates is declared either as glVertex2f(x,y) or glVertex2fv(p), where, in the latter, p[0] and p[1] specify the coordinates of the point.

 

The function glBegin() has syntax void glBegin(GLenum mode) and specifies the beginning of an object of type mode, which could be, say, GL_POINTS, GL_LINES, or GL_POLYGON.  The function prototype void glEnd() specifies the end of such a list of vertices.  You see these functions bracketing the list of vertices for the white rectangle in the simple example we’ve seen above.

 

Having encountered glEnd(), OpenGL puts the rendered image in a region of memory called the “color buffer,” usually somewhere on the graphics card.  The color buffer is one many elements that comprise the “frame buffer.” 

The command glClear(GL_COLOR_BUFFER_BIT) prepares a clean slate for rendering.  The prototype for this function is
                                              void glClear(GLbitfield mask)
which clears all buffers whose bits are set in mask   The mask is formed by the logical OR of values defined in gl.hGL_COLOR_BUFFER_BIT refers to the color buffer. 

The glFlush() command brings the current buffer command to the top and forces its execution by first executing all pending buffer commands.

 

Here are some more powerful functions we can try:


void glutInitDisplayMode(unsigned int mode)

glutInitWindowSize(int width, int height)

glutInitWindowPositions(int x, int y)