Autor Wątek: [c++] Opengl opakowany w obiekty, czy warto?  (Przeczytany 39040 razy)

Offline ArekBal

  • Użytkownik

# Luty 20, 2014, 09:08:35
Oddzielny SpriteBuilder budujący immutable by wystarczył. :)

Offline Mr. Spam

  • Miłośnik przetworów mięsnych

Offline Xion

  • Redaktor
    • xion.log

  • +3
# Luty 20, 2014, 09:52:14
Builder? Czyżbyś właśnie powiedział "Builder"?! Toż to enterprise'owa herezja! Przeproś i wyjdź :)

Offline Q

  • Użytkownik

# Luty 20, 2014, 22:00:38
Witam ponownie.
Próby okiełznania glut- a nie przyniosły pożądanego efektu. Dziś zapoznałem się z SDL i bardziej mi to przypadło do gustu. Głownie dlatego że łatwiej jest to wpisać w obiekty.
Korzystam z tego kursu http://cpp0x.pl/kursy/Kurs-SDL-C++/22
Niestety nie ma w nim nic o opengl. Przejrzałem kilka kursów ale średnio mi się one podobają. Znacie jakieś proste kursy, najlepiej po polsku albo angielsku?

Ps. Zarys biblioteki już mam. Musze jeszcze wiele przemyśleć. Postaram się dokumentować ją na bieżąco i gdy osiągnie jakiś przyzwoity poziom udostępnie ją.

Offline Xender

  • Użytkownik

# Luty 21, 2014, 00:23:21
To, co masz, to tutorial do legacy wersji 1.2. Obecna to 2.0.
Obie mają wsparcie dla GL, natomiast to z wersji 2.0 będzie raczej lepsze, bo 1.2 robiła własny rendering na procku, a wsparcie GL było tylko dodatkiem.
AFAIK 2.0 cały rendering robi przez GL na GPU, więc siłą rzeczy wsparcie będzie raczej lepsze.

Zamiast tutoriali polecam oficjalna dokumentację (bardziej można na niej polegać) + szukanie na necie.
http://www.libsdl.org/
http://wiki.libsdl.org/Introduction

Możesz też się przyjrzeć SFML, ono ma interfejs obiektowy C++, jeśli Ci na nim zależy.

Jeśli nie interesuje Cię rendering wbudowany w te biblioteki, a chcesz tylko kontekst GL, to GLFW.

Przy okazji, rzuć okiem na glLoadGen - rozwiązuje drugą część "GLinit dramy", czyli wczytanie funkcji (pierwsza to utworzenie kontekstu i zarządzanie oknem - to robią SDL, SFML, GLFW).

Offline Q

  • Użytkownik

# Luty 21, 2014, 13:35:42
Cytuj
Obecna to 2.0.
No właśnie, zainstalowałem bibliotekę ze strony ale jakoś tak mam wątpliwości że jest to wersja 2.0 bo wcześniej miałem w systemie (linux mint 14) chyba wersje 1.2.
Jak to sprawdzić jaka jest?
Druga sprawa, czy skompilowany program uruchomi się na systemie gdzie nie ma zainstalowanej SDL ?
Kolejna sprawa dotyczy bardziej projektowania kodu.
Chcę by biblioteka była prosta jak przysłowiowa budowa cepa.
Np:
Qgl window(800, 600, "nowe okno"); // główny obiekt

window.addCamera(FirstPerson); // definiowanie kamery
window.addKeybordEvent(); // właczanie obługi zdarzen klawiatury
// itd

window.addObject(SPHERE, 200); // dodawanie kuli

window.start(); // rozpoczęcie programu
No i właśnie chciałbym by można było do takiego modelu przypisać możliwość dodawania objektów i zmieniania pramatrów pracy np kamery, oświetlenia itp w czasie pracy programu. Niestety nie mam pomysłu jak to ładnie i elegancko zrobić. Tak by łatwo było to ogarnąć dla każdego kto pierwszy raz zobaczyłby kod.

Offline ArekBal

  • Użytkownik

  • +1
# Luty 21, 2014, 14:12:31
Tak by łatwo było to ogarnąć dla każdego kto pierwszy raz zobaczyłby kod.
Z czasem zrozumiesz że to nie jest najwłaściwsza droga. ;)

IMO najwłaściwsza droga, to taka w której model aplikacji wylewa się z kodu. ;)

np. w kodzie powyżej masz trochę pomieszane. Kamerę dodajesz do okna zamiast do sceny lub ujęcia, czy z drugiej strony do sterownika kamery.
Masz klasę Qgl która tworzy okno... hmm.
Dodajesz do okna obiekt sfery... tylko że logicznie pojmując... okno + sfera = ?
przykładem takiej logicznej hierarchii będzie - mniej więcej - okno>>viewport>>scena>>meshmodels>>sfera(jako specyficzny prymityw).

Tak samo z tym window start. :)
to nie startuje okno... z resztą co to znaczy? :)
Tylko "pętla komunikatów", "przetwarzacz wiadomości", zdarzeń, Dispatcher. Czy nawet proces, czy aplikacja(nie koniecznie sensu stricte) może wystartować.

1. Kod końcowy zawsze ma być jak najprostszy względem tego co robi.
2. Jestem też fanem metod w stylu InitAllWithDefaults(), czy innych helperów które opakowują model do krótkiego kodu.
Ale pisanie samych helperów bez modelu aplikacji to kodowanie od d... strony. ;)

Mógłbym dalej, ale niech najpierw poleci na mnie grad kamieni. :)

Offline Q

  • Użytkownik

# Luty 21, 2014, 14:37:47
Cytuj
np. w kodzie powyżej masz trochę pomieszane. Kamerę dodajesz do okna zamiast do sceny lub ujęcia, czy z drugiej strony do sterownika kamery.
Masz sporo racji. Nie wziąłem tego pod uwagę że można by tworzyć scenę i to do niej dodawać pozostałe rzeczy. Choć kod ten nie musi być błędny, można przez przypisanie kamery, obiektów do głównego okna dodawać do głównej sceny która będzie zdefiniowania domyślnie. 
Cytuj
Tak samo z tym window start. :)
to nie startuje okno... z resztą co to znaczy? :)
To start pętli w której będzie przetwarzana scena/sceny, kamery, oświetlenie, zdarzenia klawiatury, myszki.

Offline Xender

  • Użytkownik

  • +1
# Luty 21, 2014, 16:17:52
Q: IMHO lepiej popracuj z istniejącymi bibliotekami: SDL 2.0 czy SFML i zobacz, jak tam to jest zrobione.

W SFML są nawet klasy od VBO i shaderów (chociaż struktura wierzchołka jest predefiniowana) - można tym zrobić jakieś 3D, chociaż raczej nie tędy droga - SFML to raczej framework 2.5D.

Offline ArekBal

  • Użytkownik

# Luty 21, 2014, 17:32:24
Masz sporo racji. Nie wziąłem tego pod uwagę że można by tworzyć scenę i to do niej dodawać pozostałe rzeczy. Choć kod ten nie musi być błędny, można przez przypisanie kamery, obiektów do głównego okna dodawać do głównej sceny która będzie zdefiniowania domyślnie.
Z jednej strony masz rację... wystarczy że będziesz miał tylko "currentScene/currScene" i póki nie doimplementujesz reszty(obsługi kilku scen) to będzie spoko.
Radzę od razu wyciągać takie klasy w zgodzie z SRP. Lepiej dodać 3 klasy z jedną metodą każda niż upychać do jednej klasy metody które mają się do siebie jak jabłka do samolotów.
Jak chcesz to mieć potem w ramach jednej klasy to wyseparuj potem oddzielną klasę kompozytową. pt. Game która ma metody init, run, onInput, onUpdate, onIdle, onSound, onDraw. i wtedy to ma sens. :)

Cytuj
To start pętli w której będzie przetwarzana scena/sceny, kamery, oświetlenie, zdarzenia klawiatury, myszki.

Domyśliłem się... ;)
Chodziło mi tylko oto że miejsce tej metody jest nie właściwe. WNDPROC w oknie to łamanie SRP.
Ja mam wyseparowane to tak: klasa App ma "windows", oraz "dispatcher". Podpinam się w zdarzenia dispatchera i wywołuje okno stamtąd.

A w mainie mam App app;
app.start();

Jeszcze jest opcja taka by maina wciągnąć do swojej aplikacji i zostawić OnStart unimplemented. I jeszcze kilka innych technik...

Cytuj
Q: IMHO lepiej popracuj z istniejącymi bibliotekami: SDL 2.0 czy SFML i zobacz, jak tam to jest zrobione.
Prawdę Xender rzecze. By samemu to zrobić dobrze(nie ma idealnych rozwiązań) najlepiej zobaczyć i się odnieść do tego jak inni to próbowali rozwiązać, opakować w obiekty.
« Ostatnia zmiana: Luty 21, 2014, 17:35:39 wysłana przez ArekBal »

Offline Q

  • Użytkownik

# Luty 22, 2014, 17:18:01
Martwi mnie że na wielu stronach spotkałem się z opinia że SDL jest do tworzenia grafiki 2D.
Tzn nie kieruje sie opiniami innych ale martwi mnie wydajność opengl w SDL.
Co do samej biblioteki to przyjąłem taki model:
Qgl window(800, 600, "nazwa okna"); // definiowanie okna
QglScene scene; // definiowanie sceny, jeszcze nie ustaliłem co będzie w konstruktorze

QglObject3D sphere(SPHERE, 25); // definiowanie obiektu 3d
/* podobnie będzie definiowana kamera, oświetlenie itp */

scene.add(sphere); // dodawanie kuli do sceny
window.add(scene); // dodawanie sceny do okna

window.display();
Nie rozwiązałem jeszcze jak będzie można modyfikować kod wewnątrz pętli rysującej np. jeśli będziemy chcieli  dodać wczytywanie mapy z serwera itp. Myślałem nad przekazywaniem wskaźnika obiektu do osobnego wątka.
« Ostatnia zmiana: Luty 22, 2014, 17:22:07 wysłana przez Q »

Offline Xender

  • Użytkownik

  • +1
# Luty 22, 2014, 19:52:12
No i co Ci z ctora Object3D, który przyjmuje enuma na kilka predefiniowanych kształtów?
Możliwość zrobienia sfery czy sześcianu może i być przydatna, ale najpierw pomyśl, jak miałby wyglądać interfejs do modeli z pliku, które są o wiele częstszym przypadkiem w większości gier.

A jak już jesteśmy przy modelach - jeden może mieć wiele meshy, jak to jest w wypadku animacji szkieletowej - model jest jeden, ale każda część ciała ma inną transformację (liczoną hierarchicznie z orientacji kości szkieletu od węzła początkowego do danej kończyny).

SDL 1 nadawało się głownie do 2D, bo robiło rendering na procu. Wersja 2 używa GL.

Jeśli chcesz użyć SDL/SFML na tej samej zasadzie, do GLFW, czyli do kontekstu i okna, to nie będą miały wpływu na wydajność (o ile nie tworzą kontekstu z jakimiś dziwnymi flagami (wątpliwe, powinno być w dokumentacji)).

Jeśli chodzi o wydajność renderingu SDL/SFML, to może być różnie. Jeśli zechcesz używać ich renderingu np. tylko GUI (HUD), to nie powinno być problemu.

Wiadomo, że w SFML renderowanie np. dużej tilemapy po prostokącie na tile może ubijać wydajność - ale od tego SFML ma klasę VertexArray.

Offline Q

  • Użytkownik

# Luty 22, 2014, 21:30:44
Cytuj
No i co Ci z ctora Object3D, który przyjmuje enuma na kilka predefiniowanych kształtów?Możliwość zrobienia sfery czy sześcianu może i być przydatna, ale najpierw pomyśl, jak miałby wyglądać interfejs do modeli z pliku, które są o wiele częstszym przypadkiem w większości gier.
Biblioteka jest tworzona dla moich potrzeb, dla mojego projektu. Wyświetlanie figur (sfer, wielokątów itp) odgrywa kluczową w nim rolę. Owszem z czasem chcę dodawać nowe możliwości i na pewno znajda sie też wgrywane obiekty z pliku.
"Nie od razu Rzym zbudowano"
Biblioteka ma powstać jako coś pobocznego co jest efektem pracy nad wiekszą całością. Wiele razy już udawało mi się stworzyć tym sposobem przydatne biblioteki.

Poza tym spotkalem się na tym forum z ciepłym przyjęciem i chciałbym oferować całej spoleczności  forum coś w zamian.
Może cos to komuś pomoże, zaintersuje.
Cytuj
A jak już jesteśmy przy modelach - jeden może mieć wiele meshy,
No właśnie nigdy tego dobrze nie rozumiałem. Mam nadziejej że zrozumiem i sie troszke podszkolę

Cytuj
SFML
Przejrzałem tą bibliotekę i podoba mi się ta petla na końcu. Chyba wykorzystam podobny motyw.
Dzieki temu zrezygnuje z metody start() w której znajduje sie ta petla.
« Ostatnia zmiana: Luty 22, 2014, 21:32:34 wysłana przez Q »

Offline ArekBal

  • Użytkownik

# Luty 23, 2014, 02:17:08
Cytuj
Przejrzałem tą bibliotekę i podoba mi się ta petla na końcu. Chyba wykorzystam podobny motyw.
Dzieki temu zrezygnuje z metody start() w której znajduje sie ta petla.

Jeśli mówisz o tym przykładzie
#include <SFML/Window.hpp>

int main()
{
    sf::Window window(sf::VideoMode(800, 600), "My window");

    // run the program as long as the window is open
    while (window.isOpen())
    {
        // check all the window's events that were triggered since the last iteration of the loop
        sf::Event event;
        while (window.pollEvent(event))
        {
            // "close requested" event: we close the window
            if (event.type == sf::Event::Closed)
                window.close();
        }
    }

    return 0;
}
To jest bieda i świadczy o tym, że twórcy nie wiedzieli co z tym zrobić, więc zostawili tak jak było.
Proponuje zapoznać się z dwoma wzorcami: Command Dispatcher oraz Scheduler.

Offline Q

  • Użytkownik

# Luty 23, 2014, 04:11:39
Tak, dokładnie o tym przykładzie mówiłem.
Masz na mysli http://pl.m.wikipedia.org/wiki/Polecenie_(wzorzec_projektowy) ?
Jakoś trudno jest mi sobie wyobrazić (pewnie jest to spowodowane późną godziną) jak miało by to pomóc w moim problemie. Mógłbyś dać jakiś przyklad np. jako psełdo kod?

Założylem sobie teraz że biblioteka ma byc tak prosta (w użyciu, bo wiele opcji bedzie domyslnie ustawionych) że wyświetlenie okna, menu oraz przejscie z niego do wyświetlania obiektu 3d ma byc mozliwe po wykonaniu nie wiecej niż 10 linijek kodu.

Offline Xender

  • Użytkownik

# Luty 23, 2014, 11:41:09
^ "command dispatcher", nie "command".

ArekBal - Nie powiedziałbym że to bieda, a raczej nienarzucanie konkretnego modelu.