Sunteți pe pagina 1din 14

INTRODUCERE

DirectX (de la engl. direct — direct, nemijlocit) — este un set de API, elaborat pentru rezolvarea
problemelor legate de programare sub Microsoft Windows. Cel mai larg se foloseşte pentru
scrierea jocurilor pe calculator. Pachetul instrumental DirectX pentru Microsoft Windows este
disponibil gratis pe siteul companiei Microsoft. De obicei cu versiunile reînoite DirectX sunt
dotate aplicaţii noi de joc.

Tehnologia DirectX de la corporaţia Microsoft practic reprezintă un standard de instrumente


pentru programarea graficii, mai ales jocurilor, pentru platforma Windows. Mai mult de 90%
jocuri computerizate se scriu în limbajul C++ cu utilizarea bibliotecii DirectX. Împreună cu
apariţia primului sistem de operare grafic puternic Windows 95, corporaţia Microsoft elaborează
paralel bibliotecile multimedia, cu ajutorul cărora pot fi elaborate diferite aplicaţii grafice.
Primul pachet instrumental se numea Game SDK. El a apărut aproximativ în acel timp, când
Windows 95 cucerea piaţa mondială. Pachetul Game SDK a fost bazat pe grafică de rastru, în
acel moment încă nu existau video plăci grafice 3D puternice. Pachetul susţinea şi sunetul şi
unităţi de intrare. Un an după asta apar una după alta versiunile DirectX 2 şi DirectX 3, in
componenţa lor prezintă şi biblioteca Direct3D. După apariţia sistemului Windows 98 biblioteca
DirectX a fost completată cu versiunile 5 şi 6. În anul 1999 apare DirectX 7, care a semnalat
epoca noua de jocuri computerizate 3D. Peste un an se lansează DirectX 8, după ce devine
evident în bază cărui instrumentar trebuie de elaborat aplicaţii grafice sub SO Windows.
În 2002 firma Microsoft a lansat DirectX 9 cu susţinerea îmbunătăţită şi extinsă a shaderilor. Din
anul 2002 DirectX se reînnoieşte de mai multe ori. În august 2004 în DirectX a fost adăugată
susţinerea shaderilor de versiune 3.0 (DirectX 9.0c).
In aprilie 2005 interfaţa DirectShow a fost mutată în Microsoft Platform SDK.
Cronologia versiunilor DirectX

Versiunea DirectX Numărul vrsiunii Sistemul de operare Data relizului

DirectX 1.0 4.02.0095 Windows 95a 30 septemb 1995

Windows 95 OSR 2 şi Windows NT mai mici de


DirectX 2.0 / 2.0a 4.03.00.1096 5 iunie1996
4.0

Windows 95 OSR 2.5 şi Windows NT 4.0 SP3


DirectX 3.0 / 3.0a 4.04.0068 / 69 ultima versiunea DirectX susţinută pentru 15 septemb 1996
Windows NT 4.0

4.05.00.0155
DirectX 4.0 Accesibil ca beta pentru Windows NT 4.0 16 iulie 1997
(RC55)

4.05.01.1721 /
DirectX 5.0 Windows 98 5 mai 1998
1998

Windows 98 SE ultima versiunea DirectX Media


4.06.00.0318
DirectX 6.0 susţinută pentru Windows NT 4.0. A fost inclus 7 august 1998
(RC3)
şi în Dreamcast

4.06.02.0436
DirectX 6.1 Windows 95/98/98SE 3 febr 1999
(RC0)

4.07.00.0700
DirectX 7.0 Windows 2000 şi Windows ME 22 septemb 1999
(RC1)
Grafica 3D (Suport de curs în baza Direct3D), S.Pereteatcu, A.Pereteatcu

4.07.00.0716
DirectX 7.0a Windows 95/98/98SE/2000 1999
(RC1)

4.08.00.0400
DirectX 8.0 Windows 95/98/98SE/ME/2000 30 septemb 2000
(RC10)

4.08.00.0400 Ultima versiunea DirectX susţinută pentru


DirectX 8.0a 7 noiemb 2000
(RC14) Windows 95

4.08.01.0810
DirectX 8.1 4.08.01.0881 Windows XP 8 noiemb 2001
(RC7)

DirectX 8.1b 4.08.01.0901 ???,2002

4.08.02.0134
DirectX 8.2 ???,2002
(4.09.0000.0134)

DirectX 9.0 4.09.0000.0900 Windows Server 2003 24 dec 2002

DirectX 9.0a 4.09.0000.0901 26 martie 2003

4.09.0000.0902
DirectX 9.0b 13 августа2003
(RC2)

4.09.0000.0904 Windows XP SP2 ultima versiunea DirectX


DirectX 9.0c 9 august 2004
(RC0) susţinută pentru Windows 98SE şi Windows Me

Oferă interfeţele suplimentare IDirect3D9Ex şi


4.09.0000.0905 IDirect3DDevice9Ex cu funcţionalitatea
DirectX 9.0L
(?) accesibilă numai prin LDDM-driverii SO
Windows Vista.

DirectX 10 (inclus în
Prima versiunea Windows Vista. Informaţii
componenţa Windows 6.0.6000.16386 10 noiemb 2006
despre Direct3D10
Vista)

Service Pack 1 pentru Windows Vista, Windows


DirectX 10.1 6.00.6001.18000 4 febr 2008
Server 2008

DirectX 11 (inclus în Windows Vista Service Pack 2, Windows 7.


componenţa Windows 6.01.7600.16385 Prezentarea oficială a avut loc la Gamefest 2008. 22 iulie 2009
7) Informaţii despre Direct3D11

DirectX 11.1 (inclus în


Windows 8 26 octomb 2012
componenţaWindows 8)

DirectX 11.2 (inclus în


componenţa Windows Windows 8.1 17 octomb 2013
8.1)

DirectX 11.3 (inclus în


componenţa Windows Windows 10 29 iulie 2015
10)

DirectX 12 (inclus în
componenţa Windows Windows 10 29 iulie 2015
10)

2
Grafica 3D (Suport de curs în baza Direct3D), S.Pereteatcu, A.Pereteatcu

1. Bazele programării sub Windows

Noţiune de aplicaţie tip fereastră

Înainte de a începe programarea graficii cu DirectX 9, trebuie să elaborăm carcasul programului,


care va crea suprafaţa de lucru pentru aplicaţia grafică 3D. Windows este un SO multitasking şi
ceea ce vedem pe ecran al monitorului este aplicaţia obişnuită - tip fereastră. După ce vom crea
carcasul, putem să trecem la programarea graficii, desenând orice obiecte în cadrul aplicaţiei
create. Deci scopul principal este scrierea codului ferestrei în baza căruia vor fi create toate
modificările ulterioare. Contează şi dimensiunea ferestrei a aplicaţiei. Sunt două moduri:
fullscreen şi fereastră. În modul fereastră putem seta dimensiunile ferestrei, stilul şi poziţia pe
ecran. În modul fullscreen se indică rezoluţia şi frecvenţa de redesenare a ecranului. De la
început vom folosi numai modul fereastră. În capitolul 11 se examinează trecerea la modul
fullscreen, care de fapt nu este complicată.

Crearea aplicaţieiei în Visual C++ .NET

Pentru crearea aplicaţiilor mediul de programare Visual C++ .NET conţine mijloace incorporate.
Deschidem mediul de programere Visual С++ .NET şi creăm un proiect. Perntru aceasta
efectuăm următoarele acţiuni:

1. File / New / Project. Apare caseta de dialog New Project;

2. În caseta Project Types selectăm Visual C++ Projects, iar în caseta Templates — Win 32
Project;

3. În caseta Name scriem numele proiectului, de exemplu, Project1. În caseta Location


indicăm mapa, în carea se va păstra proiectul creat;

4. OK.

Apre caseta de dialog Win 32 Application Wizard – Project1 (fig. 1.1), în care trecem la pagina
Application Settigs şi în reginea Additional options bifăm opţiunea Empty project. În regiunea
Application type selectăm Windows application, după ce apăsăm butonul Finish.

Astfel am creat o aplicaţie vidă obişnuită, care nu are nici o linie de cod. Mai departe dezvoltăm
aplicaţia. Din partea stânga a ferestrei Visual C++. NET se află panelul cu trei pagini: Solution
Explorer, Resourse View şi Class View. După selectarea paginii Solution Explorer, apare
arborele proiectului Project1. După apăsarea butonului "+" pe lângă numele proiectului se
desfăşoară ramura cu mape: Source File (fişiere cu cod, de regulă au extensia c şi/sau cpp) şi
Header File (cu fişiere antet, de regulă au extensia h).

3
Grafica 3D (Suport de curs în baza Direct3D), S.Pereteatcu, A.Pereteatcu

Fig. 1.1. Caseta de dialog Win32 Application Wizard – Project1

Inserăm un fişier gol în mapa Source File. În el vom scrie codul programului. Pentru a insera un
fişier gol efectuăm următorii paşi:

1. Executăm clic drept pe iconiţa Source File, din meniul context selectăm opţiunea Add.
Apoi după săgeată din meniul derulant alegem opţiunea Add New Item. Pe ecran apare
caseta de dialog Add New Item - Project1 (fig. 1.2);

Fig. 1.2. Caseta de dialog Add New Item – Project1

2. În caseta Templates selectăm C++ File (.cpp);

4
Grafica 3D (Suport de curs în baza Direct3D), S.Pereteatcu, A.Pereteatcu

3. În caseta Name scriem denumirea fişierului de creare, de exemplu, WindowsBazis.


Apăsăm butonul Add. După asta pa pagina Solution Explorer - Project1 în mapa Sourse
File va apărea fişierul gol WindowsBazis.cpp.

Modelul general de mesaje în Windows

Comunicarea Windows-ului cu aplicaţiile se bazează pe modelul de evenimente. Orice aplicaţie


tip windows în timpul vieţii interacţionează cu SO prin intermediul de mesaje.

Numărul de mesaje pot fi destul de mare. Pentru a sistematiza mesajele curente, există aşa
numită coadă de evenimente. Ea este realizată în formă de buclă obişnuită. Fiecare din mesajele
apărute aşteaptă rândul său de prelucrare, după ce se extrage de către SO Windows.. Pentru a
prelucra toate mesajele Windows dispune de un prelucrător de mesaje pentru toate aplicaţiile.
Modelul de interacţiune aplicaţiilor cu mesaje este prezentat schematic în fig. 1.3.

Aplicaţia Aplicaţia
fereastră 1 fereastră 2

Coadă
Coadă Coadă
evenimen.
mesaje ap.1 mesaje ap.2
Windows

Fig. 1.3. Modelul de evenimente Windows

Reieşind din acest model de evenimente, pentru a crea o aplicaţie este necesar să creăm o
fereastră şi să pornim un prelucrător de mesaje. Punctul de pornire a oricărei aplicaţiei în
Windows este funcţia WinMain(), în care se creează fereastra şi se tratează evenimentele. De
aceea, de la bun început, vom crea funcţia WinMain(), în care vom descrie clasa
windowsclass, în care vom indica dimensiunea, stilul, culoarea, fundalul ferestrei viitoare.
Apoi vom crea fereastra cu funcţia CreateWindowEx(). Apoi vom înregistra fereastra şi vom
crea un prelucrător de evenimente, în care vor fi transmise diferite mesaje.

Funcţia principală WinMain()

În primul rând conectăm fişierul antet windows.h. El conţine declaraţiile claselor care sunt
necesare pentru a programa în mediul Windows:
#include <windows.h>
#include <tchar.h>

Fişierul antet tchar.h se foloseşte pentru utilizarea codului Unicod.

Apoi urmează funcţia principală a tuturor aplicaţiilor Windows: WinMain(). Antetul acestei
funcţii este următorul:
int WINAPI WinMain(
HINSTANCE hinstance,
HINSTANCE hprevinstance,

5
Grafica 3D (Suport de curs în baza Direct3D), S.Pereteatcu, A.Pereteatcu

LPSTR lpCmdLine,
int nCmdShow)

Funcţia WinMain() are următorii parametri:

 hinstance — este descriptorul aplicaţiei de creare, aşa numitul handle. Descriptorul se


generează de către SO Windows pentru urmărirea ulterioară a aplicaţiei. Altfel spus,
hinstance este un fel de etichetă a aplicaţiei şi a ferestrei care se creează;

 hprevinstance — acest parametru deja nu se foloseşte. El provine de la SO Windows 3.1,


şi a fost lăsat pentru compatibilitate. Valoarea permanentă a acestui parametru este 0;

 lpCmdLine — pointer la şirul de comandă, care urmează imediat după numele comenzii care
se lansează;

 nCmdShow — indică aspectul ferestrei care se creează pe ecranul monitorului. Există un şir
mare de flaguri, care descriu aspectul dorit al ferestrei, şi care pot fi combinate pentru a crea
valoarea acestui parametru. Informaţii suplimentare despre flagurile date pot fi găsite în
documentaţia pentru Win32 API.

Cercetăm clasa windowsclass.

Trebuie să descriem clasa ferestrei – windowsclass. Clasă – este ceea ce ne permite să


diferenţiem aspectul şi destinaţia ferestrei. Diferite ferestre se diferenţiază una de alta prin clasă.
SO Windows are un set mare de astfel de clase predefinite. Ne rămâne să păstrăm în structura
windclassex informaţii despre clasa windowsclass care se creează. Deci, creăm clasa
windowsclass, care va răspunde de obţinerea scopul formulat:
WNDCLASSEX windowsclass; // clasa ferestrei de creare

Declararea tipului structurat WINDCLASSEX, care este necesar pentru descrierea clasei, arată
astfel:
typedef struct _WNDCLASSEX
{
UINT cbSize;
UINT style;
WINDPOC lpfnWndProc;
int cbClsExtra;
int cbWndExtra;
HANDLE hInstance;
HICON hIcon;
HCURSOR hCursor;
HBRUSH hbrBackgroung;
LPCTSTR lpszMenuName;
LPCTSTR lpszClassName;
HICON hIconSm;
} WNDCLASSEX;

Câmpurile structurii au următoarea destinaţie:

 cbSize — dimensiunea structurii care se creează. Paralel cu descrierea câmpurilor le vom


completa. Indicăm dimensiunea structurei noastre:
6
Grafica 3D (Suport de curs în baza Direct3D), S.Pereteatcu, A.Pereteatcu

windowsclass.cbSize=sizeof(WNDCLASSEX);

 style — conţine combinaţia flagurilor ce descriu stilul dorit al ferestrei. Combinarea se face
cu ajutorul operatorului sau pe biţi "|". Completăm câmpul style:
windowsclass.style=CS_DBLCLKS|CS_OWNDC|CS_HREDRAW|CS_VREDRAW;

Descriem flagurile utilizate (informaţiile suplimentare pot fi luate din documentaţia pentru Win
32):

 CS_VREDRAW — în cazul când se schimbă înălţimea ferestrei sau fereastra a fost deplasată,
este necesară redesenarea ferestrei în întregime;

 CS_HREDRAW — în cazul când se schimbă lăţimea ferestrei sau fereastra a fost deplasată,
este necesară redesenarea ferestrei în întregime;

 CS_OWNDC — pentru fiecare fereastră a clasei date se repartizează un context dispozitiv


propriu;

 CS_DBLCLKS — în cazul unui click dublu în cadrul ferestrei, ferestrei se transmit


informaţii despre click dublu;

 lpfnWndProc — pointer la funcţia principală de tratare a evenimentelor cu ordinea inversă a


parametrilor (call back). Orice aplicaţie în Windows conţine bucla de prelucrare a
evenimentelor. În bucla respectivă se apelează funcţia MainwinProc(), de aceea scriem:
windowsclass.lpfnWndProc=MainWinProc;

 câmpurile cbClsExtra şi cbWndExtra, sunt destinate pentru păstrare informaţiilor


suplimentare. Câmpurile acestea se folosesc rar, mai ales la programare cu DirectX. De aceea
scriem:
windowsclass.cbClsExtra=0, windowsclass.cbWndExtra=0;

 hInstance — câmpul acesta răspunde de exemplarul aplicaţiei care se creează şi se


transmite funcţiei WinMain():
windowsclass.hInstance=hinstance;

 hIcon — defineşte pictograma aplicaţiei. Cu ajutorul funcţiei LoadIcon() putem încărca o


pictogramă proprie, sau o pictogramă de sistem. Antetul funcţiei LoadIcon() este
următorul:

HICON LoadIcon(HINSTANCE hInstance, LPCTSTR LpIconName)

Descriem parametrii acestei funcţii:

 hInstance — exemplarul aplicaţiei. Pentru a încărca o pictogramă standard, se foloseşte


valoarea NULL;

 LpIconName — identificatorul resursei de tip pictogramă care se încarcă. Vom folosi


pictograma standard IDI_APPLICATION — pictograma care se foloseşte implicit pentru
aplicaţii. Există o sumedenie de identificatori pentru încărcarea diferitelor pictograme.
Există posibilitatea creării unei pictograme proprii pentru a înlocui pictograma de sistem.
Având antetul funcţiei LoadIcon(), vom scrie:
windowsclass.hIcon=LoadIcon(NULL, IDI_APPLICATION);
7
Grafica 3D (Suport de curs în baza Direct3D), S.Pereteatcu, A.Pereteatcu

 hCursor — câmpul acesta răspunde de utilizarea cursorului. După utilizare câmpul acesta
este asemănător cu cel precedent hIcon. Se diferă numele funcţiei care încarcă cursorul.
Vom scrie:
windowsclass.hCursor=LoadCursor(NULL, IDC_ARROW);

Cursorul standard are formă de săgeată mică şi identificatorul IDC_ARROW. Asemenea


pictogramelor, există un set de identificatori de cursoare (programatorul poate să elaboreze
cursoare proprii);

 hbrBackgroung — culoarea de fundal al ferestrei. Pentru a colora fundalul cu o culoare


ptandard predefinită se foloseşte funcţia GetStockObject(). Funcţia are un singur
parametru — flagul care setează culoarea pensulei de umplere. Pentru umplerea fundalului cu
culoare sură scriem:
windowsclass.hbrBackground=(HBRUSH)GetStockObject(GRAY_BRUSH);

Putem să încercăm să colorăm fundalul cu o altă culoare, totuşi pentru DirectX aceasta nu are
nici o însemnătate, fiindcă pentru asta sunt definite mijloacele proprii. Totuşi mai descriem
câteva pensule de diferite culori:

 GRAY_BRUSH — umplerea cu pensula de culoare sură;

 BLACK_BRUSH — pensula neagră;

 WHITE_BRUSH — pensula albă;

 LTGRAY_BRUSH — pensula de culoare sură deschisă;

 DKGRAY_BRUSH — pensula de culoare sură închisă;

 HOLLOW_BRUSH — pensula transparentă (fără umplere);

 lpszMenuName — câmpul destinat pentru conectarea unui meniu la fereastra aplicaţiei.


Valoarea NULL indică că aplicaţia nu va avea meniul:
windowsclass.lpszMenuName=NULL;

 lpszClassName — indică numele clasei de descriere a ferestrei aplicaţiei de creare. Pot


exista simultan (de obicei aşa şi este) câteva aplicaţii, la crearea cărora s-a folosit una şi
aceeaşi clasa windowsclass, iar sistemul de operare trebuie cumva să le deosebească.
Anume pentru asta se foloseşte câmpul acesta. Aici putem indica o denumire arbitrară,
principalul să ţinem cont de ea (să nu ne încurcăm în ele dacă vom avea mai multe denumiri):
windowsclass.lpszClassName=_T("WINDOWSCLASS");

 hIconSm — descriptorul pictogramei mici, care se afişează pe bara de taskuri sau în antetul
ferestrei aplicaţiei. Vom folosi pictograma standard. Pentru asta vom scrie:
windowsclass.hIconSm=LoadIcon(NULL, IDI_APPLICATION);

Astfel, completarea tuturor câmpurilor structurii va arăta aşa:


WNDCLASSEX windowsclass; // класс создаваемого окна
windowsclass.cbSize=sizeof(WNDCLASSEX);
windowsclass.style=CS_DBLCLKS|CS_OWNDC|CS_HREDRAW|CS_VREDRAW;
windowsclass.lpfnWndProc=MainWinProc;

8
Grafica 3D (Suport de curs în baza Direct3D), S.Pereteatcu, A.Pereteatcu

windowsclass.cbClsExtra=0;
windowsclass.cbWndExtra=0;
windowsclass.hInstance=hinstance;
windowsclass.hIcon=LoadIcon(NULL, IDI_APPLICATION);
windowsclass.hCursor=LoadCursor(NULL, IDC_ARROW);
windowsclass.hbrBackground=(HBRUSH)GetStockObject(GRAY_BRUSH);
windowsclass.lpszMenuName=NULL;
windowsclass.lpszClassName=_T("WINDOWSCLASS");
windowsclass.hIconSm=LoadIcon(NULL, IDI_APPLICATION);

După ce am completat şi am salvat în structura windowsclass toate valorile, clasa


windowsclass trebuie să fie înregistrată. Aceasta se face cu funcţia RegisterclassEx().
Parametrul funcţiei reprezintă adresa structurii cu descrierea clasei. Pentru orice aplicaţie care se
creează, clasa poate fi înregistrată doar o singură dată:
if(!RegisterClassEx(&windowsclass)) // înregistrăm clasa creată
return 0;

Creăm fereastra.
După ce am înregistrat clasa, putem să creăm fereastra. Aceasta se face cu funcţia
CreateWindowEx(), care are următorul antet:
HWND CreateWindowEx(
DWORD dwExStyle,
LPCTSTR lpClassName,
LPCTSTR lpWindowName,
DWORD dwStyle,
int X,
int Y,
int nWidth,
int nHeight,
HWND hWindParent,
HWND hMenu,
HINSTANCE hInstance,
LPVOID lpParam);

Parametrii funcşiei CreateWindowEx() sunt:

 dwExStyle — flagul stilurilor ferestrei. Se foloseşte rar. În majoritatea de cazuri se foloseşte


valoarea WS_EX_TOPMOST, ceea ce indică că fereastra aplicaţiei va apărea deasupra celorlalte
ferestre. Valoarea NULL ignorează acest parametru;

 lpClassName — denumirea clasei ferestrei care se creează. În cazul nostru este


WINDOWSCLASS;

 lpWindowName — antetul ferestrei. De obicei textul antetului corespunde sensului aplicaţiei,


de exemplu, "Fereastra de bază pentru DirectX";

 dwStyle — combinaţia flagurilor ce descriu stilul şi comportarea ferestrei ce se creează.


Există un set de astfel de flaguri. Iată careva din ele:

 WS_OVERLAPPED — fereastra cu o linie de antet şi o margine;


9
Grafica 3D (Suport de curs în baza Direct3D), S.Pereteatcu, A.Pereteatcu

 WS_VISIBLE — fereastra va fi vizibilă din start;

 WS_CAPTION — fereastra cu o linie de antet (include în sine stilul WS_BORDER);

 WS_BORDER — fereastra cu o margine subţire;

 WS_ICONIC — fereastra va fi minimizată din start;

 WS_OVERLAPPEDWINDOW — fereastra cu suprapunere (include în sine următoarele 6


stiluri: WS_OVERLAPPED, WS_CAPTION, WS_SYSMENU, WS_THICKFRAME,
WS_MINIMIZEBOX şi WS_MAXIMIZEBOX) — este un flag destul de funcţional. Anume
acest flag vom folosi pentru fereastra aplicaţiei noastre;

 WS_MINIMIZE — fereastra va fi minimizată din start;

 WS_MAXIMIZE — fereastra va fi maximizată din start;

 WS_MAXIMIZEBOX — fereastra cu butonul Maximize (se foloseşte numai cu stilul


WS_SYSMENU);

 WS_MINIMIZEBOX — fereastra cu butonul Minimize (se foloseşte numai cu stilul


WS_SYSMENU);

 X, Y — poziţia iniţială a colţului stânga sus în pixeli. Se poate de indicat coordonatele prin
utilizarea flagului CW_USEDEFAULT, lăsând astfel valorile implicite. Vom folosi pentru X
valoarea 300, iar pentru Y – valoare 150, setând astfel coordonatele colţului stânga sus în
pixeli;

 nWidth şi nHeight — lăţimea şi respectiv înălţimea ferestrei în pixeli. Se poate de folosit


valorile implicite cu ajutorul flagului CW_USEDEFAULT, sau de indicat valorile concrete, de
exemplu, 500×400 pixeli;

 hWindParent — descriptorul ferestrei părinte. Dacă fereastra părinte nu este, se foloseşte


valoarea NULL;

 hMenu — descriptorul meniului, adică dacă aplicaţia are un meniu, poate fi indicat
descriptorul acestui meniu şi meniul va fi conectat la fereastra aplicaţiei. dacă meniul
lipseşte, atunci valoarea parametrului se pune pe NULL;

 hInstance — exemplarul aplicaţiei. Foloseşte valoarea hinstance pasată funcţiei


WinMain();

 lpParam — pointerul la datele ferestrei, de obicei are valoarea NULL.

Acum toate valorile ale parametrilor funcţiei sunt cunoscute. Pentru a crea fereastra, declarăm
descriptorul ferestrei şi apelăm funcţia CreateWindowEx():
HWND hwnd; // descriptorul ferestrei
if(!(hwnd=CreateWindowEx(
NULL, // stilul ferestrei
_T("WINDOWSCLASS"), // numele clasei
_T("Fereastră de bază pentru DirectX"), // antetul ferestrei

10
Grafica 3D (Suport de curs în baza Direct3D), S.Pereteatcu, A.Pereteatcu

WS_OVERLAPPEDWINDOW|WS_VISIBLE, //
0, 0, // colţul stânga sus
// CW_USEDEFAULT, 0, // colţul stânga sus
500, 400, // lîţimea şi înălţimea ferestrei
// CW_USEDEFAULT, 0, // lîţimea şi înălţimea ferestrei
NULL, // descriptoruil ferestrei pîrinte
NULL, // descriptorul meniului
hinstance, // descriptorul aplicaşiei
NULL))) // pointerul la datele ferestrei
return 0;

Cu ajutorul instrucţiunii if se prelucrează erorile.

După ce fereastra a fost creată, ea trebuie să fie afişată explicit pe ecran şi reînnoită. Lucrul
acesta se face prin două funcţii:
ShowWindow(hwnd, SW_SHOWDEFAULT); // afişăm fereastra
UpdateWindow(hwnd); // reînnoim fereastra

Tratarea evenimentelor în Windows

În SO Windows evenimentele legate de aplicaţia trebuie prelucrate cu prelucrătorul de


evenimente al acestei aplicaţiei. Pentru fiecare clasă poate fi definit unul sau mai mulţi
prelucrători proprii de evenimente. Astfel se îmbunătăţeşte funcţionalitatea programului. În timp
ce lucrează orice aplicaţie se generează o sumedenie de diferite mesaje. Ele se pun la coadă.
Evenimentele legate de fereastra aplicaţiei noastre, nimeresc în secţiunea coţii care se referă
anume la fereastra noastră. După aceasta prelucrătorul de evenimente principal extrage mesajul
de rând si îl transmite funcţiei MainWinProc() pentru prelucrarea ulterioară. Cu evenimentele
pentru care nu este asignat prelucrătorul, se ocupă însuşi SO Windows.

Cercetăm antetul funcţiei MainWinProc():


LRESULT CALLBACK MainWinProc(
HWND hwnd,
UINT msg,
WPARAM wparam,
LPARAM lparam)

Funcţia MainWinProc() are următorii parametri:

 hwnd — descriptorul ferestrei. Se foloseşte pentru a afla de la care fereastră a venit mesajul în
cazul când sunt deschise simultan mai multe ferestre ale uneia şi aceeaşi clasă;

 msg — identificatorul evenimentului, care este transmis funcţiei MainWinProc() pentru


prelucrare;

 wparam şi lparam — parametrii suplimentari la evenimentul dat. La elaborarea


prelucrătorului de evenimente, de obicei, se foloseşte construcţia switch(msg). După
analiza identificatorului msg, pot fi utilizate informaţiile suplimentare transmise prin
parametrii wparam şi lparam.

 WM_PAINT — mesagul acesta se trimite atunci când se cere redesenare ferestrei în întregime
(de exepmplu, fereastra a fost deplasată, fereastra a fost mărită, etc.);
11
Grafica 3D (Suport de curs în baza Direct3D), S.Pereteatcu, A.Pereteatcu

 WM_DESTROY — mesajul acesta se trimite de către SO Windows atunci când fereastra trebuie
să fie închisă. Mesajul acesta comunică că trebuie de eliberat toate resursele ocupate de către
aplicaţia;

 WM_QUIT — după eliberarea resurselor se generează mesajul acesta care va aduce la


închiderea aplicaţiei.

Ca rezultat obţinem funcţia MainWinProc():


LRESULT CALLBACK MainWinProc(HWND hwnd, // descriptorul ferestrei
UINT msg, // identificat. evenimentului
WPARAM wparam, // informaţii suplimentare
LPARAM lparam) // informaţii suplimentare
{
switch(msg)
{
//
case WM_PAINT:
ValidateRect(hwnd, NULL);
break;
//
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, msg, wparam, lparam);
}

Apelul PostQuitMessage(0) pune la coadă mesajul WM_QUIT, care va închide aplicaţia


noastră. WM_QUIT se aplică nemijlocit în prelucrătorul de evenimente principal. Funcţia
DefWindowProc() prelucrează implicit acele mesaje pe care nu le prelucrează aplicaţia
noastră.

Prelucrătorul principal de evenimente

Cercetăm prelucrătorul principa de evenimente, care deocamdată va arăta astfel:


MSG msg; // indicatorul de mesaj
while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg); // transferul introducerii de la tastat.
DispatchMessage(&msg); // prelucrarea şi pasarea mesajelor
// funcţiei MainWinProc()
}
return msg.wParam;

Antetul funcţiei GetMessage() arată astfel:


BOOL GetMessage(
LPMSG lpMsg,
HWND hWnd,
UINT wMsgFiltrenMin,

12
Grafica 3D (Suport de curs în baza Direct3D), S.Pereteatcu, A.Pereteatcu

UINT wMsgFiltrenMax)

Parametrii funcţiei GetMessage() sunt:

 lpMsg — poiner la structura care este responsabilă de mesaje;

 hWnd — descriptorul ferestrei care se crează;

 wMsgFiltrenMin — primul mesaj ajuns la prelucrarea;

 wMsgFiltrenMax — ultimul mesaj de prelucrare.

Bucla while se execută atâta timp cât funcţia GetMessage() întoarce valoarea diferită de zero.
Corpul buclei este simplu: la apariţia mesajului din coada mesajelor, mesajul se prelucrează cu
funcţia TranslateMessage() şi se transmite funcţiei DispatchMessage(), care pentru
prelucrarea apelează funcţia MainWinProc(), trnsmiţind ultimei toate informaţiile necesare.

Pentru compilarea codului iniţial, aflându-ne în caseta de dialog cu proiectul deschis Project1,
selectăm sau simplu deschidem WindowsBazis.cpp. Apoi apăsăm tasta <Ctrl> şi reţinând-o,
apăsăm tasta <F7>. se va compila codul iniţial din fişierul WindowsBazis.cpp. Apoi apăsăm
tasta <F7> — se va executa editare legăturilor. Pentru a vedea rezultatul folosim combinaţia de
taste <Ctrl>+<F5>. Fereastra creată de programul este prezentată în fig. 1.4.

Fig. 1.4. Fereastra de bază pentru DirectX

Astfel am creat o aplicaţie simplă tip fereastră, în care mai departe vom integra codul propriu,
utilizând funcţiile bibliotecii DirectX 9. Cum a fost arătat, aplicaţia poate fi creată cu setarea

13
Grafica 3D (Suport de curs în baza Direct3D), S.Pereteatcu, A.Pereteatcu

proprietăţilor necesare. Mai departe va fi descris conceptul de creare a scenei în DirectSD, va fi


abordată tehnologia СОМ, pe platforma căreia se bazează toată biblioteca DirectX.

14

S-ar putea să vă placă și