OpenGL Programming Guide

Dave Shreiner

Mentioned 8

OpenGL is a powerful software interface used to produce high-quality, computer-generated images and interactive applications using 2D and 3D objects, bitmaps, and color images. The OpenGL ® Programming Guide, Seventh Edition , provides definitive and comprehensive information on OpenGL and the OpenGL Utility Library. The previous edition covered OpenGL through Version 2.1. This seventh edition of the best-selling “red book” describes the latest features of OpenGL Versions 3.0 and 3.1. You will find clear explanations of OpenGL functionality and many basic computer graphics techniques, such as building and rendering 3D models; interactively viewing objects from different perspective points; and using shading, lighting, and texturing effects for greater realism. In addition, this book provides in-depth coverage of advanced techniques, including texture mapping, antialiasing, fog and atmospheric effects, NURBS, image processing, and more. The text also explores other key topics such as enhancing performance, OpenGL extensions, and cross-platform techniques. This seventh edition has been updated to include the newest features of OpenGL Versions 3.0 and 3.1, including Using framebuffer objects for off-screen rendering and texture updates Examples of the various new buffer object types, including uniform-buffer objects, transform feedback buffers, and vertex array objects Using texture arrays to increase performance when using numerous textures Efficient rendering using primitive restart and conditional rendering Discussion of OpenGL's deprecation mechanism and how to verify your programs for future versions of OpenGL This edition continues the discussion of the OpenGL Shading Language (GLSL) and explains the mechanics of using this language to create complex graphics effects and boost the computational power of OpenGL. The OpenGL Technical Library provides tutorial and reference books for OpenGL. The Library enables programmers to gain a practical understanding of OpenGL and shows them how to unlock its full potential. Originally developed by SGI, the Library continues to evolve under the auspices of the Khronos OpenGL ARB Working Group, an industry consortium responsible for guiding the evolution of OpenGL and related technologies.

More on Amazon.com

Mentioned in questions and answers.

I've got some 2D geometry. I want to take some bounding rect around my geometry, and then render a smaller version of it somewhere else on the plane. Here's more or less the code I have to do scaling and translation:

// source and dest are arbitrary rectangles.
float scaleX = dest.width / source.width;
float scaleY = dest.height / source.height;
float translateX = dest.x - source.x;
float translateY = dest.y - source.y;

glScalef(scaleX, scaleY, 0.0);
glTranslatef(translateX, translateY, 0.0);
// Draw geometry in question with its normal verts.

This works exactly as expected for a given dimension when the dest origin is 0. But if the origin for, say, x, is nonzero, the result is still scaled correctly but looks like (?) it's translated to something near zero on that axis anyways-- turns out it's not exactly the same as if dest.x were zero.

Can someone point out something obvious I'm missing?

Thanks!

FINAL UPDATE Per Bahbar's and Marcus's answers below, I did some more experimentation and solved this. Adam Bowen's comment was the tip off. I was missing two critical facts:

  1. I needed to be scaling around the center of the geometry I cared about.
  2. I needed to apply the transforms in the opposite order of the intuition (for me).

The first is kind of obvious in retrospect. But for the latter, for other good programmers/bad mathematicians like me: Turns out my intuition was operating in what the Red Book calls a "Grand, Fixed Coordinate System", in which there is an absolute plane, and your geometry moves around on that plane using transforms. This is OK, but given the nature of the math behind stacking multiple transforms into one matrix, it's the opposite of how things really work (see answers below or Red Book for more). Basically, the transforms are "applied" in "reverse order" to how they appear in code. Here's the final working solution:

// source and dest are arbitrary rectangles.
float scaleX = dest.width / source.width;
float scaleY = dest.height / source.height;
Point sourceCenter = centerPointOfRect(source);
Point destCenter = centerPointOfRect(dest);

glTranslatef(destCenter.x, destCenter.y, 0.0);
glScalef(scaleX, scaleY, 0.0);
glTranslatef(sourceCenter.x * -1.0, sourceCenter.y * -1.0, 0.0);
// Draw geometry in question with its normal verts.

In OpenGL, matrices you specify are multiplied to the right of the existing matrix, and the vertex is on the far right of the expression.

Thus, the last operation you specify are in the coordinate system of the geometry itself. (The first is usually the view transform, i.e. inverse of your camera's to-world transform.)

Bahbar makes a good point that you need to consider the center point for scaling. (or the pivot point for rotations.) Usually you translate there, rotate/scale, then translate back. (or in general, apply basis transform, the operation, then the inverse). This is called Change of Basis, which you might want to read up on.

Anyway, to get some intuition about how it works, try with some simple values (zero, etc) then alter them slightly (perhaps an animation) and see what happens with the output. Then it's much easier to see what your transforms are actually doing to your geometry.

Update

That the order is "reversed" w.r.t. intuition is rather common among beginner OpenGL-coders. I've been tutoring a computer graphics course and many react in a similar manner. It becomes easier to think about how OpenGL does it if you consider the use of pushmatrix/popmatrix while rendering a tree (scene-graph) of transforms and geometries. Then the current order-of-things becomes rather natural, and the opposite would make it rather difficult to get anything useful done.

Is there a good book that focuses on the programmable aspect of OpenGL 3.0

I want something like the OpenGL Super Bible, but focusing solely on the "new testament" part -- the programmable rather than the fixed pipeline.

The latest 5th edition of the OpenGL SuperBible does focus only on the core profile. Unfortunately it includes it's own gltools library so most of the start of the book is really more teaching that toolkit rather than the core profile itself, of course it covers the basic overall layout of a modern opengl program and does seem to fill in the harder stuff later. As you progress though it seems you reimplement the crutch library.

The OpenGL Programming Guide (The Red Book) 7th edition, unfortunately seems to be rather dated. They have marked everything that is in the compatibility profile rather than the core, but thats about it.

There is an 8th edition being released in December 2012 that is apparently a rewrite teaching modern approaches.

Realistically it would be best to learn the specific areas on the compatibility profile/OpenGL 2.1 then combine them all together into something that is core profile. Doing it all at once is just too much at once.

  • First learn Vertex Buffer Objects (and ditch glBegin/glEnd and anything that goes in between).

  • Learn manual Matrix operations and stack, or an appropriate library (ditch glPushMatrix/glTranslate/glRotate/glOrthagonal/gluLookAt/glFrustum, you may need to use some compatibility stuff to bind your manually processed marices at this stage but you can ditch them with the shader next step)

  • Learn Vertex & Fragment shaders

  • Learn how to set the OpenGL context to 3.1+ (Dependant on your windowing system).

The book OpenGL Programming Guide: The Official Guide to Learning OpenGL, Versions 3.0 and 3.1 (7th Edition) was updated and explains the new features of OpenGL 3.0.

i need few sample code projects on openGL for beginners.. i tried googling.. but still i m seeking ur suggestion on this.

You could try this: The OpenGL Programming Guide - the redbook

It's official publication for learning openGL. It's already the seventh edition concentrated on versions 3.0 and 3.1 of openGL (another edition for version 4.1 will be available soon). It covers the basics and gets into more advanced topics as well.

Or you could try these video tutorials: videotutorialsrock.com

These videos follow similar structure as the book I mentioned above. They introduce some general 3d graphics concepts and the appropriate openGL syntax. I think it is a nice first step for those new to both openGl and 3d graphics programming.

I've just started learning openGL a couple of hours ago for my work and have been tasked with rendering a concave polygon using tessellation. I'm trying to compile the following code:

#ifndef CALLBACK
#define CALLBACK
#endif

#include "GL/gl.h"
#include "GL/glu.h"

void CALLBACK beginCallback(GLenum which);

void drawHook()
{
   GLUtesselator* tessObj = gluNewTess();
   gluTessCallback(tessObj, GLU_TESS_BEGIN, beginCallback);
}

void CALLBACK beginCallback(GLenum which)
{
    glBegin(which);
}

which I've gotten from the OpenGL Programming Guide, Seventh Edition, with the relevant chapter also being available online. But the following error is being returned:

hook.cc:28: error: invalid conversion from ‘void (*)(GLenum)’ to ‘void (*)()’
hook.cc:28: error: initializing argument 3 of ‘void gluTessCallback(GLUtesselator*, GLenum, void (*)())’

This error leads me to believe that the third argument of gluTessCallback should be a function that takes no arguments, yet the 'official' openGL reference states otherwise.

Am I missing something here or is the book incorrect?

The book is correct. You just have to cast the function pointer to void(*)(). It's needed because the type is not (and cannot be) precise.

gluTessCallback(tessObj, GLU_TESS_BEGIN, (void(*)())&beginCallback);

I'm thinking to build a library to manipulate images(my own image type that I will develop), but first I need to understand the structure of a image

  • How it is mounted?
  • About the layer technology...
  • Where I can find some good resources to understand these things?

Thanks.

A quick amazon search yields a couple of books that could be very useful on the subject. Both are based around openGL, one of the most common graphic libraries. The first is a general introduction to computer graphics sort of text book and the second is a manual for openGL (commonly known as the red book).

Computer Graphics with OpenGL (3rd Edition)

OpenGL Programming Guide (The Red Book)

I can personally attest to the usefulness of both books.

If you're interested in the innards of various image file formats wotsit is a pretty good start. If you prefer hardcopy then go to the Encyclopedia of Graphics file formats. And if you want to look at sample sourcecode check out imagemagick. It can open-, convert to-, and save- most popular image file formats written in C++ with interfaces to most other languages.

My question is quite simple, I need to initialize a window and use it to display pixels moving around and touching each other (I'm doing a DLA application). I need this to be done purely in GLUT as it needs to be cross platform. I'm not going to be displaying any 3D objects btw. Oh also I'm programming it in c++

Both any edition of the Red Book, the Superbible (4th ed. or older), OpenGL-centric textbooks (like Hill, et. al.), and every outdated tutorial (particularly NeHe) will cover all of this, if the GLUT manual is inadequate.

I'm attempting to compile and run a program using code from the OpenGL Programming Guide that illustrates the tessellation functionality. The chapter I'm reading from can also be found online, as can the full source code for the example. The first time I tried to run the program, it crashed with the error combine callback required, or words to that effect. I added my combine callback to the line on which you see it now, even thought he example source did not include it that early, and that solved that problem, but the following error is being returned.

*** glibc detected *** <path to binary>: malloc(): memory corruption: 0x09b03b30 ***

The data I'm using is a verbatim copy of the example source

GLdouble rect[4][3] = {50.0, 50.0, 0.0,
                          200.0, 50.0, 0.0,
                          200.0, 200.0, 0.0,
                          50.0, 200.0, 0.0};

   GLdouble tri[3][3] = {75.0, 75.0, 0.0,
                         125.0, 175.0, 0.0,
                         175.0, 75.0, 0.0};

   GLdouble star[5][6] = {250.0, 50.0, 0.0, 1.0, 0.0, 1.0,
                          325.0, 200.0, 0.0, 1.0, 1.0, 0.0,
                          400.0, 50.0, 0.0, 0.0, 1.0, 1.0,
                          250.0, 150.0, 0.0, 1.0, 0.0, 0.0,
                          400.0, 150.0, 0.0, 0.0, 1.0, 0.0};

The relevent section of my code is as follows, again a copy

   glClearColor(0.0, 0.0, 0.0, 0.0);

   GLuint startList = glGenLists(2);

   tessObj = gluNewTess();

   gluTessCallback(tessObj, GLU_TESS_BEGIN, (void(*)())beginCallback);
   gluTessCallback(tessObj, GLU_TESS_END, (void(*)())endCallback);
   gluTessCallback(tessObj, GLU_TESS_VERTEX, (void(*)())glVertex3dv);
   gluTessCallback(tessObj, GLU_TESS_ERROR, (void(*)())errorCallback);
   gluTessCallback(tessObj, GLU_TESS_COMBINE, (void(*)())combineCallback);

   glNewList(startList, GL_COMPILE);
   glShadeModel(GL_FLAT);
   gluTessBeginPolygon(tessObj, NULL);
      gluTessBeginContour(tessObj);
         gluTessVertex(tessObj, rect[0], rect[0]);
         gluTessVertex(tessObj, rect[1], rect[1]);
         gluTessVertex(tessObj, rect[2], rect[2]);
         gluTessVertex(tessObj, rect[3], rect[3]);
      gluTessEndContour(tessObj);
      gluTessBeginContour(tessObj);
         gluTessVertex(tessObj, tri[0], tri[0]);
         gluTessVertex(tessObj, tri[2], tri[2]);
         gluTessVertex(tessObj, tri[3], tri[3]);
      gluTessEndContour(tessObj);
   gluTessEndPolygon(tessObj); //This is the problem line
   glEndList();

My combine callback is another verbatim copy of the example source

void CALLBACK combineCallback(GLdouble coords[3],
      GLdouble *vertex_data[4],
      GLfloat weight[4], GLdouble **dataOut )
{
   GLdouble *vertex;
   int i;

   vertex = (GLdouble *) malloc(6 * sizeof(GLdouble));

   vertex[0] = coords[0];
   vertex[1] = coords[1];
   vertex[2] = coords[2];
   for (i = 3; i < 7; i++)
      vertex[i] = weight[0] * vertex_data[0][i]
         + weight[1] * vertex_data[1][i]
         + weight[2] * vertex_data[2][i]
         + weight[3] * vertex_data[3][i];
   *dataOut = vertex;
}

I've managed to trace the problem back to the specified line at the bottom of the source file using GDB, and the chain of failures goes like:

gluTessEndPolygon
__gl_computeInterior
??
__gl_meshConnect
??
malloc
_int_malloc
__libc_massage
abort
raise
__Kernel_vsyscall

I'm guessing the problem lies within my combineCallback function but I only started learning openGL earlier today. My plan was to get a basic tessellation program up and running and start chaging things to see what they did, so I'm having trouble troubleshooting the code myself. Can anyone else see what I'm doing wrong?

typo? try

     gluTessVertex(tessObj, tri[0], tri[0]);
     gluTessVertex(tessObj, tri[1], tri[1]); // 2 <- 1
     gluTessVertex(tessObj, tri[2], tri[2]); // 3 <- 2

What OpenGL / GLUT reference is good for day to day programming as you learn?

Ideally I'm looking for something with lots of C++ sample code to help me learn as I develop OpenGL applications as well as details about the APIs similar to what MSDN provides for .net programming.

If there isn't a one stop shop, then please list the set of references I should use and what the strengths of each one is.

I learned OpenGL using the OpenGL Super Bible. It's still the best reference for it that I can find.

The Red Book is the standard book on OpenGL. Don't be discouraged by the fact that the Amazon review for the 7th Edition has only two stars; this is because people are disappointed that there isn't more on the newest OpenGL features in the book. Previous editions got more stars.

Another good book is the OpenGL SuperBible.

The NeHe Tutorials are one of the most often cited OpenGL tutorials, with sample code not only in C++ but in many other programming languages.

The PyOpenGL Documentation is identical to the OpenGL docs, but far more readable and user-friendly. Have a look.

I also second the OpenGL SuperBible.