glEnable(GL_DEPTH_TEST); // Enables Depth Testing
}
Nothing has changed in ReSizeGLScene() so we'll skip right to InitGL().
int InitGL(GLvoid) // All Setup For OpenGL Goes Here
{
We jump to our texture building code. If texture building fails for any reason, we return FALSE. This lets our program know that an error has occurred and the program gracefully shuts down.
if (!LoadGLTextures()) // Jump To Texture Loading Routine
{
return FALSE; // If Texture Didn't Load Return FALSE
}
If there were no errors, we jump to our font building code. Not much can go wrong when building the font so we don't bother with error checking.
BuildFont(); // Build The Font
Now we do our normal GL setup. We set the background clear color to black, the clear depth to 1.0. We choose a depth testing mode, along with a blending mode. We enable smooth shading, and finally we enable 2D texture mapping.
glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // Clear The Background Color To Black
glClearDepth(1.0); // Enables Clearing Of The Depth Buffer
glDepthFunc(GL_LEQUAL); // The Type Of Depth Test To Do
glBlendFunc(GL_SRC_ALPHA,GL_ONE); // Select The Type Of Blending
glShadeModel(GL_SMOOTH); // Enables Smooth Color Shading
glEnable(GL_TEXTURE_2D); // Enable 2D Texture Mapping
return TRUE; // Initialization Went OK
}
The section of code below will create our scene. We draw the 3D object first and the text last so that the text appears on top of the 3D object, instead of the 3D object covering up the text. The reason I decide to add a 3D object is to show that both perspective and ortho modes can be used at the same time.
int DrawGLScene(GLvoid) // Here's Where We Do All The Drawing
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear The Screen And The Depth Buffer
glLoadIdentity(); // Reset The Modelview Matrix
We select our bumps.bmp texture so that we can build our simple little 3D object. We move into the screen 5 units so that we can see the 3D object. We rotate on the z axis by 45 degrees. This will rotate our quad 45 degrees clockwise and makes our quad look more like a diamond than a square.
glBindTexture(GL_TEXTURE_2D, texture[1]); // Select Our Second Texture
glTranslatef(0.0f, 0.0f, -5.0f); // Move Into The Screen 5 Units
glRotatef(45.0f, 0.0f, 0.0f, 1.0f); // Rotate On The Z Axis 45 Degrees (Clockwise)
After we have done the 45 degree rotation, we spin the object on both the x axis and y axis based on the variable cnt1 times 30. This causes our object to spin around as if the diamond is spinning on a point.
glRotatef(cnt1*30.0f,1.0f,1.0f,0.0f); // Rotate On The X & Y Axis By cnt1 (Left To Right)
We disable blending (we want the 3D object to appear solid), and set the color to bright white. We then draw a single texture mapped quad.
glDisable(GL_BLEND); // Disable Blending Before We Draw In 3D
glColor3f(1.0f,1.0f,1.0f); // Bright White
glBegin(GL_QUADS); // Draw Our First Texture Mapped Quad
glTexCoord2d(0.0f,0.0f); // First Texture Coord
glVertex2f(-1.0f, 1.0f); // First Vertex
glTexCoord2d(1.0f,0.0f); // Second Texture Coord
glVertex2f( 1.0f, 1.0f); // Second Vertex
glTexCoord2d(1.0f,1.0f); // Third Texture Coord
glVertex2f( 1.0f,-1.0f); // Third Vertex
glTexCoord2d(0.0f,1.0f); // Fourth Texture Coord
glVertex2f(-1.0f,-1.0f); // Fourth Vertex
glEnd(); // Done Drawing The First Quad
Immediately after we've drawn the first quad, we rotate 90 degrees on both the x axis and y axis. We then draw another quad. The second quad cuts through the middle of the first quad, creating a nice looking shape.
glRotatef(90.0f,1.0f,1.0f,0.0f); // Rotate On The X & Y Axis By 90 Degrees (Left To Right)
glBegin(GL_QUADS); // Draw Our Second Texture Mapped Quad
glTexCoord2d(0.0f,0.0f); // First Texture Coord
glVertex2f(-1.0f, 1.0f); // First Vertex
glTexCoord2d(1.0f,0.0f); // Second Texture Coord
glVertex2f( 1.0f, 1.0f); // Second Vertex
glTexCoord2d(1.0f,1.0f); // Third Texture Coord
glVertex2f( 1.0f,-1.0f); // Third Vertex
glTexCoord2d(0.0f,1.0f); // Fourth Texture Coord
glVertex2f(-1.0f,-1.0f); // Fourth Vertex
glEnd(); // Done Drawing Our Second Quad
After both texture mapped quads have been drawn, we enable enable blending, and draw our text.
glEnable(GL_BLEND); // Enable Blending
glLoadIdentity(); // Reset The View
We use the same fancy coloring code from our other text tutorials. The color is changed gradually as the text moves across the screen.
// Pulsing Colors Based On Text Position
glColor3f(1.0f*float(cos(cnt1)), 1.0f*float(sin(cnt2)), 1.0f-0.5f*float(cos(cnt1+cnt2)));
Then we draw our text. We still use glPrint(). The first parameter is the x position. The second parameter is the y position. The third parameter ("NeHe") is the text to write to the screen, and the last parameter is the character set to use (0 – normal, 1 – italic).
As you can probably guess, we swing the text around the screen using COS and SIN, along with both counters cnt1 and cnt2. If you don't understand what SIN and COS do, go back and read the previous text tutorials.
glPrint(int((280+250*cos(cnt1))), int(235+200*sin(cnt2)), "NeHe", 0); // Print GL Text To The Screen
glColor3f(1.0f*float(sin(cnt2)), 1.0f-0.5f*float(cos(cnt1+cnt2)), 1.0f*float(cos(cnt1)));
glPrint(int((280+230*cos(cnt2))), int(235+200*sin(cnt1)), "OpenGL", 1); // Print GL Text To The Screen
We set the color to a dark blue and write the author's name at the bottom of the screen. We then write his name to the screen again using bright white letters. The white letters are a little to the right of the blue letters. This creates a shadowed look. (if blending wasn't enabled the effect wouldn't work).
glColor3f(0.0f,0.0f,1.0f); // Set Color To Red
glPrint(int(240+200*cos((cnt2+cnt1)/5)), 2, "Giuseppe D'Agata",0); // Draw Text To The Screen
glColor3f(1.0f,1.0f,1.0f); // Set Color To White
glPrint(int(242+200*cos((cnt2+cnt1)/5)), 2, "Giuseppe D'Agata", 0); // Draw Offset Text To The Screen
The last thing we do is increase both our counters at different rates. This causes the text to move, and the 3D object to spin.
cnt1+=0.01f; // Increase The First Counter
cnt2+=0.0081f; // Increase The Second Counter
return TRUE; // Everything Went OK
}
The code in KillGLWindow(), CreateGLWindow() and WndProc() has not changed so we'll skip over it.
int WINAPI WinMain(HINSTANCE hInstance, // Instance
HINSTANCE hPrevInstance, // Previous Instance
LPSTR lpCmdLine, // Command Line Parameters
int nCmdShow) // Window Show State
{
MSG msg; // Windows Message Structure