Számítógépes grafika DirectX 2. gyakorlat. Emlékeztető Előző órán áttekintettük a szükséges WinAPI- s alapokat Illetve röviden beletekintettünk a félév.

Slides:



Advertisements
Hasonló előadás
Manapság a számítógép legfontosabb kiviteli egysége (perifériája) a televíziókhoz hasonló számítógép- képernyő vagy monitor. A monitort egy kábel köti.
Advertisements

Számítógépes grafika DirectX 2. gyakorlat. Emlékeztető  Előző órán szó volt a COM modellről, amiben az objektumok eljárásait az általuk megvalósított.
OpenGL 2. gyakorlat Hapák József
2010/2011 ősz Klár Gergely  A DirectX egy alacsonyszintű API gyűjtemény  Multimédiás alkalmazások futtatására, írására szolgál  Részei.
C++ programozási nyelv Gyakorlat hét
Összetett adattípusok 8/b tétel
FRAME-k (keretek). FRAME-k A frame-ek (keretek) segítségével a képernyőt felosztva egyszerre jeleníthetünk meg több webes dokumentumot a képernyőn. Fejlec.html.
Programozás III KOLLEKCIÓK 2..
1 Hernyák Zoltán Programozási Nyelvek II. Eszterházy Károly Főiskola Számítástudományi tsz.
© Kozsik Tamás Beágyazott osztályok A blokkstrukturáltság támogatása –Eddig: egymásba ágyazható blokk utasítások Osztálydefiníciók is egymásba.
13.a CAD-CAM informatikus
Készítette: Kecskés Imre
Dinamikus tömbök.
Csala Péter ANDN #4. 2 Tartalom  C# - ban előre definiált típusok  Változók  Változókkal műveletek  Elágazás  Ciklus.
Bevezetés a Java programozásba
7. előadás (2005. április 12.) Láncolt lista File kezelés 1.
5. előadás (2005. március 22.) Függvények definíciója, deklarációja, hívása Enumerációs adattípus 1.
4. előadás (2005. március 8.) Pointerek Pointer aritmetika
Programozás II. 3. Gyakorlat C++ alapok.
UNIVERSITY OF SZEGED D epartment of Software Engineering UNIVERSITAS SCIENTIARUM SZEGEDIENSIS Programozás II. 6. Gyakorlat const, static, dinamikus 2D.
Fejlett Programozási Technológiák II. Világos Zsolt 12. gyakorlat.
Tömbök ismétlés Osztályok Java-ban Garbage collection
A CLIPS keretrendszer CLIPS "C" Language Integration Production System.
Mutatók, tömbök, függvények
C A C nyelv utasításai. Ismétlés Utasítások csoportosítása.
Grafika a programban Készítette: Pető László. Bevezetés Valójában nem a célobjektumra rajzolunk, hanem annak festővászon területére (canvas). Csak olyan.
A körlevél készítésének menete
A C++ programozási nyelvSoós Sándor 1/15 C++ programozási nyelv Gyakorlat hét Nyugat-Magyarországi Egyetem Faipari Mérnöki Kar Informatikai Intézet.
A C++ programozási nyelvSoós Sándor 1/12 C++ programozási nyelv Gyakorlat - 8. hét Nyugat-Magyarországi Egyetem Faipari Mérnöki Kar Informatikai Intézet.
Számítógépes grafika OpenGL 1. gyakorlat.
C++ Alapok, első óra Elemi típusok Vezérlési szerkezetek
Gútai Magyar Tannyelvű Magán Szakközépiskola, Szlovákia
Webszerkesztés Stíluslapok (CSS).
Számítógépes Grafika 2. gyakorlat Programtervező informatikus (esti) 2011/2012 őszi félév.
Számítógépes grafika 3. gyakorlat.
Számítógépes Grafika Programtervező informatikus (esti)‏ Textúrázás.
Számítógépes Grafika Megvilágítás Programtervező informatikus (esti)‏
2008/2009 tavasz Klár Gergely  A DirectX egy alacsonyszintű API gyűjtemény  Multimédiás alkalmazások futtatására, írására szolgál 
Turbo Pascal 11..
Hernyák Zoltán Programozási Nyelvek II.
AAO Csink László november.
DirectX9 empty project Szécsi László. Visual Studio Első indításkor C++ választása.
Environment mapping Szécsi László. Új osztály: Lab3EnvMap copy&paste: Lab2Trafo.h -> Lab3EnvMap.h copy&paste: Lab2Trafo.cpp -> Lab3EnvMap.cpp copy&paste:
DirectX9 empty project Szécsi László. Project létrehozása Microsoft DirectX SDK (August 2008) telepítése Start Menu \ Microsoft DirectX SDK (August 2008)\
Pipeline Vertex shader Fragment shader. Transzformációs modul A modellünket a saját koordinátarendszerében adjuk meg Azonban a saját koordinátarendszerükben.
Számítógépes grafika DirectX 5. gyakorlat. Emlékeztető Háromdimenziós alapok befejezése Textúrázás.
OpenGL 4 shaderek, GLSL Valasek Gábor
Java programozási nyelv Metódusok
HF MINTA 2012/2013. ősz. HF Minta  Objektum-orientált program  „Adatvezérelt” alkalmazás írása  Fájl kezelés (olvasás, írás)  Menü készítése  5-6.
1 Objektum orientált programozás Öröklődés: többszörös öröklődés, konstruktorok, destruktorok, overloading Nagy Szilvia.
2. gyakorlat DirectX 2007/2008 tavasz Klár Gergely
Objektum orientált programozás
A Monitor. AszámítógépAszámítógép legfontosabb kiviteli egysége (perifériája) a televíziókhoz hasonló számítógép-képernyő vagy monitor. A monitort egy.
Adatbáziskezelés. Adat és információ Információ –Új ismeret Adat –Az információ formai oldala –Jelsorozat.
Függvények a C nyelvben 1 Függvényeket a következő esetekben szokás írni: Ha ugyanazt a tevékenységet többször is el kell végeznünk ugyanolyan típusú,
CUDA C/C++ programozás CUDA C bevezetés A segédanyag készítése a TÁMOP A/ Nemzeti Kiválóság Program című kiemelt projekt keretében.
Memóriakezelés feladatok Feladat: 12 bites címtartomány. 0 ~ 2047 legyen mindig.
Számítógépes grafika gyakorlat: DirectX 2007/2008 tavasz Klár Gergely
Számítógépes Grafika OpenGL 4 shaderek, GLSL. OpenGL 4 A következő programozható fázisok vannak a 4.x-es OpenGL-ben: Vertex shader Tesselation control.
Objektum orientált programozás 4. Mutatók, típusok és struktúrák Nagy Szilvia.
Számítógépes grafika DirectX 7. gyakorlat. Emlékeztető Múlt órán mesheket és transzformációkat használtunk Most primitívkirajzoláshoz nézünk meg egy hasznos.
Függvények, mutatók Csernoch Mária. Függvények függvény definíciója az értelmezési tartomány tetszőleges eleméhez hozzárendel egy értéket –függvény helyettesítési.
Krizsán Zoltán, iit C# osztályok 2 Adattagok  Osztály hatáskörben definiált változó.  Formája: [attribútum] [módosító] típus azonosító [=kezdő érték][,
Neumann János Informatikai Kar
a programegységek között
OpenGL 2. gyakorlat Valasek Gábor
Neumann János Informatikai Kar
A CLIPS keretrendszer
OpenGL II.
CUDA – OpenGL.
Előadás másolata:

Számítógépes grafika DirectX 2. gyakorlat

Emlékeztető Előző órán áttekintettük a szükséges WinAPI- s alapokat Illetve röviden beletekintettünk a félév során használandó keretrendszerbe

Tartalom 1. DirectX Graphics felépítése 2. Első DirectX-es alkalmazás 3. Háromszög kirajzolás

DirectX Graphics felépítése Ezt írjuk mi A programunkban a Direct3D API által biztosított függvényeket hívhatjuk Amiket lefordítja a grafikus kártya driverének „nyelvére” az ún. HAL device

DirectX Graphics felépítése Az alkalmazásunkban a Direct3D API függvényeit hívjuk. Ezek végrehajtása lehet  Hardveresen gyorsított: ilyenkor a HAL-on keresztül mennek a hívások  Szoftveresen megvalósított: azaz a CPU-val számítunk mindent, GPU felhasználása nélkül

Hardware Abstraction Layer A HAL-nak köszönhetően vonatkoztathatunk el a tényleges gépi konfigurációtól Rajta keresztül történik a kommunikáció a hardverrel Megtudhatjuk például tőle, hogy milyen szolgáltatásokat valósít meg az aktuális hardver a D3D felületén keresztül elérhetőkből

Hardware Abstraction Layer Ugyanis csak azokat a dolgokat tudja „lefordítani” a videókártya nyelvére ez a réteg, amiket meg is valósítanak az adott hardverben Mivel közvetlenül használja a hardver nyújtotta szolgáltatásokat (a DDI-n keresztül), ezért a hardver gyártók fejlesztik (amit ki is használnak, ld. 3D Mark botrányok)

Mi van a nem megvalósított szolgáltatásokkal? Úgynevezett pluggable software device- okban minden szoftveresen meg van valósítva Ilyen például az SDK-val jövő Reference Rasterizer Ami tehát az aktuális DX verzió összes szolgáltatását megvalósítja Pontosságra és nem sebességre optimalizált

Mi van a nem megvalósított szolgáltatásokkal? Amikor létrehozzuk a Device-ot (ld. később) megadhatjuk, hogy HAL-on vagy Reference Rasterizer-en keresztül dolgozzon-e Illetve ha van, egyéb, harmadik fél által gyártott psd-vel

Direct3D Object Ez az első DX9-es objektum, amit az alkamazásunk létre kell, hogy hozzon és az utolsó, amit meg kell, hogy semmisítsen A számítógépben elérhető, megjelenítéshez szükséges hardvereket kérdezhetjük le rajta keresztül (monitorok felbontásai, videokártyák képességei stb.)

Direct3D Device A DirectX renderelő komponense, rajta keresztül rajzolunk A kirajzoláshoz szükséges állapotokat is tárolja A D3D Object-en keresztül hozzuk létre, miután kiválasztottuk az igényeinket kielégítő, megjelenítéshez használt eszközöket (konkrét monitor, videokártya)

Direct3D Device Két fajtája van:  HAL device: hardveresen gyorsított D3D implementáció  REF device: szoftveres D3D implementáció

Direct3DDevice A létrehozandó eszköz megjelenítési tulajdonságait egy D3DPRESENT_PARAMETERS típusú struktúra kitöltésével adhatjuk meg Itt állíthatjuk be a felbontást és egyebeket

Mi jelenik meg a képernyőn? Egy kép (IDirect3DSurface9) a memóriából (grafikus kártyáéban vagy a rendszerében) DX-ben kitüntetett „képek”:  Front Buffer: amikor frissít a monitor, a grafikus kártya a front buffer tartalmát küldi át neki megjelenítésre. Nem írunk rá programból.  Back Buffer: szintén négyszögletes kép, őt írjuk. Megjelenítéskor ezek váltogatják egymást (double bufferingnél) Miért nem a Front Buffert írjuk?

„Screen Tearing”

Swap Chain Ha frissítés közben változtatnánk a front buffert, akkor a képernyő egy (felső) részén a régebbi kép(rész), az alsón pedig az újabb lenne (tearing) Ezt többféle módon is el lehet kerülni:  a vertical retrace-t megvárni  back buffering: nem a megjelenített felületre rajzolunk, hanem egy back bufferre, amit majd cserélünk a front bufferrel. Flipping: a back buffer és a front buffer felcserélése A swap chain egy vagy több back buffer lánca.

Vertical retrace

Swap chain példa kettő darab offscreen surface-szel

Flipping A grafikus kártya egyszerűen egy memória hivatkozással tartja számon az aktuális front buffert, ezért egy pointer átállítással megoldható a flip. Presentation interval: a flipping időbeli módját határozza meg  DEFAULT: megvárja flip előtt a vsync-et  IMMEDIATE: nem várja meg a vsync-et  stb. Továbbá az is megadható, hogy miként váljon az eddigi front buffer back bufferré (törlődjön a tartalma, maradjanak az adatok stb.)

Swap Chain és a D3D Device A swap chain a Direct3D Device egy belső adattagja Minden device-nak legalább egy swap chain- je van Általában minden swap chainhez egy-egy színtérbeli nézetet társítunk A front buffer azonban nem érhető el, a device belső tulajdonságának tekintjük

Tartalom 1. DirectX Graphics felépítése 2. Első DirectX-es alkalmazás 3. Háromszög kirajzolás

1. példa Ablakos DirectX-es példaprogram

Első DX-es program Innen tölthető le: Ablak.zip Ablak.zip

Mit is kell tennünk? 1. Létre kell hoznunk egy Direct3D objektumot 2. Majd egy Direct3D Device objektumot 3. Rajzolni valamit a képernyőre az előbbin keresztül 4. Megszüntetni a Direct3D Device objektumot 5. Végül megszüntetni a Direct3D objektumot

A program váza Ablak létrehozása Direct3D objektum létrehozása Direct3D Device objektum létrehozása Rajzolás Direct3D objektum megsemmisítése Direct3D Device megsemmisítése Ablak törlése Inicializálás Futás „Takarítás”

A program váza InitWindow InitD3DRenderCleanUpD3D CleanUpWindow

CDXAppBase elvégzi nekünk A program váza InitWindow InitD3DRenderCleanUpD3D CleanUpWindow

CMyDXApp Ezeket az eljárásokat viszont már változtatjuk. A program váza InitWindow InitD3DRenderCleanUpD3D CleanUpWindow

CDXApp.h

CDXMyApp::CDXMyApp CDXMyApp::CDXMyApp(void) { }

CDXMyApp::~CDXMyApp CDXMyApp::~CDXMyApp(void) { }

HRESULT CDXMyApp::InitD3D() { m_pD3D = Direct3DCreate9( D3D_SDK_VERSION ); if (!m_pD3D) { return E_FAIL; }... DXAppBase.h-ban: class CDXAppBase {... protected: LPDIRECT3D9 m_pD3D;... };

Direct3D objektum létrehozása A D3D_SDK_VERSION az egyetlen megengedett paramétere a Direct3DCreate9-nak Sikeres végrehajtás után a visszatérési érték egy mutató lesz a létrehozott objektum IDirect3D9 interfészére A Direct3D objektum az első amit létrehozunk és az utolsó amit megsemmisítünk

Direct3D objektum létrehozása Rajta keresztül ellenőrizhetjük, hogy milyen képességekkel rendelkezik az aktuális hardver De csak a létrehozásának pillanatában is már a rendszerhez csatlakoztatott megjelenítőket kezeli Rajta keresztül hozzuk létre a Direct3D Device objektumot

HRESULT CDXMyApp::InitD3D()... ZeroMemory(&m_d3dpp, sizeof(m_d3dpp) ); m_d3dpp.BackBufferWidth= 800; m_d3dpp.BackBufferHeight= 600; m_d3dpp.BackBufferFormat= D3DFMT_UNKNOWN; m_d3dpp.Windowed= TRUE; m_d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;... DXAppBase.h-ban: class CDXAppBase {... protected: D3DPRESENT_PARAMETERS m_d3dpp;... }; void ZeroMemory( PVOID Destination, SIZE_T Length ); Destination: a cím, ahonnan kezdve 0-val töltjük fel a memóriát Length: a 0-val feltöltendő memóriaterület nagysága bájtban

Direct3D Device objektum létrehozása D3DPRESENT_PARAMETERS: A megjelenítés paramétereit adhatjuk meg vele (felbontás, teljes képernyős vagy ablakos alkalmazás-e stb.) D3DPRESENT_PARAMETERS d3dpp; Nullázzunk le minden értéket: ZeroMemory( &d3dpp, sizeof(d3dpp) );

D3DPRESENT_PARAMETERS typedef struct D3DPRESENT_PARAMETERS {… UINT BackBufferWidth, BackBufferHeight;…} A háttérpuffer (back buffer) felbontása. Teljes képernyős módban ennek az adott videokártyán és monitoron használható különböző megjelenítési módok egyikének szélességével és magasságával kell megegyeznie, ablakosan nem szükséges. Ablakos alkalmazásnál ha 0, akkor az ablak kliensterületének megfelelő érték kerül oda.

D3DPRESENT_PARAMETERS typedef struct D3DPRESENT_PARAMETERS {... D3DSWAPEFFECT SwapEffect;...} A front buffer back bufferré válásának módja:  D3DSWAPEFFECT_DISCARD: törlődik a tartalma  D3DSWAPEFFECT_FLIP: több back bufferből álló swap chain-nél használják, felcseréli a front buffert a soron következő back bufferrel.  D3DSWAPEFFECT_COPY: csak egy back buffer használata esetén választhatjuk.

HRESULT CDXMyApp::InitD3D()... HRESULT hr = m_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, m_hWnd, D3DCREATE_HARDWARE_VERTEXPROCESSING, &m_d3dpp, &m_pD3DDevice);...

IDirect3D9::CreateDevice HRESULT CreateDevice( UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow, DWORD BehaviorFlags, D3DPRESENT_PARAMETERS * pPresParams, IDirect3DDevice9 ** ppRetDeviceInterface ); Adapter: a használni kívánt megjelenítő eszköz sorszáma, D3DADAPTER_DEFAULT a rendszer elsődleges megjelenítője

IDirect3D9::CreateDevice HRESULT CreateDevice( UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow, DWORD BehaviorFlags, D3DPRESENT_PARAMETERS * pPresParams, IDirect3DDevice9 ** ppRetDeviceInterface ); DeviceType: a device típusa, a D3DDEVTYPE enum egy értékét várja (D3DDEVTYPE_HAL, D3DDEVTYPE_REF stb).

IDirect3D9::CreateDevice HRESULT CreateDevice( UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow, DWORD BehaviorFlags, D3DPRESENT_PARAMETERS * pPresParams, IDirect3DDevice9 ** ppRetDeviceInterface ); hFocusWindow: annak az ablaknak a leírója, ami figyelmezteti a Direct3D-t, hogy az alkalmazás háttérbe került Ablakos módban lehet NULL, ha a d3dpp hDeviceWindow adattagjának értéke érvényes.

IDirect3D9::CreateDevice HRESULT CreateDevice( UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow, DWORD BehaviorFlags, D3DPRESENT_PARAMETERS * pPresParams, IDirect3DDevice9 ** ppRetDeviceInterface ); BehaviorFlags: egyéb opciók a device létrehozásához (hardveres vagy szoftveres vertexfeldolgozás stb.)

IDirect3D9::CreateDevice HRESULT CreateDevice( UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow, DWORD BehaviorFlags, D3DPRESENT_PARAMETERS * pPresParams, IDirect3DDevice9 ** ppRetDeviceInterface ); pPresParams: lásd korábban

IDirect3D9::CreateDevice HRESULT CreateDevice( UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow, DWORD BehaviorFlags, D3DPRESENT_PARAMETERS * pPresParams, IDirect3DDevice9 ** ppRetDeviceInterface ); ppRetDeviceInterface: a paraméterben kapott címen lévő mutató a létrehozott Direct3D Device objektum interfészére fog mutatni.

HRESULT CDXMyApp::InitD3D()... if( FAILED( hr ) ) { return E_FAIL; } return S_OK; }

HRESULT CDXMyApp :: InitDeviceObjects() Ide majd az eszközmemóriába kerülő erőforrások létrehozásának kódja kerül Egyelőre csak ennyi: HRESULT CDXMyApp:: InitDeviceObjects() { return S_OK; }

VOID CDXMyApp :: ReleaseDeviceObjects Az eszközmemóriába kerülő erőforrások felszabadításának kódja kerül ide Mivel most nincs ilyen, ez is üres: VOID CDXMyApp:: ReleaseDeviceObjects() { }

VOID CDXMyApp :: CleanUpD3D() { if (m_pD3DDevice) { m_pD3DDevice->Release(); m_pD3DDevice = NULL; } if (m_pD3D) { m_pD3D->Release(); m_pD3D = NULL; } }

VOID CDXMyApp :: FrameUpdate() A kirajzolás a Render függvényben fog történni A FrameUpdate()-ben a kirajzolás logikai részét meghatározó műveleteket végezzük majd el (modellek mozgatása, különböző transzformációk elvégzése stb.) Egyelőre ez is üres

VOID CDXMyApp ::Render() { if (!m_pD3DDevice) return; if( SUCCEEDED(m_pD3DDevice-> BeginScene() ) ) {... Ha a device pointer valamiért NULL, akkor még ne rendereljünk Bejelentjük, hogy rajzolni fogunk, jelezzük az eszköz felé (vagyis az általa reprezentált grafikus megjelenítésben részt vevő hardverek felé), hogy elkezdjük a színtér kirajzolását.

VOID CDXMyApp ::Render()... m_pD3DDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,0), 1.0f, 0); }

IDirect3DDevice9::Clear HRESULT Clear( DWORD Count, CONST D3DRECT * pRects, DWORD Flags, D3DCOLOR Color, float Z, DWORD Stencil ); Count: amennyiben több téglalap alakú területen szeretnénk törölni, akkor itt a téglalapok számát kell megadni – ha a pRects!=0, akkor ez sem lehet 0

IDirect3DDevice9::Clear HRESULT Clear( DWORD Count, CONST D3DRECT * pRects, DWORD Flags, D3DCOLOR Color, float Z, DWORD Stencil ); pRects: A törlendő téglalapokat tartalmazó tömbre mutató pointer. Ha NULL, akkor a megjelenítési mező egészét töröljük.

IDirect3DDevice9::Clear HRESULT Clear( DWORD Count, CONST D3DRECT * pRects, DWORD Flags, D3DCOLOR Color, float Z, DWORD Stencil ); Flags: melyik felületet(eket) (surface) töröljük:  D3DCLEAR_TARGET: azt, ahová renderelünk  D3DCLEAR_ZBUFFER  D3DCLEAR_STENCIL Bináris vagy (|) karakterrel többet is választhatunk

IDirect3DDevice9::Clear HRESULT Clear( DWORD Count, CONST D3DRECT * pRects, DWORD Flags, D3DCOLOR Color, float Z, DWORD Stencil ); Color: ha a renderelési felületet is töröljük, akkor ezzel a színnel fogjuk feltölteni. D3DCOLOR_* makrók (* lehet XRGB, ARGB stb.)

IDirect3DDevice9::Clear HRESULT Clear( DWORD Count, CONST D3DRECT * pRects, DWORD Flags, D3DCOLOR Color, float Z, DWORD Stencil ); Z: ha a Z-buffert is töröljük, akkor ez az érték kerül bele a korábbiak helyére A Z-bufferben az értékek 0 és 1 közötti lebegőpontos számok Az adott pixelben látható pont távolsága

IDirect3DDevice9::Clear HRESULT Clear( DWORD Count, CONST D3DRECT * pRects, DWORD Flags, D3DCOLOR Color, float Z, DWORD Stencil ); Stencil: ha a Stencil buffert is töröljük, akkor pedig ez az érték kerül bele a korábbiak helyére 0-tól 2^n-1 –ig terjedhet az értéke, ahol n a stencil buffer bitmélysége

VOID CDXMyApp ::Render()... FrameUpdate(); m_pD3DDevice->EndScene(); } m_pD3DDevice->Present( NULL, NULL, NULL, NULL); }

Feladat Változtassuk a kirajzolási színt az idő függvényében! timeGetTime(): a Windows indulása óta eltelt milliszekundumok számát adja vissza (DWORD-ben)

Tartalom 1. DirectX Graphics felépítése 2. Első DirectX-es alkalmazás 3. Háromszög kirajzolás

Program Ezt töltsük le: zip zip

Primitívek A 3D-s modelljeinket primitívekből, építőelemekből rakjuk össze Egy 3D-s primitív csúcspontokból áll, amik egyetlen térbeli entitást alkotnak Például pontok, poligonok stb.

Pipeline Vertex shader Fragment shader

Direct3D primitívjei Ha tudjuk, hogy milyen típusú primitívet szeretnénk rajzolni, akkor onnantól már csak a pontjait kell megadni Ugyanis a 3D-s entitást a primitívtípusból és az azt jellemző pontösszekötési szabályból a csúcspontok már meghatározzák

Direct3D primitívjei Legyenek adottak a következő csúcsok: struct CUSTOMVERTEX { float x,y,z;}; CUSTOMVERTEX Vertices[] = { {-5.0,-5.0,0.0}, {0.0,5.0,0.0}, {5.0,-5.0,0.0}, {10.0,5.0,0.0}, {15.0,-5.0,0.0}, {20.0,5.0,0.0} };

Direct3D primitívjei Pontlisták A bemeneti csúcspontokat különálló pontokként rendereli le Anyagjellemzőket és textúrákat rendelhetőek hozzájuk d3dDevice->DrawPrimitive( D3DPT_POINTLIST, 0, 6 );

Direct3D primitívjei Szakaszlisták Különálló szakaszok, 2*n és 2*n+1-edik pont között Páros számú pontot kell megadni d3dDevice->DrawPrimitive( D3DPT_LINELIST, 0, 3 );

Direct3D primitívjei Linestrip Csatlakozó szakaszsorozat, legalább két pontot meg kell adni d3dDevice->DrawPrimitive( D3DPT_LINESTRIP, 0, 5 );

Direct3D primitívjei Háromszög lista Különálló háromszögek listája, 3*n pontot kell megadni d3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, 2 );

Direct3D primitívjei Háromszög strip Egy oldalban csatlakozó háromszögek listája Legalább 3 pontot kell megadni, utána minden újabb pont az előző kettővel együtt alkot egy háromszöget d3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 4);

Direct3D primitívjei Háromszög „legyező” (fan) Hasonló mint az előző, csak mindegyik háromszögnek van egy közös pontja d3dDevice->DrawPrimitive( D3DPT_TRIANGLEFAN, 0, 4 );

Vertexek A csúcspontokat (vertexeket) vertex bufferekben tároljuk A vertex bufferek pedig erőforrások

Erőforrások DirectX-ben Minden erőforrás bír a következő tulajdonságokkal:  Usage: felhasználási mód, például textúra, vagy renderelési célpont stb.  Format: adatformátum (pl. surface-nél bitmélység)  Pool: a memóriatípus, ahová kerül  Type: típus, vertex buffer, render cél stb.

Erőforrások DirectX-ben Usage Az alkalmazásnak már az erőforrás létrehozásakor meg kell mondania, hogy milyen módon fogja azt használni Lehetséges értékeit ld. D3DUSAGED3DUSAGE Például pontsprite-okat tartalmazó vertex (és index) buffernek D3DUSAGE_POINTS-ot kell megadnia D3DUSAGE_WRITEONLY-val azt mondjuk, hogy csak írni fogjuk az adott vertex buffert. Ez lényegesen gyorsíthat!

Erőforrások DirectX-ben Format Az erőforrás tárolási formátumát adja meg D3DFORMAT-ban találhatóak a lehetséges értékei D3DFORMAT Az erőforrás típusától függnek a megengedett értékek Mások tehát back bufferekhez, bufferekhez, megjelenítési felületekhez stb.

Erőforrások DirectX-ben Pool Ez határozza meg, hogy az adott erőforrás hová kerül (videókártya-memória, rendszermemória stb.) Nem változtatható meg futás során Értékeihez ld. D3DPOOLD3DPOOL

Memóriaosztályok 1/2 D3DPOOL_DEFAULT: az adott erőforrás a felhasználása szerinti legjobb helyen kerül tárolásra. Ez túlnyomórészt a videókártya memóriája. D3DPOOL_MANAGED: amint szükséges a videókártya által is elérhető memóriába másolódnak az így definiált erőforrások. Emellett mindig van egy másolat róluk a rendszermemóriában. Nem kell helyreállítani őket lost device-nál.

Memóriaosztályok 2/2 D3DPOOL_SYSTEMMEM: rendszermemória (RAM), általában az így elhelyezett dolgok nem érhetőek el a Direct3D Device által. Lost device nem érinti őt sem. D3DPOOL_SCRATCH: hasonló mint a fenti, de rájuk nem vonatkoznak a device képességeiből fakadó megkötések (méret, formátum stb.). Device nem érheti el őket.

Erőforrások DirectX-ben Type A típus futásidőben derül ki az erőforrást létrehozó eljárástól függően, implicit módon Pl. a IDirect3DDevice9::CreateTexture textúrát hoz létre

Erőforrások DirectX-ben Műveletek erőforrásokkal A színtér kirajzolása közben különböző műveleteket végzünk az erőforrásainkon Pl. létrehozzuk őket (device-on keresztül vagy D3DXCreateXXX-el,...) A tárolt adatok elérését lock-nak hívjuk Például:  textúra képpontjainak elérése: IDirect3DTexture9::LockRect  Vertex bufferek csúcsainak elérése: IDirect3DVertexBuffer9::Lock

Erőforrások DirectX-ben Lock Egy erőforrás lock-olása azt jelenti, hogy hozzáférést biztosítunk a CPU-nak a tárolt adatokhoz A lock-olás során különböző flag-ek beállításával mondjuk meg, hogy miként szeretnénk használni a megszerzett adatokat:  D3DLOCK_DISCARD  D3DLOCK_READONLY ...

Erőforrások DirectX-ben Lock Egy erőforráson egyszerre csak egy lock lehet A lockolás visszaad egy struktúrát is, ami azt jellemzi, hogy miként tárolódik fizikailag az adott erőforrás a memóriában

Erőforrások DirectX-ben Unlock Miután elvégeztük a dolgunkat a bufferrel Unlock-olni kell!

Erőforrások DirectX-ben Vertex bufferek IDirect3DVertexBuffer9 interfész Vertexadatokat tartalmazó memóriaterület A benne tárolt csúcsok transzformálhatóak, világíthatóak stb. De tárolhatunk már eleve transzformált pontokat (RHW) Egy vertex buffert a képességei írnak le  amiket egy D3DVERTEXBUFFER_DESC struktúra ad meg

Flexible Vertex Format Nem akarunk mindig minden csúcsponttal minden lehetséges dolgot megcsinálni Vannak olyan pontok amikre pl. csak egy textúrát akarunk feszíteni, esetleg nem akarjuk megvilágítani Az FVF segítségével mondhatjuk meg, hogy az aktuális vertex bufferben tárolt csúcsokkal mit szeretnénk kezdeni

Flexible Vertex Format D3DFVF_XYZ: 3D koordináták D3DFVF_XYZRHW: transzformált képpont D3DFVF_NORMAL: normálvektora is lesz (megvilágításhoz) D3DFVF_DIFFUSE, D3DFVF_SPECULAR : csúcs színe...

Flexible Vertex Format Létrehozunk egy struktúrát a programunk számára a csúcspont adatait leírni, illetve egy #define-al megadjuk Direct3D-nek a használt FVF tulajdonságokat Fontos, hogy a struct-ban az adattagok sorrendje a D3DFVF_... konstansok sorrendjében kövesse egymást Tehát általában pozíció, normális, szín, textúrakoordináták sorrendben jöjjenek

Flexible Vertex Format struct CUSTOMVERTEX { FLOAT x, y, z; DWORD color; }; #define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE)

Vertex Buffer használata - létrehozás Először a geometriánkat kell meghatároznunk  Ez a rendszermemóriában történik, saját vertex struktúrából felépített tömb segítségével Létrehozzuk a szükséges méretű VB-t (a Device-szon keresztül) Feltöltjük (lock-oljuk) a VB-t = a rendszermemóriából a VB memóriaosztályának megfelelő memóriába másolunk

Vertex Buffer használata - kirajzolás A sikeres BeginScene() eljáráshívás után:  Be kell állítani az FVF-ünket (SetFVF)  A VB bufferünket vertex forrássá (SetStreamSource)  Kirajzolni a DrawPrimitive-vel

Új adattag class CDXVerticesApp : public CDXAppBase {... private: LPDIRECT3DVERTEXBUFFER9 m_pVB;

FVF deklaráció DXVerticesApp.cpp struct VERTEX { D3DXVECTOR3 P; DWORD c; }; static const DWORD FVF = D3DFVF_XYZ | D3DFVF_DIFFUSE; A programunkban az eltárolt csúcspontokat így látjuk, ezeken az adattagokon keresztül A videókártya számára ezzel a kifejezéssel mondjuk meg, hogy a vertex bufferben eltárolt adatok csúcspontelemei milyen attribútumait írják le egy-egy pontnak

Mit fogunk tenni? Létrehozunk egy 3 elemű tömböt aminek az elemei VERTEX típusúak Létrehozunk egy vertex buffert Áttöltjük az adatokat a vertexbufferbe  ehhez a korábban említett lock – unlock segítségét vesszük igénybe A VB-t DEFAULT_POOL-ba tesszük

HRESULT CDXVerticesApp:: InitDeviceObjects() { Vertex vertices[] = { { D3DXVECTOR3(0,1,0), D3DCOLOR_XRGB(255,0,0) }, { D3DXVECTOR3(1,-1,0), D3DCOLOR_XRGB(0,255,0) }, { D3DXVECTOR3(-1,-1,0), D3DCOLOR_XRGB(0,0,255) }, };... x y z Szín RGB komponensekből

HRESULT CDXVerticesApp:: InitDeviceObjects()... HRESULT hr = m_pD3DDevice-> CreateVertexBuffer( sizeof(vertices), 0, FVF, D3DPOOL_DEFAULT, &m_pVB, NULL );...

IDirect3DDevice9::CreateVertexBuffer HRESULT CreateVertexBuffer( UINT Length, DWORD Usage, DWORD FVF, D3DPOOL Pool, IDirect3DVertexBuffer9** ppVertexBuffer, HANDLE* pSharedHandle ); Length: a buffer nagysága bájtban; legalább egy vertex tárolására elég kell, hogy legyen

IDirect3DDevice9::CreateVertexBuffer HRESULT CreateVertexBuffer( UINT Length, DWORD Usage, DWORD FVF, D3DPOOL Pool, IDirect3DVertexBuffer9** ppVertexBuffer, HANDLE* pSharedHandle ); Usage: lehet 0, egyébként ugyanaz mint eddig.

IDirect3DDevice9::CreateVertexBuffer HRESULT CreateVertexBuffer( UINT Length, DWORD Usage, DWORD FVF, D3DPOOL Pool, IDirect3DVertexBuffer9** ppVertexBuffer, HANDLE* pSharedHandle ); FVF: a használni kívánt FVF

IDirect3DDevice9::CreateVertexBuffer HRESULT CreateVertexBuffer( UINT Length, DWORD Usage, DWORD FVF, D3DPOOL Pool, IDirect3DVertexBuffer9** ppVertexBuffer, HANDLE* pSharedHandle ); Pool: memóriaosztály

IDirect3DDevice9::CreateVertexBuffer HRESULT CreateVertexBuffer( UINT Length, DWORD Usage, DWORD FVF, D3DPOOL Pool, IDirect3DVertexBuffer9** ppVertexBuffer, HANDLE* pSharedHandle ); ppVertexBuffer: kimeneti érték

IDirect3DDevice9::CreateVertexBuffer HRESULT CreateVertexBuffer( UINT Length, DWORD Usage, DWORD FVF, D3DPOOL Pool, IDirect3DVertexBuffer9** ppVertexBuffer, HANDLE* pSharedHandle ); pSharedHandle: legyen NULL

HRESULT CDXVerticesApp:: InitDeviceObjects()... VOID* pVertices; if( FAILED( m_pVB->Lock( 0, sizeof(vertices), &pVertices, 0 ) ) ) return E_FAIL; memcpy(pVertices, vertices, sizeof(vertices) ); m_pVB->Unlock();...

IDirect3DVertexBuffer9::Lock HRESULT Lock(UINT OffsetToLock, UINT SizeToLock, VOID ** ppbData, DWORD Flags ); OffsetToLock: a vertexbuffer kezdetéhez képest hány bájttal kezdődően lock-oljunk

IDirect3DVertexBuffer9::Lock HRESULT Lock(UINT OffsetToLock, UINT SizeToLock, VOID ** ppbData, DWORD Flags ); SizeToLock: hány bájtnyi vertexadatot lockoljunk

IDirect3DVertexBuffer9::Lock HRESULT Lock(UINT OffsetToLock, UINT SizeToLock, VOID ** ppbData, DWORD Flags ); ppbData: kimeneti érték, mutató egy memóriabuffer címére ahová a visszaadott adatokat másolja

IDirect3DVertexBuffer9::Lock HRESULT Lock(UINT OffsetToLock, UINT SizeToLock, VOID ** ppbData, DWORD Flags ); Flags: milyen típusú lock-ot akarunk:  D3DLOCK_DISCARD: üres adatokat kapunk vissza  D3DLOCK_READONLY: csak olvasni  stb.

HRESULT CDXVerticesApp:: ReleaseDeviceObjects() VOID CDXVerticesApp:: ReleaseDeviceObjects() { if( m_pVB != NULL ) { m_pVB->Release(); m_pVB = NULL; } }

VOID CDXVerticesApp::Render()... // színtér renderelése m_pD3DDevice-> SetStreamSource( 0, m_pVB, 0, sizeof(CUSTOMVERTEX));

IDirect3DDevice9::SetStreamSource HRESULT SetStreamSource( UINT StreamNumber, IDirect3DVertexBuffer9 * pStreamData, UINT OffsetInBytes, UINT Stride ); StreamNumber: a folyam sorszáma 0-tól maxstream-1-ig

IDirect3DDevice9::SetStreamSource HRESULT SetStreamSource( UINT StreamNumber, IDirect3DVertexBuffer9 * pStreamData, UINT OffsetInBytes, UINT Stride ); pStreamData: mutató egy vb interfészre

IDirect3DDevice9::SetStreamSource HRESULT SetStreamSource( UINT StreamNumber, IDirect3DVertexBuffer9 * pStreamData, UINT OffsetInBytes, UINT Stride ); OffsetInBytes: a stream és a vertexadat kezdete közti eltérés, bájtban

IDirect3DDevice9::SetStreamSource HRESULT SetStreamSource( UINT StreamNumber, IDirect3DVertexBuffer9 * pStreamData, UINT OffsetInBytes, UINT Stride ); Stride: mekkora „léptékben” olvassa ki a vertexbufferből az adatokat

VOID CDXVerticesApp::Render()... m_pD3DDevice-> SetFVF(D3DFVF_CUSTOMVERTEX); m_pD3DDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, 1);...

IDirect3DDevice9::SetFVF HRESULT SetFVF( DWORD FVF ); Az aktuális vertex streamhez használandó FVF-t adja meg

IDirect3DDevice9::DrawPrimitive HRESULT DrawPrimitive( D3DPRIMITIVETYPE PrimitiveType, UINT StartVertex, UINT PrimitiveCount ); PrimitiveType: milyen típusú primitív rajzolásához való vertexeket adtunk meg (pontlista, szakaszlista, stbÖ

IDirect3DDevice9::DrawPrimitive HRESULT DrawPrimitive( D3DPRIMITIVETYPE PrimitiveType, UINT StartVertex, UINT PrimitiveCount ); StartVertex: a vertexbuffer hányadik eleme legyen az első csúcspontja a primitívnek (azt, hogy egy csúcspont mekkora helyet foglal, a stride-ból tudja)

IDirect3DDevice9::DrawPrimitive HRESULT DrawPrimitive( D3DPRIMITIVETYPE PrimitiveType, UINT StartVertex, UINT PrimitiveCount ); PrimitiveCount: a kirajzolandó primitívek száma. Ld. primitíveknél, hogy ilyenkor mennyi csúcspontnak kell legalább lennie a vb-ben.

Feladat Rajzoljunk ki a képernyő közepére egy fél képernyő magas és fél képernyő széles négyszöget! Razjoljunk ki a képernyő közepére egy szabályos hétszöget!

Kiszervezés osztályba Hozzunk létre egy CMyTrig osztályt, ami magába foglalja  A kirajzolandó geometriát  A létrehozó és megsemmisítő függvényt  A frissítési és kirajzolási függvényt

CMyTrig.h #pragma once #include struct Vertex { D3DXVECTOR3 p; // pozíció DWORD c; // szín };

CMyTrig.h class CMyTrig { public: CMyTrig(void); ~CMyTrig(void); void InitDeviceObjects( LPDIRECT3DDEVICE9 _pD3DDevice ); void ReleaseDeviceObjects( LPDIRECT3DDEVICE9 _pD3DDevice ); void Update(); void Draw( LPDIRECT3DDEVICE9 _pD3DDevice ); void SetVertex(int i, D3DXVECTOR3 p, DWORD c);

CMyTrig.h private: void FillBuffer(); LPDIRECT3DVERTEXBUFFER9 m_pVB; static const DWORD FVF = D3DFVF_XYZ | D3DFVF_DIFFUSE; Vertex vertices[3]; };

Feladat Valósítsuk meg ezt az osztályt az előző kód alapján, annak megfelelően, ahogyan a zip kódban hasznljuk! zip