glInterface




#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <gl\gl.h>
#include <gl\glu.h>
#include <gl\glaux.h>


#define MAP_SIZE 1024 // .raw高程映射文件的大小
#define STEP_SIZE 16 // 每个三角形网格的宽度和高度
#define HEIGHT_RATIO 1.5f // This is the ratio that the Y is scaled according to the X and Z
#define MAX_TEXTURES 1000        // 最大的纹理数目
#define SCREEN_WIDTH 1000
#define SCREEN_HEIGHT 500  // 700
#define SCREEN_DEPTH 16

// glInterface.cpp  ---  opengl 简洁界面

#define eInfo(a)  { DWORD er=GetLastError(); LPTSTR psz;  \
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_ALLOCATE_BUFFER,0,er,0,(LPTSTR)&psz,0,0);  \
MessageBox(0,psz,a,0); LocalFree(psz); }


LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
void InitApp(HWND hWnd);  // 初始化整个程序
void clearApp();  // 释放程序占用的内存空间
void RenderScene();  // 渲染场景


#include <math.h>
#define PI 3.14159265358979323846 


#pragma comment(lib, "opengl32.lib")
#pragma comment(lib, "glu32.lib")
#pragma comment(lib, "glaux.lib")


#include <d3dx.h>
#pragma comment(lib, "d3dx.lib")   
#pragma comment(lib, "Winmm.lib")  //for timeGetTime


HWND  g_hWnd;
HDC   g_hDC;
HGLRC g_hRC;


bool  g_bRenderMode = true; // 渲染模式


UINT g_Texture[MAX_TEXTURES] = {0};
//  各位置的纹理ID
#define BACK_ID 1
#define FRONT_ID 2
#define BOTTOM_ID 3
#define TOP_ID 4
#define LEFT_ID 5
#define RIGHT_ID 6






int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, PSTR, int){


WNDCLASS wc={ CS_HREDRAW | CS_VREDRAW, WndProc, 0,0,  hInstance, 
LoadIcon(NULL, IDI_APPLICATION),LoadCursor(NULL, IDC_ARROW), 
(HBRUSH) (COLOR_WINDOW+1), 0, "GameTutorials", };


RegisterClass(&wc);
DWORD dwStyle=0;


if(!dwStyle) dwStyle = WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN;


int width=SCREEN_WIDTH, height=SCREEN_HEIGHT; 
RECT rcw={0,0,width,height,}; AdjustWindowRect( &rcw, dwStyle, false);
HWND hWnd = CreateWindow("GameTutorials", " 地形模拟 ", dwStyle, 200, 20, rcw.right-rcw.left, rcw.bottom-rcw.top,0, 0, hInstance, 0); 


if(!hWnd) return true;
ShowWindow(hWnd, SW_SHOWNORMAL); UpdateWindow(hWnd);  // SetFocus(hWnd);


InitApp(hWnd); // 初始化OpenGL



MSG msg;  // MainLoop();


while(1){


if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)){  
  if(msg.message == WM_QUIT) break;
  TranslateMessage(&msg);  DispatchMessage(&msg);
}else{    RenderScene();


}  // while 


clearApp();


UnregisterClass("GameTutorials", hInstance);
return(msg.wParam);
}






bool setPixelFormat(HDC hdc){


PIXELFORMATDESCRIPTOR pfd={sizeof(pfd),1, PFD_DRAW_TO_WINDOW | PFD_DOUBLEBUFFER, //  | PFD_SUPPORT_OPENGL
  PFD_TYPE_RGBA,SCREEN_DEPTH, 0, }; 


int pf;  if ( (pf = ChoosePixelFormat(hdc, &pfd)) == FALSE ){  eInfo("ChoosePixelFormat"); return FALSE; } 
if (SetPixelFormat(hdc, pf, &pfd) == FALSE) { eInfo("SetPixelFormat");  return FALSE; } 
 
return TRUE;
}


void glView(int w, int h){
if (h==0) h=1;
glViewport(0,0,w,h);
glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(45.0f,(float)w/h, 4 ,4000.0f);
glMatrixMode(GL_MODELVIEW); glLoadIdentity();
}




void glInit(int w, int h) {  
g_hDC = GetDC(g_hWnd);   if (!setPixelFormat(g_hDC)) PostQuitMessage (0);
g_hRC = wglCreateContext(g_hDC);    wglMakeCurrent(g_hDC, g_hRC);
glEnable(GL_TEXTURE_2D); glEnable(GL_DEPTH_TEST);
glView(w, h);
}




void clearApp(){
if (g_hRC){ wglMakeCurrent(0, 0); wglDeleteContext(g_hRC); }
if (g_hDC) ReleaseDC(g_hWnd, g_hDC);


PostQuitMessage (0);
}




//.................. Textures ..................//
bool CreateTexture(UINT &texture, LPSTR strFileName){  if(!strFileName) return false; 


FILE *pFile = NULL;
if((pFile = fopen(strFileName, "rb")) == NULL) {  // 以只读模式打开文件 
  MessageBox(g_hWnd, "Unable to load BMP File!", "Error", MB_OK);  // 如果文件无法打开,则显示错误信息
  return NULL; }  


AUX_RGBImageRec *pImage = auxDIBImageLoad(strFileName);  // 装入位图
if(pImage == NULL) return false;  // 确保位图数据已经装入


glGenTextures(1, &texture); // 生成纹理
glPixelStorei (GL_UNPACK_ALIGNMENT, 1);  // 设置像素格式
glBindTexture(GL_TEXTURE_2D, texture);   // 捆绑纹理
gluBuild2DMipmaps(GL_TEXTURE_2D, 3, pImage->sizeX, pImage->sizeY, GL_RGB, GL_UNSIGNED_BYTE, pImage->data);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);


//  释放位图数据占据的内存资源 
if(pImage){  if(pImage->data) free(pImage->data);
  free(pImage);


return true;
}






//------------------ Textures ------------------//








#define texUV(x,z)    glTexCoord2f( (float)x/ MAP_SIZE, - (float)z/MAP_SIZE ) 
 


 


void InitApp(HWND hWnd){


g_hWnd = hWnd;
RECT g_rRect; GetClientRect(g_hWnd, &g_rRect);
glInit(g_rRect.right, g_rRect.bottom);


//  读入"Terrain.raw"文件,作为高程数据


glEnable(GL_DEPTH_TEST);
glEnable(GL_TEXTURE_2D);
// glEnable(GL_CULL_FACE);


glShadeModel(GL_SMOOTH); 


CreateTexture(g_Texture[0], "wall.bmp");
CreateTexture(g_Texture[1], "wall1.bmp");


}


 




// getFPS, 计算帧率, 每 1 秒内显示帧的个数.
// fi, frame interval, 若非空, 则记录当前帧与前一帧之间的时间间隔(秒). 
float getFPS(float*fi){
static float fps       = 0.0f;     // 帧率, 每 1 秒内显示帧的个数, framesPerSecond. 
    static float lastSecond  = 0.0f;   // 前一秒的标记时刻, 每秒更新一次. 
static float lastTime = 0.0f;      // 前一帧时刻, 每帧(的秒数)更新一次 
static float currentTime=timeGetTime() * 0.001f;   // 当前帧时刻 
// static char strFrameRate[50] = {0};  


currentTime= timeGetTime() * 0.001f;   // 当前帧时刻 :  milliseconds -- /1000 --> seconds
if(fi)*fi= currentTime - lastTime;     // static float m_FrameInterval;  m_FrameInterval = currentTime - lastTime;  //  两帧之间的时间间隔
lastTime = currentTime;


++fps;  // 帧计数器递增


if( currentTime - lastSecond > 1.0f ){
  lastSecond = currentTime;  // sprintf(strFrameRate, "地形模拟 当前帧率:每秒 %d 帧", int(fps)); SetWindowText(g_hWnd, strFrameRate);
  fps = 0;  // 帧计数器复位
}  // if(...) 


return fps; 
}






//  RotateAxis, 将vIn 绕vAixs 旋转角度 a, 公式:  
//    x'=(x*n)n(1-cosθ) + cosθx + sinθn×x  
D3DXVECTOR3* D3DXVec3RotateAxis(D3DXVECTOR3*vOut,  const D3DXVECTOR3*vIn, float a, const D3DXVECTOR3*vAxis){
if(!vOut || !vIn || !vAxis) return 0L; 


D3DXVECTOR3 xv, x=*vIn, n=*vAxis;  D3DXVec3Normalize(&n,&n); 
float p=D3DXVec3Dot(&x,&n);  //  p=x*n
float ca = cos(a), sa = sin(a); 
D3DXVec3Cross(&xv,&n,&x); 
*vOut=p*(1-ca)*n+ca*x+sa*xv; 
return vOut;
}




#define kSpeed 180.0f // in Camera.h


// aimCamera, 实时调整摄像机位置. 关键调用: gluLookAt( ... );
void aimCamera(){
// 摄像机基本参数:    // g_Camera.PositionCamera( 280, 35, 225,  281, 35, 225,  0, 1, 0);
static D3DXVECTOR3 g_vLookat(700,0,800);     //280, 35, -225 m_vPosition  
static D3DXVECTOR3 g_vEye(600,35*3,-800);      // m_vView  
static D3DXVECTOR3 g_vUp(0,1,0); // m_vUpVector 摄像机初始参数: 0--x, 1--y, 2--z    
// 摄像机辅助参数: 
static D3DXVECTOR3 g_vRight(1,0,0), g_vLook(0,-1,-0.5);  // 摄像机方向 
g_vLook = g_vLookat-g_vEye;  // D3DXVec3Normalize(&g_vLook,&g_vLook); 
D3DXVec3Cross(&g_vRight, &g_vLook, &g_vUp);   D3DXVec3Normalize(&g_vRight,&g_vRight); 


glLoadIdentity();  \
gluLookAt(g_vEye.x, g_vEye.y, g_vEye.z,  g_vLookat.x, g_vLookat.y, g_vLookat.z,  g_vUp.x, g_vUp.y, g_vUp.z);  \




// g_Camera.Update(); ...... CheckForMovement();
static float v; getFPS(&v); v= kSpeed * v;  // v: 每秒位移量 ----> 每帧位移量
g_vLook = g_vLookat-g_vEye;  D3DXVec3Normalize(&g_vLook,&g_vLook); 
D3DXVec3Cross(&g_vRight, &g_vLook, &g_vUp);   D3DXVec3Normalize(&g_vRight,&g_vRight); 


if( GetKeyState(VK_UP) & 0x80 ) {  


  g_vLookat.y--;  g_vEye.y--;      


}else if( GetKeyState(VK_DOWN) & 0x80){


  g_vLookat.y++;  g_vEye.y++; 


}else if( GetKeyState('W') & 0x80 ) {  // 移动摄像机: MoveCamera(speed);


  g_vLookat+=g_vLook*v; g_vEye+=g_vLook*v;     // 改变摄像机的位置 


}else if(  GetKeyState('S') & 0x80 ){


  g_vLookat+=-g_vLook*v; g_vEye+=-g_vLook*v;      


}else if( GetKeyState(VK_LEFT) & 0x80 || GetKeyState('A') & 0x80 ){ 


  g_vLookat+=g_vRight*v;   // .y分量不加... 
  g_vEye+=g_vRight*v;    


}else if( GetKeyState(VK_RIGHT) & 0x80 || GetKeyState('D') & 0x80 ){ 


  g_vLookat+=-g_vRight*v;   // .y分量不加... 
  g_vEye+=-g_vRight*v;    


}  // if ... else ... 


}  // aimCamera 








//  glSquare, 以三角形面片的形式渲染四边形 ......  
void glSquare(int w,int h, int iTex=-1, float*pm=0L){  
// glShadeModel(GL_SMOOTH); 


glMatrixMode(GL_TEXTURE_MATRIX); glPushMatrix(); 
static float H;  H+=0.1;   // if(iTex>=0)   // 对于使用纹理的矩形, 施行世界坐标变换. 
if(pm){ glTranslatef(0,0,w/3.); glMultMatrixf(pm);  }


//            0,         1,     2,     3
float vso[]={0,0,0,   w,0,0,  0,0,h,  w,0,h,  };
float co[]={0xFF,0,0,   0,0xFF,0,  0,0,0xFF,  0xFF,0xFF,0xFF,  };  // 最后指定白色 
D3DXVECTOR3*vs=(D3DXVECTOR3*)vso; 
D3DXVECTOR3*vo=(D3DXVECTOR3*)co; 


if(iTex>=0) glBindTexture(GL_TEXTURE_2D, g_Texture[iTex]);  // 捆绑纹理


glBegin( GL_TRIANGLE_STRIP ); // 以三角形面片的形式绘制地形


static float x,y,z;   
for(int i=0; i<4; i++){  // CULL 


x=vs[i].x,y=vs[i].y, z=vs[i].z;  // x*=100, y*=100,z*=100; 


if(iTex>=0) glTexCoord2f( x/ w, -z/h  );    // 使用纹理坐标 
else glColor4f(vo[i].x,vo[i].y,vo[i].z,1);  // 使用颜色 


glVertex3i(x,y,z);


}  // for  


glEnd();  // 绘制完成


glPopMatrix(); 
}




//  glCircle, 以GL_LINE_STRIP 形式渲染圆 ......  
void glCircle(float r=10){   // glShadeModel(GL_SMOOTH); 


glMatrixMode(GL_TEXTURE_MATRIX); glPushMatrix(); 
 
static float a=20, da=-0.05; 
static float pm[16+2]={ 1,0,0,0,   0,1,0,0,   0,0,1,0,  0,0,0,1, }; 
pm[0]=cos(-a); pm[1]=sin(-a);  pm[4]=-sin(-a); pm[5]=cos(-a); 
glTranslatef(a*r,r,0);  
glMultMatrixf(pm); 
a+=da;  if(a*r<=r) da=+0.05; else if(a>=20) da=-0.05;  


float co[]={0xFF,0,0,   0,0xFF,0,  0,0,0xFF,    0xFF,0xFF,0,    0xFF,0,0xFF,   0,0xFF,0xFF,   0xFF,0xFF,0xFF,  };  // 最后指定白色 
D3DXVECTOR3*vo=(D3DXVECTOR3*)co; 


glBegin( GL_LINE_STRIP  );
static float x,y,z, c, dc=PI/12;   
static int N=24;  c=0;  z=256; 
for(int i=0; i<N; i++){  // CULL 


x=r*cos(c), y=r*sin(c);  // x*=100, y*=100,z*=100; 
glColor4f(vo[i%7].x,vo[i%7].y,vo[i%7].z,1);  // 使用颜色 
glVertex3i(x,y,z);
c+=dc;
}  // for  


glEnd();  // 绘制完成


glPopMatrix(); 
}










// RenderScene, 绘制场景
void RenderScene(){


aimCamera(); 


glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glClearColor(0.2f,0.2f,0.8f,1.0f);
// glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_ACCUM_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);


static float a=PI/2;  static float b=0; 
static float pm[16]={ 1,0,0,0,   0,1,0,0,   0,0,1,0,  0,0,0,1, };
pm[0]=cos(a); pm[1]=sin(a);  pm[4]=-sin(a); pm[5]=cos(a); 


glSquare(MAP_SIZE,MAP_SIZE);   
glSquare(MAP_SIZE/4.,MAP_SIZE/2.,0,pm);  // /STEP_SIZE




static float qm[16]={ 1,0,0,0,   0,1,0,0,   0,0,1,0,  0,0,0,1, };
qm[0]=cos(a); qm[1]=sin(a);  qm[4]=-sin(a); qm[5]=cos(a); 
qm[12]=MAP_SIZE; 
glSquare(MAP_SIZE/4.,MAP_SIZE/2.,1,qm);  


glCircle(50.); 


SwapBuffers(g_hDC); // 交换缓冲区
}










LRESULT CALLBACK WndProc(HWND hWnd,UINT uMsg, WPARAM wParam, LPARAM lParam){


switch (uMsg){ 


case WM_SIZE:{  glView(LOWORD(lParam),HIWORD(lParam));
}break; 
 
case WM_LBUTTONDOWN:
g_bRenderMode = !g_bRenderMode;  // 改变渲染模式
if(g_bRenderMode) { glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); // 纹理模式
}else{ glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); } // 线框模式
break;


case WM_KEYDOWN: switch(wParam) {
case VK_ESCAPE:PostQuitMessage(0); break;
case 'Z': g_bRenderMode = !g_bRenderMode;  // 改变渲染模式
if(g_bRenderMode)  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); // 纹理模式
else glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); // 线框模式
break; 
default: break; 
}break;


case WM_CLOSE: PostQuitMessage(0); break; 


}  //  switch (uMsg)


return DefWindowProc (hWnd, uMsg, wParam, lParam);
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值