電腦遊戲製作開發設計論壇 首頁 電腦遊戲製作開發設計論壇
任何可以在PC上跑的遊戲都可以討論,主要以遊戲之製作開發為主軸,希望讓台灣的遊戲人有個討論、交流、教學、經驗傳承的園地
 
 常見問題常見問題   搜尋搜尋   會員列表會員列表   會員群組會員群組   會員註冊會員註冊 
 個人資料個人資料   登入檢查您的私人訊息登入檢查您的私人訊息   登入登入 

Google
3D遊戲程式設計入門第13章心得-2[未解之疑問篇]

 
發表新主題   回覆主題    電腦遊戲製作開發設計論壇 首頁 -> 遊戲程式高級班:DirectX、OpenGL及各種圖型函式庫
上一篇主題 :: 下一篇主題  
發表人 內容
yag
Site Admin


註冊時間: 2007-05-02
文章: 684

2639.56 果凍幣

發表發表於: 2010-2-24, AM 12:38 星期三    文章主題: 3D遊戲程式設計入門第13章心得-2[未解之疑問篇] 引言回覆

前言:此乃補丁文。只講解心得,不提供完整教學,有興趣的人請自行購買此書。
代碼:
書名:3D遊戲程式設計入門-使用DirectX 9.0實作
作者:Frank D. Luna
譯者:黃聖峰
出版社:博碩文化

照著第13章心得-1修改完程式後,範例跑起來基本上沒什麼問題了
但是我再進一步將範例修改後,卻發現了一些奇怪的現象
研究了好一陣子,依然不明白,所以就先擱著了
在此我將此現象描述出來,希望有明白其原理的大大能幫忙解答一下

首先請照著以下方式修改 ---
terrain.h
class Terrain上面加上
代碼:
enum
{
   EM_DRAW_TEXTURE      = 0x1,
   EM_DRAW_WIREFRAME   = 0x2,
};


代碼:
bool  draw(D3DXMATRIX* world, bool drawTris);

改成
代碼:
bool  draw(D3DXMATRIX* world, BYTE byFlag);


terrain.cpp
在const DWORD Terrain::TerrainVertex::FVF = D3DFVF_XYZ | D3DFVF_TEX1;上面加上
代碼:
#define DF_TEXED_WIREFRAME


代碼:
bool Terrain::draw(D3DXMATRIX* world, bool drawTris)

改成
代碼:
bool Terrain::draw(D3DXMATRIX* world, BYTE byFlag)


在bool Terrain::draw(D3DXMATRIX* world, BYTE byFlag)函式中,將
代碼:
      _device->SetTexture(0, _tex);

      // turn off lighting since we're lighting it ourselves
      _device->SetRenderState(D3DRS_LIGHTING, false);

      hr =_device->DrawIndexedPrimitive(
         D3DPT_TRIANGLELIST,
         0,
         0,
         _numVertices,
         0,
         _numTriangles);

      _device->SetRenderState(D3DRS_LIGHTING, true);

      if( drawTris )
      {
         _device->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME);
         hr =_device->DrawIndexedPrimitive(
            D3DPT_TRIANGLELIST,
            0,
            0,
            _numVertices,
            0,
            _numTriangles);

         _device->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
      }

改成
代碼:
      if( byFlag & EM_DRAW_TEXTURE )
      {
         _device->SetTexture(0, _tex);

         // turn off lighting since we're lighting it ourselves
         _device->SetRenderState(D3DRS_LIGHTING, false);

         hr =_device->DrawIndexedPrimitive(
            D3DPT_TRIANGLELIST,
            0,
            0,
            _numVertices,
            0,
            _numTriangles);

         _device->SetRenderState(D3DRS_LIGHTING, true);
      }      

      if( byFlag & EM_DRAW_WIREFRAME )
      {

#ifndef DF_TEXED_WIREFRAME
         _device->SetTexture( 0, 0 );
#endif

         _device->SetMaterial( &d3d::WHITE_MTRL );

         _device->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME);
         hr =_device->DrawIndexedPrimitive(
            D3DPT_TRIANGLELIST,
            0,
            0,
            _numVertices,
            0,
            _numTriangles);

         _device->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
      }


terrainDriver.cpp
在#include "fps.h"下面加上
代碼:
#define DF_FREE_TO_FLY_UP_OR_DOWN



代碼:
Terrain* TheTerrain = 0;
Camera   TheCamera(Camera::LANDOBJECT);

改成
代碼:
Terrain* TheTerrain = 0;
#ifdef DF_FREE_TO_FLY_UP_OR_DOWN
Camera   TheCamera(Camera::AIRCRAFT);
#else
Camera   TheCamera(Camera::LANDOBJECT);
#endif

BYTE g_byFlag = EM_DRAW_TEXTURE;


在bool Setup()函式中,Device->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);這行的下面加上
代碼:
//
// Set Lights.
//

D3DXVECTOR3 dir(0.0f, -1.0f, 0.0f);
D3DXCOLOR col(1.0f, 1.0f, 1.0f, 1.0f);
D3DLIGHT9 light = d3d::InitDirectionalLight(&dir, &col);

Device->SetLight(0, &light);
Device->LightEnable(0, true);
Device->SetRenderState(D3DRS_NORMALIZENORMALS, true);
Device->SetRenderState(D3DRS_SPECULARENABLE, true);


在bool Display(float timeDelta)函式中,將
代碼:
      D3DXVECTOR3 pos;
      TheCamera.getPosition(&pos);
      float height = TheTerrain->getHeight( pos.x, pos.z );
      pos.y = height + 5.0f; // add height because we're standing up
      TheCamera.setPosition(&pos);

改成
代碼:
#ifdef DF_FREE_TO_FLY_UP_OR_DOWN
      if( ::GetAsyncKeyState('R') & 0x8000f )
         TheCamera.fly(100.0f * timeDelta);

      if( ::GetAsyncKeyState('F') & 0x8000f )
         TheCamera.fly(-100.0f * timeDelta);
#else
      D3DXVECTOR3 pos;
      TheCamera.getPosition(&pos);
      float height = TheTerrain->getHeight( pos.x, pos.z );
      pos.y = height + 5.0f; // add height because we're standing up
      TheCamera.setPosition(&pos);
#endif


代碼:
TheTerrain->draw(&I, false);

改成
代碼:
TheTerrain->draw(&I, g_byFlag);


在LRESULT CALLBACK d3d::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)函式中,將
代碼:
if( wParam == VK_ESCAPE )
   ::DestroyWindow(hwnd);
break;

改成
代碼:
if( wParam == VK_ESCAPE )
   ::DestroyWindow(hwnd);

if( wParam == VK_SPACE )
{
   g_byFlag++;

   if( g_byFlag > ( EM_DRAW_TEXTURE | EM_DRAW_WIREFRAME ) )
      g_byFlag = EM_DRAW_TEXTURE;
}

break;


以上修改完成後,執行範例
現在我們可以自由地調整camera的高度,按R、F即可沿著up軸移動
按space的話,則可在 材質、框線(含有材質的顏色)、材質+框線 三種狀況中切換
現在問題來了 ---
一、為什麼純框線時會帶有材質的顏色?
雖然只要把terrain.cpp開頭新增的#define DF_TEXED_WIREFRAME給註解掉,它就會變成Mtrl的顏色
但是前面第11章的範例中也曾經畫過未用
代碼:
_device->SetTexture( 0, 0 );

解除材質的框線
當時的黃色框線中似乎並沒有夾雜到材質的顏色,為什麼?

二、為什麼新增設定的打光,不管是
代碼:
D3DXVECTOR3 dir(0.0f, 1.0f, 0.0f);

或者是
代碼:
D3DXVECTOR3 dir(0.0f, -1.0f, 0.0f);

都可以看得到?平行光沒有前後之分嗎?

三、使用"框線(含有材質的顏色)"時,如果把
代碼:
Device->LightEnable(0, true);

給註解掉,為什麼看得到材質卻看不到框線了?
不是都已經使用了自行計算過打光的材質了嗎?

以上三個問題,還請知道的大大幫忙解惑一下,謝謝
回頂端
檢視會員個人資料 發送私人訊息 發送電子郵件
從之前的文章開始顯示:   
發表新主題   回覆主題    電腦遊戲製作開發設計論壇 首頁 -> 遊戲程式高級班:DirectX、OpenGL及各種圖型函式庫 所有的時間均為 台灣時間 (GMT + 8 小時)
1頁(共1頁)

 
前往:  
無法 在這個版面發表文章
無法 在這個版面回覆文章
無法 在這個版面編輯文章
無法 在這個版面刪除文章
無法 在這個版面進行投票
可以 在這個版面附加檔案
可以 在這個版面下載檔案


Powered by phpBB © 2001, 2005 phpBB Group
正體中文語系由 phpbb-tw 維護製作