Első 3D-s objetumunk

0. Töltsük le és nyissuk meg az EmptyProject-et.

1. Saját osztály létrehozása, DXFrame-ből származtatva, bármilyen néven.

#pragma once
#include "dxframe.hpp"

class Triangle :
    public DXFrame
{
public:
    Triangle(void);
    ~Triangle(void);
};

2. EmptyProject.cpp átírása, hogy az újonnan létrehozott osztály használja.

Az 5. sorban:

#include "Sample1.hpp"
#include "Trianlge.hpp"

A 130. sorban:

    //!!! Itt hozd letre a sajat fo-objektumot
    myFrameWork = new Sample1();
    myFrameWork = new Triangle();

* Már így is fordulnia kell a programnak, bár sokat még nem csinál!

3. Eseménykezelők hozzáadása az osztályunkhoz. A következőkre lesz szükségünk: onCreateDevice, onDestroyDevice, onFrameRender.

Deklarációk (header file-ban):

class Triangle :
    public DXFrame
{
public:
    Triangle(void);
    ~Triangle(void);

    HRESULT onCreateDevice();
    void onDestroyDevice();
    void onFrameRender( double fTime, float fElapsedTime );
};

Definiciók (cpp file-ban):

HRESULT Triangle::onCreateDevice()
{
    return D3D_OK;
}

void Triangle::onDestroyDevice()
{
}

void Triangle::onFrameRender( double fTime, float fElapsedTime )
{
}

4. Hozzuk létre a rajzoláshoz szükséges dolgokat: FVF leírás, FVF struktúra, vertex buffer.

class Triangle :
    public DXFrame
{
//...
protected:
    // FVF leíró:
    enum {FVF = D3DFVF_XYZ | D3DFVF_DIFFUSE};

    // FVF struktúra
    struct VERTEXFORMAT
    {
        D3DXVECTOR3 v;
        D3DCOLOR col;
    };

    // Vertex Buffer
    IDirect3DVertexBuffer9* _vbuffer;
};

5. A vertex buffer-t inicializáljuk 0-ra, és már most írjuk meg a felszabadító kódot!

Triangle::Triangle(void) : _vbuffer(0)
{
}
//...
void Triangle::onDestroyDevice()
{
    SAFE_RELEASE(_vbuffer);
}

6. Adjuk meg a kirajzolandó csúcsok pozícióját és színét egy tömbben az onCreateDevice-ban!

HRESULT Triangle::onCreateDevice()
{
    VERTEXFORMAT vs[3];

    vs[0].v = D3DXVECTOR3(0,0.5f,0);
    vs[1].v = D3DXVECTOR3( 0.5f,-0.5f,0);
    vs[2].v = D3DXVECTOR3(-0.5f,-0.5f,0);

    vs[0].col = vs[1].col = vs[2].col =  D3DXCOLOR(0.5f, 0.6f, 0.9f, 1);

7. Hozzuk létre, és töltsük fel a vertex buffert!

    HRESULT hr;
    V( _device->CreateVertexBuffer( sizeof(VERTEXFORMAT) * 3, 0, FVF,
                                    D3DPOOL_MANAGED, &_vbuffer, 0));
    void * vdata;
    V( _vbuffer->Lock(0, sizeof(VERTEXFORMAT) * 3, &vdata, 0) );
    CopyMemory(vdata, vs, sizeof(VERTEXFORMAT) * 3);
    _vbuffer->Unlock();

    return D3D_OK;
}

8. Rajzoljuk ki a vertex buffer tartalmát az onFrameRender-ben!

void Triangle::onFrameRender( double fTime, float fElapsedTime )
{
    _device->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,
                    D3DCOLOR_XRGB(107, 63, 160), 1, 0);

    if ( SUCCEEDED(_device->BeginScene()) )
    {
        _device->SetStreamSource(0, _vbuffer, 0, sizeof(VERTEXFORMAT));
        _device->SetFVF(FVF);
        _device->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1);

        _device->EndScene();
    }
}

* Miért fekete a háromszög?

A még nem adtunk meg semmit, ami a helyes megvilágítás szükséges lenne (fényforrás, felületi normálisok, stb.), ezért jelenítí meg a DirectX feketén a háromszöget.

Kapcsoljuk ki a viláítást, még a onCreateDevice-ban!

_device->SetRenderState(D3DRS_LIGHTING, FALSE);

A render state beállítások lost device esetén elveszhetnek, ezért érdemes ezt a függvényhívást az onCreateDevice helyett az onResetDevice-ba tenni.