對於剛剛編寫directx程式的朋友來說,經常遇到的乙個問題就是,風風火火寫了一大堆**,編譯-執行!哇塞,視窗裡黑乎乎一片,啥也沒有,或者是之前執行好好的程式,不只修改了**,導致以前渲染的畫面現在都沒有了。我在學習的過程中也經常遇到這種問題,索性總結下來,與大家分享。希望能給剛入門的兄弟們乙個提醒。
場景為何消失?
根據我自己的經驗,如果渲染場景中某些東西不見了,一般有以下幾個主要的原因
很簡單,在乙個伸手不見五指的黑夜裡,你能指望看見什麼呢?光照是d3d中必不可少的東西,用來計算頂點的最終顏色。但是並不是所有的頂點格式都需要光照,有些定點格式,如果設定了光照反而會導致模型無法顯示,比如lt(lit and transformed)格式。我們來看看d3d中的光照原理。
所以如果頂點是lt格式的,而且設定了光照為enable,那麼模型也是無法顯示的,因為lt格式的頂點不包含法向量,沒有法向量是無法完成光照計算的。
這個也很簡單,在乙個陽光明媚的日子,一位絕色美女站在你旁邊,可是你卻背對著她!如何欣賞到她的美呢?有了光照,有了場景,可是如果場景不在你的視野內,你依然什麼都看不見,比如模型繪製在x軸正半軸上,而視線卻指向x軸負半軸。所以,正確的設定檢視矩陣也是看見場景的重要因素。directx使用左手系,z軸指向螢幕內部的方向為正,一般來說模型都繪製在座標系的原點,而觀察點也設定為原點,眼睛的位置只要設定成z軸負半軸上的某個位置就可以了。下面就是乙個典型的設定**,也就是說,eyept的z座標一般都是負值,如果你一不小心將其設定為正值,那麼螢幕上肯定會空無一物的。
d3dxvector3 lookcenter(
0.0f
, 0.0f
, 0.0f
) ;d3dxvector3 upvec(
0.0f
, 1.0f
, 0.0f
) ;d3dxvector3 eyept(
0.0f
, 0.0f, -
20.0f
) ;
d3d預設的剔除方式是逆時針,也就是cull_ccw,如果你的頂點是按照逆時針順序定義的,而且使用了預設的剔除方式,那麼肯定什麼都看不見。所以一定要確保頂點定義的順序和剔除順序是相反的,也就是說,如果程式中定義了順時針剔除,那麼你的頂點就應該保持逆時針順序。在d3d中可以指定如下三種剪裁方式:
d3dcull_cw 順時針
d3dcull_ccw 逆時針
d3dcull_none 不剪裁
如果你懷疑程式可能是由於剪裁導致了錯誤,那麼可以將剪裁方式指定為d3dcull_none,並按照下面步驟診斷。
比如不小心將模型平移到了視野之外。如果有多個模型,要為每個模型單獨設定world matrix,且這些world matrix之間不能互相影響。
如果在建立device的時候啟用了zbuffer,如下:
d3***_.enableautodepthstencil =true ;d3***_.autodepthstencilformat = d3dfmt_d16 ;
那麼在clear render target的時候一定要記得clear zbuffer,如下:
d3ddevice_->clear(0, null, d3dclear_target | d3dclear_zbuffer, 0x4f94cd, 1.0f, 0);
如果是下面這樣,那麼將什麼也看不見。
d3ddevice_->clear(0, null, d3dclear_target, 0x4f94cd, 0.0f, 0);
注意,如果在建立device的時候像上面那樣指定了zbuffer,那麼就不用顯示設定開啟zbuffer了。因為d3d會自動設定zbuffer為開啟狀態,也就是下面的**其實是多餘的。
d3ddevice_->setrenderstate(d3drs_zenable, d3dzb_true);
這也算是乙個低階錯誤了,是在stackoverflow上看到的乙個問題,有一哥們將視窗背景設定為白色,輸出的模型也是白色,結果,啥也看不見。
這個原因聽起來很滑稽,不過不可否認的是,我曾多次犯了這個錯誤,程式中沒有繪製任何東西!其實這個問題的原因往往是修改**造成的,一開始程式的行為是正確的,但是後來為了修改某些功能為render函式就行修改,可能會無意間注釋掉某些內容,如果將繪製的**注釋掉,那肯定就什麼也看不見了。
我 的 閃 戀 之 一
我的 閃戀 紀念2009 我們一起軍訓的日子 2009 年我如願的考上了研究生,帶著乙份期待,在火熱的九月回到了母校 國防科大,開始自己的研究生生活。學校原本定於28號開學,由於實驗室的原因我早了乙個星期來到了學校。在實驗室打點了一下之後,便到學員隊報到了,由於本科的時候一直在科大,對研究生隊的隊長...
我的第乙個DirectX程式
之前本來就有這樣的打算的,學了一點hge引擎之後,再回過頭來看dx的sdk,會容易一些。就像我之前,做過乙個mfc的課程設計之後,現在回過頭來學孫鑫的第一集win32sdk會更容易理解。這樣做的好處就是 在你看不懂的時候仍然能做出東西來,讓你不灰心,有興趣學下去。如果我開始就看dx的話難度肯定比現在...
IO模型之一 Unix的五種I O模型
1 阻塞i o blocking io 應用程式呼叫乙個io函式,導致應用程式阻塞,如果資料已經準備好,從核心拷貝到使用者空間,否則一直等待下去。乙個典型的讀操作流程大致如下圖,當使用者程序呼叫recvfrom這個系統呼叫時,kernel就開始了io的第乙個階段 準備資料,就是資料被拷貝到核心緩衝區...