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.