資源簡介
前面幾日我重新實現(xiàn)了迷宮的自動生成方法,并且添加了迷宮自動尋路方法。有了一個獨立于GUI的迷宮庫,我開始迫不及待地實現(xiàn)三維迷宮了!
下面是我在開發(fā)迷宮程序中遇到的問題。
1、怎樣將迷宮類的行和列映射到真實的三維坐標中?迷宮應該用哪個參考系來描述?
其實我在制作的時候為了簡化,將二維迷宮的左上角與三維的原點重合,二維迷宮的右對應三維的X軸正方向,迷宮的下對應Z軸的正方向。
2、迷宮的“上、下、左、右”在三維中應該叫做什么?
在確定好迷宮的位置后,我們將迷宮的上對應Z軸的負半軸,下對應Z軸的正半軸,左對應X軸的負半軸,右對應Y軸的正半軸。
3、三維點繪制順序以及OpenGL裁剪模式造成的一些面不可見問題。
這個問題是我在編寫二維迷宮沒有想到的。主要是因為二維迷宮中描述墻是用一條直線,而到了三維則是一個面。由于在OpenGL中有裁剪模式可以選擇,我使用了
glFrontFace( GL_CW ); // 順時針的繪制為正面
glEnable( GL_CULL_FACE ); // 剔除不是正面的面
進行設定,也就是說,所有在攝像機看來是逆時針繪制的圖形都無法顯示。因此我不得不用同樣的頂點繪制兩個面。下面是相關的函數(shù):
void DrawInnerWall( Point3F& p1, Point3F& p2, Point3F& p3, Point3F& p4 )
{
glTexCoord2f( 0.0f, 1.0f ); glVertex3fv( p1 );
glTexCoord2f( 1.0f, 1.0f ); glVertex3fv( p2 );
glTexCoord2f( 1.0f, 0.0f ); glVertex3fv( p3 );
glTexCoord2f( 0.0f, 0.0f ); glVertex3fv( p4 );
}
void DrawOuterWall( Point3F& p1, Point3F& p2, Point3F& p3, Point3F& p4 )
{
glTexCoord2f( 1.0f, 1.0f ); glVertex3fv( p1 );
glTexCoord2f( 0.0f, 1.0f ); glVertex3fv( p2 );
glTexCoord2f( 0.0f, 0.0f ); glVertex3fv( p3 );
glTexCoord2f( 1.0f, 0.0f ); glVertex3fv( p4 );
}
在編寫這些函數(shù)的時候尤其注意紋理坐標的繪制順序??梢栽诩埳侠L制一個草圖。下面是我調(diào)用的代碼:
if ( Cell_UpWall( cell ) )
{
DrawInnerWall( p8, p7, p3, p4 );
DrawOuterWall( p7, p8, p4, p3 );
}
4、怎樣設置阻擋?
設置阻擋的基本原則還是先檢測后執(zhí)行。首先我先嘗試著執(zhí)行走一步,再判斷這一步是不是出現(xiàn)了越界問題。如果出現(xiàn)了越界問題,那么不執(zhí)行這一步,否則執(zhí)行這一步。為了不讓我們無限地靠近墻,我設定了一個gap,即攝像機必須與墻保持gap的距離。
下面是我相關的代碼:
bool View3D::CanGo( Maze& maze, float step )
{
static float gap = m_CellSize.w / 8.0f;// 攝像機與墻最近不能超過的間隔
const Point3F& pos = m_Camera.Pos( );
Point3F tryPos;
if ( pos.y > 0 && pos.y ( row - 1 ) * m_CellSize.w );
if (
代碼片段和文件信息
//?GLWidget.cpp?包含了控件的使用
//?11:14:27?最后編輯
//?如果在windows下編譯,那么要加上windows.h,否則有很多鏈接錯誤
#ifdef?_WIN32
#include?
#endif
#include?
#include?
#include?“LuaInclude.h“
#include?“GLWidget.h“
//-----------------------------------------------------------------------------
void?GLWidget::AdditionalSetup(?void?) //?額外的初始化
{
????m_FPSCount?=?0;
????//?設定一些默認值
????m_Row?=?4?m_Column?=?4;
????m_MoveStep?=?0.2f;
????m_RotateAngle?=?0.02f;
????m_Display2DView?=?true;
????if?(?m_scriptLoaded?)//?已經(jīng)成功地載入腳本
????{
????????//?讀取腳本的值
????????lua_getglobal(?m_L?“row“?);
????????m_Row?=?luaL_checkunsigned(?m_L?-1?);
????????lua_getglobal(?m_L?“column“?);
????????m_Column?=?luaL_checkunsigned(?m_L?-1?);
????????lua_getglobal(?m_L?“moveStep“?);
????????m_MoveStep?=?luaL_checknumber(?m_L?-1?);
????????lua_getglobal(?m_L?“rotateAngle“?);
????????m_RotateAngle?=?luaL_checknumber(?m_L?-1?);
????}
????//?初始化迷宮
????m_Maze.Init(?m_Row?m_Column?);
????m_Maze.RandomCreate(?);
????View3D::Init(?m_Maze?);
????View2D::Init(?m_Maze
??????????????????Point2F(?float(?m_Width?*?2?/?3?)
???????????????????????????float(?m_Height?*?2?/?3?)?)
??????????????????Point2F(?float(?m_Width?)?float(?m_Height?)?)
??????????????????Color4B(?255?255?255?100?)?);
????UpdateRotation(?);//?更新箭頭的坐標
}
//-----------------------------------------------------------------------------
GLWidget::GLWidget(?void?)
{
????//?構造函數(shù)的代碼在這里
????m_Width =?0.0;
????m_Height =?0.0;
}
//-----------------------------------------------------------------------------
GLWidget::~GLWidget(?void?)
{
????Release(?);
}
//-----------------------------------------------------------------------------
void?GLWidget::Init(?int?width?int?height?)
{
????//?保存初始化時窗口的寬和高
????m_Width?=?GLdouble(?width?);
????m_Height?=?GLdouble(?height?);
????m_AspectRatio?=?m_Width?/?m_Height;
????//?開啟紋理貼圖以及其它內(nèi)容
????glEnable(?GL_TEXTURE_2D?);
????glEnable(?GL_DEPTH_TEST?);??????//?使用深度測試
????glFrontFace(?GL_CW?);???????????//?順時針的繪制為正面
????glEnable(?GL_CULL_FACE?);???????//?剔除不是正面的面
????glEnable(?GL_BLEND?);???????????//?開啟Alpha混合
????glBlendFunc(?GL_SRC_ALPHA?GL_ONE_MINUS_SRC_ALPHA?);
????AdditionalSetup(?);
????//?初始化Logo
????m_Logo.SetPath(?“../Resource/Luo_Tianyi.tga“?“../Resource/ExitHint.tga“?);
????m_Logo.Init(?m_Width?m_Height?);
????//?其余的初始化代碼
????glClearColor(?0?/?255.0?0?/?255.0?0?/?255.0?1.0?);
????glColor3ub(?255?255?255?);
????memset(?m_title?0?64?);//?標題全都清零
}
//-----------------------------------------------------------------------------
void?GLWidget::Render(?void?)
{
????glDisable(?GL_BLEND?);//?三維紋理貼圖若打開Alpha混合則不顯示,所以關閉
????View3D::Render(?);
????//?繪制Logo
????glEnable(?GL_BLEND?);//?開啟Alpha混合
????glMatrixMode(?GL_PROJECTION?);
????m_Logo.SetProjectionMatrix(?);
????m_Logo.Draw(?);
????if?(?m_Display2DView?)?View2D::Render(?);
????SetProjectionMatrix(?);
????++m_FPSCount;
}
//-----------------------------------------------------------------------------
void?GLWidget::R
評論
共有 條評論