yag Site Admin
註冊時間: 2007-05-02 文章: 689
2704.11 果凍幣
|
發表於: 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); |
給註解掉,為什麼看得到材質卻看不到框線了?
不是都已經使用了自行計算過打光的材質了嗎?
以上三個問題,還請知道的大大幫忙解惑一下,謝謝 |
|