#include <windows.h> // Header File For Windows
#include <gl\gl.h> // Header File For The OpenGL32 Library
#include <gl\glu.h> // Header File For The GLu32 Library
#include <gl\glaux.h> // Header File For The Glaux Library
#include <stdio.h>
#include <olectl.h>
#include <math.h>
#include <list>
int fps(72); //帧数
#include "Misc.h"
#include "Camera.h"
#include "3DS.h"
HDC hDC=NULL; // Private GDI Device Context
HGLRC hRC=NULL; // Permanent Rendering Context
HWND hWnd=NULL; // Holds Our Window Handle
HINSTANCE hInstance; // Holds The Instance Of The Application
bool keys[256]; // Array Used For The Keyboard Routine
bool active=TRUE; // Window Active Flag Set To TRUE By Default
bool fullscreen=TRUE; // Fullscreen Flag Set To Fullscreen Mode By Default
char* brand=NULL; //显卡型号
char* vendor=NULL; //显卡制造商
char* version=NULL; //版本号
CCamera camera;
CVect3 EyePosition;
t3DModel Room;
GLuint Tex_menu;
GLuint Tex_cursor;
GLuint Tex_note;
GLuint bloom;
bool Textured(true);
bool Light1(true);
bool Light2(true);
bool Light3(true);
bool Light4(true);
bool ShowMenu(false);
int cursorx, cursory;
void DrawModel(t3DModel& Model);
/////////// 鼠标调整视野 /////////////////
float angle_x(45.0f);
float angle_y(45.0f);
void AnjustViewByMouse()
{
static int mouse_x=0;
static int mouse_y=0;
if(fullscreen == true)
{
POINT newpos;
GetCursorPos(&newpos);
angle_x+=(newpos.y - mouse_y)/360.0f;
angle_y+=(newpos.x - mouse_x)/360.0f;
//confine the movement
if(angle_x>3.14159f/2.0f) angle_x=3.14159f/2.0f;
if(angle_x<-3.14159f/2.0f) angle_x=-3.14159f/2.0f;
//newpos.x=320;
//newpos.y=240;
SetCursorPos(320, 240);
}
if(GetAsyncKeyState(VK_LBUTTON))
{
POINT newpos;
GetCursorPos(&newpos);
angle_x+=(newpos.y - mouse_y)/360.0f;
angle_y+=(newpos.x - mouse_x)/360.0f;
//confine the movement
if(angle_x>3.14159f/2.0f) angle_x=3.14159f/2.0f;
if(angle_x<-3.14159f/2.0f) angle_x=-3.14159f/2.0f;
}
POINT pos;
GetCursorPos(&pos);
mouse_x=pos.x;
mouse_y=pos.y;
}
/////////// 鼠标调整视野结束 /////////////
////////////////////////// 绘制模型 ///////////////////////////////////////////////////
//画这个模型
void DrawModel(t3DModel& Model)
{
// 遍历模型中所有的对象
for(int i = 0; i < Model.numOfObjects; i++)
{
// 如果对象的大小小于0,则退出
if(Model.pObject.size() <= 0) break;
// 获得当前显示的对象
t3DObject *pObject = &Model.pObject[i];
// 判断该对象是否有纹理映射
if(pObject->bHasTexture && Textured==true) {
// 打开纹理映射
glEnable(GL_TEXTURE_2D);
glColor3ub(255, 255, 255);
glBindTexture(GL_TEXTURE_2D, Model.texture[pObject->materialID]);
} else {
// 关闭纹理映射
glDisable(GL_TEXTURE_2D);
glColor3ub(255, 255, 255);
}
// 开始以g_ViewMode模式绘制
glBegin(GL_TRIANGLES);
// 遍历所有的面
for(int j = 0; j < pObject->numOfFaces; j++)
{
// 遍历三角形的所有点
for(int whichVertex = 0; whichVertex < 3; whichVertex++)
{
// 获得面对每个点的索引
int index = pObject->pFaces[j].vertIndex[whichVertex];
// 给出法向量
glNormal3f(pObject->pNormals[ index ].x, pObject->pNormals[ index ].y, pObject->pNormals[ index ].z);
// 如果对象具有纹理
if(pObject->bHasTexture) {
// 确定是否有UVW纹理坐标
if(pObject->pTexVerts) {
glTexCoord2f(pObject->pTexVerts[ index ].x, pObject->pTexVerts[ index ].y);
}
} else {
if(Model.pMaterials.size() && pObject->materialID >= 0)
{
BYTE *pColor = Model.pMaterials[pObject->materialID].color;
glColor3ub(pColor[0], pColor[1], pColor[2]);
}
}
glVertex3f(pObject->pVerts[ index ].x, pObject->pVerts[ index ].y, pObject->pVerts[ index ].z);
}
}
glEnd(); // 绘制结束
}
}
////////////////////////// 绘制模型结束 ///////////////////////////////////////////////
/////// 初始化一个空白的纹理,为拷贝到纹理做准备 ///////////
GLuint EmptyTexture(int Height, int Width)
{
GLuint txtnumber; // Texture ID
unsigned int* data; // Stored Data
// Create Storage Space For Texture Data (128x128x4)
data = (unsigned int*)new GLuint[((Height * Width)* 4 * sizeof(unsigned int))];
ZeroMemory(data,((Height * Width)* 4 * sizeof(unsigned int))); // Clear Storage Memory
glGenTextures(1, &txtnumber); // Create 1 Texture
glBindTexture(GL_TEXTURE_2D, txtnumber); // Bind The Texture
glTexImage2D(GL_TEXTURE_2D, 0, 4, Height, Width, 0,
GL_RGBA, GL_UNSIGNED_BYTE, data); // Build Texture Using Information In data
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
delete [] data; // Release data
return txtnumber; // Return The Texture ID
}
///////////////// 创建纹理 //////////////////////////////////
BOOL BuildTexture(char *szPathName, GLuint &texid)
{
HDC hdcTemp; // The DC To Hold Our Bitmap
HBITMAP hbmpTemp; // Holds The Bitmap Temporarily
IPicture *pPicture; // IPicture Interface
OLECHAR wszPath[MAX_PATH+1]; // Full Path To Picture (WCHAR)
char szPath[MAX_PATH+1]; // Full Path To Picture
long lWidth; // Width In Logical Units
long lHeight; // Height In Logical Units
long lWidthPixels; // Width In Pixels
long lHeightPixels; // Height In Pixels
GLint glMaxTexDim ; // Holds Maximum Texture Size
if (strstr(szPathName, "http://")) // If PathName Contains http:// Then...
{
strcpy(szPath, szPathName); // Append The PathName To szPath
}
else // Otherwise... We Are Loading From A File
{
GetCurrentDirectory(MAX_PATH, szPath); // Get Our Working Directory
strcat(szPath, "\\"); // Append "\" After The Working Directory
strcat(szPath, szPathName); // Append The PathName
}
MultiByteToWideChar(CP_ACP, 0, szPath, -1, wszPath, MAX_PATH); // Convert From ASCII To Unicode
HRESULT hr = OleLoadPicturePath(wszPath, 0, 0, 0, IID_IPicture, (void**)&pPicture);
if(FAILED(hr)) // If Loading Failed
return FALSE; // Return False
hdcTemp = CreateCompatibleDC(GetDC(0)); // Create The Windows Compatible Device Context
if(!hdcTemp) // Did Creation Fail?
{
pPicture->Release(); // Decrements IPicture Reference Count
return FALSE; // Return False (Failure)
}
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &glMaxTexDim); // Get Maximum Texture Size Supported
pPicture->get_Width(&lWidth); // Get IPicture Width (Convert To Pixels)
lWidthPixels = MulDiv(lWidth, GetDeviceCaps(hdcTemp, LOGPIXELSX), 2540);
pPicture->get_Height(&lHeight); // Get IPicture Height (Convert To Pixels)
lHeightPixels = MulDiv(lHeight, GetDeviceCaps(hdcTemp, LOGPIXELSY), 2540);
// Resize Image To Closest Power Of Two
if (lWidthPixels <= glMaxTexDim) // Is Image Width Less Than Or Equal To Cards Limit
lWidthPixels = 1 << (int)floor((log((double)lWidthPixels)/log(2.0f)) + 0.5f);
else // Otherwise Set Width To "Max Power Of Two" That The Card Can Handle
lWidthPixels = gl