📄 main.cpp
字号:
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear The Screen And The Depth Buffer
glLoadIdentity(); // Reset The matrix
//////////// *** NEW *** ////////// *** NEW *** ///////////// *** NEW *** ////////////////////
// Give OpenGL our position, then view, then up vector
gluLookAt( 0, 1.5f, 90, 0, 0.5f, 0, 0, 1, 0);
// We want the model to rotate around the axis so we give it a rotation
// value, then increase/decrease it. You can rotate right of left with the arrow keys.
glRotatef(g_RotateX, 0, 1.0f, 0); // Rotate the object around the Y-Axis
g_RotateX += g_RotationSpeed; // Increase the speed of rotation
// Make sure we have valid objects just in case. (size() is in the vector class)
if(g_3DModel.pObject.size() <= 0) return;
// Get the current object that we are displaying
t3DObject *pObject = &g_3DModel.pObject[0];
// Render lines or normal triangles mode, depending on the global variable
glBegin(g_ViewMode);
// Go through all of the faces (polygons) of the object and draw them
for(int j = 0; j < pObject->numOfFaces; j++)
{
// Go through each corner of the triangle and draw it.
for(int whichVertex = 0; whichVertex < 3; whichVertex++)
{
// Get the index for each point in the face
int index = pObject->pFaces[j].vertIndex[whichVertex];
// Get the index for each texture coord in the face
int index2 = pObject->pFaces[j].coordIndex[whichVertex];
// Give OpenGL the normal for this vertex. Notice that we put a
// - sign in front. It appears that because of the ordering of Quake2's
// polygons, we need to invert the normal
glNormal3f(-pObject->pNormals[ index ].x, -pObject->pNormals[ index ].y, -pObject->pNormals[ index ].z);
// Make sure there was a UVW map applied to the object or else it won't have tex coords.
if(pObject->pTexVerts)
{
glTexCoord2f(pObject->pTexVerts[ index2 ].x, pObject->pTexVerts[ index2 ].y);
}
// Pass in the current vertex of the object (Corner of current face)
glVertex3f(pObject->pVerts[ index ].x, pObject->pVerts[ index ].y, pObject->pVerts[ index ].z);
}
}
glEnd();
//////////// *** NEW *** ////////// *** NEW *** ///////////// *** NEW *** ////////////////////
SwapBuffers(g_hDC); // Swap the backbuffers to the foreground
}
///////////////////////////////// WIN PROC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
/////
///// This function handles the window messages.
/////
///////////////////////////////// WIN PROC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
LRESULT CALLBACK WinProc(HWND hWnd,UINT uMsg, WPARAM wParam, LPARAM lParam)
{
LONG lRet = 0;
PAINTSTRUCT ps;
switch (uMsg)
{
case WM_SIZE: // If the window is resized
if(!g_bFullScreen) // Do this only if we are NOT in full screen
{
SizeOpenGLScreen(LOWORD(lParam),HIWORD(lParam));// LoWord=Width, HiWord=Height
GetClientRect(hWnd, &g_rRect); // Get the window rectangle
}
break;
case WM_PAINT: // If we need to repaint the scene
BeginPaint(hWnd, &ps); // Init the paint struct
EndPaint(hWnd, &ps); // EndPaint, Clean up
break;
//////////// *** NEW *** ////////// *** NEW *** ///////////// *** NEW *** ////////////////////
// Below we define our controls for this simple tutorial.
// The controls are:
// Left Mouse Button - Changes the Render mode from normal to wireframe.
// Right Mouse Button - Turns lighting On/Off
// Left Arrow Key - Spins the model to the left
// Right Arrow Key - Spins the model to the right
// Escape - Quits
case WM_LBUTTONDOWN: // If the left mouse button was clicked
if(g_ViewMode == GL_TRIANGLES) { // We our drawing mode is at triangles
g_ViewMode = GL_LINE_STRIP; // Go to line stips
} else {
g_ViewMode = GL_TRIANGLES; // Go to triangles
}
break;
case WM_RBUTTONDOWN: // If the right mouse button was clicked.
g_bLighting = !g_bLighting; // Turn lighting ON/OFF
if(g_bLighting) { // If lighting is ON
glEnable(GL_LIGHTING); // Enable OpenGL lighting
} else {
glDisable(GL_LIGHTING); // Disable OpenGL lighting
}
break;
case WM_KEYDOWN: // If we pressed a key
switch(wParam) { // Check if we hit a key
case VK_ESCAPE: // If we hit the escape key
PostQuitMessage(0); // Send a QUIT message to the window
break;
case VK_LEFT: // If the LEFT arrow key was pressed
g_RotationSpeed -= 0.05f; // Decrease the rotation speed (eventually rotates left)
break;
case VK_RIGHT: // If the RIGHT arrow key is pressed
g_RotationSpeed += 0.05f; // Increase the rotation speed (rotates right)
break;
}
break;
//////////// *** NEW *** ////////// *** NEW *** ///////////// *** NEW *** ////////////////////
case WM_CLOSE: // If the window is being closed
PostQuitMessage(0); // Send a QUIT Message to the window
break;
default: // Return by default
lRet = DefWindowProc (hWnd, uMsg, wParam, lParam);
break;
}
return lRet; // Return by default
}
/////////////////////////////////////////////////////////////////////////////////
//
// * QUICK NOTES *
//
// This tutorial shows how to load a .Md2 file. This is a good addition to an engine.
// In the next tutorial we will show you how to handle the key frame animation.
// I think this is the best and easiest 3D file format I have worked with, especially
// for animation.
//
// * What's An STL (Standard Template Library) Vector? *
// Let me quickly explain the STL vector for those of you who are not familiar with them.
// To use a vector you must include <vector> and use the std namespace: using namespace std;
// A vector is an array based link list. It allows you to dynamically add and remove nodes.
// This is a template class so it can be a list of ANY type. To create a vector of type
// "int" you would say: vector<int> myIntList;
// Now you can add a integer to the dynamic array by saying: myIntList.push_back(10);
// or you can say: myIntList.push_back(num);. The more you push back, the larger
// your array gets. You can index the vector like an array. myIntList[0] = 0;
// To get rid of a node you use the pop_back() function. To clear the vector use clear().
// It frees itself so you don't need to worry about it, except if you have data
// structures that need information freed from inside them, like our objects.
//
// Once again I should point out that the coordinate system of OpenGL and .Md2 files are different.
// Since Quake2 Models have the Z-Axis pointing up (strange and ugly I know! :),
// we need to flip the y values with the z values in our vertices. That way it
// will be normal, with Y pointing up. Also, because we swap the Y and Z we need to negate
// the Z to make it come out correctly. This is also explained and done in ReadMd2Data().
//
// I would like to thank Daniel E. Schoenblum <dansch@hops.cs.jhu.edu> for help
// with explaining the file format. You can check it out at:
//
// http://www.ugrad.cs.jhu.edu/~dansch/md2/#model_magic
//
// Let me know if this helps you out!
//
//
// Ben Humphrey (DigiBen)
// Game Programmer
// DigiBen@GameTutorials.com
// Co-Web Host of www.GameTutorials.com
//
// The Quake2 .Md2 file format is owned by ID Software. This tutorial is being used
// as a teaching tool to help understand model loading and animation. This should
// not be sold or used under any way for commercial use with out written conset
// from ID Software.
//
// Quake and Quake2 are trademarks of id Software.
// All trademarks used are properties of their respective owners.
//
//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -