Gdyby zorganizować konkurs na jak największą ilość kodu napisaną celem osiągnięcia jak najprostszego efektu, to pewnie obrazek po lewej (i kod, który za nim stoi) mógłby zająć w nim całkiem dobrą lokatę. Na pierwszy rzut oka to tylko niebieski trójkąt na żółtym tle; na drugi, trzeci i każdy następny zresztą też :) Na tym arcyprostym obrazku nie widać całego, dość skomplikowanego mechanizmu, dzięki któremu możemy go oglądać.
Rzeczony trójkąt jest bowiem efektem pracy programowego renderera, którego to od jakiegoś czasu – z konieczności, acz nie bez pewnej przyjemności – staram się popełnić. Taki kawałek oprogramowania ma za zadanie robić mniej więcej to, co potrafią zaawansowane biblioteki graficzne w rodzaju DirectX i OpenGL. Są oczywiście istotne różnice, wśród których największą jest brak wykorzystania typowych możliwości współczesnych kart graficznych – czyli właśnie przetwarzania trójkątów. Wręcz przeciwnie: wszystkie obliczenia pracowicie wykonuje główny procesor, zajmując się po kolei nie tylko każdym wielokątem, ale także każdym pikselem. Ma więc wyjątkowo dużo roboty, z którą jednak potrafi sobie poradzić.
O czym świadczy więc pokazany tutaj trójkąt? Ano o tym, że podstawowy potok renderowana ma się całkiem dobrze. W jego skład wchodzi transformowanie trójkątów przekształceniami macierzowymi, oświetlenie per-vertex, sprawdzanie widoczności pikseli przy pomocy bufora Z oraz rzutowanie perspektywiczne i rasteryzacja wynikowej płaskiej geometrii. Zgadza się, to zupełne podstawy podstaw, nieobejmujące chociażby teksturowania, lecz i tak realizujący je kod nie wiadomo kiedy rozrósł się do ponad dwóch tysięcy linijek. Faktycznie więc to był dosyć pracochłonny trójkąt :)
Zabłysnę jeszcze przykładowym kodem wykorzystującym renderer, który to wyglądać może mniej więcej tak:
Inspiracje pewną popularną biblioteką w zakresie interfejsu są, jak sądzę, doskonale widoczne :)
To prawie jakbyś pisał jedną z pierwszych gier w 3D za czasów DOS-a :) Nie ma to jak “samemu”.
Jesli moge miec male, dziwne pytanie – po co? ;)
Pieprzony geniusz :D twoj IQ pewnie duzo ponad 200 wykracza (o ja pyrtole ) :O właśnie próbuje własnych sił z twoim Tutrialem o C++ aż nie chce mi się wierzyć że jesteś tylko o dwa lata starszy odemnie
Nie ma AA… brzydkie ;)
Java… bleeeee…. bardzo brzydkie ;)
Ale przenośne ^.^
Jakich ty funkcji używasz do softwarowego putpixel? Nigdy o nich nie słyszałem ;p (bo siedzę w oglu)
RedHot: Jak koder się postara, to C++ też jest przenośny :).
SirMike: Z powodu posiadania na studiach takiego przedmiotu jak Grafika komputerowa, gdzie “Wizualizacja sceny 3D” jest jednym z projektów do wykonania :)
TeMPOraL: Tak, to Java, więc brzydkie – ale dzięki temu załatwiam również inny przedmiot o nazwie Java 2 :)
Netrick: Ano właśnie to OGL jest :) Mówiąc ściślej, używam JOGLa do rysowania point-sprite’ów, co działa jak stawianie pikseli. Wiem, że to nie najlepsze rozwiązanie (zapewne lepiej byłoby dobrać się do tekstury, a potem wyświetlić ją na quadzie), ale najprostsze (z tych szybkich, pomijam użycie java.awt.Graphics).
O jak ja się cieszę, że u mnie na uczelni byłem z grafiki zwolniony :)
Siemien: a co ja mam powiedzieć? On jest w moim wieku ;) I jeszcze kilku innych wymiataczy też.
@Xion – no tak, zapomnialem – takie rzeczy to tylko w szkole ;)
Odnośnie tego projektu wymyśliłem dowcip-zagadkę:
– Jakie jest przeciwieństwo grafiki czasu rzeczywistego?
– Software renderer w Javie.
Co do optymalizacji, to jedną rzecz mógłbyś przyspieszyć – przekazywać float x, float y, float z zamiast new Vector3(x, y, z).
Reg: wystarczy w Javie, nie musi być nawet software ;)