directX学习系列8 颜色融合(转)
? 1, Multipass(多通道)?
? 將一個任務劃分成幾個階段,由多個pass處理不同階段,后續pass總是處理前一個pass的結果。例如復雜的光照方程可以分成幾個pass來計算。?
? 用不同的紋理通過多個pass來多次渲染一個圖元,這樣可以實現許多很酷的特效。例如LightMap,它就是用不同的紋理來表示復雜的光、影效果。?
? 2, Multitexture(多紋理)?
? 很顯然,pass越多,效率越低。為了降低pass的數量,有些硬件加速卡支持在一個pass中渲染兩個或更多的紋理,這種技術就叫做multitexture。D3D在一個pass中最多支持8個紋理的混合。?
? 3, Pipeline(管道)?
? 可以將管道想像成一條流水線,它完成某項任務。?
? 4, Stage?
? 一個管道可以由多個stage組成,這些stage同時運行,所以管道的速度取決于最慢的stage。?
? 5, Texture?? blending?? cascade?
? Texture?? blending?? cascade是一個pipeline,它完成在一個pass中混合多個紋理這個任務。?
? 6, Texture?? Stage(也叫做texture?? unit)?
? Texture?? blending?? cascade由許多Texture?? Stage構成,每個Texture?? Stage混合兩個紋理(或經過計算的頂點集),通常是RGB和Alpha值,并將結果(經過計算的頂點集)傳遞給下一個Texture?? Stage。?
? 理解了上面的那些概念,理解SetTextureStageState函數就很容易了。?
? HRESULT?? SetTextureStageState(?
????? DWORD?? Stage,?
????? D3DTEXTURESTAGESTATETYPE?? Type,?
????? DWORD?? Value?
? );?
? 1, Stage參數,D3D支持8個Texture?? Unit,索引值由0~7,通過此參數你可以指定是哪一個Texture?? Unit。?
? 2, Type參數,用來選擇Texture?? Stage不同的狀態,如D3DTSS_COLOROP代表顏色混合操作,D3DTSS_ALPHAOP代表ALPHA值混合操作。?
? 3,???????????? Value參數,根據不同的Type,來設置其狀態值。如:SetTextureStageState(?? 0,?? D3DTSS_COLOROP,?????? D3DTOP_ADD?? ),就是指在第一個Texture?? Unit中,將兩個顏色值的混合操作設定為累加。? /
HRESULT SetTextureStageState(
?? DWORD Stage,
?? D3DTEXTURESTAGESTATETYPE Type,
?? DWORD Value
?? );
?? stage這個參數是指第幾層紋理,1.2.3...9,, 這個版本的dx最多支持9層紋理。
?? Type:Defines the type of operation that a texture stage will perform.//定義對該紋理的哪個屬進行設置,值很多。。。
?? Value: 指的是前面所選屬性的值
type:
??? D3DTSS_ALPHAOP = 4,????????? //alpha通道的運算,
??? D3DTSS_COLOROP = 1,?????????? //顏色的運算
?????????????????????????????????????????????????? //這里的op 是operations,指對前面設置的顏色進行運算
?????????????????????????????????????????????????? //既后面的2個type:D3DTSS_COLORARG1,D3DTSS_COLORARG2
?????????????????????????????????????????????????? //或D3DTSS_ALPHAARG1,D3DTSS_ALPHAARG2 = 6
value:
??? D3DTOP_DISABLE = 1,?????????????????????????? //該紋理無效,既不顯示
??? D3DTOP_SELECTARG1 = 2,????????????????? //Arg1
??? D3DTOP_SELECTARG2 = 3,?????????????????? //Arg2
??? D3DTOP_MODULATE = 4,??????????????????????? //Arg1 * Arg2
??? D3DTOP_MODULATE2X = 5,????????????????????? //Arg1 * Arg2 * 2
??? D3DTOP_MODULATE4X = 6,????????????????????? //Arg1 * Arg2 * 4
??? D3DTOP_ADD = 7,???????????????????????????? // Arg1 + Arg2
??? D3DTOP_ADDSIGNED = 8,?????????????????? //(Arg1 + Arg2 - 0.5)
??? D3DTOP_ADDSIGNED2X = 9,?? //(Arg1 + Arg2 - 0.5)*2
??? D3DTOP_SUBTRACT = 10,?? //Arg1 - Arg2
??? D3DTOP_ADDSMOOTH = 11,?? //Arg1 + Arg2 – Arg1 * Arg2
??? D3DTOP_BLENDDIFFUSEALPHA = 12,? //將Arg1與Arg2使用Alpha值進行線性插值。這是標準的Alpha混合效果。紋理參數常數???????? TextureArgumentConstants同樣可以設置到Value里
??? D3DTOP_BLENDTEXTUREALPHA = 13,
??? D3DTOP_BLENDFACTORALPHA = 14,
??? D3DTOP_BLENDTEXTUREALPHAPM = 15,
??? D3DTOP_BLENDCURRENTALPHA = 16,
??? D3DTOP_PREMODULATE = 17,
??? D3DTOP_MODULATEALPHA_ADDCOLOR = 18,
??? D3DTOP_MODULATECOLOR_ADDALPHA = 19,
??? D3DTOP_MODULATEINVALPHA_ADDCOLOR = 20,
??? D3DTOP_MODULATEINVCOLOR_ADDALPHA = 21,
??? D3DTOP_BUMPENVMAP = 22,
??? D3DTOP_BUMPENVMAPLUMINANCE = 23,
??? D3DTOP_DOTPRODUCT3 = 24,
??? D3DTOP_MULTIPLYADD = 25,?? //SRGBA = Arg1 + Arg2 * Arg3
??? D3DTOP_LERP = 26,
??? D3DTOP_FORCE_DWORD = 0x7fffffff,
type:
??? D3DTSS_COLORARG1 = 2,?
??? D3DTSS_COLORARG2 = 3,
??? D3DTSS_ALPHAARG1 = 5,
??? D3DTSS_ALPHAARG2 = 6,
??? D3DTSS_COLORARG0 = 26,
??? D3DTSS_ALPHAARG0 = 27,
??? D3DTSS_RESULTARG = 28,
value:
???? 這里的TA指的是texture arguments ,
????? D3DTA_CURRENT?? 表示上一個Stage混合的結果。Stage=0時,這個值表示的是D3DTA_DIFFUSE
????? D3DTA_CONSTANT??????????????????? //給當前紋理一個固定的值;
????? D3DTA_DIFFUSE;???????????????? //diffuse的值作為參數 diffuse 可能有多個來源。。比如材質,vertex
????? D3DTA_SELECTMASK???????? //Mask value for all arguments; not used when setting texture arguments 這句話不理解啊,為什么要偽裝呢?
????? D3DTA_SPECULAR???????????? //取spercular 的值作為參數? 來源同diffuse
????? D3DTA_TEMP???????????????????? //待定。。
????? D3DTA_TEXTURE????????????? //用紋理的顏色值作為參數
????? D3DTA_TFACTOR????????????? //待定。。
D3DTSS_BUMPENVMAT00 = 7,
D3DTSS_BUMPENVMAT01 = 8,
D3DTSS_BUMPENVMAT10 = 9,
D3DTSS_BUMPENVMAT11 = 10,
D3DTSS_TEXCOORDINDEX = 11,
D3DTSS_BUMPENVLSCALE = 22,
D3DTSS_BUMPENVLOFFSET = 23,
D3DTSS_TEXTURETRANSFORMFLAGS = 24,
D3DTSS_CONSTANT = 32,
D3DTSS_FORCE_DWORD = 0x7fffffff,
m_pD3DDevice->SetTexture( 0, m_pTexture0 ); // 土地材質
m_pD3DDevice->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, 0 );
// TextureStage 0 (不做任何改變)
m_pD3DDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1 );
m_pD3DDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
m_pD3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE );
//------------
m_pD3DDevice->SetTexture( 1, m_pTexture1 ); // 草地材質
m_pD3DDevice->SetTextureStageState( 1, D3DTSS_TEXCOORDINDEX, 0 );
// TextureStage 1 (使用頂點alpha值計算混合)
m_pD3DDevice->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_BLENDDIFFUSEALPHA );
m_pD3DDevice->SetTextureStageState( 1, D3DTSS_COLORARG1, D3DTA_TEXTURE );
m_pD3DDevice->SetTextureStageState( 1, D3DTSS_COLORARG2, D3DTA_CURRENT );
m_pD3DDevice->SetTextureStageState( 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE );
//------------
// TextureStage 2 (使用光影遮罩圖) // 光影材質
m_pD3DDevice->SetTexture( 2, m_pTexture2 );
m_pD3DDevice->SetTextureStageState( 2, D3DTSS_TEXCOORDINDEX, 1 );
m_pD3DDevice->SetTextureStageState( 2, D3DTSS_COLOROP, D3DTOP_MODULATE2X );
m_pD3DDevice->SetTextureStageState( 2, D3DTSS_COLORARG1, D3DTA_TEXTURE );
m_pD3DDevice->SetTextureStageState( 2, D3DTSS_COLORARG2, D3DTA_CURRENT );
m_pD3DDevice->SetTextureStageState( 2, D3DTSS_ALPHAOP, D3DTOP_DISABLE );
//------------
// TextureStage 3 (使用頂點值計算陰影)
m_pD3DDevice->SetTextureStageState( 3, D3DTSS_COLOROP, D3DTOP_MODULATE );
m_pD3DDevice->SetTextureStageState( 3, D3DTSS_COLORARG1, D3DTA_DIFFUSE );
m_pD3DDevice->SetTextureStageState( 3, D3DTSS_COLORARG2, D3DTA_CURRENT );
m_pD3DDevice->SetTextureStageState( 3, D3DTSS_ALPHAOP, D3DTOP_DISABLE );
黑暗紋理
通過紋理映射來模擬逐像素光照效果,通常是將第一層紋理設置為物體原來的表面紋理,將第二層紋理設置為光照紋理,然后將兩張紋理的顏色相乘,所以有時將兩張紋理的顏色相乘稱為光照映射(light mapping)。由于這種技術經常被用于使一張紋理變暗,有時也稱為黑暗映射(dark mapping)。
混合紋理與頂點漫反射顏色
當很強的陽光照射在物體表面上時,會使它表面的顏色變得更加明亮,這可以通過將紋理與頂點的漫反射顏色相混合來模擬這種效果。當一個白色材質反射一個方向光時,反射量越多,就意味著紋理顏色在最終顯示結果中所占的成分越少。因此,那些被光直接照射到表面會呈現出白色。示例代碼如下:
// setup light
ZeroMemory(&g_light, sizeof(D3DLIGHT9));
g_light.Type = D3DLIGHT_DIRECTIONAL;
g_light.Diffuse.r = 0.5f;
g_light.Diffuse.g = 0.5f;
g_light.Diffuse.b = 0.5f;
D3DXVECTOR3 light_dir(0, 0, 10);
D3DXVec3Normalize((D3DXVECTOR3*) &g_light.Direction, &light_dir);
// setup material
ZeroMemory(&g_material, sizeof(D3DMATERIAL9));
g_material.Ambient.r = 1.0f;
g_material.Ambient.g = 1.0f;
g_material.Ambient.b = 1.0f;
g_material.Ambient.a = 1.0f;
g_material.Diffuse.r = 0.7f;
g_material.Diffuse.g = 0.7f;
g_material.Diffuse.b = 0.7f;
g_material.Diffuse.a = 0.5f;
pd3dDevice->SetRenderState(D3DRS_LIGHTING, TRUE);
pd3dDevice->SetRenderState(D3DRS_AMBIENT, 0x00808080);
pd3dDevice->SetLight(0, &g_light);
pd3dDevice->LightEnable(0, TRUE);
pd3dDevice->SetMaterial(&g_material);
pd3dDevice->SetTexture(0, g_base_texture);
pd3dDevice->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, 0);
pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
pd3dDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_ADD);
pd3dDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
發光映射
發光映射(glowing mapping)與黑暗映射正好相反,它對于模擬那些具有獨立于基礎貼圖的發光部分的物體很有用,比如模擬發光二極管、按鈕、建筑物內的燈光、太空船上的燈光等。發光映射應僅影響基礎貼圖上的發光區域,而不影響其他部分。因此需要對發光效果做加法,而不是做乘法。
pd3dDevice->SetTexture(0, g_base_texture);
pd3dDevice->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, 0);
pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
pd3dDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
pd3dDevice->SetTexture(1, g_dark_texture);
pd3dDevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 0);
pd3dDevice->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
pd3dDevice->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT);
pd3dDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_ADD);
細節映射
如果要模擬一塊粗糙的石灰泥墻壁,可以通過細節映射(detail mapping)來實現。實現過程是:將基礎貼圖(也就是第一張紋理)的顏色未經修改便作為第二個紋理操作階段中的第二個參數,然后通過D3DTOP_ADDSIGNED將灰色的細節紋理與基礎貼圖相加。這個操作本質上是做了一個加法,只是使用了有符號的顏色值來代替平時使用的無符號值。在對兩張紋理的像素顏色進行D3DTOP_ADDSIGNED操作時,它將參數的每個成分相加后再減去偏移量0.5,從而使有效值域變為-0.5 ~ 0.5。對一些比較舊的顯卡,當其不能支持D3DTOP_ADDSIGNED操作時,可以使用D3DTOP_MODULATE2X代替D3DTOP_ADDSIGNED操作進行模擬。
在細節貼圖中較亮的灰色紋理元素會使基礎貼圖變得更亮,而較暗的灰色紋理元素會使基礎貼圖變得更暗。由此可使物體呈現出粗糙的表面,從而使之看上去更為真實。示例代碼如下:
pd3dDevice->SetTexture(0, g_base_texture);
pd3dDevice->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, 0);
pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG1,? D3DTA_TEXTURE);?
pd3dDevice->SetTextureStageState(0, D3DTSS_COLOROP,? D3DTOP_SELECTARG1);
pd3dDevice->SetTexture(1, g_detail_texture);
pd3dDevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 0);
pd3dDevice->SetTextureStageState(1, D3DTSS_COLORARG1,? D3DTA_TEXTURE);
pd3dDevice->SetTextureStageState(1, D3DTSS_COLORARG2,? D3DTA_CURRENT);
hr = pd3dDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_ADDSIGNED);
if(FAILED(hr))
pd3dDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATE2X);
ALPHA混合操作
Direct3D在渲染一個場景時,它可以結合幾種來源的顏色信息:頂點、當前材質、紋理貼圖、先前寫入渲染目標的顏色信息,然后將其中的一些顏色混合起來。同時也可以使用Alpha來指定Direct3D該以怎樣的權重混合這些顏色,Alpha信息可以存儲在頂點中、材質中、紋理貼圖中。Alpha值為0表示完全透明,Alpha值為1表示不透明,其余0~1之間的值表示不同程度的透明。
如果要從一張紋理中獲取Alpha值,應將D3DTA_TEXTURE作為Alpha參數。
如果要使用來自頂點中的Alpha值,應將D3DTA_DIFFUSE作為Alpha參數,并確保渲染狀態D3DRS_DIFFUSEMATERIALSOURCE被設置為D3DMCS_COLOR1(這也是默認狀態)。
如果要使用來自材質中的Alpha值,應將D3DTA_DIFFUSE作為Alpha參數,并確保渲染狀態D3DRS_DIFFUSEMATERIALSOURCE被設置為D3DMCS_MATERIAL。
如果未用SetRenderState()設置D3DRS_DIFFUSEMATERIALSOURCE參數,則從默認來源(即頂點)獲取漫反射顏色。
pd3dDevice->SetTexture(0, g_texture);
pd3dDevice->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, 0);
pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
pd3dDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
紋理坐標自動生成
在Direct3D程序中,不僅可以在模型載入階段或渲染階段指定物體的紋理坐標,還可以通過Direct3D渲染引擎自動生成紋理坐標,用于諸如環境映射等特殊的視覺效果。與手動設置紋理坐標相比,紋理坐標自動生成在Direct3D坐標變換和光照流水線中完成,執行速度更快。
Direct3D系統可以使用經過變換的攝像機空間頂點位置坐標、法線信息來生成紋理坐標。如果使用紋理坐標自動生成,那么在頂點中就可以不用包含紋理坐標數據,從而可以降低圖形渲染時的數據傳輸量。紋理坐標自動生成主要用于產生一些特殊效果,在大多數情況下還是手工為每個頂點指定紋理坐標。
通過調用SetTextureStageState()并將第二個參數設置為D3DTSS_TEXCOORDINDEX來控制Direct3D系統如何自動生成紋理坐標。
D3DTSS_TEXCOORDINDEX用于指定特定紋理層使用頂點中的第幾組紋理坐標,但如果指定了上表中的成員值,Direct3D將忽略頂點中的紋理坐標,轉而使用自動生成的紋理坐標。
D3DTSS_TEXTURETRANSFORMFLAGS用來控制生成的紋理坐標的輸出,在大多數情況下紋理坐標是二維的,即將D3DTSS_TEXTURETRANSFORMFLAGS設置為D3DTTFF_COUNT2。但當繪制線段或三維紋理時,紋理坐標可能是一維或三維的。
紋理坐標變換
Direct3D提供了對生成的紋理坐標進行坐標變換的功能,與頂點坐標變換相類似,可以指定一個4x4的紋理坐標變換矩陣,把它與生成的紋理坐標相乘,然后將變換之后的紋理坐標輸出至Direct3D渲染流水線。使用紋理坐標變換可以對紋理坐標進行諸如平移、旋轉和縮放等三維變換。紋理坐標變換對于生成一些特殊效果是非常有用的,它不用直接修改頂點的紋理坐標。例如可以通過一個簡單的平移矩陣對紋理坐標進行變換,從而使物體表面上的紋理不斷變換位置,產生動畫效果。紋理坐標自動生成在三維圖形程序中最廣泛的應用是環境映射。
可通過函數IDirect3DDevice9::SetTransform()來設置4x4的紋理坐標變換矩陣,它以D3DTS_TEXTURE0~ D3DTS_TEXTURE7作為第一個參數,表示設置紋理層0~7的紋理矩陣。下列代碼對紋理層0設置了一個將紋理坐標u、v縮小到原來一半的紋理矩陣:
D3DXMATRIX mat;
D3DXMatrixIdentity(&mat);
mat._11 = 0.5f;
mat._22 = 0.5f;
pd3dDevice->SetTransform(D3DTS_TEXTURE0, &mat);
下面的代碼將原來的紋理坐標平移(1.0, 1.0, 0)個單位。
D3DXMATRIX mat;
D3DXMatrixIdentity(&mat);
mat._41 = 1.0f;
mat._42 = 1.0f;
mat._43 = 0.0f;
pd3dDevice->SetTransform(D3DTS_TEXTURE0, &mat);
示例程序通過下列代碼對自動生成的紋理坐標進行變換:
// texture coordinate transform
D3DXMATRIX mat_texture, mat_scale, mat_trans;
D3DXMatrixIdentity(&mat_texture);
D3DXMatrixScaling(&mat_scale, 0.5f, -0.5f, 1.0f);
D3DXMatrixTranslation(&mat_trans, 0.5f, 0.5f, 1.0f);
mat_texture = mat_texture * mat_scale * mat_trans;
pd3dDevice->SetTransform(D3DTS_TEXTURE0, &mat_texture);
立方體環境映射
立方體環境映射圖有時又稱為立方體映射圖,是一組包含物體周圍環境圖像的紋理貼圖,好像物體在立方體的中心。立方體環境圖的每個面覆蓋水平和垂直方向上各90度視角區域,一共6個面.
球形環境映射
球形環境映射圖(或稱為球形映射圖)和立方體環境映射圖類似,也是一幅包含周圍場景圖像的特殊紋理。和立方體環境映射圖不同的是,球形環境映射圖不直接代表物體周圍的環境。球形映射圖就好像通過魚眼(fish-eye)凸透鏡觀察到的景象一樣,是一個物體周圍環境360度全方位視域的三維表現。
首先使用一張球形的背景圖作為環境映射紋理,接著在回調函數OnCreateDevice()中加載紋理和網格模型,接著在回調函數OnResetDevice()中自動生成紋理坐標,并設置紋理階段顏色混合方法,最后在回調函數OnFrameRender()中渲染茶壺:
V_RETURN(D3DXCreateTextureFromFile(pd3dDevice, L"spheremap.bmp", &g_env_texture));
ID3DXBuffer* material_buffer;
V_RETURN(D3DXLoadMeshFromXW(L"teapot.x", D3DXMESH_MANAGED, pd3dDevice, NULL, &material_buffer, NULL,??????? &g_num_materials, &g_mesh));
D3DXMATERIAL* xmaterials = (D3DXMATERIAL*) material_buffer->GetBufferPointer();g_mesh_materials = new D3DMATERIAL9[g_num_materials];
for(DWORD i = 0; i < g_num_materials; i++){ g_mesh_materials[i] = xmaterials[i].MatD3D;
// .x file do not save ambient data, so set it here. g_mesh_materials[i].Ambient = g_mesh_materials[i].Diffuse; }
material_buffer->Release();
pd3dDevice->SetTexture(0, g_env_texture);
pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
pd3dDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
pd3dDevice->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_SPHEREMAP);
pd3dDevice->SetTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
// Clear the render target and the zbuffer V( pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_ARGB(0, 0, 0, 0), 1.0f, 0) );
// Render the scene
if( SUCCEEDED( pd3dDevice->BeginScene() ) )
{ for(DWORD i = 0; i < g_num_materials; i++)
{?
? pd3dDevice->SetMaterial(&g_mesh_materials[i]);?
? g_mesh->DrawSubset(i);
}
RenderText();
V(g_button_dlg.OnRender(fElapsedTime));
???? V( pd3dDevice->EndScene() );
}
DXT紋理壓縮
要渲染看起來真實的場景,最好是使用高分辨率而且顏色豐富的紋理,但這樣的紋理可能會耗費大量的內存,例如,一張每像素16位顏色的256 x 256紋理將使用128KB的內存。如果在該紋理中使用多級漸進紋理,還需要額外的43KB內存。一個使用50張這種紋理的場景將需要8MB的內存,如果需要更強的真實性,可以使用每像素32位顏色的512 x 512紋理,但那就需要8倍的內存。
為了減少紋理消耗的系統帶寬和內存空間,Direct3D支持紋理壓縮和實時解壓,即DXT紋理壓縮。壓縮后的紋理被存儲在Direct3D紋理指針中,當Direct3D渲染物體時,Direct3D引擎自動對紋理進行解壓。應用DXT壓縮紋理不僅可以節省內存空間,而且能有效地降低紋理傳輸帶寬,提高圖形系統的整體性能。
隨著DirectX對紋理壓縮格式的推廣,目前大部分顯卡都支持DXT壓縮紋理,而且DXT壓縮紋理在圖形質量和運行速度之間取得了很好的平衡。
DXT是一種DirectDraw表面,它以壓縮形式存儲圖形數據,該表面可以節省大量的系統帶寬和內存。即使不直接使用DXT表面渲染,也可以通過DXT格式創建紋理的方法節省磁盤空間。Direct3D提供了D3DFMT_DXT1 ~ D3DFMT_DXT5共5種壓縮紋理格式。其中,D3DFMT_DXT1支持15位RGB和1位alpha圖形格式,D3DFMT_DXT2、D3DFMT_DXT3支持12位RGB和4位alpha,D3DFMT_DXT4、D3DFMT_DXT5則采取了線性插值方式生成alpha。
DXT1格式的壓縮比例是4 : 1(4x4塊16位RGB紋理元素可壓縮為64位,2個16位RGB565值和16個2位索引),這樣的壓縮比并不很高,但足以有效地將3D加速卡用于存儲紋理的容量提高4倍
轉載于:https://www.cnblogs.com/zsb517/p/3540842.html
總結
以上是生活随笔為你收集整理的directX学习系列8 颜色融合(转)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 经方时方接轨之――茵陈蒿汤合甘露饮
- 下一篇: 第四范式蒋仁皓:什么才是构建企业AI的关