Open GL Pierwszy program


Warsztat - Programowanie gier komputerowych :: Open GL - Pierwszy program







Strona główna Forum Szukaj Lista użytkowników
Grupy
Zarejestruj Zaloguj

Artykuły
Kliknij na kategorię żeby dodać artykuł Szukaj
Programowanie gier » Artykuły » Grafika 3D [Wersja do
drukowania]
Open GL - Pierwszy program
Opis Jak powinien wyglądać szablon applikacji
wykożystującej biblioteke OpenGL.
Autor Wojciech Dudek Data Czw 07 Paź, 2004 10:56 pm Typ
***
Słowa klucze
Kategoria Grafika 3D
Odsłony 959


Open GL - Pierwszy program
Jak powinien wyglądać szablon applikacji wykożystującej
biblioteke OpenGL.

Wstęp, czyli po co komu ten artykułOpisy Open GL można
znaleźć w wielu miejscach (książki, pliki z sieci itp.).
W większości jednak są one albo bardzo nieprecyzyjne,
albo bardzo szerokie, co skutecznie do nich zniechęca
osoby chcące zacząć zabawę z grafiką 3D.
W tym artykule chcę przedstawić podstawowy program w
standardzie GL, od jakiego powinno się zaczynać.
Konkretnie, bez zbytniego wgłębiania się opiszę, jak
zbudować pierwszą aplikację korzystającą z Open GL.
Uwierzcie mi 90% rozbudowanych programów w GL opiera się
na niej.
W opisie tym nie ma podanych nagłówków funkcji wraz z
opisem, zakładam, że każdy coś na ten temat ma. Są za to
dość dokładnie opisane kolejne kroki przykładowego
programu.
Mam nadzieję, że artykuł będzie pomocą w rozpoczęciu
programowania w Open GL.

1. Co jest potrzebne do pisania programów w Open GL.

Kompilator języka C/C++ generujący kod 32 bitowy,
czyli po ludzku taki, na którym można tworzyć programy
pod Win 95 (lub nowszym),

Biblioteki statyczne Open GL: opengl32.lib i
glu32.lib,

Pliki nagłówkowe Open GL: gl.h i glu.h,

W systemie MUSI znajdować się sterownik Open GL o
nazwie opengl32.dll i biblioteka pomocnicza glu32.dll.
Mogą być w katalogu programu, albo w podkatalogu
Windows'a /System,

Bardzo zalecany byłby akcelerator 3D, chociaż nie jest
konieczny.
Wszystko to (oprócz bibliotek .dll) jest w pliku do
tego artykułu gl.rar.

Uwaga 1: Biblioteki statyczne (lib) są różne dla Borland
C++ i Visual C++. Są w podkatalogach: /libBOR i /libVC.
Uwaga 2: Sterownik opengl32.dll dla niektórych kart może
mieć inną nazwę. No cóż, trzeba poeksperymentować (np.
skopiować go do katalogu programu i zmienić nazwę).

2. Szkielet programu w Open GL.
Głównym plikiem programu jest gl.cpp.
Jest to standardowy program pod Win 95, w API.
Jest funkcja WinMain:

int WINAPI WinMain(HINSTANCE Zad,HINSTANCE, LPSTR,int
To)

która inicjuje okno i rozpoczyna cykl obsługi
komunikatów.

W programie Open GL we właściwościach okna należy
wpisać:
WS_CLIPCHILDREN i WS_CLIPSIBLINGS, zalecam też WS_POPUP,
czyli pracę na pełnym ekranie.

Dalej znajduje się funkcja która obsługuje komunikaty:


LRESULT CALLBACK ProcOkna(HWND Okno,UINT Kom,WPARAM
WP,LPARAM LP)


Interesują nas zdarzenia:
. Rozpoczęcie programu: WM_CREATE,
. Naciśnięcie klawisza: WM_KEYDOWN,
. Zmiany rozmiaru okna: WM_SIZE,
. Zakończenia programu: WM_DESTROY,
. Odrysowywania zawartości okna: WM_PAINT.

Program Open GL podczas rozpoczęcia programu inicjuje
pewne rzeczy (o tym dalej). Odrysowanie zawartości okna
to najlepsza część programu (GL rendering). Musimy
wychwycić naciśnięcie klawiszy: kursorów, Entera i Esc.
Na końcu programu pewne rzeczy należy doprowadzić do
stanu przed jego uruchomieniem. Zmiana rozmiaru okna nam
raczej nie grozi-rysujemy po całym ekranie. Z pewnych
jednak względów ten komunikat będzie jednak potrzebny.

3. Inicjalizacja Open GL.
Jest realizowana w ramach komunikatu WM_CREATE, i jest
to najdłuższa (i niezbędna) część programu.

Po kolei działa to tak:

hDC=GetDC(Okno); //Pobranie tzw. kontekstu
okna
SetDCPixelFormat(hDC); //Ustawienie formatu
pixeli (o tym poniżej)
hRC=wglCreateContext(hDC); //Stworzenie tzw.
kontekstu Open GL
wglMakeCurrent(hDC, hRC); //I ustawienie go
glViewport(0,0,GetSystemMetrics( SM_CXSCREEN
),GetSystemMetrics( SM_CYSCREEN ));
// Ustawienie widoku, czyli tej części ekranu, na
której będziemy renderować. W tym przypadku
cały ekran
gluPerspective(90.0f,1.0f,1.0f,1000.0f);
//Ustawienie tzw. ostrosłupa widzenia. Kamera będzie
mieć pole widzenia 90 stopni, będzie widzieć obiekty
położone względem niej od 1 pixla do 1000 pixli,
i będzie widzieć obiekty nie zniekształcone
glEnable(GL_DEPTH_TEST); //Włączenie
usuwania powierzchni zasłoniętych
glDepthFunc(GL_LEQUAL); //Taki nieistotny
szczegół związany z powyższym, można usunąć

glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST);
//tzw. korekcja, tekstura będzie "ładnie" nałożona
glEnable(GL_CULL_FACE); //usuwanie
wielokątów odwróconych tyłem do obserwatora. Stosowane w
grach,
na razie można wyłączyć.

I to tyle niezbędnych ustawień. Teraz tylko trzeba
załadować tekstury, których będziemy używać. W
przykładzie są dwie: t0.bmp i t1.bmp.

Tu małe wyjaśnienie po co jest plik pomoc.cpp. W tym
pliku znajdują się procedury ładujące bitmapę oraz
ustawiające format pixeli. Na razie można je traktować
jako coś co jest i nie ważne skąd się wzięło. Nie jest
to potrzebne do zrozumienia programu.

Za załadowanie tekstur odpowiada fragment kodu:

bits = LoadDIBitmap("t1.bmp",&info);
rgb = ConvertRGB(info, bits);

glBindTexture(GL_TEXTURE_2D,1); // od tego momentu
tekstura "t1.bmp" jest pod uchwytem 1

glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);

glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);

glTexImage2D(GL_TEXTURE_2D, 0, 3,
info->bmiHeader.biWidth, info->Header.biHeight, 0,
GL_RGB, GL_UNSIGNED_BYTE, rgb);

free(info);
free(bits);
free(rgb);

Pewne fragmenty kodu powtarzają się w komunikacie
WM_SIZE. Jest to niestety konieczne, ze względu na
właściwość API, która "traci" pewne ustawienia przy
wyświetlaniu okna (które traktuje jako zmianę
rozmiarów).

Od tego momentu można zająć się już ciekawszymi
sprawami.

4. Klawiatura.
Podczas obsługi komunikatu WM_KEYDOWN rejestrujemy
naciśnięcia kursorów (konkretnie zmieniamy pewne kąty, o
których za chwilę), Entera (zmienia sposób renderowania)
i Esc (wyjście z programu).

5. Wyjście z programu.
I usuwamy ten którego używaliśmy:

wglDeleteContext(hRC);


6. Rendering.
Czyli najważniejsza część programu.

Renderowanie jest realizowane podczas obsługi komunikatu
WM_PAINT. Niektóre źródła podają, że można je włączyć do
pętli obsługi komunikatów. Ma to zaletę w postaci
zwiększenia szybkości (minimalnie). Wadą natomiast jest
możliwość utraty niektórych zdarzeń np. naciśnięcia
klawisza. Ja proponuję pozostać przy WM_PAINT.

W naszym programie za renderowanie odpowiada funkcja
void RenderujX(void); gdzie X to nr od 0 do 3. Cztery
funkcje renderujące na cztery różne sposoby.

Obsługa WM_PAINT wygląda tak:

Renderuj0(); //Renderuje funkcja 0
SwapBuffers(hDC); //tzw. przerzucenie buforów, mające
zapobiec migotaniu obrazu.

Zajmijmy się teraz funkcją renderującą. Najprostsza jest
Renderuj0, rysująca ładnie pokolorowany trójkąt:


void Renderuj0(void)
{

Najpierw wyłączamy texturowanie:

glDisable(GL_TEXTURE_2D);

Teraz czyścimy bufory koloru i tzw Bufor Z:

glClearColor(0.50f, 0.50f, 0.50f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glClear(GL_DEPTH_BUFFER_BIT);

Zerujemy macierz transformacji:

glLoadIdentity();

Sprawdzamy, czy kąty o które obrócimy trójkąt są w
granicach <0, 360) stopni:

if(KatX<0.0f) KatX+=360.0f;
if(KatX>=360.0f) KatX-=360.0f;

if(KatY<0.0f) KatY+=360.0f;
if(KatY>=360.0f) KatY-=360.0f;

Teraz ważna część. Chcemy obrócić trójkąt mniej więcej
względem jego środka ciężkości o odpowiednie kąty KatX i
KatY. W tym celu przesuwamy obserwatora do środka
(plus/minus) trójkąta, obracamy i oddalamy obserwatora z
powrotem. Tu należy zwrócić uwagę na ciekawą właściwość
macierzy transformacji: transformacje Open GL należy
przeprowadzać "od końca". Dlaczego ? Jak ktoś chce niech
sobie pomnoży kilka macierzy i będzie wiedział. Dla
naszych potrzeb wystarczy wiedzieć, że jeśli chcemy
obiekt najpierw przybliżyć (glTranslate), a potem
przekręcić (glRotate), to należy użyć: glRotate,
glTranslate:

glTranslatef(0.0f,0.0f,-200.0f);
glRotatef(KatY,1.0f,0.0f,0.0f);
glRotatef(KatX,0.0f,1.0f,0.0f);
glTranslatef(0.0f,0.0f,200.0f);

Teraz już tylko narysowanie trójkąta. W tym celu używamy
"klamer" glBegin...glEnd, wewnątrz których umieszczamy
wierzchołki trójkąta. Dodatkowo każdy wierzchołek
kolorujemy innym kolorem:

glBegin(GL_TRIANGLES);
glColor3f(1.0f, 0.0f, 0.0f);
glVertex3f(150.0f,-150.0f,-200.0f);

glColor3f(0.0f, 1.0f, 0.0f);
glVertex3f(0.0f,150.0f,-200.0f);

glColor3f(0.0f, 0.0f, 1.0f);
glVertex3f(-150.0f,-150.0f,-200.0f);

glEnd();

Na koniec informujemy Open GL o skończonym renderingu.
Teraz niech się martwi akcelerator (albo ostatecznie
procesor).

glFinish();
}

Funkcja Renderuj1 jest znacznie ciekawsza, przedstawia
teksturowany trójkąt. Nowe elementy to:
Włączenie texturownia:

glEnable(GL_TEXTURE_2D);

Włączenie textury pierwszej:

glBindTexture(GL_TEXTURE_2D,1);

I podanie współrzędnych nabitmapie dla każdego
wierzchołka:

glTexCoord2f(0.0f,0.0f);

Funkcja Renderuj2 to połączenie obu poprzednich.

Funkcja Renderuj3 pokazuje efekt Light Map'owania, czyli
nakładania na teksturę światła obliczonego wcześniej
(efekt stosowany w grach 3D). Realizuje się to przez
dwukrotne nałożenie tekstury (zwykłej + światło). W
nowych kartach 3D (od VooDoo 2) robi się to w jednym
przebiegu na raz, ale efekt jest ten sam.

Z nowych rzeczy występują funkcje mieszające nałożone
tekstury:

glEnable(GL_BLEND);
glBlendFunc(GL_DST_COLOR,GL_SRC_COLOR);

W programie Light Map'a została narysowana w Paint'cie,
dlatego wygląda niezbyt ciekawie. Ale idea jest
właściwa.

7. Co dalej?
Dalej niech każdy poeksperymentuje sam... Proponuję
rozbudować program tak, żeby wyświetlał np. więcej
wielokątów, jakiś sześcian, może prosty engine 3D w
stylu Wolfa. Na podstawie tego kodu dużo da się zrobić.

8. Jak stąd daleko do Quake 3?
No cóż, to pytanie jest raczej bardziej śmieszne niż
poważne, ale nie do końca... Funkcje renderujące w
enginach 3D nie różnią się bardzo. Należy zauważyć, że
obecnie każdy może bawić się w programowanie silniczka
3D korzystającego z akceleratora. W Quake 1 w renderingu
programowym też jest funkcja rysująca trójkąt. Ile
autorowi zajęło jej napisanie ? Miesiąc, dwa, albo
więcej. Do tego konieczność stosowania asemblera...
Straszne ! Open GL rozwiązuje to w kilku linijkach kodu.


9. Open GL kontra Direct 3D.

Zalety GL:

Bardzo łatwy w porównaniu w D3D,

Nieobiektowy, GL to raczej konsola do grafiki,

Ma więcej bajerów graficznych niż D3D,

Lepiej działa na VooDoo,

Dużo opisów dostępnych w sieci.
Wady GL:

Brak funkcji więżących program ze sterownikiem,

Zaawansowane właściwości GL (np. multiteksturowanie)
są zawarte w tzw. GL Extensions, co zmusza do
dokładnego badania używanego sterownika.


D3D nie ma dwóch ostatnich wad, jest za to strasznie
skomplikowany.

Przeważnie jednak przydaje się znajomość obu, cóż takie
czasy.

Powodzenia !

Wojciech Dudek

Opinie, pytania, sugestie kierować na adres:

wojdudek@poczta.onet.pl
http://www.redchaos.republika.pl


Skocz do: Wybierz forumWarsztat - Programowanie
gier komputerowych|--Szkółka| |--Szkółka -
języki| |--Szkółka - grafika| |--Szkółka -
inne|--Programowanie gier| |--Ogólnie|
|--Dźwięk| |--Sztuczna Inteligencja|
|--Inne|--Programowanie grafiki|
|--Programowanie grafiki| |--OpenGL|
|--DirectX|--Produkcja| |--Pomysły|
|--Projektowanie| |--Projekty| |--Grafika|
|--Ogłoszenia|--O czym innym| |--Konferencje,
spotkania| |--Warsztat| |--Aktualności|
|--Artykuły| |--Wykłady| |--Compo|
|--Lepperlandia|--Śmietnik| |--Z odrzutu



Powered by Knowledge Base, wGEric (C) 2002 PHPBB.com MOD
This script (Knowledge Base - MX Addon v. 1.03e) is modified
by Haplo





W1.5b (C) 2004
[admin: ayufan, g[R]eK, Goliatus, mikael_, Regedit]
Wszystkie czasy w strefie CET (Europa)

Powered by phpBB2 Plus 1.52 based on phpBB 2.0.10 © 2001, 2002 phpBB
Group :: FI Theme :: Mody i Podziękowania












Wyszukiwarka

Podobne podstrony:
Open GL Pierwszy program
Elektronika Analogowa Kurs Bascom Avr W Przykĺ‚Adach Pierwszy Program
kurs open gl
Open GL Podstawy
1 TurboPascal Pierwsze programy
01 mój pierwszy program kod
1 Pierwszy program konsolowyid?47
pierwszy Program
pierwsze 5 programów
2006 02 Qt ISO Maker–moja pierwsza aplikacja w Qt [Programowanie]
labolatoria komputerowe =programy pierwszazaawazmatlabem
labolatoria komputerowe =programy pierwszezaj
programowanie mikrokontrolerow 8051 w jezyku c pierwsze kroki rapidshare
Java Programowanie, biblioteki open source i pomysly na nowe projekty
2004 05 Tworzenie modułów jądra – ten pierwszy raz [Programowanie]
program sprawdzający czy liczba jest pierwsza

więcej podobnych podstron