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

Offline ArekBal

  • Użytkownik

# Luty 23, 2014, 12:14:58
Xender: Jak sobie to przemyślałem to prawdę rzeczesz.

sig2::signal<void(const MSG& msg, bool& cancelDispatch)> message;
sig2::signal<void(void)> idle;

int start()
  {
    MSG msg = { 0 }; 
   
    m_running = true;

    while(m_running)
    {       
      if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) != NULL)
      {
        if(msg.message == WM_QUIT)
          m_running = false;
        else
        {
          bool cancelDispatch = false;
          message(msg, cancelDispatch);
          if(cancelDispatch == false)
          {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
          }
        }       
      }
      else
      {   
        idle();         
        //WaitMessage(); //it is siet with 60 fps and IOCP, fuck u intel... gonna try with sleep(0), it should be easier than generating timer events with system clock (16.666666666667 ms tickkk).
      } // If the message is WM_QUIT, exit the while loop     
    }
    return msg.message;
  }
Ten kod jest mocno związany z winapi(struktura MSG), i boost::signals2, ale tak samo można oprzeć o SFMLa i rxcpp. No w każdym razie oto chodzi. Wszystkie wiadomości lecą przez message bus/pump(czyli tak jak to w winapi, SFML), a ty się rejestrujesz pod zdarzenie z handlerem. Można tez powystawiać inne zdarzenia... Opcji jest wiele potem.

Jak zaczniesz na tej pętli to końca świata nie będzie, ale wcześniej czy później wypadałoby to opakować.

Offline Mr. Spam

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

Offline Xender

  • Użytkownik

# Luty 23, 2014, 15:36:56
^ Nie wiem, jak z obsługą WM_QUIT.

Jeśli (już nie pamiętam na pewno) WinAPI ma 2 rodzaje wiadomości - jedna to "user prosi o zamknięcie okna" (którą można zignorować lub pozwolić zamknąć zwracając z procedury obsługi okna odpowiednią wartość), a WM_QUIT to ta druga, która pojawia się, po zgodzeniu się programu za zamknięcie, to wszystko ok - ta pierwsza zostanie obsłużona jak wszystkie inne.

Natomiast w niektórych framerowkach (chyba większości tu omawianych) jest tylko jedna wiadomość - prośba o zamknięcie okna. W tym momencie natychmiastowa zgoda z pętli głównej nie jest najlepszym pomysłem - nie będzie nawet okazji zapytać usera "czy chcesz zapisać". Więc ta wiadomość powinna raczej pójść do normalnego dispatchu, jak wszystkie inne.

Offline Rolek

  • Użytkownik

  • +1
# Luty 23, 2014, 16:57:46
@up
Kiedy user kliknie X, okno dostaje wiadomość WM_CLOSE, która informuje, że user kliknął X; wartość zwracana nie ma znaczenia i jak program nic nie zrobi w odpowiedzi na tą wiadomość to nic się nie stanie; program może przesłać wiadomość do DefWindowProc, która wykona domyślną operację, dla WM_CLOSE jest to zniszczenie okna.
Kiedy okno jest niszczone, dostaje wiadomość WM_DESTROY, tu też wartość zwracana nie ma znaczenia, a DefWindowProc nic nie robi; okno bezodwołalnie zostaje usunięte po powrocie z procedury obsługi wiadomości.
Nic samo nie wysyła WM_QUIT; WM_QUIT jest wysyłane, kiedy program uzna, że powinien się zakończyć, często jest to podczas niszczenia głównego okna (przy czym to zależy od programu, czy któreś okno uważa za główne).
WM_QUIT jest jedną z tzw. wiadomości wątkowych, tzn. nie jest kierowana do konkretnego okna, a do wątku, a jej intencją jest zakończenie programu.

Offline ArekBal

  • Użytkownik

# Luty 23, 2014, 19:32:21
Rolek dobrze gada. Masz WM_CLOSE które od tego jest. A WM_DESTROY od sprzątania jest.
Stąd też pewien logiczny błąd w wielu frameworkach. Gdzie zamknięcie jednego okna zamyka program. W praktyce zamknięcie wszystkich okien albo okna głównego(zależy jak leży) powinno dopiero skutkować WM_QUIT na wątku z GUI.
WM_QUIT też wcale nie oznacza zamknięcia programu, a tylko zakończenie Message Pump/loop. W kontekście kilku wątków(i kilku message pump) lub okna modalnego nazwa WM_QUIT staje się jeszcze bardziej niefrasobliwa. :)
« Ostatnia zmiana: Luty 23, 2014, 19:38:10 wysłana przez ArekBal »

Offline Q

  • Użytkownik

# Luty 23, 2014, 23:10:56
W SDL2/SDL2_ttf.h jest chyba jakiś bug który uniemożliwia wgranie fontów. Walczę już z tym od rana i chyba poległem. Co ciekawe w 1.2 działało bez zarzutu.

Offline Raptor

  • Użytkownik

# Luty 23, 2014, 23:15:59
Wszystkim biblioteka poprawnie działa poza Tobą. Tak, to musi być bug ;p
Może lepiej opisz problem i wstaw problematyczny fragment kodu? :)

Offline Q

  • Użytkownik

# Luty 23, 2014, 23:23:24
No właśnie nie wszystkim bo na necie jest masa ludzi na to narzekających.
Problem występuje tu:
font = TTF_OpenFont(font_path, size);
if (!font)
{
printf("TTF_OpenFont: %s\n", TTF_GetError());
TTF_Quit();
SDL_Quit();
exit(1);
}
Dostaje komunikat:
Cytuj
TTF_OpenFont: Couldn't load font file

Offline Raptor

  • Użytkownik

# Luty 23, 2014, 23:29:05
Po czymś takim można tylko obstawiać w ciemno:
-zła ścieżka
-zły plik (chociaż z tym się jeszcze nie spotkałem)
-brak wywołania wcześniej funkcji TTF_Init()

Offline Q

  • Użytkownik

# Luty 23, 2014, 23:33:12
Cytuj
-zła ścieżka
Wypróbowałem niemal wszystkie kombinacje.
Cytuj
-zły plik (chociaż z tym się jeszcze nie spotkałem)
Wypróbowałem na 2 różnych.
Cytuj
-brak wywołania wcześniej funkcji TTF_Init()
kod:
if (TTF_Init() != 0)
{
  printf("TTF_Init() Failed: ");
  SDL_Quit();
  exit(1);
}
TTF_Font * font;
font = TTF_OpenFont(font_path, size);
if (!font)
{
printf("TTF_OpenFont: %s\n", TTF_GetError());
TTF_Quit();
SDL_Quit();
exit(1);
}
// Write text to surface
SDL_Color text_color = {255, 255, 255};
SDL_Surface * t = TTF_RenderText_Solid(font, text, text_color);
SDL_Texture * texture = SDL_CreateTextureFromSurface(ren, t);
textArray.push_back(texture);
Jak widać funkcja jest wywoływana.

Offline Xender

  • Użytkownik

# Luty 24, 2014, 11:16:54
Wypróbowałem niemal wszystkie kombinacje.
Masz wiedzieć, jak ścieżka ma wyglądać, a nie próbować kombinacji.

W każdym razie prawdopodobnie to będzie chciało ścieżkę względem CWD (current working directory) lub absolutną. Nie spodziewałbym się, aby nazwa czcionki systemowej działała.

Offline Q

  • Użytkownik

# Luty 24, 2014, 11:44:58
Właśnie doszedłem do tego co nie grało. Kosztowało mnie to sporo nerwów.
Kompilowałem z opcją -lSDL_ttf a powinno być -lSDL2_ttf.
Dopiero jak pogrzebałem w bibliotekach to mnie olśniło.
Ktoś kiedyś powiedział że: "Upór to mądrość głupców"

1 dzień stracony. Też tak macie że potraficie utknąć na czymś tak banalnym?

Offline Q

  • Użytkownik

# Luty 27, 2014, 00:37:43
http://www.youtube.com/watch?v=pZtRpHXd5Sk&list=UUp2ZeC5yC_UX5LaiJWjbrmw&feature=share
To efekt działania kodu:
Qgl GameWindow(800, 600,"test 1");
GameWindow.debug_fps = true;

Scene scena1;

Geometry geom(HEXAHEDRON, 0.5, 0.25, 0.5);

Color color(25, 24, 123); // to na razie nie działa
MaterialType typ = SOLID;
Material mater(&typ, &color);

Mesh mesh(&geom, &mater);

scena1.addMesh(&mesh);

GameWindow.setScene(&scena1);
GameWindow.Start();

Chce wprowadzić podział na sceny 2D i 3D. 2D nie używały by opengl i służyły do robienia menu, ekranów powitalnych itp.

Co o tym sądzicie?
« Ostatnia zmiana: Luty 27, 2014, 00:45:17 wysłana przez Q »

Offline Rolek

  • Użytkownik

# Luty 27, 2014, 02:08:18
2D nie używały by opengl i służyły do robienia menu, ekranów powitalnych itp.
http://xion.org.pl/productions/texts/coding/game-programming/gfx2d/ (co prawda w artykule jest Direct3D, ale chodzi o ogólną ideę)

Offline Xender

  • Użytkownik

# Luty 27, 2014, 09:59:15
2D nie używały by opengl i służyły do robienia menu, ekranów powitalnych itp.
Bez sensu. Jak już bierzesz GL, to nada się i do tego.

http://xion.org.pl/productions/texts/coding/game-programming/gfx2d/ (co prawda w artykule jest Direct3D, ale chodzi o ogólną ideę)
Albo sięgnąć po gotową libkę, która to robi, czyli SFML albo SDL2, które od początku przewijają się przez ten wątek. ;)

Offline ArekBal

  • Użytkownik

# Luty 27, 2014, 20:18:34
Albo zaimplementować SpriteBatch/DXSprite