DirectX (27.)

Dnes budeme upravovat dßle nßÜ engine, p°idßme nap°φklad t°φdu kamery. Ukß₧eme si, co se vlastn∞ na kame°e dß programovat. Kameru pak budeme pot°ebovat v p°φÜtφch lekcφch, kdy se budeme zab²vat optimalizaΦnφmi metodami nad terΘnem.

27.1. Kamera a t°φda XCamera

Do dneÜnφ lekce jsme m∞li pouze statickou kameru tj. dφvali jsme se stßle na stejnΘ mφsto v prostoru, jen jsme pohybovali objekty. Dnes p°idßme do projektu Display novou t°φdu, kterß se bude starat o kameru scΘny (zatφm budeme podporovat pouze jednu kameru). S touto kamerou p∙jdou provßd∞t vÜechny mo₧nΘ kousky: pohyb (translace) do vÜech sm∞r∙, rotace nebo t°eba naklßp∞nφ. To nßm bude prozatφm staΦit. V naÜich p°φkladech jsme zatφm pohybovat kamerou nepot°ebovali, tak proΦ novou t°φdu? Cφl p°φÜtφch lekcφ bude vysv∞tlit princip optimalizace metodou quadtree, kterou si ukß₧eme na terΘnu. Tento terΘn bude podobn² znßmΘmu terΘnu nap°φklad ze hry Transport Tycoon (i kdy₧ tam je ve skuteΦnosti 2D:). O tomto terΘnu si povφme vφce v dalÜφ lekci. Nynφ zp∞t ke kame°e.

Ji₧ vφme, ₧e kamera je v Direct3D urΦena n∞kolika vektory. Za prvΘ je t°eba urΦit jakß osa bude v 3D sv∞t∞ vertikßlnφ. ╚asto se volφ osa Y, ale jß rad∞ji volφm osu Z (p°ijde mi to logiΦt∞jÜφ). Dßle se definujφ dva body, pomocφ nich₧ je urΦen sm∞rov² vektor. Jeho sm∞rem "pozorujeme" scΘnu. Tohle jsme u₧ jsme pou₧ili v naÜem p°φkladu, ale nastavovali jsme vÜe "natvrdo" a toto nastavenφ neÜlo zm∞nit za chodu aplikace. Jak²m zp∙sobem zinicializujeme a nastavφme tyto parametry si ukß₧eme za chvilku.

Perspektiva

Dßle je t°eba peΦliv∞ nastavit perspektivu. I zde mßme n∞kolik parametr∙, navφc perspektivu m∙₧eme nastavit n∞kolika zp∙soby, z nich₧ ka₧d² pou₧ije jinΘ hodnoty. Definujeme tyto hodnoty:

T∞mito parametry vlastn∞ p°esn∞ definujeme jak²si Φty°st∞n. NejlΘpe je vÜe vid∞t na nßsledujφcφm obrßzku:

Vypadß to docela slo₧it∞, ale je to velice jednoduchΘ. VÜe co je za fialov²m obdΘlnφkem se u₧ nevykreslφ, tak₧e nap°φklad kdy₧ chceme vykreslit rozlehlou scΘnu, omezφme takto "nekoneΦn∞" velkΘ obzory a zv²Üφme FPS. Stejn∞ tak se nic nevykreslφ p°ed modr²m obdΘlnφkem. Nynφ budeme chtφt rotovat kolem bodu, na kter² se dφvßme. Budeme pohybovat pouze s tφmto bodem a potΘ dopoΦφtßme EyePoint. Zde budeme pot°ebovat dalÜφ obrßzek, kde je vid∞t v²poΦet sou°adnic obou bod∙:

Op∞t obrßzky vypadajφ pon∞kud slo₧it∞, tentokrßt °eÜenφ nemusφ b²t ihned vid∞t. V₧dy nejd°φve umφstφme LookAtPoint a potΘ z n∞ho dopoΦφtßme EyePoint (to platφ pro vÜechny sou°adnice). Vidφte, ₧e jsme pou₧ili t°i novΘ parametry scΘny: ·hel Z, co₧ je vlastn∞ ·hel sklopenφ kamery, dßle v²Üka kamery nad terΘnem a ·hel pohledu, co₧ je ·hel urΦujφcφ sm∞r pohledu. Pomocφ t∞chto parametr∙ m∙₧eme urΦit polohu obou bod∙.

Metoda billboard∙

U₧iteΦn²m atributem kamery by mohla b²t tzv. Billboard matice. Jist∞ jste si v n∞kterΘ h°e vÜimli, ₧e n∞kterΘ "3D" objekty vlastn∞ nejsou 3D, ale jsou to pouze 2D placky, na kter²ch je nanesenß textura. T∞chto jednoduch²ch objekt∙ m∙₧e b²t ve scΘn∞ °ßdov∞ mnohem vφc, ne₧ kdyby to byly skuteΦn∞ 3D objekty (meshe). Typick²m p°φkladem jsou stromy, kdy₧ jsou ud∞lßny Üikovn∞, laik ani nepoznß, ₧e je to billboard. Aby byl efekt co nejlepÜφ, je t°eba tyto placky natßΦet kolmo v∙Φi kame°e p°i ka₧dΘm pohybu kamery. A prßv∞ billboard matice je specißlnφ transformaΦnφ matice, kterou transformujeme vÜechny tyto objekty, aby se otoΦily kolmo ke kame°e. Tuto matici nenφ velk² problΘm vytvo°it, nebo¥ se jednß pouze o rotaΦnφ matici tak ve sm∞ru osy Z, aby se t∞leso ocitlo kolmo ke kame°e a my znßme sm∞rov² vektor kamery, tak₧e snadno spoΦφtßme ·hel, kter² naÜe placka svφrß prßv∞ s tφmto vektorem a p°ipoΦteme (p°φpadn∞ odeΦteme) 90 stup≥∙, Φφm₧ t∞leso natoΦφme proti kame°e. Podrobn∞ si postup ukß₧eme v p°φkladu za chvilku.

V DirectX SDK je p°φklad, kter² demonstruje billboarding - jmenuje se Billboard.

T°φda XCamera

Poj∩me se nynφ v∞novat t°φd∞ XCamera. Tento objekt bude internφ v knihovn∞ Display a bude jedineΦn² (povolφme tedy pouze jednu kameru v systΘmu). Ovlßdat kameru bude samoz°ejm∞ mo₧no i zvenku (jinak by to celΘ nem∞lo smysl). V₧dy kdy₧ budeme chtφt pohnout s kamerou, nastavφme sm∞r a rychlost pohybu. T°φda je relativn∞ jednoduchß. Budeme mφt metodu pro inicializaci, dalÜφ metodu, kterß spoΦφtß aktußlnφ pozice vÜech bod∙ a nastavφ matici pohledu a projekΦnφ matici. Tuto metodu budeme volat ka₧d² cyklus aplikace.

JeÜt∞ jedna poznßmka, tato kamera je urΦena pro pohyb nad komplexnφm terΘnem tj. kamera se m∙₧e pohybovat ve sm∞ru os X a Y. Umo₧≥uje p°iblφ₧enφ (Zoom) (tj. zkrßcenφ sm∞rovΘho vektoru), pohyb kamery nahoru a dol∙, naklßp∞nφ tj. zm∞na ·hlu Z a samoz°ejm∞ rotace tj. zm∞na ·hlu pohledu. Dßle bychom mohli p°idat funkci volnΘho letu (ovlßdanou nap°φklad pomocφ myÜky).

Nejd°φve nadefinujeme pßr konstant, urΦujφcφ parametry kamery (tyto parametry m∙₧ete podle pot°eby ud∞lat jako prom∞nnΘ).

#define _C_MAX_ROTATION_SPEED 5.0f
#define _C_MAX_ZOOMING_SPEED 5.0f
#define _C_MAX_SCROLLING_SPEED 20.0f
#define _C_MAX_ZANGLE_SPEED 2.0f

#define MAX_ZOOM 40
#define MIN_ZOOM 5

#define Z_ANGLE D3DX_PI / 2

#define MAX_Z_ANGLE D3DX_PI / 2
#define MIN_Z_ANGLE D3DX_PI / 7

const float NEAR_CLIP = 0.1f;
const float FAR_CLIP = 200.0f;
const float FOV = D3DX_PI / 4.0f;
const float ASPECT = 4.0f / 3.0f

Dßle uve∩me deklaraci t°φdy XCamera:

class DISPLAY_API XCamera
{

// D3D device object...
LPDIRECT3DDEVICE8 m_lpDevice;
//
// Camera bounds

int m_iMinPos;
int m_iMaxPos;
//
// Velocities in all directions

float m_fScrlVelX;
float m_fScrlVelY;
float m_fRotVel;
float m_fZoomVel;
float m_fZAngleVel;
//
// Camera position

D3DXVECTOR3 m_vLookAtPoint;
D3DXVECTOR3 m_vEyePt;
float m_fZoomDistance;
float m_fZAngle;
float m_fViewAngle;
float m_fCameraHeight;
//
// Camera matrices

D3DXMATRIX m_matBillboard;
D3DXMATRIX m_matProjection;
D3DXMATRIX m_matView;

public:

//
// Inicialization

HRESULT InitCamera(IDirect3DDevice8* lpDevice, int iMinBound, int iMaxBound);
// Update
HRESULT ProcessCamera(float fElapsedTime);
// Camera motion
void ZoomIn() {m_fZoomVel = -(_C_MAX_ZOOMING_SPEED);}
void ZoomOut() {m_fZoomVel = _C_MAX_ZOOMING_SPEED;}
void RotateLeft() {m_fRotVel = _C_MAX_ROTATION_SPEED;}
void RotateRight() {m_fRotVel = -(_C_MAX_ROTATION_SPEED);}
void MoveLeft() {m_fScrlVelX = _C_MAX_SCROLLING_SPEED;}
void MoveRight() {m_fScrlVelX = -(_C_MAX_SCROLLING_SPEED);}
void MoveUp() {m_fScrlVelY = -(_C_MAX_SCROLLING_SPEED);}
void MoveDown() {m_fScrlVelY = _C_MAX_SCROLLING_SPEED;}
void IncreaseZAngle() {m_fZAngleVel = _C_MAX_ZANGLE_SPEED;}
void DecreaseZAngle() {m_fZAngleVel = -(_C_MAX_ZANGLE_SPEED);}
void SetCameraHeight(float fHeight) {m_fCameraHeight = fHeight;}
//
// Get methods

float GetViewAngle() {return m_fViewAngle;}
float GetZoom() { return m_fZoomDistance;}
float GetZAngle() {return m_fZAngle;}
D3DXVECTOR3* GetCameraPos() {return &m_vLookAtPoint;}
D3DXVECTOR3* GetEyePoint() {return &m_vEyePt;}
D3DXMATRIX* GetBillboardMatrix() {return &m_matBillboard;}
void GetWorldViewProjMatrix(D3DXMATRIX * matWVP);

XCamera();
~XCamera();

}

Zde najdeme vÜechny v²Üe vysv∞tlenΘ atributy. Nejprve je zde odkaz na objekt za°φzenφ Direct3D, dßle omezenφ kamery v prostoru, rychlosti pohybu ve vÜech mo₧n²ch sm∞rech, pozice kamery, sm∞r natoΦenφ atd. a nakonec matice projekce, pohledu a billboard matice. JeÜt∞ se zmφnφm o inline funkcφch pohybu. Tyto funkce pouze nastavujφ rychlost v po₧adovanΘm sm∞ru pohybu. Tato rychlost je zachycena v metod∞ ProcessCamera(), kde je zßrove≥ vynulovßna, aby se anuloval efekt v dalÜφm cyklu.

P°i inicializaci objektu XCamera je nejprve nutnΘ volat metodu InitCamera(), kde nastavφme za°φzenφ a omezenφ kamery. Ve funkci UpdateFrame() je t°eba volat metodu ProcessCamera(), pomocφ nφ₧ aplikujeme pohyb kamery, spoΦφtßme novou matici pohledu a nastavφme ji. Na zßv∞r takΘ spoΦφtßme billboard matici. Nynφ si podrobn∞ rozebereme vÜechny metody t°φdy XCamera.

ZaΦneme konstruktorem a destruktorem:

XCamera::XCamera()
{

m_lpDevice = NULL;
m_fZoomDistance = 10.0f;
m_vLookAtPoint = D3DXVECTOR3(10, 10, 0);
// origin

m_fViewAngle = D3DX_PI / 4; // 45 degree

m_fScrlVelX = 0.0f;
m_fScrlVelY = 0.0f;
m_fZAngleVel = 0.0f;

m_iMinPos = 0;
m_iMaxPos = 10;
m_fZAngle = Z_ANGLE;

m_fCameraHeight = 10.0f;

}

XCamera::~XCamera()
{

m_lpDevice = NULL;

}

Ukazatel na objekt za°φzenφ je t°eba vynulovat, abychom poznali, ₧e je objekt ziniciliazovßn Φi nikoliv. Dßle nastavφme implicitnφ hodnoty vÜech prom∞nn²ch na n∞jakΘ rozumnΘ hodnoty. Kamera se bude "dφvat" z poΦßtku systΘmu kamsi do prostoru pod ·hlem 45 stup≥∙.

Dßle se podφvejme na zajφmav∞jÜφ metodu InitCamera():

HRESULT XCamera::InitCamera(IDirect3DDevice8* lpDevice, int iMinBound, int MaxBound)
{

HRESULT dwRet = S_FALSE;
if(lpDevice)
{

m_lpDevice = lpDevice;
m_iMinPos = iMinBound;
m_iMaxPos = iMaxBound;

//
// Set transformations

D3DXMATRIX matWorld;
//
// Set world matrix

D3DXMatrixIdentity(&matWorld);
m_lpDevice->SetTransform(D3DTS_WORLD, &matWorld);
//
// Create view matrix

D3DXVECTOR3 vUpDir;
m_vEyePt.x = m_fZoomDistance * cosf(m_fViewAngle) + m_vLookAtPoint.x;
m_vEyePt.y = m_fZoomDistance * sinf(m_fViewAngle) + m_vLookAtPoint.y;
m_vEyePt.z = m_fZoomDistance * sinf(Z_ANGLE);
//
vUpDir = D3DXVECTOR3(0.0f, 0.0f, 1.0f);
//
D3DXMatrixLookAtLH(&m_matView, &m_vEyePt, &m_vLookAtPoint, &vUpDir);
D3DXMatrixPerspectiveFovLH(&m_matProjection, FOV, ASPECT, NEAR_CLIP, FAR_CLIP);

m_lpDevice->SetTransform(D3DTS_VIEW, &m_matView);
m_lpDevice->SetTransform(D3DTS_PROJECTION, &m_matProjection);
dwRet = S_OK;

}
return dwRet;

}

Zde si zapamatujeme vstupnφ parametry. Druh²m ·kolem je spoΦφtat pozici kamery, kdy₧ znßme bod, na kter² se kamera "dφvß". Tento bod jsme nastavili v konstruktoru t°φdy. Zde pou₧ijeme trochu chytrΘ matematiky a obrßzk∙ z ·vodu lekce. Nastavenφ sv∞tovΘ matice je zde jen symbolickΘ, nebo¥ se nastavuje pro ka₧d² objekt jinß matice. OvÜem dalÜφ °ßdky nemusφ b²t zcela jasnΘ. Vychßzφme z bodu, na kter² se dφvßme. Zam∞°φme se zatφm na X a Y sou°adnice. D∙le₧itΘ hodnoty jsou p°φmß vzdßlenost od LookAtPointu, co₧ je hodnota m_fZoomDistance. Dßle pot°ebujeme ·hel, pod kter²m pozorujeme scΘnu, to je m_fViewAngle. Pomocφ goniometrick²ch funkcφ spoΦφtßme protilehlou resp. p°ilehlou stranu troj·helnφka z obrßzku pro zφskßnφ X resp. Y sou°adnice kamery. Nakonec bod posuneme na sprßvnΘ mφsto v prostoru. Nynφ se soust°e∩me na Z-tovou sou°adnici. Zde je situace o trochu jednoduÜÜφ, jen vyu₧ijeme ·hel Z definovan² jako konstanta (mimochodem, tato konstanta se nastavφ jen p°i inicializaci tj. sklon m∙₧eme takΘ nastavovat).

Nakonec tu mßme metodu, kterß spoΦφtß vÜechny parametry kamery v pr∙b∞hu programu:

HRESULT XCamera::ProcessCamera(float fElapsedTime)
{

DWORD dwRet = S_FALSE; // CAMERA NOT INITIALIZED
if(m_lpDevice) {


D3DXVECTOR3 vUpDir;
vUpDir = D3DXVECTOR3(0.0f, 0.0f, 1.0f);
//
// Apply rotation

m_fViewAngle += m_fRotVel * fElapsedTime;
//
// Apply zooming

m_fZoomDistance += m_fZoomVel * fElapsedTime;
//
// Check zoom distance

if(m_fZoomDistance > MAX_ZOOM)
m_fZoomDistance = MAX_ZOOM;
if(m_fZoomDistance < MIN_ZOOM)
m_fZoomDistance = MIN_ZOOM;
//
// Apply Z angle

m_fZAngle += m_fZAngleVel * fElapsedTime;
if(m_fZAngle > MAX_Z_ANGLE)
m_fZAngle = MAX_Z_ANGLE;
if(m_fZAngle < MIN_Z_ANGLE)
m_fZAngle = MIN_Z_ANGLE;
//
// Apply position

m_vLookAtPoint.x += (m_fScrlVelX * cosf(m_fViewAngle + D3DX_PI / 2)) * fElapsedTime;
m_vLookAtPoint.y += (m_fScrlVelX * sinf(m_fViewAngle + D3DX_PI / 2)) * fElapsedTime;
m_vLookAtPoint.x += (m_fScrlVelY * cosf(m_fViewAngle)) * fElapsedTime;
m_vLookAtPoint.y += (m_fScrlVelY * sinf(m_fViewAngle)) * fElapsedTime;
m_vLookAtPoint.z = m_fCameraHeight;
//
// Bound camera position

if(m_vLookAtPoint.x < m_iMinPos)
m_vLookAtPoint.x = (float)m_iMinPos;
if(m_vLookAtPoint.y < m_iMinPos)
m_vLookAtPoint.y = (float)m_iMinPos;
if(m_vLookAtPoint.x > m_iMaxPos)
m_vLookAtPoint.x = (float)m_iMaxPos;
if(m_vLookAtPoint.y > m_iMaxPos)
m_vLookAtPoint.y = (float)m_iMaxPos;
//
// Computes eye point position

m_vEyePt.x = m_fZoomDistance * cosf(m_fViewAngle) + m_vLookAtPoint.x;
m_vEyePt.y = m_fZoomDistance * sinf(m_fViewAngle) + m_vLookAtPoint.y;
m_vEyePt.z = m_fZoomDistance * sinf(m_fZAngle) + m_fCameraHeight;
//
// Create new view matrix

D3DXMatrixLookAtLH(&m_matView, &m_vEyePt, &m_vLookAtPoint, &vUpDir);
// Apply transfromation
m_lpDevice->SetTransform(D3DTS_VIEW, &m_matView);
//
// Reset velocities

m_fScrlVelX = 0;
m_fScrlVelY = 0;
m_fRotVel = 0;
m_fZoomVel = 0;
m_fZAngleVel = 0;

dwRet = ERROR_SUCCESS;
//
// Computes billboard matrix

D3DXVECTOR3 vDir = m_vLookAtPoint - m_vEyePt;
if( vDir.y > 0.0f ) {

D3DXMatrixRotationZ(&m_matBillboard, -atanf(vDir.x/vDir.y)+D3DX_PI/2 );

}
else {

D3DXMatrixRotationZ(&m_matBillboard, -atanf(vDir.x/vDir.y)-D3DX_PI/2 );

}

}
return dwRet;

}

Zde je situace hodn∞ podobnß. Zde ovÜem navφc musφme p°epoΦφtat i LookAtPoint. Zde tedy modifikujeme vÜechny parametry v zßvislosti na rychlosti v danΘm sm∞ru.Dßle jsou tu omezenφ pohybu (nap°φklad sklßp∞nφ kamery je mo₧nΘ jen v urΦitΘm intervalu atd.). Zde pou₧ijeme podobn² princip jako v p°edchozφ metod∞. Ke ka₧dΘ slo₧ce vektoru LookAtPoint p°ipoΦteme p°φr∙stky danΘ rychlostmi ve sm∞ru X a Y. V dalÜφm kroku omezφme kameru na jistΘm prostoru. Dßle spoΦφtßme EyePoint ·pln∞ stejn∞ jako v metod∞ InitCamera(). Vytvo°φme a nastavφme novou matici pohledu, vynulujeme rychlosti ve vÜech sm∞rech a nakonec spoΦφtßme billboard matici. U tΘto Φinnosti se na chvilku zastavφme. Prom∞nnß vDir je vektor sm∞°ujφcφ ve sm∞ru pohledu kamery. Z funkce atan() (arc tg) vypadne ·hel, o kter² je t°eba pootoΦit p°φpadn² billboard tak, aby byl ve sm∞ru vektoru vDir. My ale chceme, aby objekt byl kolmo na kameru, tudφ₧ je t°eba ho otoΦit o dalÜφch 90 stup≥∙. UrΦit∞ jste si vÜimli, ₧e p°i zm∞n∞ pozice kamery nßsobφme vÜe jeÜt∞ jakousi konstantou (i o tom jist∞ byla °eΦ). Nenφ to samoz°ejm∞ nic jinΘho ne₧ uplynul² Φas od p°edchozφho snφmku a d∞lßme to z toho d∙vodu, aby kamera byla na vÜech systΘmech stejn∞ rychlß-pomalß tj. aby pohyb-rychlost kamery nebyl zßvisl² na FPS.

27.2. P°φklad

Na zßv∞r lekce trochu upravφme nßÜ p°φklad (projekt Tester), abychom vyzkouÜeli novinky v naÜem enginu.

Za prvΘ je t°eba p°idat objekt kamery do t°φdy XDisplay, dßle p°idßme inline metodu GetCamera(), kterß nßm bude vracet ukazatel na uveden² objekt. Od te∩ m∙₧eme s kamerou pracovat.

Nejprve tedy zavolßme metodu InitCamera() a p°edßme n∞jakΘ rozumnΘ parametry:

// inicializace Direct3D
g_theDisplay.Init(g_hWnd);
g_theInput.Init(hInstance, g_hWnd, g_theDisplay.GetResolution(), g_theDisplay.GetDevice());

g_theDisplay.GetCamera()->InitCamera(g_theDisplay.GetDevice(), -20, 20);

NßÜ vesmφr je mal², jen 40x40 (Φeho? t°eba metr∙:) Dßle upravφme funkci UpdateFrame():

DWORD dwOldAdrMode;
float fFactor = cmnGetTime(TIMER_GETELAPSEDTIME1);

g_theInput.ProcessInput();
g_theDisplay.GetCamera()->ProcessCamera(fFactor);

V²poΦet faktoru (Φasu) p°esuneme na zaΦßtek funkce, abychom ho mohli vyu₧φt v metod∞ ProcessCamera().

Nakonec p°idßme ovlßdanφ kamery:

if(g_theInput.IsKeyDown(DIK_ADD , FALSE)) {

g_theDisplay.GetCamera()->ZoomIn();

}
if(g_theInput.IsKeyDown(DIK_SUBTRACT , FALSE)) {

g_theDisplay.GetCamera()->ZoomOut();

}
if(g_theInput.IsKeyDown(DIK_NUMPAD1 , FALSE)) {

g_theDisplay.GetCamera()->RotateLeft();

}
if(g_theInput.IsKeyDown(DIK_NUMPAD3 , FALSE)) {

g_theDisplay.GetCamera()->RotateRight();

}
if(g_theInput.IsKeyDown(DIK_NUMPAD8 , FALSE)) {

g_theDisplay.GetCamera()->IncreaseZAngle();

}
if(g_theInput.IsKeyDown(DIK_NUMPAD2 , FALSE)) {

g_theDisplay.GetCamera()->DecreaseZAngle();

}

int iMouseZone = int(g_theDisplay.GetResolution()->x * 5 / 1024);
if(g_theInput.IsKeyDown(DIK_UP, FALSE)) {

g_theDisplay.GetCamera()->MoveUp();

} else {

if(g_theInput.GetCursor()->y < iMouseZone) {

g_theDisplay.GetCamera()->MoveUp();

}

}
if(g_theInput.IsKeyDown(DIK_LEFT , FALSE)) {

g_theDisplay.GetCamera()->MoveLeft();

} else {

if(g_theInput.GetCursor()->x < iMouseZone) {

g_theDisplay.GetCamera()->MoveLeft();

}

}
iMouseZone += int( g_theDisplay.GetResolution()->x * 32 / 1024);
if(g_theInput.IsKeyDown(DIK_DOWN , FALSE)) {

g_theDisplay.GetCamera()->MoveDown();

} else {

if(g_theInput.GetCursor()->y >= g_theDisplay.GetResolution()->y-iMouseZone) {

g_theDisplay.GetCamera()->MoveDown();

}

}
if(g_theInput.IsKeyDown(DIK_RIGHT , FALSE)) {

g_theDisplay.GetCamera()->MoveRight();

} else {

if(g_theInput.GetCursor()->x >= g_theDisplay.GetResolution()->x-iMouseZone) {

g_theDisplay.GetCamera()->MoveRight();

}

}

Zde vyu₧ijeme metody z minulΘ lekce, kde jsme vklßdali projekt Input. V₧dy otestujeme po₧adovanou klßvesu (bez obsluhy tzn. projevφ se reakce na vφcenßsobnΘ dr₧enφ klßvesy). PotΘ volßme p°φsluÜnou metodu, kterß pohne s kamerou. U pohybu ve sm∞ru X a Y je zapojena i myÜka. Sledujeme, kdy₧ je myÜ na okraji obrazovky a potΘ spustφme pohyb v po₧adovanΘm sm∞ru.

Po kompilaci je mo₧no ovlßdat kameru Üipkami ve sm∞rech osy X a Y. Zoom (p°iblφ₧enφ, oddßlenφ) provedeme klßvesou + a -. Sklopenφ kamery je na klßvesßch Num 8 a Num 2. Rotaci provedeme pomocφ Num 1 doleva a Num 3 doprava.

27.3. Zßv∞r

Jak bylo zmφn∞no v ·vodu, v p°φÜtφ lekci se budeme v∞novat optimalizacφm p°i vykreslovßnφ terΘnu, kter² se bude sklßdat ze sφt∞ polygon∙, ale my chceme vykreslit pouze ty polygony, kterΘ jsou viditelnΘ. Na to je n∞kolik metod, my zaΦneme s metodou quadtree.

Ji°φ Formßnek