Wizualizacja danych sensorycznych Sprawozdanie Tworzenie
Transkrypt
Wizualizacja danych sensorycznych Sprawozdanie Tworzenie
Wizualizacja danych sensorycznych Sprawozdanie Tworzenie obrazu stereoskopowego Tomasz Jakubowski 163128 9 czerwca 2010 1 Spis treści 1 Zadanie do zrealizowania 3 2 Tworzenie obrazu anaglifowego 3 3 Koncepcja działania programu i najważniejsze wykorzystane funkcje 5 4 Funkcjonalność i interfejs graficzny aplikacji 6 5 Diagram klas w języku UML 7 6 Diagram przepływu sterowania 7 7 Wynik działania aplikacji 7 8 Wnioski 11 2 1 Zadanie do zrealizowania Na zdolność postrzegania głębi obrazu u człowieka składa się szereg czynników1 : • perspektywa - przedmioty bardziej oddalone od obserwatora wydają się być mniejsze, a wszystkie linie proste zbiegają w nieskończoności do jednego punktu, • szczegółowość - im mniej szczegółów jesteśmy w stanie zauważyć, tym dalej wydaje nam się, że znajduje się obserwowany przedmiot, • zasłanianie - jeśli jeden przedmiot zasłania drugi, to oczywistym jest, że znajduje się on przed nim, • oświetlenie i cienie - bliższe nam przedmioty są jaśniejsze, dalsze - ciemniejsze, • względny ruch - przedmioty oddalone wydają się poruszać wolniej, • rozbieżność postrzeganych obrazów dla każdego oka - oczy człowieka są oddalone od siebie o pewną odległość, przez co ten sam przedmiot ustawiony przed nami oglądany jest z prawego i z lewego oka z nieco innej perspektywy, • akomodacja oka - napięcie mięśni potrzebne do zmiany długość ogniskowej, aby spoglądać na przedmiot znajdujący się w innej odległości niż obecnie oglądany. Nie są to wszystkie czynniki, które mają wpływ na odbieranie głębi obrazu. Wydają się to jednak być aspekty najbardziej znaczące. W dotychczasowym rozwoju fotografii, kinematografii i grafiki komputerowej uwzględniana jest większość z nich. Pomijane są jednak ostatnie dwa. Na płaskim ekranie bądź też zdjęciu obraz dostarczany do każdego oka jest identyczny, co utrudnia pełne postrzeganie głębi obrazu. Dodatkowo ekran jest płaski, więc niezależnie od miejsca, w które spojrzymy (nawet jeśli teoretycznie w danym miejscu ekranu obserwujemy przedmiot bardzo oddalony), to ogniskowa oka jest umieszczona na płaszczyźnie ekranu, przez co pomijany jest aspekt akomodacji oka. Celem projektu jest stworzenie obrazu stereoskopowego bryły, a więc takiego, w którym obraz jest nagrywany z dwóch kamer, a następnie podawany osobno odpowiednio do prawego i lewego oka. Uwzględniona zostanie w ten sposób rozbieżność postrzeganych obrazów dla każdego oka. Poprzez wyświetlenie takiego obrazu zostanie zbadany wpływ tego aspektu na zdolność postrzegania głębi przestrzennej. Istnieje wiele metod realizowania obrazu stereoskopowego. W projekcie wykorzystana została metoda anaglifowa. Obrazy dla prawego i lewego oka są odpowiednio zabarwione na różne kolory, a następnie złożone w jeden obraz, z uwzględnieniem odpowiedniego przesunięcia między nimi. Uzyskany obraz oglądać należy w specjalnych okularach z zabarwionymi szkłami, które filtrują światło, jakie do nich dociera, w efekcie przepuszczając do danego oka jedynie ten obraz, który jest dla niego przeznaczony. Do zrealizowania zadania wykorzystana została biblioteka OpenGL, zapewniająca wyświetlenie obrazu anaglifowego, oraz biblioteka Qt, dostarczająca interfejs użytkownika. 2 Tworzenie obrazu anaglifowego Oczy człowieka są przesunięte względem siebie o ok. 8cm. Z tego względu figura, którą oglądamy tuż przed sobą widziana jest przez każde oko z nieco innej perspektywy. Sytuację tę ilustruje rysunek 1. W ludzkim mózgu oba obrazy są następnie przetwarzane i dostajemy informację, że widzimy jedną figurę, odpowiednio oddaloną od nas, co przedstawione jest na rysunku 2. Wartość tego oddalenia „obliczana jest” na podstawie rozbieżności pomiędzy obrazami z każdego oka. Im te rozbieżności są większe, tym bryła jest bliżej. Dla bardzo oddalonych przedmiotów obrazy widziane przez każde z oczu są identyczne. Obraz wyświetlany na ekranie jest tylko jeden, dlatego potrzebne jest stosowanie specjalnych okularów, które odseparują składowe obrazu przeznaczone dla oka lewego i prawego i podadzą je tylko do odpowiedniego oka. W metodzie anaglifowej składowe obrazu oddzielane są na podstawie ich zabarwienia. Do oglądania takiego obrazu potrzebne są okulary wyposażone w odpowiednio zabarwione szkła. Obraz przeznaczony dla lewego oka zabarwiony jest na czerwono i przepuszczany jest do oka lewego, 1 Jak podają pozycje [9] i [5] 3 (a) Oko lewe (b) Oko prawe Rysunek 1: Postrzeganie bryły przez każde oko osobno Rysunek 2: Złożony w mózgu obraz bryły które posiada szkło o barwie czerwonej. Szkło takie przepuszcza tylko czerwone składowe koloru, dlatego czerwony obraz przejdzie przez to szkło i trafi do lewego oka. Analogicznie wygląda sytuacja w przypadku prawego oka. Jednakże dostępne okulary anaglifowe różnią się między sobą kolorem prawego szkła. Może ono być niebieskie, zielone bądź cyjanowe (niebiesko-zielone). Z tego względu okulary i obraz anaglifowy muszą być do siebie dopasowane. W zrealizowanym projekcie uwzględniono taką sytuację i istnieje możliwość dostosowania obrazu do użytych okularów. W celu stworzenia obrazu anaglifowego konieczne jest zrobienie zdjęcia sceny dwukrotnie, dla różnych ustawień kamery, symulującej widok odpowiednio z oka prawego i lewego. Sytuację ilustruje rysunek 3. Załóżmy, iż chcemy wygenerować obraz punktu p widocznego na rysunku. W przypadku pojedynczej kamery umieszczona ona jest w środku układu współrzędnych i robi pojedyncze zdjęcie, które następnie jest wyświetlane na ekranie. W efekcie tracimy informację o głębi obrazu. Jeżeli punkt jest większy, to nie musi to wcale oznaczać, że znajduje się bliżej kamery, może mieć po prostu większe rozmiary. Przy tworzeniu anaglifu używane są dwie kamery, dla ułatwienia pokolorowane na rysunku na cyjanowo i czerwono. Kamera cyjanowa nagrywa obraz dostarczany do oka prawego (na które nałożone jest cyjanowe szkło). Co ważne, obraz dostarczany przez tę kamerę musi być zabarwiony na cyjanowo, aby został przepuszczony przez szkło okularów. Analogicznie kamera czerwona zabarwia swój obraz na czerwono i dostarcza go do lewego oka z czerwonym szkłem. W efekcie widz dostaje do każdego oka tylko przeznaczony dla niego obraz i w jego mózgu powstaje złudzenie trójwymiarowości obrazu. Ważne jest, aby osie optyczne kamer biegły równolegle do osi pojedynczej kamery, a nie zbiegały się w punkcie p. Dzięki temu otrzymamy lepsze złudzenie trójwymiarowości obrazu. Ważnym aspektem, na jaki należy zwrócić uwagę jest szerokość rozstawienia obu kamer. Jest to 4 p f e Rysunek 3: Tworzenie obrazu anaglifowego kwestia, która mocno zależy od indywidualnych preferencji widza. Zgodnie z informacjami podanymi w f f pracach [5], [6], odległość ta powinna wynosić od e = 20 do e = 30 , gdzie f to wartość ogniskowej, a więc odległość od oczu widza do oglądanego przedmiotu. Ciężko jednak jednoznacznie określić wartość f , gdyż widz może znajdować się w różnej odległości od ekranu, ponadto ekran może mieć różne wymiary. Dodatkowo sama bryła może się znajdować bliżej lub dalej „wewnątrz“ monitora. Z tego względu wartość e ustawiona została arbitralnie, ale istnieje możliwość jej zmiany w trakcie działania programu. 3 Koncepcja działania programu i najważniejsze wykorzystane funkcje Do wygenerowania obrazu anaglifowego wykorzystano bibliotekę OpenGL. Informacje na temat jej funkcjonalności i sposobu wykorzystania zaczerpnięto z pozycji [13], [1], [3] oraz [2]. Natomiast sposób implementacji obrazu stereoskopowego opisany został w szeregu prac [5],[6],[7],[4],[8]. Oprogramowanie zostało napisane w taki sposób, aby oddzielić od siebie kod odpowiedzialny za generowanie obrazu anaglifowego od kodu modelującego scenę. W efekcie przy wykorzystaniu stworzonego oprogramowania można wyświetlić praktycznie dowolną scenę, zmieniając kod w funkcji void draw(). Główną funkcją odpowiedzialną za rysowanie sceny jest void paintGL(), w niej czyszczony jest aktualny bufor głębi i koloru, następnie ustawiana jest odpowiednia maska kolorów przy pomocy glColorMask(). Maska tak odpowiedzialna jest za odpowiednie zabarwienie obrazu. Ustawiana jest także asymetryczna macierz Frustum (zgodnie z rysunkiem 3) oraz ustawiana jest kamera, aby dawała perspektywę prawego oka (funkcja gluLookAt()) i wywoływana jest funkcja void draw(), rysująca scenę. Następnie czyszczony jest bufor głębi, ale bufor kolorów pozostawiany jest bez zmian, a to dlatego, że obrazy dla każdego oka mają inne, nienakładające się, składowe kolorów, dzięki czemu otrzymujemy od razu złożenie obu obrazów. Ustawiana jest kamera na lewe oko i po raz drugi rysowana jest scena. W efekcie na ekranie wyświetlany jest obraz anaglifowy, który możemy oglądać w odpowiednich okularach. 5 Aby zapewnić właściwą wartość przesunięcia i stworzenie odpowiedniej asymetrycznej macierzy Frustum należy ją przesunąć o odcinek obliczany ze wzoru l= nearPlane eyesep · distToObject 2 (1) Nazwy parametrów w równaniu 1 odpowiadają nazwom zmiennych w programie i oznaczają odpowiednio: nearPlane – odległość od kamery do bliższej płaszczyzny obcinającej, distToObject – odległość kamery do obserwowanego obiektu, eyesep – szerokość rozstawienia kamer w systemie stereowizyjnym. Przedstawiony wzór można otrzymać na przykład wykorzystując podobieństwo trójkątów. Należy go wykorzystać, gdyż przesunięcie macierz Frustum określa się poprzez przesunięcie bliższej płaszczyzny ograniczającej, a nie płaszczyzny, na której znajduje się obserwowany obiekt. Interfejs użytkownika zaimplementowany został z wykorzystaniem biblioteki Qt. Informacje jak połączyć ze sobą biblioteki Qt i OpenGL, a także możliwości, jakie daje biblioteka Qt zostały szeroko przestawione w pracach [12], [10] oraz [11]. Jako bazę tworzonego programu wykorzystano przykładowy program zamieszczony w [10], w którym wyświetlany jest czworościan, z dodaną m. in. możliwością obracania kamery. Program stworzony w projekcie został w znacznym stopniu rozszerzony, niemniej znajdują się w nim fragmenty kodu zaczerpnięte z tej książki (jak chociażby kod rysujący czworościan czy też odczytujący gest drag-and-drop). Obraz wyświetlanej bryły wyświetlany jest na QGLWidget. Główne okno programu zawiera w sobie ten widget, a także rozwijalne menu, w którym można wybrać szereg opcji działania programu. 4 Funkcjonalność i interfejs graficzny aplikacji Rysunek 4: Zrzut ekranu działającej aplikacji W projekcie stworzony został animowany, anaglifowy obraz obracającej się bryły z wykorzystaniem biblioteki OpenGL oraz Qt. Efekt prac został przedstawiony na rysunku 4. W programie celem jest osiągnięcie odpowiedniego efektu wizualnego, dlatego starano się ograniczyć do minimum graficzny interfejs użytkownika. Możliwie największa liczba funkcji przypisana jest do myszy, co zapewnia intuicyjne sterowanie, a także nie przysłania ekranu aplikacji różnego rodzaju suwakami, 6 przyciskami i labelami. Jedynie na górze okna znajduje się rozwijalne menu, w którym można zmieniać główne parametry działania programu. Użytkownik ma możliwość wpływania na prędkość i kierunek obracania się bryły poprzez obracanie rolką myszy. Może obracać kamerą wokół osi X oraz Y (wg oznaczeń osi w OpenGL), poprzez przytrzymanie lewego przycisku myszy i odpowiednie przesunięcie kursora. Ma również możliwość zmieniać szerokość rozstawienia kamer systemu stereowizyjnego przytrzymując prawy przycisk myszy i przesuwając kursor w poziomie. Przesuwając go w pionie może zmieniać oddalenie kamery od przedmiotu. Program umożliwia również wybranie jednej z kilku różnych brył w rozwijanym menu, wybranie rodzaju używanych okularów oraz zmianę rozdzielczości wyświetlanego obrazu. 5 Diagram klas w języku UML Na rysunku 5 przedstawiony został diagram klas stworzonego oprogramowania utworzony w programie umbrello. Główną klasą programu jest klasa MainWindow, która zawiera wspomniane wcześniej menu oraz klasę Anaglyph, która wyświetla obraz anaglifowy. Pomiędzy tymi klasami istnieje szereg połączeń, aby wybierane opcje w menu znalazły swoje odzwierciedlenie w wyświetlanym obrazie. Klasa Anaglyph jest klasą dziedziczącą po QGLWidget i zapewnia wyświetlanie anaglifowego obrazu. Są w niej przedefiniowane standardowe metody wykorzystywane przez OpenGL do narysowania obrazu sceny. Dodatkowo, dzięki bibliotece Qt możliwe jest odpowiednie reagowanie na gesty myszą, które zapewniają m. in. przemieszczanie i obrót kamery. Kolejną klasą jest StereoCamera, która jest odpowiedzialna za przechowywanie parametrów systemu stereowizyjnego, takie jak położenie systemu, punkt, na który jest skierowany system, wektor wskazujący górę oraz wartość rozstawienia kamer. Na podstawie tych parametrów ustawiane są odpowiednio prawa i lewa kamera przy tworzeniu obrazu anaglifowego. Ostatnią wykorzystaną klasą jest Vector3f. Jest to klasa implementująca wektor o 3 współrzędnych, wraz ze zdefiniowanym interfejsem pozwalającym wykonywać podstawowe operacje arytmetyczne, a także obliczyć iloczyn skalarny i wektorowy czy też znormalizować wektor. 6 Diagram przepływu sterowania Diagram przepływu sterowania utworzony w programie umbrello umieszczony został na rysunku 6. 7 Wynik działania aplikacji Na rysunku 7 umieszczone zostały zrzuty ekranu działającej aplikacji dla różnych brył oraz różnych rodzajów okularów. Na przedstawionych rysunkach możemy zobaczyć (oglądając je bez okularów), iż zmiana okularów skutkuje w zmianie kolorów, na jakie zabarwione są poszczególne składowe obrazu. Niestety, jako że dysponuję tylko jednym rodzajem okularów, czerwono-cyjanowym, nie dane mi było porównać otrzymywanych efektów w zależności od wykorzystanych okularów. Przyglądając się wyświetlonym bryłom możemy stwierdzić, że poszczególne obrazy generowane są w sposób prawidłowy. Przykładowo obraz sześcianu dla prawego oka jest faktycznie widziany trochę bardziej z prawej strony, analogiczna sytuacja występuje dla oka lewego. Zbliżanie i oddalanie brył na ekranie nie wpływa na bezwzględną wartość rozstawienia brył. Jednakże bryły przy oddalaniu stają się coraz mniejsze, przez co obie połówki zaczynają się coraz bardziej rozchodzić. Dzieje się tak dlatego, iż wartość przesunięcia dobrana jest na sztywno na początku programu, a podczas jego działania jest niezależna od oddalenia kamery od przedmiotu. Możemy jednak w prosty sposób zmienić wielkość odseparowania obydwu kamer przy wykorzystaniu myszy. Umożliwi to także testowanie i dostosowanie wartości rozstawu kamer indywidualnie przez każdego użytkownika programu. 7 8 Diagram: class diagram Page 1 + + + + + + + QGLWidget + + + + + + + + + + + x : GLfloat y : GLfloat z : GLfloat Vector3f(x_ : GLfloat, y_ : GLfloat, z_ : GLfloat) Normalize() operator +(v2 : const Vector3f&) : Vector3f operator -(v2 : const Vector3f&) : Vector3f operator *(value : const GLfloat&) : Vector3f operator /(value : const GLfloat&) : Vector3f operator *(v2 : const Vector3f&) : Vector3f operator &(v2 : const Vector3f&) : GLfloat -center -up -eye Vector3f StereoCamera - eye : Vector3f - center : Vector3f - up : Vector3f - eyesep : GLfloat + StereoCamera(eyesep_ : GLfloat, eyex : GLfloat, eyey : GLfloat, eyez : GLfloat) + SetEyeSep(nEyesep : GLfloat) + SetEye(nEye : Vector3f) -stereo + SetCenter(nCenter : Vector3f) + SetUp(nUp : Vector3f) + GetEyeSep() : GLfloat + GetEye() : Vector3f + GetCenter() : Vector3f + GetUp() : Vector3f Rysunek 5: Diagram klas Anaglyph - RotX : GLfloat - RotY : GLfloat MainWindow - RotZ : GLfloat - RotSpeed : GLfloat windowSmall() - timerId : int windowMedium() - currentBody : Body windowLarge() - currentGlasses : Glasses windowWideSmall() - quadratic : GLUquadricObj* windowWideMedium() - stereo : StereoCamera windowWideLarge() - nearPlane : GLfloat windowFullScreen() - farPlane : GLfloat - size : GLfloat - distToObject : GLfloat - CameraRotX : GLfloat «enum» - CameraRotY : GLfloat -currentBody Body - lastCursorPosition : QPoint Cube + Anaglyph(parent : QGLWidget*) Sphere + setCube() Tetrahedron + setSphere() All + setTetrahedron() + setAll() QPoint -lastCursorPosition + setBlue() + setGreen() + setCyan() # initializeGL() # resizeGL(width : int, height : int) «enum» # paintGL() Eye # mousePressEvent(event : QMouseEvent*) rightEye # mouseMoveEvent(event : QMouseEvent*) leftEye # wheelEvent(event : QWheelEvent*) # timerEvent(event : QTimerEvent*) - draw() «enum» -currentGlasses - drawCube() - drawSphere() Glasses - drawTetrahedron() blue - drawAll() green - setPerspective(eye : Eye) cyan - ChangeRotXY(dx : int, dy : int) QMainWindow uruchom timer figura=sześcian okulary=cyjan inicjalizacja innych zmiennych czy upłynął czas? tak nie RotX+=0.7*RotSpeed RotY+=RotSpeed rysuj sześcian RotZ+=1.3*RotSpeed rysuj sferę rysuj rysuj czworościan rysuj wszystkie wciśnięto przycisk: niebieskie? tak nie wciśnięto przycisk: cyjanowe? niebieskie ustaw niebieskie okulary=niebieskie cyjanowe ustaw cyjanowe okulary=cyjanowe tak nie wciśnięto przycisk: zielone? tak zielone nie wciśnięto przycisk: sześcian? tak sześcian ustaw zielone okulary=zielone ustaw sześcian figura=sześcian nie wciśnięto przycisk: sfera? tak sfera nie wciśnięto przycisk: czworościan? tak nie wciśnięto przycisk: wszystkie? przesunięto kursor? ustaw sferę ustaw czworościan czworościan tak ustaw wszystkie wszystkie tak tak CameraRotY+=dx wciśnięto lewy przycisk? CameraRotX+=dy nie nie wciśnięto prawy przycisk? eyesep+=dx tak odległość do obiektu+=dy nie nie tak zmień rozdzielczość zamknięto program? tak Diagram: activity diagram Page 1 Rysunek 6: Diagram przepływu sterowania 9 figura=sfera figura=czworościan figura=wszystkie 10 Rysunek 7: Zrzuty ekranu przedstawiające działanie aplikacji dla różnych opcji 8 Wnioski Zagadnienia związane z wyświetlaniem obrazu trójwymiarowego stały się w ostatnich czasach bardzo popularne. W kinach pojawia się coraz więcej filmów, które możemy obejrzeć w tej technologii (jak np. Avatar). Jednakże samo zagadnienie wyświetlania obrazu w 3D było już poruszane w przeszłości, właśnie przy użyciu anaglifów. Jak zostało pokazane w projekcie, taki efekt można osiągnąć w domu, przy użyciu zwykłego komputera i darmowych bibliotek. Przy wykorzystaniu OpenGL’a można w bardzo prosty sposób dodać trzeci wymiar do wyświetlanej sceny. Wyświetlając obraz anaglifowy i zakładając specjalne okulary możemy odczuć głębię w obrazie. Efekt ten jest zwłaszcza widoczny, jeśli na obrazie znajduje się kilka brył, w różnej odległości od widza. Wtedy to jesteśmy w stanie wyraźnie wskazać, które bryły są bliżej, a które dalej od nas. Metoda anaglifowa ma jednak szereg wad, co jest dostrzegalne przy oglądaniu obrazów brył w stworzonym przeze mnie programie. Po pierwsze, okulary nie posiadają idealnie filtrujących szkieł. Przez to część obrazu przeznaczonego tylko dla oka prawego przedostaje się do lewego i odwrotnie, co zaburza postrzeganie przestrzenne i nieco psuje efekt. W obrazach anaglifowych tracimy także częściowo informacje o kolorach, gdyż do każdego oka przekazywana jest jedynie część składowych kolorów, a nie cała paleta barw, jak to ma miejsce w percepcji rzeczywistego świata. Wymienione tutaj wady przeważyły o tym, iż w przeszłości anaglifowe filmy pokazywane w kinach i telewizji zostały szybko wyparte przez zwykłe, dwuwymiarowe obrazy, ale oferujące całą paletę barw. Wyświetlanie obrazów stereoskopowych jest techniką, która zaczyna już być, a w niedługim czasie będzie jeszcze mocniej promowana przez producentów telewizorów. Firma Sony ma już ustaloną całą kampanię produkcyjną i reklamową, która ma na celu popularyzowanie tego standardu w domowym zaciszu. Ich konsola, Sony Playstation 3 zyskała uaktualnienie oprogramowania, które pozwala jej wyświetlać specjalnie przygotowane do tego gry w trzech wymiarach. Cała technologia 3D opiera się na tej samej zasadzie, opisanej przeze mnie - dostarczanie widzowi osobnych obrazów dla każdego oka. Rozwinęła się jedynie technologia, dzięki czemu możemy teraz każdym okiem odbierać obraz o pełnej palecie kolorów. Zrealizowany projekt pozwolił mi zapoznać się z technikami tworzenia obrazu trójwymiarowego, oraz wykorzystaniem grafiki komputerowej do tworzenia takich obrazów. Umożliwił mi także zdobycie wiedzy dotyczącej integracji wyświetlanego obrazu z graficznym interfejsem użytkownika oraz z odczytywaniem gestów wykonywanych przy użyciu myszy. W ramach rozwoju projektu można spróbować wygenerować bardziej złożoną, oteksturowaną scenę, a nawet prostą grę, którą będzie można wzbogacić o trzeci wymiar. Dzięki temu będzie można doświadczyć zapowiadanej m. in. przez Sony rewolucji 3D nie wydając kilku tysięcy złotych na telewizor i konsolę wyposażone w nowoczesną technologię. Literatura [1] Opengl 2.1 reference pages. http://www.opengl.org/sdk/docs/man/. [2] Opengl tutorials. http://nehe.gamedev.net/. [3] Pyopengl 2.0.1.04 man pages. http://pyopengl.sourceforge.net/documentation/manual/http: //www.opengl.org/sdk/docs/man/. [4] 3d stereo rendering using opengl (and glut). http://local.wasp.uwa.edu.au/~pbourke/ miscellaneous/stereographics/stereorender/, listopad 1999. [5] Calculating stereo pairs. http://local.wasp.uwa.edu.au/~pbourke/miscellaneous/ stereographics/stereorender/, lipiec 1999. [6] Creating correct stereo pairs from any raytracer. http://local.wasp.uwa.edu.au/~pbourke/ miscellaneous/stereographics/stereorender/, luty 2001. [7] Creating stereoscopic images that are easy on the eyes. http://local.wasp.uwa.edu.au/~pbourke/ miscellaneous/stereographics/stereorender/, luty 2003. 11 [8] Offaxis frustums - opengl. http://local.wasp.uwa.edu.au/~pbourke/miscellaneous/ stereographics/stereorender/, lipiec 2007. [9] Stereoscopy. http://en.wikipedia.org/wiki/Stereoscopy, lipiec 2010. [10] J. Blanchette and M. Summerfield. C++ GUI Programming with Qt 4, Second Edition. Prentice Hall, 2008. [11] B. Kreczmer. Wizualizacja danych sensorycznych. ARES00101W, materiały niepublikowane, PWr, 2010. [12] D. Molkentin. The Book of Qt 4 The Art of Building Qt Applications. Open Source Press GmbH, 2007. [13] D. Shreiner. OpenGL Programming Guide Seventh Edition. The Khronos OpenGL ARB Working Group, 2009. 12