Missing CD Source Code

It appears that the first batch of books have a problem with the CD - the book's source code is not included (empty .ZIP files). For the time being, you can download the source code for each chapter on the CD from the CD Source Code page.

OpenGLWindow2 Source Code Missing

The source code for the OpenGLWindow2 program mentioned in Chapter 2 is missing from the source code compilation (rotating red triangle). You can download it here.

Technical Errors

The following errors have been found:

  • Figure 19-4 is incorrect for people with the first printing of the book. In this printing, Figure 19-4 is the same as Figure 18-4, which is correct. The correct Figure 19-4 is shown below:

  • In chapter 3, at the top of the page, the matrix should be transposed to get the indicated results. Thanks to Eshan Kamrani for pointing this out.

  • In chapter 4, the example program doesn't account for the height or width possibly being zero in the DisplayScene method, causing a possible divide by zero error. There are several ways to avoid this, the most straightforward of which is to just check for the height and width being zero before randomly generating primitives. (Reported by Eric Danker)

  • Chapter 6, Calculating Normals, p. 164
    The CrossProduct() function should be:
    void CrossProduct(float vector1[3], float vector2[3],float normal[3])
    	normal[0] = vector1[1]*vector2[2] - vector1[2]*vector2[1]; 
    	normal[1] = vector1[2]*vector2[0] - vector1[0]*vector2[2];
    	normal[2] = vector1[0]*vector2[1] - vector1[1]*vector2[0];

  • There is an unnecessary "for" loop in the MD2 model loading code. You do not need to loop the number of frames to store the triangle indices. This error is not urgent as fixing it will only increase the speed of the MD2 loading code. The code should be:
    for(i = 0; i < modelHeader->numTris; i++)
       triIndex[i].meshIndex[0] = bufIndexPtr[i].meshIndex[0];
       triIndex[i].meshIndex[1] = bufIndexPtr[i].meshIndex[1];
       triIndex[i].meshIndex[2] = bufIndexPtr[i].meshIndex[2];
       triIndex[i].stIndex[0] = bufIndexPtr[i].stIndex[0];
       triIndex[i].stIndex[1] = bufIndexPtr[i].stIndex[1];
       triIndex[i].stIndex[2] = bufIndexPtr[i].stIndex[2];

  • There is an error in Chapter 10's terrain program and Chapter 15's billboarding demo (cacti). In both cases, and incorrect value is being passed to the glLockArraysEXT method, causing the demos to crash on some machines. The source code available on this site has been updated, or you can just make the changes below:
        glLockArraysEXT(0, MAP_X * MAP_Z * 6);

    Needs to be changed to

        glLockArraysEXT(0, MAP_X * MAP_Z);

  • The keyboard code in Chapter 17 and Chapter 21 has a bug. In the KeyDown and KeyUp methods, the parameter is a char. This needs to be an int or an unsigned char to work correctly with all DIK codes (anything with a value greater than 127 always returns true otherwise).