青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

2010年7月9日

MMORPG游戲服務器框架的可行性報告 (提高生產效率)

縱觀游戲服務器技術框架,  以運行在Linux操作系統上的居多, 為什么要運行在Linux上呢? 相信很多人會給出肯定的答案, Linux操作系統是開源的,而且是免費的,那叫做專業!是的,不錯,是專業。但有一個問題讓我們值得思考的是,雖然是免費的,但Linux工具比較貧乏,在某種程度上大大加在了開發成本及后期調試時間,所以我們不得不研究出一種代碼可以運行在Linux,但又要節省開發成本,提高生產效率的可行性方案。

在Linux上,古老的Linux C程序員一般會采用一個文本編輯工具,比如:VI等,由于我以前是在windows下生活的,對VS.net這一類的工具頗為喜愛,它的開發方便快捷,又有開發輔助插件的支持,使你可以盡情使用智能提示,快捷鍵,代碼模板等高效生產代碼。可以說編碼更多的是依靠可視化工具查錯,快速跳轉代碼等。反正我的意思就是開發相當愉悅。但Linux下的C程序員則不然,我也曾經問過他們為什么要采用VI等編輯工具來編代碼,首先,他們給到我的第一答案是"專業", 其實我也不太懂他們說的專業是什么,是傳統意義上的,還是習慣性必須的;然后他們說:“使用makefile文件來編譯代碼很爽,速度很快”,這一點我是贊同的,但有個問題是程序員的入門門檻比較高,要求大家都要會這東西,還是麻煩,從HR招聘處可以看到,本來投C++程序員的人就比較少了,因為C++應用的領域基礎是應用軟件,游戲啊,電信啊,還是一些MFC界面性的東西,而且要求功底比較好,確實有時候招人還是挺難的,更不用說還要有Linux開發經驗的人了。最后,我問了linux開發不員說那你們的調試用什么工具,他們說:“gdb”, 又是一個"手打牛肉丸",自我感覺很痛苦,心里想“為什么有那么先進的工具,比方說:Eclipse CDT, 你們不用呢?”,其實他們心中也是有答案的,“編碼要養成一種好習慣,而不是依靠于某種工具”,顯然Linux程序員在編碼上大體要比windows上的程序員來得嚴格,也感覺到他們的代碼比較有質量。但很顯然的,由于開發環境的布署比較麻煩,對于大規模生產是否能夠每個人都有那么高素質的編程能力,那就是個"謎"!------ “猜不準!”

針對上面的情況,我也自己分析了一下,軟件開發的三大要素是什么,成本,質量,進度, 只有這三項東西控制得好,那才能控制好項目。
那軟件編程的基礎是什么? 當然是調用操作系統的API了,很顯然的, 不同操作系統有不同的API,除非你有一個跨平臺的開發框架,或者叫類庫也行。
接下來軟件架構在不同領域是否通用?比方說:通信框架,很顯然的,還是有區別的,比方說電信系統與游戲系統,那顯然還是不一樣的。
最后,軟件編碼與接口(API)是不是應該更多人常用的,而且容易上手的(友好第一!),這樣才可以減少開發成本及協調工作。

總結一下,我心中已有答案了,必須采用一種大多數程序員可以接受的,而且是他們熟悉的(不要DIY的),而且開發速度快速的開發方式那才是真道理。
以下是我的基本方案:
 

一、   跨平臺框架的基礎設施 (組件圖)

1.    MySQL數據庫操作組件

2.    線程池 讀寫鎖

3.    基礎數據類型,容器,內存池,環形緩沖區

4.    IOCPEpoll跨平臺的面向對象通信框架

5.    集成LuaTinker腳本交互模塊等

 

二、   開發方式與調試環境

本框架的初步設想是前期在Windows下使用VS.net 2008進行開發調試,爭取在Windows下解決80%左右的邏輯錯誤。之后由主程序員把代碼移植到Linux,并使用Eclipse CDT可視化開發環境進行后期的調試工作。這樣也大大降低招聘人員的知識要求(不用懂Linux),在某一程度降低了人員成本和加快了開發效率。


posted @ 2010-07-09 02:45 RedLight 閱讀(1627) | 評論 (2)編輯 收藏

MMORPG服務器組集群方案






 

1.     LoginApp

即登錄服務器, 它主要完成玩家帳號的驗證, 同時它通過BaseAppMgr并向玩家發送一個SessionKey作為基礎服務器(BaseApp)的登錄密鑰;同時LoginServer還向玩家發送服務器列表信息。

2. BaseApp

     即基礎服務器, 也稱連接服務器,它還維持著一個客戶端連接列表(用戶列表), 這樣它可以實現區域消息廣播及通過BaseAppMgr實現世界聊天, 玩家信息查看等功能;它還負責消息的分發到CellApp進行處理,并把結果返回到客戶端。

3. CellApp

即游戲服務器,它負責世界數據的加載,游戲邏輯的處理及世界對象的管理。在本架構中當為支線服務器。

4. DBMgr

用戶服務器,它負責用戶相關數據的存取。一般是用戶登錄選擇角色后就獲得角色所有相關數據給到MapServer, 并由MapServer定時保存角色的相關數據。

5. BaseAppMgr

            基礎服務器管理器,主要負責分配基礎服務器給到客戶端連接,同時它采用某種策略可以實現用戶的均衡負載等。

6. CellAppMgr

            支線服務器管理器, 它主要根據支線ID為基礎代理對象分配支線服務器實體, 這樣就可以實現與客戶端的通信了。

7. DB

     數據庫服務器主要分為三個庫來存取,AccountDB為玩家賬戶信息,CharacterDB為玩家角色相關信息,WorldDB為所胡的世界數據。

posted @ 2010-07-09 02:05 RedLight 閱讀(2244) | 評論 (2)編輯 收藏

2009年12月15日

編程常用快捷鍵

1. 調試快捷鍵
2. 編輯快捷鍵
3. 代碼快捷鍵
4. 窗口快捷鍵


Ctrl+Tab 切換編輯主窗口中的代碼選項頁

Esc鍵關閉當前的非模式窗口 (比方說 查找窗口, 切誤用 Alt + F4, 這樣會連VS.net2005都關掉)

F5: 啟動調試
Ctrl+F5: 開始執行(不調試)

Shift+F5: 停止調試
Ctrl+Shift+F5: 重啟調試

F7: 生成解決方案
Ctrl+U: 生成當前項目

F11: 獨句調試
F10: 過程調試

F9: 打斷點 或 取消斷點
Alt+F9: 顯示斷點窗口

F12: 定位到函數的實現體
???: 定位到函數的聲明, 只能用右鍵--->選擇A

Shift+Alt+Enter: 切換全屏編輯

Ctrl+F: 查找
Ctrl+Shift+F: 在文件中查找

F3: 查找下一個
Shift+F3: 查找上一個

Ctrl+H: 替換
Ctrl+Shift+H: 在文件中替換

Ctrl+左右箭頭鍵: 一次可以移動一個單詞
Ctrl+上下箭頭鍵: 滾動代碼屏幕,但不移動光標位置。

Ctrl+L: 刪除當前行


Ctrl+M,M: 隱藏或展開當前嵌套的折疊狀態
Ctrl+M,L: 將所有過程設置為相同的隱藏或展開狀態 或者 右鍵 + L + O
Ctrl+M,P: 停止大綱顯示 或者再按一次Ctrl+M,L  或者 右鍵 + L + O

Ctrl+G: 轉到指定行
Shift+Alt+箭頭鍵: 選擇矩形文本
Alt+鼠標左按鈕: 選擇矩形文本
Ctrl+Shift+U: 全部變為大寫
Ctrl+U: 全部變為小寫

//有點難度的:
Ctrl+K, Ctrl+C: 注釋   
Ctrl+K, Ctrl+U: 解除注釋

Ctrl+Shift+A: 添加新項
//----------------------------------------
VAssistX: 操作
1. 定義標準的代碼段, 并設置快捷鍵
2. Alt+M, 再打上函數名的前幾個字母, 就會過濾掉很多函數, 最后按Enter定位到當前文件所查找的函數體
3. Shift+Alt+O, 查找文件, 輸入文件名的前幾個字母, 就會過濾掉很多文件, 最后按Enter定位到當前文件所查找的文件
4. Alt+O: 切換到.h和.cpp文件
5. 右鍵+查看所有引用 或 VassistX菜單中的Find References, Find References in Files : 查看函數引用的所有地方
6. Shift+Alt+S: 查找全局變量
//----------------------------------------
F7: 查看代碼
Shift+F7: 查看窗體設計器

Windows鍵+E 打開資源管理器。
Windows鍵+D 顯示桌面。
Windows鍵+M 最小化所有被打開的窗口。
Alt+Tab  切換任務欄中的激活窗口


 

posted @ 2009-12-15 06:12 RedLight 閱讀(728) | 評論 (0)編輯 收藏

2009年12月11日

WOW地形Shader分析(轉)

SPXG // 標識
// 用到5張圖片:
{
   blendTexture  = 0
   layer0Texture = 1
   layer1Texture = 2
   layer2Texture = 3
   layer3Texture = 4
}
!!ARBfp1.0
// 定義常量:
PARAM c[1] = { { 1, 0.30000001, 0.69999999 } };
// 聲明3個寄存器:
TEMP R0;
TEMP R1;
TEMP R2;
// 開始混合:
// 一.第0層和第1層使用第4張圖的x通道作為alpha進行混合:
TEX R1, fragment.texcoord[0], texture[0], 2D;
TEX R0, fragment.texcoord[1], texture[1], 2D;
ADD R2, R0, -R1;
// r2=Tex1-Tex0
TEX R0, fragment.texcoord[4], texture[4], 2D;
MAD R2, R0.x, R2, R1;
// r2 = Tex4.x*r2+Tex0
// 說明:
// 其中的Tex4.x是對應第1層alpha值, 下面把Tex4.x當a1看
// 即 r2 = a1 * (Tex1-Tex0) + Tex0
// 轉換一下即是: Tex0*(1-a1)+a1*Tex1, 呵呵,看到了吧,這就是混合公式!
// 二.第2層和前面結果使用第4張圖的y通道作為alpha進行混合:
TEX R1, fragment.texcoord[2], texture[2], 2D;
ADD R1, R1, -R2;
// r1=Tex2-r2
MAD R2, R0.y, R1, R2;
// r2 = Tex4.y*r1+r2, 即 a2*r1+r2 = a2*(Tex2-r2)+r2, 即r2*(1-a2)+Tex2*a2, 其中r2即是上次0和1層混合后的結果
// 三.第3層和前面結果使用第4張圖的z通道作為alpha進行混合:
TEX R1, fragment.texcoord[3], texture[3], 2D;
ADD R1, R1, -R2;
// r1=Tex3-r2
MAD R1, R0.z, R1, R2;
// r1=a3*r1+r2 , 即 a3*r1+r2 = a3*(Tex3-r2)+r2, 即r2*(1-a3)+Tex3*a3
// 這樣r1就保存了最終的混合結果
// 四.讓陰影地表光澤系數為0(Tex4.w即a通道代表地形的陰影,0為陰影,1為正常.而每層貼圖中的a通道是光澤通道,所以R1.w保存的是最終的光澤通道值):
MUL R0.x, R1.w, R0.w;
// r0.x = r1.w(光澤)*Tex4.w(陰影值, 是陰影則=0,否則=1)
// 計算削減系數?
MAD R0.w, R0, c[0].y, c[0].z; // r0乘上0.3(削減了30%)再加上一個常量0.69999999
// 反射高光 = secondary_color(反射光)*光澤:
MUL R0.xyz, R0.x, fragment.color.secondary;
// 貼圖最終color = 最終貼圖混出的color*削減系數:
MUL R1.xyz, R1, R0.w;
// 貼圖最終color * primary_color(光照色或是頂點色) + 反射高光:
MAD result.color.xyz, R1, fragment.color.primary, R0;
// alpha:
MOV result.color.w, c[0].x;
END
  
  

本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/flipcode/archive/2008/03/03/2143452.aspx

posted @ 2009-12-11 02:04 RedLight 閱讀(858) | 評論 (0)編輯 收藏

2009年12月5日

RedLight引擎原型初成

一直都沒勇氣去寫一個游戲引擎,也許是太懶了,也許是太大了。雖然寫了些零零碎碎的Test Case! 但你知道的,這始終不成氣候!
最近我被安排到一個小組中,做的項目是一個體感游戲,之前考慮過用ogre開源引擎來做,可惜我對這東西又不熟的,聽人家說還要用第三方類庫CEGUI, 還要配置一些東西,一聽頭都大了,光學習理想都用半個月了,我們的工程只給兩個月的時間,唉呀!算了吧,自己不是還有些亂七八糟的代碼可用嗎?狠下決心,決定干它一把!哪怕辛苦一點,做下來一個游戲引擎以后就容易干事了。
經過和另外一個同事兩個月的時間奮斗,一路中雖說遇到些困難,也常加班的,項目終于也做完了。





一個游戲引擎原型基本蛋生了,我們命名它為 RedLight,它基本實現了

(0) Win32程序渲染框架
(1) UI的基本消息交互流程,XML窗體配置管理,UI皮膚配置管理,基本的UI控件庫,多分辯率無縫UI拼圖
(2) 室外場景管理
(3) 攝相機路徑攝像
(4) 3D Max8模型及骨骼動畫導出插件
(5) 模型渲染, 關鍵幀動畫及骨骼動畫控制
(6) 基本的水面反射效果
(7) 簡單的面粒子系統
(8) 聲音控制接口

這是一個單機游戲引擎的原型,功能有限,但它總算不辱使命完成了一個項目了,以后再擴展使它日益強大吧!

posted @ 2009-12-05 09:36 RedLight 閱讀(783) | 評論 (0)編輯 收藏

超級工具-----NVPerfHUD分析Beijing 2008

     摘要:   閱讀全文

posted @ 2009-12-05 09:06 RedLight 閱讀(1276) | 評論 (0)編輯 收藏

2009年12月1日

WOW字體研究報告

我喜歡玩WOW的UI風格,尤其是它的高清字體-------任務窗口的內容總感覺十分舒暢。這是從魔獸世界中任務窗口的游戲截圖
                                      

經研究, 其實,上面的字體是用方正楷體(不是windows楷體)字體來做的, 用Freetype類庫得到每個字符的對應圖,并組裝排版到一張預先創建好的空紋理中(256*256),  組成一張灰度圖,這樣可以防止重復字符貼圖兩遍,提高效率,就像活字印刷術一樣靈活組合。
渲染的時候,采用字體顏色RGB + 灰度圖合成最終效果。

也許你會發現,左圖為什么這么清晰,右圖好像稍差一點。對了,其實人的眼睛很奇怪,對顏色的識別是通過對比的,wow正是利用這一點,背景色采用以黃色為主色調,夾雜一些噪聲,然后再渲上黑色的文字,這樣可以給人感覺到很清晰。

其實wow中還是其他一些文字效果,比方說:陰影文字,原理是渲染兩次同一字符,并在第二次遍渲染作偏移即可。當然,還有那種字體外邊包起來的效果,不過這種我還沒研究它的算法。

怎么說呢?一個游戲世界中,字體我覺得相當重要,豐富的字體表現會給人相當美滿的效果,帶給人美好的印象,所以還是相當重要的。我也在做我的文字配置系統,祝福我早日完成吧! 謝謝!

posted @ 2009-12-01 09:13 RedLight 閱讀(966) | 評論 (1)編輯 收藏

2009年11月14日

BigWorld引擎初識大觀

     摘要:   閱讀全文

posted @ 2009-11-14 05:16 RedLight 閱讀(2250) | 評論 (2)編輯 收藏

D3D與OpenGL常用API對譯

作為一個3D程序員, 我用了OpenGL兩年多, 最近在搞一個項目, 從OpenGL轉到D3D, 雖然工程外在的框架都封裝得不錯, 但想完全地從OpenGL轉換到D3D, 看起來還是有難度的, 花了我兩個星期的時間, 我終于轉換過來了。
D3D與OpenGL的幾點比較明顯不同的地方:
(一)、正交投影時:OpenGL以屏幕左上角為(0,0), 而D3D卻以屏幕中心為(0,0)
(二)、OpenGL使用右手坐標系, 而D3D使用左手坐標系
(三)、OpenGL使用旋轉操作等轉入的角度參數是 角度, 而D3D是 弧度,所以注意要PI * Angle / 180

下面我把具體地API對照關系列出來(不是很全,以后添加中.......)


1. 坐標變換
 pos = D3DXVECTOR3(0,2,-1.5);
 at  = D3DXVECTOR3(0,0,0);
 up  = D3DXVECTOR3(0,1,0);
 D3DXMatrixLookAtLH(&view,&pos,&at,&up);
 pd3dDevice->SetTransform(D3DTS_VIEW,&view);

2. 繪制
 pd3dDevice->SetRenderState(D3DRS_FILLMODE,D3DFILL_WIREFRAME);

    DrawPrimitive()
 DrawIndexedPrimitive()
 
 DrawPrimitiveUP()
 DrawIndexedPrimitiveUP()
3. 顏色


4. 片段測試

 (1) 深度測試
 g_pDevice->SetRenderState(D3DRS_ZENABLE, TRUE);           //glEnable(GL_DEPTH_TEST);  
 g_pDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESSEQUAL);    //glDepthFunc(GL_LEQUAL);
 //--------------------------------------------------------------------------------------------------------
 g_pDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);      //glEnable(GL_CULL_FACE);

 
 (2) Alpha測試
 //-------------------------------------------------------------------------------------------------------- 
 g_pDevice->SetRenderState(D3DRS_ALPHATESTENABLE, TRUE);                //glEnable(GL_ALPHA_TEST);
 g_pDevice->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATER);    //glAlphaFunc(GL_GREATER, 0.1f);
 g_pDevice->SetRenderState(D3DRS_ALPHAREF, 0.1 * 255); //取值范圍 0 ~ 255
 
 (3) 剪裁測試 (平面剪切)
 //--------------------------------------------------------------------------------------------------------
 // Enable clip plane for reflection map
 CMatrix44f pWorldViewProjIT=m_pWorldViewProj;
 //pWorldViewProjIT.Transpose();
 pWorldViewProjIT.Invert();   

 // Transform plane to clip-space
 float pClipSpacePlane[4];
 float pClipPlane[]= { 0, 0, 1, 0};   

 // Check if camera is below water surface, if so invert clip plane
 CVector3f pEye=(CVector3f)m_pCamera.GetPosition();
 if(-pEye.m_fZ<0.0)
 {
  pClipPlane[2]=-pClipPlane[2];
 }

 MatrixTransformPlane(pClipSpacePlane, pClipPlane, pWorldViewProjIT);

 // enable clip plane now
 g_pDevice->SetClipPlane(0, pClipSpacePlane);  
 g_pDevice->SetRenderState(D3DRS_CLIPPLANEENABLE, 1);
 
 
 
 (4) 模板測試
 //--------------------------------------------------------------------------------------------------------
 g_pDevice->SetRenderState(D3DRS_STENCILENABLE, TRUE);
    g_pDevice->SetRenderState(D3DRS_STENCILFUNC, 3DCMP_ALWAYS);
    g_pDevice->SetRenderState(D3DRS_STENCILREF, 0x1); //取值范圍 0 ~ 255
   
    Device->SetRenderState(D3DRS_STENCILPASS,  D3DSTENCILOP_KEEP);
 
5. 紋理操作
 
 g_pDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
   g_pDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
   g_pDevice->SetSamplerState( 0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);
   
 g_pDevice->SetSamplerState( 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
  g_pDevice->SetSamplerState( 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);

6. 緩沖區操作
  
 (1) 顏色緩沖
 //--------------------------------------------------------------------------------------------------------
 g_pDevice->SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_ALPHA);
 g_pDevice->SetRenderState(D3DRS_COLORWRITEENABLE, 0x000000F);
 
 (2) 深度緩沖
 //--------------------------------------------------------------------------------------------------------
 g_pDevice->SetRenderState(D3DRS_ZENABLE, TRUE);           //glEnable(GL_DEPTH_TEST);
 g_pDevice->SetRenderState(D3DRS_ZWRITEENABLE, TRUE);        //glDepthMask(GL_TRUE);

 (3) 模板緩沖
 //--------------------------------------------------------------------------------------------------------
 
 (4) 渲染到紋理
 //--------------------------------------------------------------------------------------------------------
 // Render targets
 IDirect3DSurface9 *m_plD3DBackbufferSurf,
  *m_plD3DDepthStencilSurfAA,
  *m_plD3DDepthStencilSurf;

 CRenderTarget *m_pRTRefraction, *m_pRTReflection; //(自定義紋理類)

 //-----------------------------------------------------------------------------------

 // Get backbuffer
 g_pDevice->GetRenderTarget(0, &m_plD3DBackbufferSurf);
 
 // Get depthstencil
 g_pDevice->GetDepthStencilSurface(&m_plD3DDepthStencilSurfAA);
 

 // Restore previous states
 g_pDevice->SetRenderTarget(0, m_plD3DBackbufferSurf);
 g_pDevice->SetDepthStencilSurface(m_plD3DDepthStencilSurfAA);
 
 // (1)折射圖--------------------------------------------------------------------------
 
 //下面的語句調用了 g_pDevice->CreateRenderTarget(iWidth, iHeight, (D3DFORMAT) iFormat, (D3DMULTISAMPLE_TYPE)iAASamples, 0, 0, &m_plD3Surf, 0));
 if(FAILED(m_pRTRefraction->Create(m_fWidth>>1, m_fHeight>>1, D3DFMT_A8R8G8B8)))
 {
  return APP_ERR_INITFAIL;
 }
 
 // Create depthstencil withouth multisampling
 g_pDevice->CreateDepthStencilSurface(m_fWidth, m_fHeight, D3DFMT_D24X8, (D3DMULTISAMPLE_TYPE)0, 0, 0, &m_plD3DDepthStencilSurf, 0);
 
 
 g_pDevice->SetRenderTarget(0, m_pRTReflection->GetSurface());
 
 g_pDevice->StretchRect(m_plD3DBackbufferSurf, 0, m_pRTRefraction->GetSurface(), 0, D3DTEXF_NONE);
 
 // (2)反射圖-----------------------------------------------------------------------------------
 m_pRTReflection=new CRenderTarget;
 if(FAILED(m_pRTReflection->Create(m_fWidth>>2, m_fHeight>>2, D3DFMT_A8R8G8B8)))
 {
  return APP_ERR_INITFAIL;
 }
 
 g_pDevice->SetRenderTarget(0, m_pRTReflection->GetSurface());
 
 
 //-----------------------------------------------------------------------------------
 g_pDevice->SetRenderTarget(0, m_pRTReflection->GetSurface());
 g_pDevice->SetDepthStencilSurface(m_plD3DDepthStencilSurf);
 g_pDevice->Clear(0, 0, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, D3DCOLOR_ARGB(255, 0, 0, 128), 1.0f, 0);  
 SetViewport(m_pRTReflection->GetWidth(), m_pRTReflection->GetHeight());
 //-----------------------------------------------------------------------------------
 
 D3DXSaveTextureToFile("imageTex.jpg",D3DXIFF_JPG,(IDirect3DTexture9*)m_pWavesBump->GetTexture(),NULL);
 
7. 混合操作
 g_pDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);    //glDisable(GL_BLEND);
 g_pDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);  //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
 g_pDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
 

8. 燈光與材質
 g_pDevice->SetRenderState(D3DRS_LIGHTING, FALSE); //glDisable(GL_LIGHTING);
 
 D3DMATERIAL9 mtrl;
 mtrl.Ambient  = a;
 mtrl.Diffuse  = d;
 mtrl.Specular = s;
 mtrl.Emissive = e;
 mtrl.Power    = p;
 Device->SetMaterial(&mtrl);  //在設置紋理前設定
 //設置當前使用的紋理
 

posted @ 2009-11-14 04:49 RedLight 閱讀(1696) | 評論 (0)編輯 收藏

2009年9月25日

wmo(wow map object) research

wmo(wow map object) research
The wmo是一個非常有趣的設計,wow中比較小的物體使用doodad,而building使用wmo,
這里的building可以是橋梁、了望臺、簡單的小房子、復雜點的旅館這樣的房屋、非常
復雜的建筑群(例如地下城場景),本文對wmo場景文件進行簡單的介紹,關于wmo文件的具
體信息請參考wowmapview的source code,這里非常感謝ufoz所做的貢獻。
1、命名規則
wmo保存在以.wmo結尾的文件中,這個文件使用數據塊來保存數據。一個wmo通常由一個或多個
group組成,而group數據也保存在以.wmo結尾的文件中,不過文件名稱存在不同,例如一個wmo
保存在name.wmo文件中,那么group文件名就為name_001.wmo name_002.wmo......
2、結構
wmo就組織結構來說包含兩個層次,group和batch。一個group通常包含多個batch,其中group包含
一個AABB。batch是wmo最小的渲染單元,它保存了頂點索引列表,可以直接調用DP進行渲染。group
內保存一個標志位,可以將group分為indoor/outdoor兩類,這一個信息非常重要,通過它wmo就將
building分成了內外兩部分,outdoor group就是building的外殼,他通過portal與室內場景連接
在一起。
3、portal
wmo文件中保存了portal信息,在wmo中規定group必須通過portal進行連接,portal由PVS和PRS
兩部分組成,PVS記錄portal頂點信息,PRS記錄portal和group的連接信息,PRS結構如下:
struct WMOPR {
int portal;
int group;
int dir;
};
需要注意的是dir,這個成員只有兩個值-1或1,由于portal的頂點信息按照順時針記錄,因此group
位于portal的正面時dir為1,否則為-1,通過dir可以快速確定group到底位于portal的哪一側。
通過wmo中記錄的portal信息可以使用portal culling來檢查group的可見性,但是這里還是有一些
難度,主要是指portal的記錄方式。由于一個group可能有多個portal,而查找連接的portal只能
通過PRS,這樣在大的場景中非常不方便。而且在wmo中竟然沒有記錄portal的plane信息,如何確定
camera到底是位于portal的正面還是反面呢?(現在wmo文件由于沒有完全破解,存在一些wowmapview
未讀入的數據塊,例如MVER、MOPT、MOVV、MOVB等,其中MVER應該是wmo文件的版本號,MOPT懷疑是保
存所有plane信息,而MOVV可能是保存包圍體頂點信息,而MOVB保存包圍體信息,MOVV、MOVB應當用于
碰撞檢測,這些暫時沒有驗證)我的做法是在載入時計算portal的plane信息,并將PRS信息轉換為類似
Q3 BSP中portal的結構。
struct portal_t {
int othergroup;
int pvs;//pvs index
int dir;
};
struct group_t {
int firstportal;
int numportals;
};
4、碰撞檢測
在wmo中并沒有使用BSP、OC TREE這樣的結構來進行場景管理,可能所有人都感覺非常困惑。
場景管理的功能主要是為了加速渲染和方便碰撞檢測,由于存在portal,這樣第一個功能已經完成。
而對于碰撞檢測,我的想法應當是AABB TREE。仔細觀察WOW的場景可以發現在indoor場景中曲面、斜面
這樣的幾何物體非常少,大多數是規則物體,因此可以判斷在wmo中所有的物體都是嚴格按照軸對齊
方式進行建模,也就是對規則性物體AABB=OBB。由于MOVV和MOVB信息并沒有完全研究透徹,因此關于
這一部分只能是我的猜測。
5、渲染
對wmo的渲染由于batch的存在從而變的簡單化,但還有可以優化的地方。由于wmo中使用portal將其分割
成group,因此有大量的材質相同的model被分割成不同的batch,在渲染時將材質相同的batch合并到一起
渲染可以避免一些無謂的DP調用。wmo一個令人詬病的地方是使用vertex light,為了減少圖元數量從而
使頂點數量降低,造成渲染的時候出現色帶效果,應當加入lightmap,由于wmo的場景通常不大,預處理
時做radiosity的時間也不會太長。
6、動態載入
對于只包含幾個group的小場景的wmo,由于載入時間不是太長,在動態載入時一次性載入對程序影響
并不會太大。但是對于超大場景的wmo就需要考慮載入策略,這樣場景典型的就是wow中的地下城場景,
它一個wmo中包含了幾百個group,一次性載入時間非常長,需要分段進行載入。此時就顯示出wmo分
文件保存group的優勢了,為了實現動態載入wmo場景,一種可能的做法是在載入wmo后需要根據camera
所在的group快速的建立group連接層次圖,這個圖通過PRS數據建立,建立流程如下:
一、將camera所在group作為當前group,獲得所有相連的protal;
二、將protal連接的group保存到第一層列表中,遍歷第一層列表中所有的group;
三、獲得第一層列表中group的portal,檢查portal所連接的group是否保存在第一層列表中,如果沒有
    將其保存到第二層列表中;
四、重復上述過程,直到整個層次圖建立。
這個層次圖可以預先建立然后保存到文件中運行時載入,這樣wmo就是分層載入而不需要一次性載入。
(這里我考慮是否在wmo中也可以建立類似bsp的pvs數據呢?雖然pvs現在已經開始淘汰,但是如果
存在pvs就可以方便確定哪些group需要立即載入,只是不知被portal分割后的group到底是不是convex
hull,如果是的話可以建立pvs,但對建模時限制更加明顯,兩難的選擇!!!)
7、建模
由于wmo是按照group對場景進行保存,因此為了建立wmo需要設計一個強力的模型構建工具,這個工具
主要功能就是對從建模工具(3DS MAX)中建立的場景模型進行分組和處理。美工在制作模型時需要非常
小心,所有的模型要嚴格的軸對齊(軸對齊的原因是需要模型的AABB=OBB),然后將模型導入工具中。
模型構建工具有以下功能:分組(group)功能、group選擇、group顯示/隱藏、指定portal,portal對
齊(考慮門、窗戶這樣天然的portal,手動指定portal時肯定無法與外表墻壁對齊,需要程序自動對齊)
、batch操作(分割、選擇、顯示/隱藏等)、圖元級操作(triangle揀選,用于batch分割)、光照運算
(產生vertex light數據)、放置光源、放置doodad(場景中的道具,如桌子、椅子等)。可能還需要其
他一些功能,但是對比其他引擎的場景建模工具(hammer、sandbox)明顯簡單化許多。
8、優勢及不足
當前處理室內場景的主流技術依然是bsp,但是隨著硬件的發展bsp的優勢在慢慢地喪失,bsp賴以生存的
預處理PVS現在已經完全被實時的portal culling所取代,bsp優勢只剩下對圖元排序(用于透明物體的
渲染)和基于brush的快速碰撞檢測上,但是對比建模工具的復雜化和場景的限制,采用bsp的開銷確實
顯得太大。而基于純portal引擎的結構開始流行,例如cryengine中處理室內場景時就完全拋棄bsp,
場景完全由一塊塊固定大小的墻壁組成,一塊墻壁基本和bsp中brush類似,這樣做的好處是建模工具變
的簡單(不需要進行CSG運算),而且非常容易的產生portal,同時由于場景使用brush構成也兼具了
bsp方便進行碰撞檢測的優勢。wmo有些類似cryengine,但是在某些方面更具優勢。
首先在建模方面,wmo的場景完全可以通過成熟的建模工具來構建,這樣對于美工不需要重新學習新的
建模工具,可以節約大量的時間。其次模型構建工具需要的功能非常少,減少了程序的復雜性,縮短了
編寫相關工具的時間。再次,場景管理簡單化,相應代碼量大幅度減少,同時由于portal的存在,可以方便
的與其他引擎相對接。可以說wmo是一種可以進行快速開發的場景結構。

posted @ 2009-09-25 08:39 RedLight 閱讀(631) | 評論 (0)編輯 收藏

僅列出標題  下一頁
<2008年4月>
303112345
6789101112
13141516171819
20212223242526
27282930123
45678910

導航

統計

公告


Name: Galen
QQ: 88104725

常用鏈接

留言簿(3)

隨筆分類

隨筆檔案

相冊

My Friend

搜索

最新評論

閱讀排行榜

評論排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            亚洲大胆人体视频| 在线一区视频| 欧美在线综合视频| 欧美大成色www永久网站婷| 亚洲欧美在线网| 国产精品不卡在线| 99精品热视频只有精品10| 亚洲人成网站在线播| 欧美日韩一区高清| 欧美在线一二三四区| 国产精品白丝av嫩草影院| 欧美一区二区三区四区在线| 99re66热这里只有精品4| 亚洲一二三区精品| 国产午夜精品美女毛片视频| 欧美金8天国| 亚洲午夜久久久久久久久电影网| 久久久久久久久久久久久女国产乱 | 欧美一区二区成人| 亚洲欧美日韩精品久久奇米色影视| 国产精品久久福利| 久久国产66| 亚洲精品乱码久久久久久黑人| 一区二区免费在线视频| 在线精品亚洲| 欧美资源在线观看| 国产日韩精品视频一区二区三区 | 国产人成一区二区三区影院| 久久精品91久久久久久再现| 亚洲永久免费| 欧美日韩国产成人精品| 伊人久久综合97精品| 一区二区三区 在线观看视频| 国产欧美精品日韩精品| 欧美精品福利| 亚洲一区二三| 久久久一区二区三区| 老司机亚洲精品| 欧美日韩免费看| 国产精品视频久久久| 国内精品久久久久伊人av| 久久久久久夜精品精品免费| 欧美一区二区三区四区高清| 亚洲欧美视频在线观看视频| 亚洲欧美一区二区在线观看| 亚洲欧洲日本一区二区三区| 亚洲图片欧美日产| 国产专区一区| 国产精品日韩一区二区| 国产专区综合网| 欧美在线黄色| 一区二区三区日韩欧美| 欧美国产高潮xxxx1819| 午夜精品偷拍| 一本久道久久综合中文字幕| 中日韩视频在线观看| 亚洲伦理在线免费看| 欧美精品在欧美一区二区少妇| 亚洲小说春色综合另类电影| 欧美一区三区三区高中清蜜桃 | 国产精品久久久999| 久久综合99re88久久爱| 国产欧美日韩综合一区在线播放| 免费不卡中文字幕视频| 裸体丰满少妇做受久久99精品| 久久亚洲视频| 欧美日韩在线一二三| 欧美视频在线一区二区三区| 国产精品久久久久天堂| 国产区精品在线观看| 黄色免费成人| 日韩视频在线免费| 亚洲尤物在线| 午夜视频在线观看一区二区| 亚洲一二三区精品| 久久免费99精品久久久久久| 欧美激情在线观看| 亚洲视频一起| 欧美成人精品在线观看| 国产免费成人av| 校园激情久久| 国产精品99久久不卡二区| 蜜月aⅴ免费一区二区三区| 一区二区三区在线视频免费观看| 亚洲一本视频| 亚洲欧美在线观看| 欧美福利影院| 久久青青草综合| 国产精品极品美女粉嫩高清在线| 一本色道久久88精品综合| 欧美v国产在线一区二区三区| 国内精品模特av私拍在线观看| 一本一本a久久| 亚洲精品乱码久久久久久蜜桃麻豆 | 亚洲欧洲精品一区二区三区不卡 | 亚洲午夜性刺激影院| 欧美精品三级| 毛片av中文字幕一区二区| 欧美成人a视频| 午夜精品久久久久久久99热浪潮| 亚洲专区一区| 欧美一区二区三区电影在线观看| 欧美一区2区视频在线观看| 国外成人性视频| 91久久精品国产91性色| 国产欧美日韩91| 99国内精品| 一本不卡影院| av成人免费在线观看| 久久久国产一区二区三区| 午夜电影亚洲| 欧美+亚洲+精品+三区| 亚洲综合电影一区二区三区| 免费成人高清视频| 亚洲国产高清aⅴ视频| 欧美mv日韩mv国产网站| 美女爽到呻吟久久久久| 亚洲在线播放电影| 香蕉国产精品偷在线观看不卡| 在线观看欧美日韩国产| 亚洲专区在线| 老司机免费视频一区二区| 一区二区三区日韩欧美精品| 一区二区成人精品| 亚洲精品你懂的| 日韩一区二区久久| 一区二区三区国产在线观看| 韩国女主播一区二区三区| 亚洲高清久久久| 亚洲国产精品久久久久| 久久免费一区| 在线天堂一区av电影| 国产日韩精品电影| 久久激情中文| 久久综合九色综合网站 | 免费国产自线拍一欧美视频| 欧美精品在线观看一区二区| 一区二区欧美视频| 亚洲欧美日韩综合aⅴ视频| 亚洲韩日在线| 99国产精品视频免费观看一公开| 玖玖玖国产精品| 午夜在线视频一区二区区别| 美女日韩欧美| 国产日韩欧美一区二区三区在线观看 | 一区二区高清| 欧美激情一级片一区二区| 免费成人av| 一区三区视频| 久久久91精品| 欧美第一黄网免费网站| 国产真实久久| 久久亚洲精品欧美| 国产欧美日韩一区二区三区在线观看| 蜜桃伊人久久| 国产精品video| 亚洲一区二区三区涩| 9人人澡人人爽人人精品| 免费欧美高清视频| 亚洲电影免费观看高清| 激情成人av| 免费影视亚洲| 欧美福利视频一区| 亚洲第一中文字幕| 狂野欧美一区| 在线看成人片| 欧美日韩免费观看一区| 99热精品在线观看| 久久不射中文字幕| 亚洲黄色一区二区三区| 久久一区激情| 亚洲日韩视频| 性欧美激情精品| 亚洲欧洲在线免费| 国产日韩欧美精品在线| 欧美电影在线观看完整版| 日韩午夜av电影| 蜜桃av久久久亚洲精品| 一区二区欧美日韩视频| 国产亚洲精品福利| 欧美日韩一区二区三区免费| 午夜视频在线观看一区二区| 亚洲国产一区在线| 免费黄网站欧美| 亚洲手机在线| 一本色道综合亚洲| 亚洲激情社区| 亚洲高清中文字幕| 亚洲高清中文字幕| 9人人澡人人爽人人精品| 亚洲免费观看视频| 亚洲在线免费视频| 久久精品欧洲| 亚洲国产高清aⅴ视频| 亚洲国产欧美一区| 亚洲人成网站色ww在线| 亚洲免费视频在线观看| 久久精品日产第一区二区三区 | 国产一区二区欧美| 一区二区三区欧美激情|