+ All Categories
Home > Documents > SuportDirect3D ROM Lectia1

SuportDirect3D ROM Lectia1

Date post: 04-Dec-2015
Category:
Upload: elly
View: 8 times
Download: 3 times
Share this document with a friend
Description:
vh
19
MINISTERUL DE EDUCAŢIE DIN REPUBLICA MOLDOVA UNIVERSITATEA DE STAT DIN MOLDOVA Departamentul de Informatică Conf. doct. S. Pereteatcu Mag. în inf. A. Pereteatcu Grafica 3D pe calculator (Suport de curs în baza Direct 3D) Chişinău - 2014
Transcript
Page 1: SuportDirect3D ROM Lectia1

MINISTERUL DE EDUCAŢIE DIN REPUBLICA MOLDOVA

UNIVERSITATEA DE STAT DIN MOLDOVA

Departamentul de Informatică

Conf. doct. S. Pereteatcu

Mag. în inf. A. Pereteatcu

Grafica 3D pe calculator

(Suport de curs în baza Direct 3D)

Chişinău - 2014

Page 2: SuportDirect3D ROM Lectia1

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

2

C U P R I N S

INTRODUCERE ............................................................................................................................................... 4

1. Bazele programării sub Windows.......................................................................................................... 8

Noţiune de aplicaţie tip fereastră ......................................................................................................... 8

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

Modelul general de mesaje în Windows ............................................................................................. 10

Funcţia principală WinMain() .............................................................................................................. 10

Tratarea evenimentelor în Windows .................................................................................................. 16

Prelucrătorul principal de evenimente ............................................................................................... 17

2. DirectX 9 .............................................................................................................................................. 20

Destinaţia DirectX 9 ............................................................................................................................. 20

Componente DirectX 9 ........................................................................................................................ 21

HAL ...................................................................................................................................................... 22

СОМ ..................................................................................................................................................... 22

Interfaţa IUnknown ............................................................................................................................. 22

Direct3D 9 ............................................................................................................................................ 23

Crearea scenei în Direct3D .................................................................................................................. 24

Interfeţe Direct3D 9 ............................................................................................................................ 25

Crearea pointerului spre interfaţă ...................................................................................................... 26

Instalarea DirectX 9 SDK ...................................................................................................................... 27

3. Iniţializarea Direct3D ........................................................................................................................... 29

Noţiune de iniţializare ......................................................................................................................... 29

Crearea funcţiei de iniţializare Direct3D ............................................................................................. 29

Prelucrarea erorilor în DirectX ............................................................................................................ 39

Rendering, sau desenarea în cadrul ferestrei a aplicaţiei ................................................................... 40

Eliberarea resurselor, ocupate de Direct3D ........................................................................................ 43

4. Desenarea obiectelor 2D ..................................................................................................................... 45

Page 3: SuportDirect3D ROM Lectia1

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

3

Etape ................................................................................................................................................... 45

Setarea formatului vertexurilor .......................................................................................................... 45

Crearea bufferuluii vertexurilor .......................................................................................................... 47

Renderingul obiectului ........................................................................................................................ 52

Desenarea pătratului ........................................................................................................................... 57

5. Matrice în Direct3D ............................................................................................................................. 59

Utilizarea matricelor ............................................................................................................................ 59

Matricea globală .................................................................................................................................. 59

Matricea de vizualizare (view matrix) ................................................................................................. 61

Matricea de proiecţie .......................................................................................................................... 62

6. Afişarea pe ecran a obiectului 3D ....................................................................................................... 66

Crearea vertexurilor ............................................................................................................................ 66

Matrice de transformări ...................................................................................................................... 68

Desenarea cubului ............................................................................................................................... 73

Indexarea vertexurilor ......................................................................................................................... 75

7. Bufferul de adâncime (Z-buffer) .......................................................................................................... 79

Crearea bufferului de adâncime ......................................................................................................... 79

Legarea părţilor ................................................................................................................................... 83

8. Lumini şi materiale .............................................................................................................................. 85

Noţiune de material ............................................................................................................................ 85

Lumină ................................................................................................................................................. 86

Normală ............................................................................................................................................... 88

Iniţializarea luminii şi materialului ...................................................................................................... 91

Page 4: SuportDirect3D ROM Lectia1

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

4

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

DirectX 2.0 / 2.0a 4.03.00.1096 Windows 95 OSR 2 şi Windows NT mai mici de

4.0 5 iunie1996

DirectX 3.0 / 3.0a 4.04.0068 / 69

Windows 95 OSR 2.5 şi Windows NT 4.0 SP3

ultima versiunea DirectX susţinută pentru

Windows NT 4.0

15 septemb 1996

DirectX 4.0 4.05.00.0155

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

DirectX 5.0 4.05.01.1721 /

1998 Windows 98 5 mai 1998

DirectX 6.0 4.06.00.0318

(RC3)

Windows 98 SE ultima versiunea DirectX Media

susţinută pentru Windows NT 4.0. A fost inclus

şi în Dreamcast

7 august 1998

DirectX 6.1 4.06.02.0436

(RC0) Windows 95/98/98SE 3 febr 1999

DirectX 7.0 4.07.00.0700 Windows 2000 şi Windows ME 22 septemb 1999

Page 5: SuportDirect3D ROM Lectia1

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

5

(RC1)

DirectX 7.0a 4.07.00.0716

(RC1) Windows 95/98/98SE/2000 1999

DirectX 8.0 4.08.00.0400

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

DirectX 8.0a 4.08.00.0400

(RC14)

Ultima versiunea DirectX susţinută pentru

Windows 95 7 noiemb 2000

DirectX 8.1

4.08.01.0810

4.08.01.0881

(RC7)

Windows XP 8 noiemb 2001

DirectX 8.1b 4.08.01.0901 ???,2002

DirectX 8.2 4.08.02.0134

(4.09.0000.0134) ???,2002

DirectX 9.0 4.09.0000.0900 Windows Server 2003 24 dec 2002

DirectX 9.0a 4.09.0000.0901 26 martie 2003

DirectX 9.0b 4.09.0000.0902

(RC2) 13 августа2003

DirectX 9.0c 4.09.0000.0904

(RC0)

Windows XP SP2 ultima versiunea DirectX

susţinută pentru Windows 98SE şi Windows Me 9 august 2004

DirectX 9.0L 4.09.0000.0905

(?)

Oferă interfeţele suplimentare IDirect3D9Ex şi

IDirect3DDevice9Ex cu funcţionalitatea

accesibilă numai prin LDDM-driverii SO

Windows Vista.

DirectX 10 (inclus în

componenţa Windows

Vista)

6.0.6000.16386 Prima versiunea Windows Vista. Informaţii

despre Direct3D10 10 noiemb 2006

DirectX 10.1 6.00.6001.18000 Service Pack 1 pentru Windows Vista, Windows

Server 2008 4 febr 2008

DirectX 11 (inclus în

componenţa Windows

7)

6.01.7600.16385

Windows Vista Service Pack 2, Windows 7.

Prezentarea oficială a avut loc la Gamefest 2008.

Informaţii despre Direct3D11

22 iulie 2009

DirectX 11.1 (inclus în

componenţaWindows 8) Windows 8 26 octomb 2012

DirectX 11.2 (inclus în

componenţa Windows

8.1)

Windows 8.1 17 octomb 2013

DirectX 11.3 (inclus în

componenţa Windows

10)

Windows 10 29 iulie 2015

DirectX 12 (inclus în

componenţa Windows

10)

Windows 10 29 iulie 2015

Page 6: SuportDirect3D ROM Lectia1

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

6

În capitolul 1 se descriu bazele programării sub SO Windows, se creează aplicaţia de tip

fereastră. Aplicaţia creată permanent va fi dezvoltată pe parcursul studierii a materialului.

Capitolul 2 reprezintă o introducere în biblioteca DirectX. Aici sunt enumerate componentele

acestei bibliotecii, sunt descrise pe scurt tehnologiile utilizate la crearea DirectX. Sunt prezentate

informaţii despre СОМ, Direct3D, conceptul de creare a scenelor în Direct3D. În sfârşit, este

descrisă instalarea DirectX 9 SDK pe calculator.

În capitolul 3 sunt expuse informaţii cheie despre etapa iniţială de utilizare a Direct3D —

iniţializarea Direct3D, crearea dispozitivului Direct3D şi reglarea dispozitivelor.

În capitolul 4 ce creează şi se afişează pe ecran una din cele mai simple figuri – un triunghi

simplu. Se foloseşte bufferul vertexurilor şi conveierul de randare. Astfel se obţin informaţii

principale despre geometria scenei în Direct3D.

Capitolul 5 este consacrat matricelor. Matricele joacă un rol foarte important în Direct3D.

În capitolul 6 este examinată afişarea pe ecran unui obiect tridimensional adevărat. Este expus

conceptul de indexare a vertexurilor.

În capitolul 7 este descris bufferul de adâncime. Sortarea pixelilor după distanţa până la

observator — iată pentru ce este necesar bufferul de adâncime, se mai numeşte şi Z-buffer.

Capitolul 8 conţine informaţii despre materiale ţi lumini. Sunt descrise modele de iluminare,

informaţii despre surse de lumină, principiile de interacţiune a materialului cu iluminarea

obiectului. Anume în baza acestor principii se construieşte percepţia culorilor de către

observator. Tot în capitolul acesta sunt cercetaţi şi vectori normali, care se folosesc la calcularea

iluminării.

În capitolul 9 sunt descrise bazele ale texturării. Se examinează metoda standard de suprapunerea

texturilor pe obiect.

Capitolul 10 continuă tema capitolului precedent prin expunerea materialului despre

multitexturare.

În capitolul 11 se descrie afişare de texte. Afişarea textului pe ecran este foarte importantă pentru

diferite aplicaţii (de exemplu, jocuri). la sfârşitul capitolului se discută modul de trecere de la

aplicaţia tip fereastră la aplicaţia tip ecranul plin (fullscreen).

În capitolul 12 В следующем разделе рассматривается вопрос загрузки модели, сделанной

сторонним ЗD-редактором şi конвертированной в Х-формат.

În capitolul 13 Далее рассматриваются устройства ввода, представленные интерфейсом

DirectInput.

În capitolul 14 Рассматривается работа с клавиатурой

În capitolul 15и мышью.

În capitolul 16 Последующие разделы посвящены звуку. Для этих целей в DirectX

существуют интерфейсы DirectMusic

Page 7: SuportDirect3D ROM Lectia1

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

7

În capitolul 17 şi DirectSound.

În capitolul 18 Следующий раздел представляет введение в тематику вершинных

шейдеров. Этот большой теоретический раздел раскрывает общую концепцию работы

вершинных шейдеров, затрагивая вершинные шейдеры первой версии.

Page 8: SuportDirect3D ROM Lectia1

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

8

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).

Page 9: SuportDirect3D ROM Lectia1

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

9

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);

Page 10: SuportDirect3D ROM Lectia1

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

10

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.

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,

Aplicaţia

fereastră 1

Aplicaţia

fereastră 2

Coadă

evenimen.

Windows

Coadă

mesaje ap.1

Coadă

mesaje ap.2

Page 11: SuportDirect3D ROM Lectia1

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

11

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:

Page 12: SuportDirect3D ROM Lectia1

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

12

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);

Page 13: SuportDirect3D ROM Lectia1

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

13

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;

Page 14: SuportDirect3D ROM Lectia1

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

14

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;

Page 15: SuportDirect3D ROM Lectia1

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

15

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

Page 16: SuportDirect3D ROM Lectia1

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

16

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.);

Page 17: SuportDirect3D ROM Lectia1

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

17

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,

Page 18: SuportDirect3D ROM Lectia1

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

18

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

Page 19: SuportDirect3D ROM Lectia1

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

19

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.


Recommended