Az elmúlt SlimDX leckékben megismerkedtünk a fények, anyagok és textúrák adta lehetőségekkel. Láthattuk, hogy milyen egyszerű az alkalmazásuk és, hogy milyen gyönyörű grafikai hatások valósíthatóak meg velük. Az anyagok, illetve textúrák hozzárendelésével a felületek is élethűbb hatást keltenek. De még meggyőzőbbé válik a kép, ha az anyagokat, textúrákat és fényeket együtt alkalmazzuk. Ehhez mos az előző leckékben bemutatott ismereteket ötvözzük egy új projektben. Lássunk is hozzá.
Mivel anyagokat és textúrákat is használunk, vertexünk és vertexformátumunk megfelelően kibővül:[StructLayout(LayoutKind.Sequential)]
struct Vertex
{
public Vector3 Position;
public Vector3 Normal;
public Vector2 Texel;
public static readonly int Stride = Marshal.SizeOf(typeof(Vertex));
public static readonly VertexFormat Format = VertexFormat.Position | VertexFormat.Normal | VertexFormat.Texture1;
public Vertex(float vx, float vy, float vz,
float nx, float ny, float nz, float u, float v)
{
Position = new Vector3(vx, vy, vz);
Normal = new Vector3(nx, ny, nz);
Texel = new Vector2(u, v);
}
}
A fenti vertexformátúm a vertex, a felületi normális és a textúra koordinátákat tárolja el. A kocka vertexeinek megadásakor minden tag inicializásáról gondoskodni kell:
data = new Vertex[]{
// elülső oldal
new Vertex(-1.5f, +1.5f, -1.5f, 0, 0, -1, 0, 0),
new Vertex(+1.5f, +1.5f, -1.5f, 0, 0, -1, 1, 0),
new Vertex(-1.5f, -1.5f, -1.5f, 0, 0, -1, 0, 1),
new Vertex(-1.5f, -1.5f, -1.5f, 0, 0, -1, 0, 1),
new Vertex(+1.5f, +1.5f, -1.5f, 0, 0, -1, 1, 0),
new Vertex(+1.5f, -1.5f, -1.5f, 0, 0, -1, 1, 1),
…
Az alkalmazott anyagtulajdonságokat a SetupMaterial(), a textúrákat pedig a SetupTexture() metódusban állítjuk, ill. töltjük be. A fényforrás beállításáról a SetupLight() metódus gondoskodik. Ennek eredményeként a képernyőn, három forgó kockát láthatnánk, amelyek a megadott anyagtulajdonságoknak megfelelően verik vissza a fényt. Igen, ennyi az egész, de még nem érdemes megállni…
Anyag és alfa keverés
Az alfa keverésről már írtam az OpenGL leckesorozatban, az elv itt is ugyan az: a színeket RGBA formátumban kell megadni ahol is az (A) érték szolgál alfa-csatornaként. Az alfa-csatorna értéke azt mutatja, hogy a létrehozandó képpont színéhez milyen arányban járul hozzá a forrás pixelének színe. Szerencsére az alfa keveréshez kényelmes függvényeket biztosít számunkra a DirectX API. Első lépésként engedélyezni kell az alfa keverést:
device.SetRenderState(RenderState.AlphaBlendEnable, true);
Azt szeretnénk, hogy anyagunk színe érvényesüljön, ezért beállítjuk az anyagot mint a diffúz fényvisszaverődés forrását:
device.SetRenderState(RenderState.DiffuseMaterialSource, true);
Ezután beállítjuk az első textúramegjelenítés szakasz alfa műveletét, amely a TextureStage.AlphaArg1 értéket fogja használni. Esetünkben ez a diffúz komponens, tehát az anyag színe:
device.SetTextureStageState(0, TextureStage.AlphaArg1, TextureArgument.Diffuse);
device.SetTextureStageState(0, TextureStage.AlphaOperation, TextureOperation.SelectArg1);
device.SetTextureStageState(0, TextureStage.AlphaOperation, TextureOperation.SelectArg1);
Végül az alfa keverés módszerét kell beállítani. A példában a következő képletet fogjuk megvalósítani:
szín = forrás_szín × forrás_alfa + cél_színe × (1 - forrás_alfa)
Ugyanez a SlimDX nyelvére fordítva:
device.SetRenderState(RenderState.SourceBlend, Blend.SourceAlpha);
device.SetRenderState(RenderState.DestinationBlend, Blend.InverseSourceAlpha);
Az anyag diffúz komponensének alfa értékét futás alatt folyamatosan fogjuk változtatni egy szinusz függvény segítségével a DrawCube() metódusban (lásd forráskód). A végeredmény pedig itt látható, az ablakban három forgó kockát csodálhatunk, amelyek fokozatosan elfakulnak, majd újra megjelennek.
A teljes forrás itt érhető el:DOWNLOAD
A bejegyzés megírásában nagy segítségemre voltak Nyisztor Károly DirectX-el kapcsolatos könyvei.
0 megjegyzés :
Megjegyzés küldése