2010. augusztus 26., csütörtök

SlimDX9 03 - És legyen világosság…

Legutóbb ott hagytuk abba a SDX leckénket, hogy létrehoztunk egy csonka gúlát a háromdimenziós térben és megforgattuk azt. Mivel nem definiáltunk normál vektorokat ezért a megvilágítást ki kellet kapcsolnunk, hogy valamit lássunk a gúlánkból. Persze fények nélkül a számítógépes grafika semmit sem ér, ezért most egy egyszerű példa segítségével belekóstolunk a fények világába.

Természetesen az első lépés a megvilágítás bekapcsolása, amit a következő sorral tehetünk meg:

device.SetRenderState(RenderState.Lighting, true);

A következő fontos dolog a megfelelő Vertex formátum megadása, ahol már helyet kapnak a normál vektorok is:
  [StructLayout(LayoutKind.Sequential)]
struct Vertex
{
public Vector3 Position;
public Vector3 Normal;
public int Color;
public static readonly VertexFormat Format = VertexFormat.Position | VertexFormat.Normal | VertexFormat.Diffuse;

public Vertex(float vX, float vY, float vZ, float nX, float nY, float nZ, int color)
{
Position = new Vector3(vX, vY, vZ);
Normal = new Vector3(nX, nY, nZ);
Color = color;
}
}
Ezután a modell létrehozása következik, ami ebben az esetben egy kocka. Itt a csúcspontok mellet, a normálvektorokat és a csúcspontok színértékét is megadjuk:
    private void OnResourceLoad()
{
int c1 = Color.Red.ToArgb();
int c2 = Color.Green.ToArgb();
int c3 = Color.Blue.ToArgb();

vertices = new Vertex[]
{
// elülső oldal
new Vertex(-1.5f, +1.5f, -1.5f, 0, 0, -1, c1),
new Vertex(+1.5f, +1.5f, -1.5f, 0, 0, -1, c1),
new Vertex(-1.5f, -1.5f, -1.5f, 0, 0, -1, c1),
new Vertex(-1.5f, -1.5f, -1.5f, 0, 0, -1, c1),
new Vertex(+1.5f, +1.5f, -1.5f, 0, 0, -1, c1),
new Vertex(+1.5f, -1.5f, -1.5f, 0, 0, -1, c1),

// jobb oldal
new Vertex(+1.5f, +1.5f, -1.5f, +1, 0, 0, c2),
new Vertex(+1.5f, +1.5f, +1.5f, +1, 0, 0, c2),
new Vertex(+1.5f, -1.5f, -1.5f, +1, 0, 0, c2),
new Vertex(+1.5f, -1.5f, -1.5f, +1, 0, 0, c2),
new Vertex(+1.5f, +1.5f, +1.5f, +1, 0, 0, c2),
new Vertex(+1.5f, -1.5f, +1.5f, +1, 0, 0, c2),

// hátsó oldal
new Vertex(+1.5f, +1.5f, +1.5f, 0, 0, +1, c1),
new Vertex(-1.5f, +1.5f, +1.5f, 0, 0, +1, c1),
new Vertex(+1.5f, -1.5f, +1.5f, 0, 0, +1, c1),
new Vertex(+1.5f, -1.5f, +1.5f, 0, 0, +1, c1),
new Vertex(-1.5f, +1.5f, +1.5f, 0, 0, +1, c1),
new Vertex(-1.5f, -1.5f, +1.5f, 0, 0, +1, c1),

// bal oldal
new Vertex(-1.5f, +1.5f, +1.5f, -1, 0, 0, c2),
new Vertex(-1.5f, +1.5f, -1.5f, -1, 0, 0, c2),
new Vertex(-1.5f, -1.5f, +1.5f, -1, 0, 0, c2),
new Vertex(-1.5f, -1.5f, +1.5f, -1, 0, 0, c2),
new Vertex(-1.5f, +1.5f, -1.5f, -1, 0, 0, c2),
new Vertex(-1.5f, -1.5f, -1.5f, -1, 0, 0, c2),

// kocka teteje
new Vertex(-1.5f, +1.5f, +1.5f, 0, +1, 0, c3),
new Vertex(+1.5f, +1.5f, +1.5f, 0, +1, 0, c3),
new Vertex(-1.5f, +1.5f, -1.5f, 0, +1, 0, c3),
new Vertex(-1.5f, +1.5f, -1.5f, 0, +1, 0, c3),
new Vertex(+1.5f, +1.5f, +1.5f, 0, +1, 0, c3),
new Vertex(+1.5f, +1.5f, -1.5f, 0, +1, 0, c3),

// kocka alja
new Vertex(-1.5f, -1.5f, -1.5f, 0, -1, 0, c3),
new Vertex(+1.5f, -1.5f, -1.5f, 0, -1, 0, c3),
new Vertex(-1.5f, -1.5f, +1.5f, 0, -1, 0, c3),
new Vertex(-1.5f, -1.5f, +1.5f, 0, -1, 0, c3),
new Vertex(+1.5f, -1.5f, -1.5f, 0, -1, 0, c3),
new Vertex(+1.5f, -1.5f, +1.5f, 0, -1, 0, c3),
};
}
A normálvektor egy olyan vektor, ami az adott háromszögre merőleges. Ennek ellenére normálvektort csak csúcsponthoz rendelhetünk hozzá.

Egy háromszög és a rá merőleges normál vektor

Ezután létre kell hozni egy fényforrást, ami jelen példánkban pontszerű lesz (Point light). A fényforrásokat a Light struktúra segítségével hozhatjuk létre:
           Light light = new Light()
{
Type = LightType.Point,
Range = 10000f,
Attenuation0 = 1f,
Diffuse = Color.White,
Position = new Vector3(-2, -2, +10)
};
A pontszerű fényforrás egyenletesen sugározz, a fény minden irányban haladhat. A pontszerű fényforrás definiálásakor meg kell adni a pozíciót (Position), a fény hatótávolságát (Range), valamint a fény intenzitásának távolsággal arányos csökkenését meghatározó együtthatót (Attenuation0, Attenuation1, Attenuation2). A létrehozott fényforrást be kell állítani:

device.SetLight(0, light);

Az első szám a Light Index, míg a második az index-el hivatkozható Light struktúra. Majd a beállított fényforrást engedélyezni kell:

device.EnableLight(0, true);

A fentieket a SetupLight() metódus foglalja össze:
       private void SetupLight()
{
device.SetRenderState(RenderState.Lighting, true);

Light light = new Light()
{
Type = LightType.Point,
Range = 10000f,
Attenuation0 = 1f,
Diffuse = Color.White,
Position = new Vector3(-2, -2, +10)
};

device.SetLight(0, light);
device.EnableLight(0, true);
}
Természetesen a fényekkel később ennél sokkal részletesebben fogunk foglalkozni, ez csak egy kis ízelítő belőle. A példa többi része már ismerős és könnyedén értelmezhető, eredménye pedig itt látható:


A teljes forrás pedig letölthető innen:


Most is meg kell jegyeznem, hogy Nyisztor Károly könyvei is sokat segítettek a bejegyzés írása közben.

2 megjegyzés :

  1. pont ilyen cikksorozatot kerestem.
    Köszönöm, és kitartást a cikkekhez!

    Bakter

    VálaszTörlés
  2. Örülök annak, hogy írtál és persze annak is, ha a kis leckékkel tudok segíteni másoknak. Remélem hasznosak lesznek számodra az itt leírtak, véleményedre kritikádra számítok.
    Ahogyan az időm engedi folytatni fogom a SDX leckéket, persze, ha van akit ez érdekel, akkor az erőt ad a folytatáshoz!!!
    Üdv
    Boheem

    VálaszTörlés