[Kurs OpenGL, C++] IV Prze

background image

Strona główna

Kursy

Artykuły

Forum

Pliki

Promuj Nas!

[Kurs OpenGL, C++] IV. Przekształcenia geometryczne

http://kursy.ddt.pl/?LessonId=186

1 z 8

2010-04-30 14:22

background image

Powrót

Historia odwiedzonych stron

Poprzednia lekcja

Kurs OpenGL, C++

Następna lekcja

Autor: Janusz Ganczarski

http://januszg.hg.pl/opengl/

IV. Przekształcenia geometryczne

W tym odcinku kursu poznamy mechanizmy biblioteki OpenGL umożliwiające dowolne przekształcenia

geometryczne obiektów. Wykorzystamy takze stos macierzy w celu modelowania sceny 3D zawierajacej wiele
elementów.

4.1. Obrót

Obrót w OpenGL wykonuja funkcje glRotated i glRotatef:

void

glRotated (GLdouble angle, GLdouble x, GLdouble y, GLdouble z)

void

glRotatef (GLfloat angle, GLfloat x, GLfloat y, GLfloat z)

których parametry oznaczaja:

angle - kat obrotu w stopniach,
x, y, z - współrzedne wektora okreslajacego os obrotu.

Obrót realizowany jest w kierunku przeciwnym do ruchu wskazówek zegara w kierunku prostej

wyznaczonej przez wektor [x, y, z] zaczepionym w początku układu współrzednych. Jezeli wektor ma długosc
rózna od 1 wektor jest normalizowany.

Funkcje glRotated i glRotatef mnoza biezaca macierz przez przez macierz obrotu, która ma nastepujaca

postac (parametr angle zamieniono na a):

4.2. Skalowanie

Skalowanie wykonuja nastepujace funkcje:

void

glScalef (GLfloat x, GLfloat y, GLfloat z)

void

glScalex (GLfixed x, GLfixed y, GLfixed z)

gdzie x, y, z sa współczynnikami skalowania wzgledem kolejnych osi układu współrzednych. Funkcje te

mnoza biezaca macierz przez macierz skalowania, która ma postac:

1.3. Przesunięcie

Trzecia z podstawowych operacji geometrycznych jest przesuniecie o wektor (transalcja), która realizuja

funkcje:

void

glTranslatef (GLfloat x, GLfloat y, GLfloat z)

void

glTranslatex (GLfixed x, GLfixed y, GLfixed z)

gdzie x, y, z sa współrzednymi wektora przesuniecia. Podobnie jak poprzednio opisane funkcje, glTranslatef

i glTranslatex mnoza biezaca macierz przez macierz translacji, która ma postac:

4.4. Mnożenie macierzy

W przypadku, gdy zestaw standardowych przekształcen macierzowych okazuje sie niewystarczajacy,

biblioteka OpenGL udostepnia mozliwosc przemnożenia biezacej macierzy przez macierz okreslona funkcja z
grupy glMultMatrix:

void

glMultMatrixd (

const

GLdouble *m)

void

glMultMatrixf (

const

GLfloat *m)

Parametr m obu funkcji zawiera wskaznik na dane macierzy o rozmiarach 4 × 4, które musza byc ułozone

kolejno kolumnami, tj. w kolejności transponowanej w stosunku do przyjetej w jezykach C i C++:

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

[Kurs OpenGL, C++] IV. Przekształcenia geometryczne

http://kursy.ddt.pl/?LessonId=186

2 z 8

2010-04-30 14:22

background image

4.5. Ładowanie macierzy

Ostatnia z opisywanych operacji na macierzach jest zastepowanie bieżącej macierzy przez dowolnie

okreslona macierz o rozmiarach 4 × 4. Operacje te wykonuja funkcje z grupy glLoadMatrix:

void

glLoadMatrixd (

const

GLdouble *m)

void

glLoadMatrixf (

const

GLfloat *m)

Format danych ładowanej macierzy jest taki sam jak w przedstawionych wyzej funkcjach glMultMatrixd i

glMultMatrixf.

1.6. Składanie przekształceń

Macierzowy opis przekształcen geometrycznych znacznie ułatwia składanie kilku róznych przekształcen

obiektów. Wywołujac funkcje generujące macierze odpowiednich przekształcen dokonujemy jednoczesnie ich
składania. W tej sytuacji jedyna rzecza, o której nalezy pamietac, to kolejność przekształcen, bowiem od tego
zalezy koncowy efekt. Przykładowy program (plik przeksztalcenia.cpp) przedstawia przekształcenia
geometryczne dostepne w bibliotece OpenGL. Scena 3D zawiera pojedynczy obiekt geometryczny zawarty w
bibliotece GLUT. Klawisze kursora pozwalaja na obracanie wyswietlanego obiektu, przyciski „+” i „-” na jego
skalowanie, a lewy przycisk myszki przesuwa obiekt. W ramach eksperymentu Czytelnik moze w programie
zamienic kolejnosc składania wykonywanych tam przekształcen (funkcja Display) np. przesuniecia i obrotu.
Poznajmy jeszcze nowe elementy biblioteki GLUT wykorzystanie w przykładowym programie tj. sposób obsługi
myszki i zdefiniowane obiekty geometryczne. Biblioteka GLUT udostepnia obiekty 3D w wersji szkieletowej
(tzw. „druciaki”) oraz w wersji pełnej. W najblizszych przykładowych programach wykorzystamy wersje
szkieletowe obiektów.

4.6.1. Kula

Powierzchnia kuli rysowana jest jako szkielet składajacy sie z południków i równolezników (rysunek 1).

Powierzchnie kuli, której srodek znajduje się w poczatku układu współrzednych rysuje funkcja:

void

glutWireSphere (GLdouble radius, GLint slices, GLint stacks)

której parametry oznaczaja:

radius - promien kuli,
slices - ilosc południków,
stacks - ilosc równolezników.

Rysunek 1. P rogram P rzekształcenia - kula

4.6.2. Szescian

Szescian o boku długosci size i srodku połozonym w poczatku układu współrzednych rysuje funkcja:

void

glutWireCube (GLdouble size)

4.6.3. Stozek

Stozek rysowany jest podobnie jak kula - jako szkielet oparty na równoległe do podstawy „południki” i

tworzace biegnace od wierzchołka stozka do krawedzi jego podstawy (rysunek 2). Stozek ze srodkiem podstawy
umieszczonym w poczatku układu współrzednych i wierzchołkiem umieszczonym na dodatniej półosi OZ rysuje
funkcja:

void

glutWireCone (GLdouble base, GLdouble height, GLint slices, GLint

stacks)

której parametry oznaczaja:

base - promien podstawy stozka,
height - wysokosc stozka,
slices - ilosc tworzacych,
stacks - ilosc „południków”.

[Kurs OpenGL, C++] IV. Przekształcenia geometryczne

http://kursy.ddt.pl/?LessonId=186

3 z 8

2010-04-30 14:22

background image

Rysunek 2. P rogram P rzekształcenia - s tożek

4.6.4. Torus

Kolejna bryła obrotowa dostepna w bibliotece GLUT jest torus rysowany jako seria walców o

nierównoległych podstawach (rysunek 3) i osi obrotu pokrywajacej sie z osia OZ. Torus rysuje funkcja:

void

glutWireTorus (GLdouble innerRadius, GLdouble outerRadius, GLint

sides, GLint rings)

której parametry oznaczaja odpowiednio:

innerRadius - promien koła tworzacego torus,
outerRadius - promien torusa,
sides - ilosc scian bocznych, z których składa sie pojedynczy walec,
rings - ilosc walców, z których składa sie torus.

Rysunek 3. P rogram P rzekształcenia - torus

4.6.5. Dwunastoscian

Dwunastoscian o srodku połozonym w poczatku układu współrzędnych rysuje funkcja:

void

glutWireDodecahedron (

void

)

4.6.6. Czajnik

Klasycznym obiektem 3D dostepnym w bibliotece GLUT jest opracowany w 1975 roku przez Martina

Newella czajnik - przedstawiony na rysunku 4. Czajnik o wielkosci regulowanej parametrem size rysuje funkcja:

void

glutWireTeapot (GLdouble size)

[Kurs OpenGL, C++] IV. Przekształcenia geometryczne

http://kursy.ddt.pl/?LessonId=186

4 z 8

2010-04-30 14:22

background image

Rysunek 4. P rogram P rzekształcenia - czajnik

4.6.7. Osmioscian

Osmioscian o srodku połozonym w poczatku układu współrzednych rysuje funkcja:

void

glutWireOctahedron (

void

)

4.6.8. Czworoscian

Czworoscian o srodku połozonym w poczatku układu współrzednych rysuje funkcja:

void

glutWireTetrahedron (

void

)

4.6.9. Dwudziestoscian

Dwudziestoscian o srodku połozonym w poczatku układu współrzędnych rysuje funkcja:

void

glutWireIcosahedron (

void

)

4.6.10. Obsługa myszki

Obsługa myszki składa sie z dwóch etapów i jest wykonywana przez dwie funkcje. Pierwsza z nich to:

void

MouseButton (

int

button,

int

state,

int

x,

int

y)

która wykrywa nacisniecie i zwolnienie lewego przycisku myszki. W zależności od stanu lewego przycisku

myszki ustawiana jest wartosc zmiennej globalnej button state na przekazana przez parametr state. Druga
funkcja:

void

MouseMotion (

int

x,

int

y)

wywoływana jest podczas ruchu kursora myszki a jej zadaniem jest odpowiednie (dobrane czesciowo

doswiadczalnie) przeliczenie ruchu myszki na przesuniecie obiektu znajdujacego sie na scenie. Efekt przeliczen
ruchu kursora myszki umieszczony jest w zmiennych globalnych translatex i translatey, które sa bezposredni
przekazywane jako parametry funkcji glTranslatef. Parametry x i y obu funkcji oznaczaja współrzedne kursora
myszki w odniesieniu do układu współrzednych okna, które oczywiscie nie maja nic

wspólnego ze współrzednymi okreslonymi w scenie 3D. Parametr buton funkcji MouseButton okresla który

przycisk myszki został nacisniety lub zwolniony. Parametr ten przyjmuje jedna z wartosci:

GLUT LEFT BUTTON - lewy przycisk myszki,
GLUT MIDDLE BUTTON - srodkowy przycisk myszki,
GLUT RIGHT BUTTON - prawy przycisk myszki.

Jezeli w danym systemie myszka ma tylko dwa przyciski, wartosc GLUT MIDDLE BUTTON nie bedzie

generowana. Natomiast w przypadku myszki z jednym przyciskiem funkcja generuje jedynie wartosc GLUT
LEFT BUTTON. Ostatni nieopisany parametr funkcji MouseButton to state, który okresla czy przycisk myszki
został nacisniety (stała GLUT UP) czy zwolniony (stała GLUT - DOWN).

Aby opisane funkcje obsługi myszki działały nalezy je dołaczyc do listy funkcji zwrotnych wywołujac

odpowiednio:

void

glutMouseFunc (

void

(*func)(

int

button,

int

state,

int

x,

int

y))

void

glutMotionFunc (

void

(*func)(

int

x,

int

y))

1.6.11. Menu wielopoziomowe

W programie został uzyty nowy element biblioteki GLUT — wielopoziomowe menu podreczne. Czesc

menu podrecznego, które bedzie znajdowało sie na drugim (lub wyzszym) poziomie tworzymy w taki sam sposób
jak dotychczas tworzylismy główne menu, czyli przy uzyciu funkcji glutCreateMenu i glutAddMenuEntry. Tak
utworzony fragment menu umieszczamy w menu głównym (nadrzednym) uzywajac funkcji:

void

glutAddSubMenu (

const

char

*label,

int

submenu)

Parametr label okresla nazwe menu podrecznego, a submenu jego identyfikator zwrócony przez funkcje

glutCreateMenu.

[Kurs OpenGL, C++] IV. Przekształcenia geometryczne

http://kursy.ddt.pl/?LessonId=186

5 z 8

2010-04-30 14:22

background image

4.6.12. Odrysowanie okna

Aby zmiany sceny 3D zostały wyswietlone na ekranie potrzebne jest odrysowanie biezacego okna. Mozna

to zrealizowac wywołujac funkcje:

void

glutPostRedisplay (

void

)

4.6.13. Plik przeksztalcenia.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

WIRE_SPHERE,

// kula

WIRE_CONE,

// stożek

WIRE_CUBE,

// sześcian

WIRE_TORUS,

// torus

WIRE_DODECAHEDRON,

// dwunastościan

WIRE_TEAPOT,

// czajnik

WIRE_OCTAHEDRON,

// ośmiościan

WIRE_TETRAHEDRON,

// czworościan

WIRE_ICOSAHEDRON,

// dwudziestościan

EXIT

// wyjście

4.7. Stos macierzy modelowania

Do składania przekształcen biblioteka OpenGL wykorzystuje wspomniany juz wczesniej stos macierzy

modelowania. W dotychczasowych programach, oraz pierwszym z przykładowych programów z tego odcinka
kursu, mechanizm stosu nie był faktycznie wykorzystywany. Wszystkie operacje zwiazane ze stosem macierzy
modelowania wykonywane były na macierzy połozonej na szczycie stosu. Pozwala to jednak na efektywna
manipulacje jedynie jednym obiektem na scenie. Oczywiscie obsługa wielu obiektów także jest mozliwa, ale
wymaga to stosowania mniej wygodnych i efektywnych mechanizmów. W szczególnosci mogło by sie okazac
konieczne przechowywanie macierzy modelowania - czyli dublowanie mozliwosci oferowanej przez mechanizm
stosu.

Po lekturze powyzszego wstepu Czytelnik zastanawia sie zapewne jak w praktyce efektywnie mozna

wykorzystac mechanizm stosu macierzy modelowania. Klasycznym przykładem jest budowa obiektów złozonych
z wielu obiektów podstawowych (np. takich jak wyzej opisane obiekty 3D dostępne w bibliotece GLUT).
Drugim, równie czesto wykorzystywanym przykładem, jest animacja sceny składajacej sie z wielu obiektów 3D.

4.7.1. Operacje na stosie

Specyfikacja biblioteki OpenGL przewiduje, ze stos macierzy modelowania przechowuje co najmniej 32

macierze. Oczywiscie konkretne implementacje OpenGL moga dowolnie zwiekszac maksymalna pojemnosc tego
stosu. Opisane ponizej funkcje słuza do operacji na kazdym rodzaju stosu dostepnym w OpenGL. Operacja
zawsze zostanie wykonana na aktualnie wybranym rodzaju stosu. Operacje odłozenia biezacej macierzy na stos
realizuje funkcja:

void

glPushMatrix (

void

)

Natomiast operacje zdjecia macierzy ze stosu wykonuje funkcja:

void

glPopMatrix (

void

)

Próba wykonania niedozwolonej operacji na stosie spowoduje wygenerowanie kodu błedu zwracanego przez

funkcje glGetError:

GL STACK UNDERFLOW - próba pobrania elementu z pustego stosu (niedobór stosu),
GL STACK OVERFLOW - przepełnienie stosu.

Przykładowy program (plik stos modelowania.cpp) opiera sie na poprzednim przykładzie. Podstawowa

róznica jest rysowanie jednego obiektu - piramidy, ale złozonego z duzej ilosci elementów podstawowych -
szescianów. Dla ułatwienia pracy program zawiera dwie funkcje rysujace czesci piramidy w postaci bloków 3 ×
3 (funkcja Cube3x3) i bloków 2 × 2 (funkcja Cube2x2). Pierwszy poziom piramidy ma rozmiary 6 × 6 i jest
rysowany z czterech bloków 3 × 3 (funkcja Pyramid). Przed narysowaniem kazdego z elementów pierwszego
poziomu macierz modelowania odkładana jest na stos – po zakonczeniu rysowania nastepuje zdjecie macierzy ze
stosu. Przy rysowaniu drugiego i trzeciego poziomu piramidy nastepuje dwukrotne odłozenie macierzy
modelowania na stos. Po pierwszym przesuwamy układ współrzednych od odpowiednia ilosc jednostek do góry.
Drugie w kolejności odkładanie macierzy na stos wiaze sie juz bezposrednio z rysowaniem kolejnych elementów
danego poziomu piramidy. Rysowanie kolejnych poziomów nie wymaga juz dodatkowego opisu – wystarcza
jednokrotne odłozenie macierzy modelowania na stos. Przykładowy efekt tych wszystkich przekształcen zawiera
rysunek 5. Oczywiscie uzyskanie takiej figury nie wymaga stosowania mechanizmu stosu macierzy
modelowania. Jednak juz w tak prostym przykładzie widoczne sa korzysci wynikajace z takiego rozwiazania. Po
pierwsze wszystkie elementy obiektu 3D, w tym wypadku poziomy piramidy, sa od siebie niezalezne. Czytelnik
moze to łatwo sprawdzic odpowiednio modyfikujac tekst zródłowy programu. Trudno nie docenic takiej cechy
przy tworzeniu bardziej skomplikowanych obiektów. Druga zaleta jest duza przejrzystosc rozwiazania, co ułatwia
pózniejsza modyfikacje programu i usuwanie ewentualnych błedów.Warto takze dodac, ze mechanizm stosu jest
bardzo szybki i dotyczy to wszystkich implementacji biblioteki OpenGL, nie tylko sprzetowych.

[Kurs OpenGL, C++] IV. Przekształcenia geometryczne

http://kursy.ddt.pl/?LessonId=186

6 z 8

2010-04-30 14:22

background image

W programie wykorzystano takze kilka innych nieopisanych wczesniej funkcji biblioteki OpenGL i GLU. W

poprzednim przykładzie przy przesuwaniu obiektu za pomoca myszki obliczanie wektora przesuniecia oparto o
dobrane doswiadczalnie współczynniki. W przypadku, gdy zmienimy parametry bryły odcinania te współczynniki
trzeba bedzie dobierac ponownie. Biblioteka GLU zawiera funkcje przeliczajace współrzedne w przestrzeni okna
na współrzedne w przestrzeni widoku i odwrotnie.

Przeliczenie współrzednych w przestrzeni widoku (objx, objy, objz) na współrzedne w przestrzeni okna

(winx,winy,winz) wykonuje funkcja gluProject:

GLint gluProject (GLdouble objx, GLdouble objy, GLdouble objz,

const

GLdouble modelMatrix [16],

const

GLdouble projMatrix [16],

const

GLint viewport [4],

GLdouble *winx, GLdouble *winy, GLdouble *winz)

Do przeliczania współrzednych funkcja gluProject wykorzystuje macierz modelowania, macierz rzutowania

oraz współrzedne okna renderingu, które zawarte sa kolejno w parametrach: modelMatrix, projMatrix i viewport

Przeliczenie współrzednych w przestrzeni okna (winx,winy,winz) na współrzedne w przestrzeni widoku

(objx, objy, objz) wykonuje funkcja gluUnProject:

GLint gluUnProject (GLdouble winx, GLdouble winy, GLdouble winz,

const

GLdouble modelMatrix [16],

const

GLdouble projMatrix [16],

const

GLint viewport [4],

GLdouble *objx, GLdouble *objy, GLdouble *objz)

której parametry maja analogiczne znaczenie jak parametry poprzedniej funkcji gluProject.
W wersji 1.3 biblioteki GLU dodano funkcje gluUnProject4:

GLint gluUnProject4 (GLdouble winx, GLdouble winy, GLdouble winz,
GLdouble clipw,

const

GLdouble modelMatrix[16],

const

GLdouble projMatrix[16],

const

GLint viewport[4],

GLdouble near, GLdouble far, GLdouble *objx,
GLdouble *objy, GLdouble *objz, GLdouble *objw)

stanowiaca rozszerzenie gluUnProject umozliwiajaca obliczenia przy niestandardowych ustawieniach bufora

głebokosci (parametry near i far odpowiadające parametrom funkcji glDepthRange) lub w przypadku, gdy
czwarta współrzedna (parametr clipw) przestrzeni okna przyjmuje inna wartość niz 1. Funkcja zwraca dodatkowo
wartosc czwartej współrzednej w przestrzeni widoku (parametr objw). Znaczenie tych dodatkowych
współrzędnych poznamy w kolejnych odcinkach kursu. Wartosci macierzy modelowania, macierzy rzutowania
oraz obszaru renderingu stanowia zmienne stanu maszyny stanu OpenGL. Do odczytu zmiennych stanu słuzy
bardzo liczna grupa funkcji glGet, z których najbardziej uniwersalne sa nastepujace funkcje:

void

glGetBooleanv (GLenum pname, GLboolean *params)

void

glGetDoublev (GLenum pname, GLdouble *params)

void

glGetFloatv (GLenum pname, GLfloat *params)

void

glGetIntegerv (GLenum pname, GLint *params)

Parametr pname okresla która wartosc maszyny stanów OpenGL chcemy pobrac (tabela wszystkich

mozliwych wartosci zajmuje 35 stron specyfikacji OpenGL 2.1), a params wskaznik na zwracana wartosc. W
zależności od rodzaju pobieranej wartosci params wskazuje na pojedyncza zmienna lub tablice. Rodzaj
zwracanej (zwracanych) wartosci jednoznacznie okresla koncowa czesc nazwy funkcji.

Rysunek 5. P rogram Stos modelowania

4.7.2. Plik stos modelowania.cpp

[Kurs OpenGL, C++] IV. Przekształcenia geometryczne

http://kursy.ddt.pl/?LessonId=186

7 z 8

2010-04-30 14:22

background image

/*
(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;

// rozmiary bryły obcinania

const

GLdouble left = -10.0;

4.8. Ź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.183s

Autor: Piotr Szawdyński

[Kurs OpenGL, C++] IV. Przekształcenia geometryczne

http://kursy.ddt.pl/?LessonId=186

8 z 8

2010-04-30 14:22


Wyszukiwarka

Podobne podstrony:
[Kurs OpenGL, C++] VII Wie
[Kurs OpenGL, C++] VIII Ko
[Kurs OpenGL, C++] III Def
[Kurs OpenGL, C++] VI Elem
[Kurs OpenGL, C++] II Pier
Krótki kurs C Część IV
[Kurs OpenGL, C++] V Okraw
[Kurs OpenGL, C++] I Podstawy
Darmowy Kurs OpenGL, C++ On
Przebieg mobbingu – faza IV, LO, kurs pedagogiczny, patologie w pracy
Pielęgniarki kurs wersja 22 IV
Statystyka - teoria, IiE, IV kurs, Statystyka
kurs html rozdział IV
Przebieg mobbingu – faza IV, LO, kurs pedagogiczny, patologie w pracy
Tomasz M Sadowski Praktyczny kurs Turbo Pascala Wydanie IV helion
Praktyczny kurs Turbo Pascala Wydanie IV
Praktyczny kurs Turbo Pascala Wydanie IV 2
KURS UPRAWNIENIA BUD TEST IV 2008
Praktyczny kurs Turbo Pascala Wydanie IV 2

więcej podobnych podstron