Archive for the ‘opengl’ Category

Material Colors

Wednesday, May 10th, 2006

Here’s a function to set the current drawing color, whether or not lighting is enabled:

void color(double r, double g, double b)
{
    float color[4] = { r, g, b, 1.0 };

    if (glIsEnabled(GL_LIGHTING)) {
        glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, color);
    } else {
        glColor3f(r, g, b);
    }
}

Note that although the color can be set for GL_AMBIENT and GL_DIFFUSE separately, you’ll usually want them to be the same.

Alternatively, you could try reading about GL_COLOR_MATERIAL.

GLIntercept

Saturday, April 1st, 2006

Here’s a cool debugging tool for OpenGL on Windows: GLIntercept. You can use it to track every OpenGL function call along with its parameters. (For those of you familiar with UNIX, this is like truss(1) or strace(1), only for OpenGL calls instead of system calls.)

Here’s a 30-second walkthrough:

  1. Download and run the Windows installer. You’ll end up with a new directory, C:\Program Files\GLIntercept0_5.
  2. Copy OpenGL32.dll and gliConfig_FullDebug.ini to the same directory as your program. Rename gliConfig_FullDebug.ini to gliConfig.ini
  3. Run your program. A new file will be created in the same directory called gliInterceptLog.txt, containing every OpenGL call your program makes. (You may also find that your program is a little slower).

Here’s some of the output from running assignment5.c:

glClearColor(0.000000,0.000000,0.000000,0.000000)
wglGetCurrentContext()=0x10000
wglGetCurrentDC()=0xb70114f8
wglGetCurrentContext()=0x10000
wglGetCurrentDC()=0xb70114f8
glViewport(0,0,600,300)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
glOrtho(0.000000,2.000000,0.000000,1.000000,-1.000000,1.000000)
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
glClear(GL_COLOR_BUFFER_BIT)
glColor3f(1.000000,1.000000,0.000000)
glBegin(GL_LINES)
glVertex3f(1.000000,0.000000,0.000000)
glVertex3f(1.000000,1.000000,0.000000)
glEnd()
glViewport(300,0,300,300)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
glFrustum(-1.500000,1.500000,-1.500000,1.500000,2.000000,8.000000)
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
glMultMatrixf([1.000000,0.000000,0.000000,0.000000,
             0.000000,1.000000,0.000000,0.000000,
             0.000000,0.000000,1.000000,0.000000,
             0.000000,0.000000,0.000000,1.000000])
glTranslated(0.000000,0.000000,-6.500000)
glPushMatrix()
glPushMatrix()
glColor3f(1.000000,0.000000,0.000000)
glBegin(GL_LINE_LOOP)
glNormal3fv([0.000000,0.000000,-1.000000])
glVertex3fv([0.500000,0.500000,-0.500000])
glVertex3fv([0.500000,-0.500000,-0.500000])
glVertex3fv([-0.500000,-0.500000,-0.500000])
glVertex3fv([-0.500000,0.500000,-0.500000])
glEnd()

Running with gliConfig_FullDebug.ini also makes sure that every call to an OpenGL function is checked with glGetError(), which will catch things like passing bad values to functions or trying to pop the matrix stack more times that it’s been pushed.

To make the best use of a tool like this, you’ll probably want a utility to tail the log as your program is running. (I’m told there are also GUI versions).

Note that you don’t need access to the source code — if you have a game at home that uses OpenGL, you can watch what it’s doing, too. (Just don’t steal their code, and don’t tell them I’m the one who told you how.)

GLIntercept has a few more tricks up its sleeve, but I’ll leave it up to you to read about them. For Linux people, there’s a similar program called BuGLe, but I haven’t tried it. And, of course, we smug OS X weenies have the OpenGL Profiler.

For those of you using Igloo, I’ve put together a new debug package that includes GLIntercept and Windows port of GNU tail. I’m not entirely sure about the legality of all this — GLIntercept and GNU tail are available under the GNU General Public license, but EiC is still MIA.

A correction

Monday, March 6th, 2006

If you were paying attention over the weekend, you noticed that I updated the screenshot for Assignment 4.If you compare it with the original screenshot, you’ll notice that the original wasn’t really a parallel projection.

The problem is that (as you should recall from your reading) OpenGL is a state machine. When you make a function call like gluPerspective() to update the current projection matrix, that change stays in effect until you reset the matrix (e.g., with glLoadIdentity().

My mistake was to draw the parallel projections (calling glOrtho()) without remembering to reset the projection matrix, which had already been set with gluPerspective. The result was that we took a cube in perspective, then drew a parallel projection of the perspective rendering. Oops. I didn’t notice because it looks “sort of” right — there was, in fact, a parallel projection happening.

To avoid making silly mistakes like me, do the following whenever you go to render a model (e.g., in your display callback):

  1. Set the viewport.
    glViewport(0, 0, width, height);
  2. Set up the projection.
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(-2.0, 2.0, -2.0, 2.0, 0.0, 10.0);
  3. Set your viewing parameters.
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    gluLookAt(0.0, 0.0, 3.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
  4. Draw the scene.
    glClearColor(0.0, 0.0, 0.0, 1.0);
    glClear(GL_COLOR_BUFFER_BIT);
    
    glColor(0.0, 0.0, 1.0);
    glutWireSphere(1.0, 10, 10);

An easy way to run OpenGL programs

Thursday, February 16th, 2006

Now that I’ve put you through the pain of setting up your own
programming environment
, I’ll show you the easy way to run gears.c.

Grab a copy of igloo.zip and unzip it somewhere convenient. Run the program by typing

C:igloo> igloo gears.c

Cool. No compilation step, no moving headers and library files around, just type and go. And in less than 230 Kb.

Igloo is a version of the EIC C Interpreter, an Open Source project that seems to have gone missing in action.

Luckily, I saved a copy, just for you. I wish I’d saved a copy of the source code, too, but at least there are lots of other C interpreters.

So what’s the catch?

  1. The error messages generated by the interpreter aren’t perfect. But then again, neither are the error messages generated by Visual Studio.
  2. I’m not sure how exact it is about implementing the ANSI C Standard, and can’t find out because the web site is gone. There may be constructs that won’t work. But gears.c is pretty complicated, and it works just fine.
  3. It’s a C interpreter, not C++. Feel free to Google for one of those, and e-mail me if you find a good one.

Hints for Assignment 1

Saturday, February 11th, 2006
  1. If you’re writing your program in C++, note that <GL/glut.h> needs to be #included after <iostream> or you’ll get

    error C2381: ‘exit’ : redefinition; __declspec(noreturn) differs

  2. In order to toggle double-buffering on and off, you’ll need to destroy and re-create the window. See the API Reference for details.

Setting up OpenGL in CS-300

Saturday, February 11th, 2006

If you’re working in the lab, instead of messing around with placing the GLUT header and import library files in the right directories, just download glut.zip and unzip it into C:\.

PyOpenGL

Saturday, February 4th, 2006

For an example of OpenGL bindings in another language, check out hello.py. This is a Python version of Example 1-2 from the OpenGL Programming Guide. Compare this to the C version you’re using for your homework — the language may be different, but OpenGL is the same.

OpenGL Bindings

Saturday, February 4th, 2006

Things have come a long way since the last time I went looking for OpenGL bindings. While scripting languages have always tended to have them (e.g., Perl, Python, Ruby, Lua, Io, even PHP — yikes!), bindings for “industrial-strength” languages have always seemed to lag behind.

Instead of the panoply of Java bindings that held sway in the early years, sanity finally seems to have taken hold in the form of semi-official JOGL project. Heck, they even have a JSR.

Over in the proprietary, closed-source, Windows-only, Microsoft-owned world of C# (can you tell I’m biased? And don’t tell me about CsGL (old and busted)

  • Tao (new hotness)
  • C# OpenGL Framework (commercial, but there is a “Basic” edition)
  • SharpGL
  • Roll your own
  • As with all things Lisp-y, OpenGL support is pretty fragmented. Whether there is an OpenGL binding, how well it works, and whether you get get any help if it doesn’t is largely dependent on which Lisp you’re using. You may be better off with Scheme, where the Sgl library for PLT Scheme appears to be officially supported.

    When it comes to getting all this set up, though, as I said earlier, you’re on your own.

    Win32 GLUT setup help

    Saturday, February 4th, 2006

    If we went too fast in lab Friday night, or if you’re finding that the instructions in the README file included with the Win32 GLUT distribution are insufficient, you may also want to check out these resources:

    If you’re not planning to do your programming in C or C++ or on Windows, that’s perfectly fine, but note two things:

    1. When you submit assignments, you need to document any build dependencies (i.e., libraries that you rely on)
    2. When it comes to getting your environment up and running, you’re on your own.

    The Reshape Callback

    Wednesday, February 16th, 2005

    Ok, so I had to go back and re-read the documentation to get this working.

    The default reshape callback (the one you get if you don’t call glutReshapeFunc()) calls glViewport(0, 0, w, h) and doesn’t change the coordinate system. The default coordinate system (which won’t change unless you call gluOrtho2D()) has its origin in thelower left corner of the window.

    Unfortunately, the coordinate system used for the mouse position has its origin in the upper left corner. That means that if you don’t have a reshape callback, or if you call gluOrtho2d(0, w, 0, h);, you’ll end up with mouse coordinates that are the opposite of drawing coordinates. To fix that, you need to do one of two things:

    1. Subtract the mouse y-coordinate from the height of the window
    2. Change your drawing coordinate system to match the mouse coordinate system

    Luckily, option (2) also allows us to resize the window without stretching the drawing or moving it all over the screen. Use the following reshape callback:

    void reshape(int w, int h)
    {
        glViewport(0, 0, w, h);
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        gluOrtho2D(0, w, h, 0);
    }

    Don’t forget to register the callback in main() with glutReshapeFunc(reshape).

    Here’s what the function does:

    glViewport(0, 0, w, h);

    Specifies that the viewport rectangle should occupy the entire window. The default reshape callback does the same thing.

    glMatrixMode(GL_PROJECTION);

    We’re about to specify 2D Orthographic projection. The default matrix mode is GL_MODELVIEW, so we need to switch.

    glLoadIdentity();

    Clear any existing projection matrix

    gluOrtho2D(0, w, h, 0);

    Specify the left, right, bottom, and top clipping planes. Note that the bottom clipping plane is h, not 0.