DirectX 渲染到紋理

2021-05-26 12:44:30 字數 2977 閱讀 1606

熟悉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 ==

FBO 渲染到紋理

這是書中第八章的最後一節內容,在我機制的簡化問題後,寫出了想要的效果.應用fbo渲染到紋理,可以直接用.這個用來實現鏡面效果什麼的,好啊.再乙個,貌似我現在已經可以去寫延遲渲染流水線了,那個用到多渲染目標,之後再處理.呼,繼續學習吧,這些東西還真得實踐才行啊.rendertotexture.cpp ...

ogre渲染到動態紋理

材質指令碼 material screen texture unit bluescreen.jpg必須是blank white的影象,因為多重紋理混合預設是modulate。texture screen就是在程式裡面動態建立的二維影象。ogre textureptr screentex ogre t...

Opengl中的FBO渲染到紋理

渲染到紋理用途 遊戲中水的倒影,汽車的反光鏡,gpgpu必備。實現參見紅皮書的 至於ogre中的渲染到紋理可以參考翻譯文件第八章 ogre渲染目標 渲染到紋理 技術,本質上來說就是一次對場景中幾何體的渲染過程。它本身要花費一些執行時間,進而導致幀速的下降。當你渲染複雜耗時的內容的時候,你不得不考慮相...