3. OpenGL Tips
If you have any suggestions as to what should be on this page, please email me at email@example.com
Lighting – Point vs Directional
Cross Platform Compiling
Having moved from Windows to Linux to Mac. The conversion of most of my code from Windows to Linux was extremely straightforward, just remove all windows dependencies. But when going to Mac, I found the following if statement quite useful, as the header files for OpenGL are located in a different directory.
#if ((defined(__MACH__))&&(defined(__APPLE__))) #include <OpenGL/gl.h> #include <GLUT/glut.h> #include <OpenGL/glext.h> #else #include <GL/glew.h> #include <GL/gl.h> #include <GL/glut.h> #include <GL/glext.h> #endif
Z Buffer Precision
The Z buffer is one of the key items overlooked by beginner OpenGL programmers. If you find an application that is using a near plane of something like 0.001 and a far plane similar to 10000. This is going to cause alot of problems along the line.
Because of the way the Z buffer works, it looses depth accuracy for shapes further away. And it can get to a point where the precision is that poor, that two objects can be interpreted as having the same z value. This can cause sheering, and backward objects to be rendered first.
To fix this, it is always best to set your near plane to just before the closest object, and your far plane just past the last object you want to render.
When placing your lights in the scene, some people make the mistake of placing it during the init method (I have been guilty of this), or calling their lighting position before they place their camera in the world.
They may then run their program, and find that rotating around the scene, and moving, can cause weird artifacts where their shapes become darker, or lighter.
To fix this, you have to remember that when you make the call to set the position of the light, it is multiplied by the current ModelView Matrix. This means that if you call it before you place your camera, the lights are based around the origin (0,0,0) and your objects will actually be moving around them.
You need to first place your camera, and then set your lights, and finally draw all your objects.
This will give you correct lighting, no matter where you have place the camera in the scene.
Lighting – Point vs Directional
One of the snags people get into with lighting, is that they don’t understand the W component of the light position. This value tells OpenGL what type of light we are using. This can have either 1 of 2 values. They are:
0.0 and 1.0
Now the difference between these two, is that a value of 1.0 will tell OpenGL that we want a point light. A point light sits in a particular place in the world, and emits the light in all directions, you can think of it as a light bulb.
A value of 0.0 will give you a directional light, which is similar to an ambient light, as in it affects everything, but it faces a certain direction instead of emitting in all directions.
The point of a point light, is that we can add attenuation values, these determine how far our light affects from the light position.
Now you may ask, what about a spotlight? Well this is simply a point light with some extra attenuation values. It still takes a 1.0 value in the W component, but it takes particular spot light attentuation values, which give it a direction, a range and an angle for the field of view of the light.
A spotlight is best thought of as a torch. It is a point light (it has a bulb), but it has something obscuring it from shining behind, and the casing also tells us how far around we can shine.
When using GLEW, there is one crucial thing, which unless you are on OSX, a lot of people overlook, and then wonder why their application fails at runtime.
This is the call to glewInit();
Because OSX’s user interface uses OpenGL, GLEW is already initiated, and therefore a specific call to glewIinit() in your application is redundant. But on a Windows and Linux machine, this call needs to be made *before* any of the GLEW methods are used. Otherwise you will receive an error when you launch your application and your application will fail.
For Windows users(not sure if this applies to Mac or Linux) it might good to note, that glew must always be listed before glut(even when using freeglut.h under the header glut.h).
And, glew.h calls gl.h, glext.h, and even gl_ati.h (in this order) so adding the includes for gl.h and glext.h can be dropped without a problem.
The version of glew.h I’m using is 1.5.7 and glut is 3.7.6(freeglut 2.60).
It’s very useful. Specially the light init issue.
The list is very informative. I also like the sample programs. Thanks.
might be worth mentioning that when using glut in c++, do all your standard includes before you include the glut/glew/whatever libraries. i had it give me an error when trying to use functions from the std libraries, and it was fixed buy including them before including glut. (hope this saves someone some trouble, took a while for me to find that out)
I’d have to ask, what version of GLUT and what compiler are you using? Because I have no problems including GLEW, FreeGLUT and then all other headers in Visual Studio.
Here’s one that has come in handy for me, if I want to know the extensions my video card supports. The program is called OpenGL extension viewer 3.16 (because of OpenGL 4 there might be a newer version) and its at
the program runs benchmark tests has links to download drivers, and links to DirectX, and my favorite part, a database build into the application that lists stuff like vendors, cards, and the extensions that each card supports. Did I mention its FREE! 😉
Wow, even for a short list that’s extremely useful already!! Thanks for the great tutorial series man =)