📄 glmain.cpp
字号:
/*
This file is generated by AppWizard
Add this string to the project->Setting
kernel32.lib user32.lib gdi32.lib opengl32.lib glu32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib
Stanly Lee Xpert - HeartBlue
2002-7-25
*/
#include "Texturemgr.h"
#include "billboardMgr.h"
#include "LOD.h"
#include "Data.h"
#include "map.h"
#include "Terrain.h"
#include "initsence.h"
#include "Console.h"
#include <GL\glext.h>
#include "timer.h"
#include "input.h"
#include "MotionCtrl.h"
#include "MotionBlur.h"
#include "GamaControl.h"
#include "Effect.h"
TCHAR szAppTitle[] = "Power Render 引擎 -- XheartBlue";
bool is_debug=false;
//应用程序对象
CGameApp g_app(szAppTitle);
CGamaControl g_Gama;
CTextureMgr g_tex_mgr;
//场景中的物体
//镜头玄光体
CLensFlar flare;
//2D的BillBoard管理器
C2DBillBoardMgr g_bbm;
//天空体
CSkyBox g_sky;
//地形数据
CTerrain terrain;
//Level of Detail 控制器
CLOD* pLOD;
//裁减器
CViewFrustum Culler;
//摄影机对象
CCamera* g_pcm;
//效果器
CMotionBlur g_MBlur;
COverBurtEff g_OverBurt;
CMapPilotEff g_MapPilot;
CGamaEff g_GamaEff;
CScrapEff g_ScapEff;
CSnipEff g_SnipEff;
CCrossEff g_CrossEff;
//运动控制器
CMotionCtrl g_MCtrl;
//============================================================
//函数声明
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int RenderSence(LONG fps);
int GameLoop(LONG fps);
void Resize();
void RenderFont(int fps);
RunApp(LPSTR ,int);
//===========================================================
//********************************************
//程序的真正入口点。
//********************************************
int RunApp(LPSTR CmdLine ,int sw_mode)
{
srand(GetTickCount());
LoadAppCfg();
LoadMapCfg();
int w = Configure.GetInteger("General","screen_w");
int h = Configure.GetInteger("General","screen_h");
int cb = Configure.GetInteger("General","color_depth");
int df = Configure.GetInteger("General","display_fre");
BOOL isFullScreen = Configure.GetBool("General","fullscreen");
if(isFullScreen)
g_app.CreateExcApp(WndProc,w,h);
else
g_app.CreateNormalApp(WndProc);
Console.Open();
Console.Printf("-------------------------------------------------------------");
Console.Printf(" 大规模室外场景渲染技术Demo");
Console.Printf(" SimNature Ver 2.2");
Console.Printf(" 作者:潘李亮");
Console.Printf(" 版权所有");
Console.Printf(" 2002 - 2003 ");
Console.Printf("-------------------------------------------------------------");
Console.Printf("程序启动");
if(isFullScreen)
Console.Printf("使用全屏幕模式");
else
Console.Printf("使用窗口模式");
ifstream in;
in.open(MapCfg.GetString("Map","mapfile"),ios::in|ios::binary);
if(in.fail())
{
Console.Printf("地图文件不存在,需要创建!");
Console.Printf("现在开始创建地图,这将要花费很长的时间");
Console.Printf("地图创建中,请耐心的等待(现在你可以先去喝杯茶^_^)");
int size = MapCfg.GetInteger("Map","size");
RPMAP map = CreateRPMap(size,size,0.132);
SaveRPMap(map,MapCfg.GetString("Map","mapfile"));
FreeRPMap(map);
Console.Printf("地图创建完毕!");
}
in.close();
//=====Console Output===============
Console.Printf("OpenGL 开始初始化........");
g_GL.InitOpenGL(g_app.m_hMainWnd);
if(InitMultiTex() == NULL)
{
Console.Printf("GL extention 错误: 不支持多遍纹理映射");
TerminateApp();
}
else
Console.Printf("多遍纹理映射功能初始化成功!");
//=====Console Output===============
Console.Printf("OpenGL 初始化成功");
ApplyConfigure();
//=====Console Output===============
Console.Printf("配置文件加载成功!.....");
g_GL.CreateFont();
//=====Console Output===============
Console.Printf("字体创建成功!");
InitTerrain();
//=====Console Output===============
Console.Printf("地形加载成功!");
InitCamera();
//=====Console Output===============
Console.Printf("摄影机设置完毕");
InitFog();
//=====Console Output===============
Console.Printf("雾效果初始化成功");
InitFlare();
//=====Console Output===============
Console.Printf("太阳创建完毕....");
InitSky();
//=====Console Output===============
Console.Printf("天空体创建完毕");
RECT region=
{
10,10,terrain.GetX()-10,terrain.GetY()-10
};
g_MCtrl.SetInput(&g_Input);
g_MCtrl.SetTerrain(&terrain);
g_MCtrl.SetSkyHeight(g_sb_h);
g_MCtrl.SetCamera(g_pcm);
g_MCtrl.SetRegion(region);
terrain.SetCamera(g_pcm);
Culler.SetCamera(g_pcm);
InitBillBoard();
//=====Console Output===============
Console.Printf("树木创建完毕");
glEnable(GL_CULL_FACE);
//===========开始初始化效果器=============================
/*******************非常重要*************************
注意这个时候,窗口的大小还是没有确定的。
如果你没有为运动模糊的图象纹理指定大小的话。
你必须在 窗口的大小已经确定的时候,
调用COpenGL.Resize() & CMotionBlur.Resize函数。
这个很重要,不然你的程序开启运动模糊的时候会不正常
*******************************************************/
Console.Printf("开始初始化所有的效果器");
//初始化Motion Blur
int blur_x = Configure.GetInteger("Blur","x");
int blur_y = Configure.GetInteger("Blur","y");
if(blur_x && blur_y)
{
Console.Printf("运动模糊图象大小 : %d X %d ",blur_x,blur_y);
g_MBlur.Create(blur_x,blur_y);
}
else
{
Console.Printf("运动模糊图象大小和屏幕(窗口相同大小)");
}
Console.Printf("运动模糊因子: %f",Configure.GetFloat("Blur","value"));
g_MBlur.SetBlurValue(Configure.GetFloat("Blur","value"));
Console.Printf("MotioN blur初始化完毕");
//把其它的效果器加到链中。注意,MotionBlur就是这个链的开始。
g_MBlur.AddEffect(&g_OverBurt);
Console.Printf("加入过度燃烧效果器");
g_SnipEff.Create(g_tex_mgr.LoadTexture(Configure.GetString("Snip","mask")));
g_MBlur.AddEffect(&g_SnipEff);
g_SnipEff.SetEffect(0);
// g_MBlur.AddEffect(&g_CrossEff);
// g_CrossEff.SetEffect(0);
g_MapPilot.SetTerrainSize(terrain.GetX(),terrain.GetY());
g_MapPilot.SetCamraInfo(g_pcm);
g_MapPilot.SetTerrainTex(terrain.GetTexArray()[0]);
g_MBlur.AddEffect(&g_MapPilot);
Console.Printf("加入地图导航器");
g_MBlur.AddEffect(&g_GamaEff);
Console.Printf("加伪Gama控制效果器");
g_ScapEff.SetEffect(TRUE);
g_MBlur.AddEffect(&g_ScapEff);
Console.Printf("所有的效果器初始化完毕");
//=============所有的效果器初始化完毕=========================
if(isFullScreen)
{
//=====Console Output===============
Console.Printf("全屏幕设置,宽: %d高:%d 色深:%d 刷新率: %d",w,h,cb,df);
g_app.SetDisplayMode(w,h,cb,df);
}
//=====Console Output===============
Console.Printf("开始运行程序.......");
Console.Printf("关闭控制台!");
Console.Close();
//=======所有的东西初始化完毕,启动程序=============================
g_app.ShowWindow(sw_mode);
g_app.Run();
ShowCursor(FALSE);
SetCursorPos(400,400);
//改变窗口的大小
g_GL.Resize();
g_pcm->Project(g_GL.m_view_factor);
g_MBlur.Resize();
//用一个亮度控制器产生一种渐渐显现的效果
for(float ga=0.02;ga<0.98;ga += 0.01)
{
CTimer::UpdateTime();
g_Input.Update();
g_MCtrl.Move();
g_MBlur.BeginRender();
RenderSence(0);
g_Gama.SetGama(ga);
g_Gama.Apply();
g_GL.SwapBuffer();
}
//MessageBox(NULL,"","",MB_OK);
g_app.MainLoop(GameLoop);
Console.SaveToLogFile();
Console.Clear();
g_GL.ReleaseFont();
g_GL.ReleaseGL();
ShowCursor(TRUE);
Configure.FreeData();
MapCfg.FreeData();
return 1;
}
int GameLoop(LONG fps)
{
CTimer::UpdateTime();
g_Input.Update();
g_MCtrl.Move();
g_MBlur.BeginRender();
//Render the sence
//RenderSence(fps);
g_MBlur.Render(RenderSence,fps);
RenderFont(fps);
g_GL.SwapBuffer();
return fps;
}
int RenderSence(LONG fps)
{
//初始化绘制场景
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
//===========================================================
//应用摄影机
g_pcm->Look();
//从摄影机信息更新裁剪器。
Culler.UpdateCamera();
//天空体
g_sky.Draw();
//画地形 数据
terrain.Render();
//=======================================================================
//〈〉〈〉〈〉〈〉〈〉〈〉〈〉〈〉〈〉〈〉〈〉〈〉〈〉〈〉〈〉〈〉〈〉〈〉
//以下是透明物体的绘制
//〈〉〈〉〈〉〈〉〈〉〈〉〈〉〈〉〈〉〈〉〈〉〈〉〈〉〈〉〈〉〈〉〈〉〈〉
//=======================================================================
if(is_bb_draw)
{
g_bbm.Draw();
}
//画眩光物体----太阳
flare.Draw();
//屏幕信息的绘制
return fps;
}
void RenderFont(int fps)
{
char buf[255];
glColor4f(1.0,1.0,1.0,1.0);
g_GL.BeginRenderFont();
sprintf(buf,"Fps: %d ",fps);
g_GL.RenderFont(buf,-90,-75);
sprintf(buf,"Object/Space Error %g/%g",g_object_error,g_space_error);
g_GL.RenderFont(buf,-90,-85);
#ifdef _COUNT_TRIAN_COUNT
sprintf(buf,"Traingls Number: %d",(int)pLOD->GetTrianglesCount());
g_GL.RenderFont(buf,-90,-95);
#endif
g_GL.EndRenderFont();
}
void ReProject(float a)
{
RECT rt;
GetClientRect(g_app.m_hMainWnd,&rt);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(a,float(rt.right -rt.left)/(rt.bottom - rt.top),0.1,10000);
glMatrixMode(GL_MODELVIEW);
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
static int ox,oy;
static int tex = 1;
static bool is_move=false;
static bool is_Grid = false;
switch(msg)
{
case WM_RBUTTONDOWN:
{
g_pcm->Zoomed(!g_pcm->IsZoomed());
float f= 0.6*g_pcm->GetViewerAngle()/g_pcm->GetZoomAngle();
if(g_pcm->IsZoomed())
{
pLOD->SetObjectError(pLOD->GetObjectError()*f);
//Culler.m_view_dist *= f;
}
else
{
pLOD->SetObjectError(pLOD->GetObjectError()/f);
//Culler.m_view_dist /= f;
}
g_pcm->Project(g_GL.m_view_factor);
}
break;
case WM_CREATE:
case WM_SIZE:
case WM_MOVE:
g_GL.Resize();
if(g_pcm)
g_pcm->Project(g_GL.m_view_factor);
break;
case WM_KEYDOWN:
switch(wParam)
{
case VK_RETURN:
is_Grid = !is_Grid;
pLOD->EnableGridRender(is_Grid);
break;
case VK_SPACE:
g_is_detail_tex = ! g_is_detail_tex;
pLOD->EnableDetailTex(g_is_detail_tex);
break;
case VK_HOME:
g_object_error += 0.01;
pLOD->SetObjectError(g_object_error);
break;
case VK_END:
if(g_object_error >0.1)
g_object_error -= 0.01;
pLOD->SetObjectError(g_object_error);
break;
case VK_INSERT:
if(g_space_error<500)
g_space_error += 0.2;
pLOD->SetSpaceError(g_space_error);
break;
case VK_DELETE:
if(g_space_error>1)
g_space_error -= 0.2;
pLOD->SetSpaceError(g_space_error);
break;
case VK_PRIOR:
g_MBlur.SetBlurValue(g_MBlur.GetBlurValue() + 0.02);
break;
case VK_NEXT:
g_MBlur.SetBlurValue(g_MBlur.GetBlurValue() - 0.02);
break;
case VK_ESCAPE:
{
float d = 0.02;
if(rand()%2)
d = -d;
for(float ga=1.;ga > 0 && ga< 2;ga -= d)
{
CTimer::UpdateTime();
g_Input.Update();
g_MCtrl.Move();
g_MBlur.BeginRender();
RenderSence(0);
g_Gama.SetGama(ga);
g_Gama.Apply();
g_MBlur.Render();
g_GL.SwapBuffer();
}
}
PostQuitMessage(0);
break;
case VK_F2:
g_ScapEff.Scrap();
break;
case VK_F3:
g_isFog =!g_isFog;
if(g_isFog)
glDisable(GL_FOG);
else
glEnable(GL_FOG);
break;
case VK_F4:
g_MCtrl.EnableAutoPilot(!g_MCtrl.IsAutoPilot());
break;
case VK_F5:
g_MBlur.SetEffected(!g_MBlur.IsEffected());
break;
case VK_F6:
g_MapPilot.SetEffect(!g_MapPilot.IsEffect());
break;
case VK_F7:
g_OverBurt.SetEffect(!g_OverBurt.IsEffect());
break;
case VK_F8:
g_GamaEff.SetEffect(!g_GamaEff.IsEffect());
break;
case VK_F9:
g_SnipEff.SetEffect(!g_SnipEff.IsEffect()&&g_pcm->IsZoomed());
break;
case VK_F10:
g_CrossEff.SetEffect(!g_CrossEff.IsEffect());
break;
case VK_F12:
pLOD->SetLodMethod(pLOD->GetLodMethod() + 1 ) ;
break;
case VK_ADD:
pLOD->IncreaseTexDetail(1);
break;
case VK_SUBTRACT:
pLOD->IncreaseTexDetail(-1);
break;
case 'T':
pLOD->ChangeDetailTex(tex++);
break;
case 'B':
is_bb_draw = !is_bb_draw;
break;
case 'F':
glPolygonMode(GL_FRONT,GL_LINE);
glPolygonMode(GL_BACK,GL_LINE);
break;
case 'C':
glPolygonMode(GL_FRONT,GL_FILL);
glPolygonMode(GL_BACK,GL_FILL);
break;
case 'P':
terrain.Strecth(1.2);
break;
case 'L':
terrain.Strecth(0.9);
break;
case 'O':
g_OverBurt.SetValue(g_OverBurt.GetValue() + 0.01);
break;
case 'K':
g_OverBurt.SetValue(g_OverBurt.GetValue() - 0.01);
break;
}
break;
case WM_CHAR:
switch(wParam)
{
case ',':
g_GamaEff.SetValue(g_GamaEff.GetValue()-0.02);
break;
case '.':
g_GamaEff.SetValue(g_GamaEff.GetValue()+0.02);
break;
}
break;
case WM_CLOSE:
DestroyWindow(hWnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return ::DefWindowProc(hWnd,msg,wParam,lParam);
}
return 1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -