Direct3D渲染到紋理 (部分轉)

2021-08-31 23:42:05 字數 2544 閱讀 3631

遊戲中應用的例子:

遊戲中開啟觀察人物的介面,ui上顯示的人物就是通過這種方式繪製出來的。

熟悉dx的兄弟們都知道什麼叫紋理了,這裡簡單介紹一下,先看看現實生活中的例子吧,其實紋理的例子比比皆是,比如地板,牆面都是紋理。在圖形學中,紋理主要是為了增強場景的真實感,比如你想繪製乙個地面,簡單一點可以直接使用乙個矩形,稍微複雜一點可以用三角形網格,再複雜一點可以使用地面紋理,有了紋理以後真實感明顯增強了。dx中的紋理其實就是就是對現實生活中紋理的模擬,但是它不僅僅是一張那麼簡單,有著完整的資料結構,比如寬度,高度,記憶體型別,表面(su***ce)等。

常規的渲染操作都是直接將場景呈現到backbuffer中的,backbuffer說白了其實就是乙個表面,再說白了就是一塊記憶體,場景通過繪製函式載入視訊記憶體後,再通過present函式送至顯示器。那麼為什麼還要渲染到紋理呢?這是為了實現一些特殊的效果,比如常見的環境對映,簡單的說,想象你有乙個光滑的球體,它應該是可以反射周圍的物體的,這就是環境對映。

上面說了常規的渲染操作是將場景送至backbuffer,而backbuffer實際上是乙個su***ce,而紋理恰恰又包含了su***ce,所以我們只需要取得紋理的su***ce,其次將場景送至這個su***ce,最後再把這個紋理渲染到backbuffer中即可。舉個例子,假設你要在一面牆壁上畫一幅畫,你有兩種方法

1 直接在牆上畫,這個很好理解,就對應常規的backbuffer渲染。

2 先將畫畫在紙上,然後將紙貼到牆上,這就對應渲染到紋理的過程。

這裡牆壁相當於backbuffer,而紙張相當於紋理的su***ce,在紙上作畫相當於渲染到紋理,把紙貼到牆上相當於把紋理渲染到backbuffer,希望大家沒有迷糊就好。具體的步驟如下

1 建立紋理並獲得紋理的表面(su***ce)

2 向紋理的表面渲染場景

3 渲染紋理本身

為了在紋理上渲染,我們應該先準備乙個紋理,使用dx的函式createtexture就可以建立乙個紋理了,注意在設定引數的時候需要將usage設定為d3dusage_rendertarget,因為只有這樣才能在紋理上渲染。

idirect3dtexture9*        g_prendertexture    = null ; // create texture hresult hr = g_pd3ddevice->createtexture( 256, 256, 1, d3dusage_rendertarget, d3dfmt_r5g6b5, d3dpool_default,&g_prendertexture, null) ; if (failed(hr))

下面我們要取得紋理對應的su***ce,以便在其上繪製場景,

idirect3dsu***ce9*        g_prendersu***ce    = null ; // get texture su***ce hr = g_prendertexture->getsu***celevel(0, &g_prendersu***ce) ; if (failed(hr))

下面開始向紋理的su***ce中繪製場景,為了簡單起見,這裡繪製乙個茶壺,需要注意的是,繪製時需要將紋理的表面設定為當前的rendertarget,所以首先要儲存原來的rendertarget。

// 儲存舊的rendertarget g_pd3ddevice->getrendertarget(0, &g_poldrendertarget) ; // 設定紋理表面為當前rendertarget g_pd3ddevice->setrendertarget(0, g_prendersu***ce) ; g_pd3ddevice->clear( 0, null, d3dclear_target | d3dclear_zbuffer, 0xff0000ff, 1.0f, 0 );   if( succeeded( g_pd3ddevice->beginscene() ) )

接下來將紋理渲染到backbuffer,在這之前要恢復原來的rendertarget,因為這次是將紋理送到backbuffer,而backbuff而就是原來的rendertarget。

// 恢復rendertarget g_pd3ddevice->setrendertarget(0, g_poldrendertarget) ; g_pd3ddevice->clear( 0, null, d3dclear_target | d3dclear_zbuffer, 0xff00ff00, 1.0f, 0 );   if( succeeded( g_pd3ddevice->beginscene() ) )    g_pd3ddevice->present( null, null, null, null );

雖然是兩次渲染,但是只需要呼叫一次present函式,因為之前的繪製只是將場景送至視訊記憶體,而present函式才真正將場景顯示出來。

上面的**用到了自定義函式renderquad,這個函式將紋理渲染出來,細節如下

void renderquad()

最後,看一下效果圖

其實這個圖並沒有真正體現渲染到紋理的威力,雖然技術上是,但給人的感覺就好像直接渲染了一張一樣,為了實現更加高階的效果,我們可以設定乙個cube,並給這個cube加上紋理,然後在每個紋理的表面繪製場景,甚至可以是動態場景,效果如下。

動態效果檔案

== the end ==

Direct3D多視口渲染

多視口渲染主要是改變了視口矩陣,一般我們的shader程式沒有直接處理這個視口矩陣,注意多視口渲染的順序 void render 上面任何乙個步驟出錯都會帶來以外的結果。1.除最後乙個視口外全螢幕閃爍,這也是為什麼要還原原視口的原因,如果我們不還原,那麼下一次clear 的是上次渲染的最後乙個視口,...

direct 3d 渲染紅藍立體效果

自從阿凡達賺了大錢以後,遍地都開始追捧3d電影了。其實阿凡達上映前半年我就已經給過網龍在遊戲中實現3d視覺的建議,只不過沒有引起重視。雖然紅藍立體在視覺效果上是有一定的缺憾的,但是在目前的硬體裝置條件下,這在遊戲中實現3d視覺的各種方案中,紅藍分光成本是最低廉的。前兩天整理舊硬碟上的檔案,偶然發現當...

Direct3D入門 一 配置Direct3D環境

b url 先鋒隊 北京貝武易科技公司 b 我們要編寫directx direct3d 程式,需要先安裝兩個檔案 directx sdk directx開發包 這個開發包大,大概500兆 url 執行環境 這個檔案小,大概30 40兆 url 很多初學者會混淆了這個兩個directx有什麼區別。乙個...