Strona główna
Kursy
Artykuły
Forum
Pliki
Promuj Nas!
[Kurs OpenGL, C++] III. Definiowanie sceny 3D
http://kursy.ddt.pl/?LessonId=181
1 z 9
2010-04-30 14:22
Powrót
Historia odwiedzonych stron
Poprzednia lekcja
Kurs OpenGL, C++
Następna lekcja
Autor: Janusz Ganczarski
http://januszg.hg.pl/opengl/
III. Definiowanie sceny 3D
W kolejnych programach korzystajacych z biblioteki OpenGL zajmiemy sie podstawowymi zagadnieniami,
zwiazanymi ze scena 3D: obszarem renderingu, rzutowaniem i połozeniem obserwatora. Informacje tu zawarte
stanowia podstawe do wszystkich nastepnych programów.
3.1. Obszar renderingu
W pierwszym programie obszar renderingu, który zajmował początkowo całe okno, nie był modyfikowany
podczas zmiany rozmiarów tego okna. W efekcie jedyny element sceny 3D - kwadrat - zawsze znajdował sie w
tym samym miejscu wzgledem lewego dolnego naroznika okna. W aplikacjach pracujacych w systemach
okienkowych problem zmiany rozmiaru okna jest jednak tak powszechny, ze wymaga specjalnego potraktowania.
Jednym z mozliwych sposobów jego rozwiazania jest dynamiczna
modyfikacja obszaru renderingu. Słuzy to tego funkcja:
void
glViewport (GLint x, GLint y, GLsizei width, GLsizei height)
której parametry oznaczaja:
x, y - współrzedne lewego dolnego naroznika obszaru renderingu względem lewego dolnego naroznika
okna,
width - szerokosc okna renderingu,
height - wysokosc okna renderingu.
Domyslnie obszar renderingu zajmuje całe okno udostepnione dla aplikacji OpenGL. W naszym drugim
programie w trakcie zmiany rozmiaru okna (funkcja Reshape) bedziemy modyfikowac obszar renderingu na dwa
sposoby.
Pierwszy polega na objeciu obszarem renderingu całego dostępnego okna, drugi na takim wyborze okna
renderingu aby okno zachowało pierwotny aspekt obrazu, czyli stosunek szerokosci do wysokosci. Oczywiście
przy zastosowaniu pierwszej metody kwadrat bedzie zazwyczaj zdeformowany (patrz rysunki 1 i 2). Zmiany
sposobu definiowania okna renderingu mozna dokonac w dowolnym momencie, poprzez wybranie odpowiedniej
opcji w menu podrecznym.
W funkcji Menu została uzyta do tej pory nieopisana funkcja z biblioteki GLUT:
int
glutGet (GLenum type)
O tym jakiego rodzaju informacje zwróci funkcja glutGet decyduje parametr type. W przykładowym
programie sa to szerokosc i wysokosc okna, co odpowiada parametrom opisanym stałymi GLUT WINDOW
WIDTH i GLUT WINDOW HEIGHT.
Warto jeszcze kilka słów poswiecic zagadnieniu aspektu obrazu. Typowe monitory komputerowe posiadaja
aspekt 4:3, który jest zgodny z większością popularnych rozdzielczosci roboczych (np. 640 × 480, 800 × 600,
1.024 × 768, 1.600 × 1.200), ale inna popularna rozdzielczosc 1.280 × 1.024 pikseli odpowiada aspektowi 5:4.
Rysunek 1. P rogramu K wadrat 2 - rendering na całym oknie
Rysunek 2. P rogramu K wadrat 2 - rendering z zachowaniem as pektu 1:1
3.1.1. Plik kwadrat2.cpp
P anel Logowania
dast19
Administracja
Twój profil
Wyloguj
Uż yt kowników
Obecnie aktywnych:
14
Zalogowanych:
2
Zarejestrowanych:
3855
Ostatnie 24h:
646
Non-cookie 24h:
2051
Wszystkich:
178944
O c z e kuj ąc e t e mat y
Lista jest pusta.
Pokaż wszystkie (0)
Os tatnia Aktualizacja
2010-04-29 22:01:07
(wczoraj)
O st atnio akt ywni
dast19
1 min
Piotr Szawdyński
5 min
Iname
(√ιק)
17 min
szywro5
29 min
Saiph
34 min
markon
57 min
imandre
75 min
WunM
93 min
kuba1817
2 godz
killersft
2 godz
fish13
2 godz
kizia
2 godz
Szkolenia: programowanie
Bazy danych, SQL,
projektowanie. PHP. AJAX.
Java. Python. (WAW, KRK)
akademia.linuksa.pl
Kurs programowania 699zł
50%teoria 50%praktyki - 120
godzin nauka w
centrum,male grupy 5-10 os
www.gowork.pl
[Kurs OpenGL, C++] III. Definiowanie sceny 3D
http://kursy.ddt.pl/?LessonId=181
2 z 9
2010-04-30 14:22
/*
(c) Janusz Ganczarski
http://www.januszg.hg.pl
JanuszG(małpeczka)enter.net.pl
*/
#include <GL/glut.h>
#include <stdlib.h>
// stałe do obsługi menu podręcznego
enum
{
FULL_WINDOW,
// obszar renderingu - całe okno
ASPECT_1_1,
// obszar renderingu - aspekt 1:1
EXIT
// wyjście
};
// aspekt obrazu
int
Aspect = FULL_WINDOW;
// funkcja generująca scenę 3D
void
Display ()
3.2. Rzutowanie prostokątne
Rzutowaniem okreslamy odwzorowanie zawartosci trójwymiarowej sceny graficznej na płaskim ekranie
monitora. Biblioteka OpenGL oferuje standardowo dwie metody rzutowania: rzutowanie prostokatne i rzutowanie
perspektywiczne. Domyslnie stosowane jest rzutowanie prostokatne. W rzutowaniu prostokatnym (lub
ortogonalnym) proste rzutowania sa prostopadłe do rzutni, która jest reprezentowana przez obszar renderingu. Z
rzutowaniem prostokatnym scisle zwiazane jest pojecie bryły odcinania -
prostopadłoscianu, który stanowi ograniczenie sceny 3D. Obiekty znajdujące sie poza bryła odcinania nie
sa rysowane, a obiekty ja przecinajace rysowane sa tylko czesciowo. Rozmiar bryły odcinania w rzutowaniu
prostokatnym okresla funkcja:
void
glOrtho (GLdouble left, GLdouble right, GLdouble bottom, GLdouble
top, GLdouble near, GLdouble far)
której parametry okreslaja współrzedne punktów przeciecia płaszczyzn tworzących bryłe odcinania z osiami
układu współrzednych kartezjanskich. Płaszczyzny te opisane sa nastepujacymi równaniami:
x = right
x = left
y = top
y = bottm
z = −near
z = −far
Obszar renderingu zawiera sie w płaszczyznie o równaniu z = −near. Połozenie poszczególnych płaszczyzn
tworzacych bryłe odcinania przedstawia rysunek 3. Trzeba jednak wyraznie zwrócic uwage, ze poczatek układu
współrzednych nie musi znajdowac sie wewnatrz bryły odcinania – rozmiary i połozenie bryły ograniczone sa
jedynie zakresem stosowanych liczb.
Rysunek 3. P ołozenie płas zczyzn bryły odcinania w rzutowaniu pros tokatnym
Domyslnie bryła odcinania ma postac szescianu o bokach równych 2, którego srodek pokrywa sie z
poczatkiem układu współrzednych, co odpowiada wywołaniu funkcji glOrtho (-1,1,-1,1,-1,1). Os OZ jest
prostopadła do płaszczyzny obszaru renderingu i przechodzi przez srodek tego obszaru. Dlatego rysowany w
pierwszym i drugim programie kwadrat zajmował poczatkowo czwarta czesc okna.
Funkcja glOrtho tworzy macierz rzutu prostokatnego:
która jest nastepnie mnozona przez biezaca macierz i umieszczona na szczycie stosu z biezaca macierza.
OpenGL zawiera kilka stosów macierzy, z których w przykładowym programie wykorzystamy stos macierzy
[Kurs OpenGL, C++] III. Definiowanie sceny 3D
http://kursy.ddt.pl/?LessonId=181
3 z 9
2010-04-30 14:22
rzutowania oraz stos macierzy modelowania. Wybór biezacej macierzy umozliwia funkcja:
void
glMatrixMode (GLenum mode)
gdzie parametr mode moze przyjac jedna z wartosci:
GL MODELVIEW - macierz modelowania,
GL PROJECTION - macierz rzutowania,
GL TEXTURE - macierz tekstury (omówiona pózniej).
Poniewaz poczatkowa wartosc wybranej macierzy jest nieokreslona, przed wywołaniem glOrtho nalezy
biezacej macierzy przyporzadkowac macierz jednostkowa. Najłatwiej mozna to zrobic uzywajac funkcji:
void
glLoadIdentity (
void
)
Analogiczne postepowanie dotyczy macierzy modelowania. Po jej wyborze przykładowym programie (plik
szescian1.cpp) w funkcji Display macierzy modelowania takze przyporzadkowywana jest macierz jednostkowa.
Jezeli renderowana scena jest dwuwymiarowa, do ustawienia parametrów bryły odcinania w rzutowaniu
prostokatnym mozna uzyc funkcji z biblioteki GLU:
void
gluOrtho2D (GLdouble left, GLdouble right, GLdouble bottom, GLdouble
top)
której parametry left, right, bottom i top odpowiadaja parametrom funkcji glOrtho, a przednia (near) i tylna
(far) płaszczyzna obcinania maja wartosci odpowiednio -1 i 1. W przykładowym programie poczatkowa bryła
odcinania ma postac sześcianu o krawedziach długosci 4, a rysowana figura - takze szescian – ma krawedzie o
długosci 2. Centralne umieszczenie rysowanego szescianu w połaczeniu z zastosowanym rzutowaniem
prostokatnym daje w efekcie kwadrat (patrz rysunek 4). Podobnie jak w poprzednim programie mozliwy jest
wybór, czy scena ma byc rysowana z zachowaniem poczatkowego aspektu obrazu czy tez bez zachowania tej
proporcji. Jednak w tym przypadku nie jest modyfikowany obszar renderingu ale współrzedne bryły odcinania
(funkcja Reshape).
Rysunek 4. P oczatkowe okno programu Szes cian 1
3.2.1. Plik szescian1.cpp
/*
(c) Janusz Ganczarski
http://www.januszg.hg.pl
JanuszG(małpeczka)enter.net.pl
*/
#include <GL/glut.h>
#include <stdlib.h>
// stałe do obsługi menu podręcznego
enum
{
FULL_WINDOW,
// aspekt obrazu - całe okno
ASPECT_1_1,
// aspekt obrazu 1:1
EXIT
// wyjście
};
// aspekt obrazu
int
Aspect = FULL_WINDOW;
// funkcja generująca scenę 3D
void
Display ()
3.3. Rzutowanie perspektywiczne
Rzutowanie perspektywiczne daje bardziej realistyczne efekty niz rzutowanie prostokatne, stad jest szeroko
stosowane np. w grach. Parametry bryły odcinania, która przy rzutowaniu perspektywicznym ma postac
[Kurs OpenGL, C++] III. Definiowanie sceny 3D
http://kursy.ddt.pl/?LessonId=181
4 z 9
2010-04-30 14:22
ostrosłupa scietego o wierzchołku znajdujacym sie w poczatku układu współrzędnych (patrz rysunek 5), okresla
funkcja:
void
glFrustum (GLdouble left, GLdouble right, GLdouble bottom, GLdouble
top, GLdouble near, GLdouble far)
Parametry left, right, bottom i top wyznaczaja rozmiary górnej podstawy bryły odcinania (jest to obszar
bezposrednio odwzorowywany na obszar renderingu), a near i far wyznaczaja połozenie odpowiednio górnej i
dolnej podstawy ostrosłupa (przedniej i tylnej płaszczyzny odcinania), które zawieraja sie w płaszczyznach o
równaniach: z = −near i z = −far. Parametry near i far musza miec wartosci dodatnie.
Macierz rzutowania perspektywicznego, tworzona przez funkcje glFrustum i mnozona przez aktualnie
wybrana macierz, ma postac:
Warto zauwazyc, ze precyzja działania jeszcze przez nas nieużywanego z-bufora, zalezy od wartosci
stosunku parametrów near i far:
Rysunek 5. P ołozenie płaszczyzn bryły odcinania w rzutowaniu pers pektywicznym
Im wieksza wartosc r, tym mniej efektywne jest działanie z-bufora. Oczywiście near nigdy nie moze przyjac
wartosci równej 0, bowiem przednia płaszczyzna odcinania przechodziła by wówczas przez srodek perspektywy.
Alternatywny sposób okreslania rzutu perspektywicznego umozliwia funkcja z biblioteki GLU:
void
gluPerspective (GLdouble fovy, GLdouble aspect, GLdouble zNear,
GLdouble zFar)
gdzie parametr fovy okresla w stopniach kat widzenia obserwatora zawarty w płaszczyznie YZ (6 (top, 0,
bottom)), a aspect jest stosunkiem szerokości do wysokosci przedniej płaszczyzny odcinania, czyli górnej
podstawy ostrosłupa ograniczajacego scene 3D. Parametry zNear i zFar odpowiadaja parametrom near i far
funkcji glFrustum. Macierz rzutowania perspektywicznego, tworzona przez funkcje gluPerspective
i mnozona przez aktualnie wybrana macierz, ma postac:
Wewnetrznie funkcja gluPerspective wykorzystuje do ustawienia macierzy rzutowania perspektywicznego
funkcje glFrustum. Oto wzory przekształcenia parametrów funkcji gluPerspective na parametry glFrustum:
W kolejnym przykładowym programie (plik szescian2.cpp) do utworzenia macierzy rzutowania
perspektywicznego wykorzystamy funkcje glFrustum. Przednia płaszczyzna odcinania bedzie miała takie same
rozmiary jak w poprzednim programie. Zmianie ulegna natomiast współrzedne przedniej i tylnej płaszczyzny
obcinania - poprzednio jedna z tych płaszczyzn miała wartosc ujemna, której nie akceptuje funkcja glFrustum.
Rysowanym obiektem ponownie bedzie szescian ale próba narysowania go w tym samym miejscu jak w
poprzednim programie spowoduje, ze będzie widoczna tylko jedna jego sciana. Wszystko dlatego, ze pozostałe
sciany szescianu znajduja sie poza obszarem bryły odcinania. Mozliwe sa trzy sposoby rozwiazania tego
problemu. Pierwszy polega na zmianie współrzędnych wierzchołków szescianu w taki sposób, aby szescian
zmiescił sie w zmienionej bryle obcinania. Rozwiazanie to ma jedna zasadnicza wade – wierzchołki szescianu
trzeba bedzie modyfikowac przy kazdej zmianie parametrów sceny 3D. W przypadku jednego obiektu nie
stanowi to specjalnego problemu, ale czyni pomysł niewykonalnym przy kazdej bardziej skomplikowanej scenie
3D.
Drugie, zastosowane w programie rozwiazanie, polega na przesunieciu wierzchołków szescianu o wektor [0,
[Kurs OpenGL, C++] III. Definiowanie sceny 3D
http://kursy.ddt.pl/?LessonId=181
5 z 9
2010-04-30 14:22
0,−3], czyli o -3 jednostki wzdłuz osi OZ. Realizuje to funkcja glTranslatef, która wywoływana jest bezpośrednio
po zainicjowaniu macierzy modelowania macierza jednostkowa (patrz funkcja Display). W efekcie otrzymamy
szescian przedstawiony na rysunku 6. Nalezy dodac, ze taka metoda jest czesto stosowana praktyka. Obiekty 3D
definiowane sa z róznymi współrzednymi, a nastepnie odpowiednio transformowane do docelowego połozenia w
scenie 3D. Funkcje umożliwiające takie przekształcenia poznamy blizej w nastepnym odcinku kursu. Trzecia
metoda jest modyfikacja połozenia obserwatora sceny 3D - zapoznamy się z ta technika jeszcze w tym odcinku.
Rysunek 6. P oczatkowe okno programu Szes cian 2
3.3.1. Plik szescian2.cpp
/*
(c) Janusz Ganczarski
http://www.januszg.hg.pl
JanuszG(małpeczka)enter.net.pl
*/
#include <GL/glut.h>
#include <stdlib.h>
// stałe do obsługi menu podręcznego
enum
{
FULL_WINDOW,
// aspekt obrazu - całe okno
ASPECT_1_1,
// aspekt obrazu 1:1
EXIT
// wyjście
};
// aspekt obrazu
int
Aspect = FULL_WINDOW;
// funkcja generująca scenę 3D
void
Display ()
Drugi program przedstawiajacy rzutowanie perspektywiczne (plik szescian3.cpp) stosuje funkcje
gluPerspective. Aby jednak nie powielac rozwiązań z poprzedniego programu dodamy mechanizm pokazujacy
jaki wpływ na wyglad obiektów 3D ma zmiana połozenie srodka perspektywy, realizowana
poprzez zmiane kata widzenia obserwatora (parametr fovy funkcji gluPerspective). W tym celu potrzebna
jest obsługa klawiatury. Podstawowa funkcja obsługi klawiatury (w przykładowym programie jest to funkcja
Keyboard) ma trzy parametry:
key - kod ASCII klawisza,
x, y - współrzedne kursora myszki w chwili nacisniecia przycisku klawiatury.
Aby obsługa klawiatury działała, w czesci głównej programu nalezy włączyć funkcje obsługi klawiatury
wywołujac funkcje:
void
glutKeyboardFunc (
void
(*func)(
unsigned
char
key,
int
x,
int
y))
Poczatkowe okno programu Szescian 3 zawiera rysunek 7. Przyciskając klawisze „+” i „-” mozna
modyfikowac kat patrzenia obserwatora, który poczatkowo wynosi 90 stopni.
[Kurs OpenGL, C++] III. Definiowanie sceny 3D
http://kursy.ddt.pl/?LessonId=181
6 z 9
2010-04-30 14:22
Rysunek 7. P oczatkowe okno programu Szes cian 3
3.3.2. Plik szescian3.cpp
/*
(c) Janusz Ganczarski
http://www.januszg.hg.pl
JanuszG(małpeczka)enter.net.pl
*/
#include <GL/glut.h>
#include <stdlib.h>
// stała do obsługi menu podręcznego
enum
{
EXIT
// wyjście
};
// pionowy kąt pola widzenia
GLdouble fovy = 90;
// funkcja generująca scenę 3D
void
Display ()
{
// kolor tła - zawartość bufora koloru
3.4. Położenie obserwatora
Ostatnim z podstawowych elementów wymagajacych omówienia przy tworzeniu sceny 3D jest połozenie
obserwatora, nazywane takze położeniem kamery lub „oka”. Domyslnie obserwator w OpenGL połozony jest w
poczatku układu współrzednych i skierowany jest w strone ujemnej półosi OZ. Obserwator jest tak zorientowany
w przestrzeni, ze kierunek „do góry” pokrywa sie z kierunkiem osi OY. Zasadniczo OpenGL nie umozliwia
zmiany połozenia obserwatora. Wszystkie przekształcenia połozenia obserwatora faktycznie realizowane SA jako
odpowiednie przekształcenia układu współrzednych. Aby jednak ułatwic prace zwiazane z definiowaniem tych
przekształcen, biblioteka GLU zawiera funkcje gluLookAt, która pozwala na jednorazowe zdefiniowanie
wszystkich parametrów opisujacych obserwatora:
void
gluLookAt (GLdouble eyex, GLdouble eyey, GLdouble eyez,
GLdouble centerx, GLdouble centery,
GLdouble centerz,
GLdouble upx, GLdouble upy, GLdouble upz)
Kolejne trójki parametrów funkcji gluLookAt oznaczaja:
eyex, eyey, eyez - współrzedne połozenia obserwatora,
centerx, centery, centerz - współrzedne punktu, w którego kierunku
jest zwrócony obserwator,
upx, upy, upz - współrzedne wektora okreslajacego kierunek „do góry”.
Domyslne połozenie obserwatora odpowiada wywołaniu
gluLookat (0.0, 0.0, 0.0, 0.0, 0.0, -100.0, 0.0, 1.0, 0.0)
W kolejnym przykładowym programie (plik szescian4.cpp) będziemy modyfikowac tylko współrzedne
połozenia obserwatora. Przy niezmiennych współrzednych punktu, w którego kierunku patrzy obserwator, daje to
ciekawy efekt obserwacji sceny z pewnej odległosci. Zmiana połozenia obserwatora realizowana jest w
funkcjach Keyboard (przyciski „+” i „-”) oraz SpecialKeys (klawisze kursora).Warto zauwazyc, ze zmiany
współrzednych obserwatora, które reprezentuja zmienne eyex, eyey i eyez, sa odwrotne niz mozna by sie
spodziewac. Przykładowo nacisniecie strzałki w dół powoduje zwiekszenie o 0,1 zmiennej eyey, która okresla
współrzedna Y połozenia obserwatora. Jest to spowodowane tym, ze macierz modelowania, modyfikowana przy
wywołaniu funkcji gluLookAt, odgrywa podwójna role. Z jednej strony umozliwia przekształcenia współrzędnych
[Kurs OpenGL, C++] III. Definiowanie sceny 3D
http://kursy.ddt.pl/?LessonId=181
7 z 9
2010-04-30 14:22
obiektu (patrz poprzedni przykład), a z drugiej przekształcenia współrzednych obserwatora. Przykładowo, to co z
punktu widzenia obiektu jest przesunieciem o wektor [1, 0, 0], dla obserwatora jest przesunieciem o wektor
przeciwny tj. [−1, 0, 0]. Dobre poznanie opisanego mechanizmy wymaga eksperymentów, do których goraco
zachecam Czytelników.
Do omówienia pozostała wprowadzona w ostatnim przykładzie obsługa klawiszy kursora. Jest ona
realizowana odrebnie od obsługi przycisków, które reprezentowane sa bezposrednio przez kody ASCII (funkcja
Keyboard). Funkcja obsługujaca klawisze kursora oraz przyciski funkcyjne (w przykładowym programie jest to
funkcja SpecialKeys) ma trzy parametry:
— key - kod przycisku; zwracana jest jedna z ponizszych wartosci:
GLUT KEY F1 - przycisk F1,
GLUT KEY F2 - przycisk F2,
GLUT KEY F3 - przycisk F3,
GLUT KEY F4 - przycisk F4,
GLUT KEY F5 - przycisk F5,
GLUT KEY F6 - przycisk F6,
GLUT KEY F7 - przycisk F7,
GLUT KEY F8 - przycisk F8,
GLUT KEY F9 - przycisk F9,
GLUT KEY F10 - przycisk F10,
GLUT KEY F11 - przycisk F11,
GLUT KEY F12 - przycisk F12,
GLUT KEY LEFT - kursor w lewo,
GLUT KEY UP - kursor do góry,
GLUT KEY RIGHT - kursor w prawo,
GLUT KEY DOWN - kursor w dół,
GLUT KEY PAGE UP - przycisk Page Up
GLUT KEY PAGE DOWN - przycisk Page Down,
GLUT KEY HOME - przycisk Home,
GLUT KEY END - przycisk End,
GLUT KEY INSERT - przycisk Insert.
— x, y - współrzedne kursora myszki w chwili nacisniecia przycisku klawiatury.
Podobnie jak w przypadku poprzedniej funkcji obsługujacej klawiature, w głównym programie nalezy
właczyc obsługe klawiszy kursora i klawiszy funkcyjnych wywołujac funkcje:
void
glutSpecialFunc (
void
(*func)(
int
key,
int
x,
int
y))
Rysunek 8 przedstawia przykładowe okno programu Szescian 4, którego kod zródłowy znajduje sie ponizej.
Rysunek 8. P rzykładowe okno programu Szescian 4
3.4.1. Plik szescian4.cpp
[Kurs OpenGL, C++] III. Definiowanie sceny 3D
http://kursy.ddt.pl/?LessonId=181
8 z 9
2010-04-30 14:22
/*
(c) Janusz Ganczarski
http://www.januszg.hg.pl
JanuszG(małpeczka)enter.net.pl
*/
#include <GL/glut.h>
#include <stdlib.h>
// stałe do obsługi menu podręcznego
enum
{
FULL_WINDOW,
// aspekt obrazu - całe okno
ASPECT_1_1,
// aspekt obrazu 1:1
EXIT
// wyjście
};
// aspekt obrazu
int
Aspect = FULL_WINDOW;
// wpółrzędne położenia obserwatora
GLdouble eyex = 0;
3.5. Źródło materiału
Materiał został pobrany ze strony
http://januszg.hg.pl/opengl/
, za uprzednim otrzymaniem zgody od jego
autora. Podziekowania dla
Janusza Ganczarskiego
za udostępnienie materiałów
Poprzednia lekcja
Kurs OpenGL, C++
Następna lekcja
Wsz e lkie prawa z ast rz e ż one . Aut or: ź ródło z e wnę t rz ne
Wszystkie teksty są chronione prawami autorskimi. Kopiowanie lub
rozpowszechnianie treści bez wyraźnej zgody jego autora jest zabronione.
Powrót
Historia odwiedzonych stron
O portalu
Archiwum
Historia
Indeks
Regulamin
Wyszukiwarka
Linki
© Wszelkie prawa zastrzeżone 2005-2010
Czas wygenerowania strony: 0.218s
Autor: Piotr Szawdyński
[Kurs OpenGL, C++] III. Definiowanie sceny 3D
http://kursy.ddt.pl/?LessonId=181
9 z 9
2010-04-30 14:22