OpenGL Podrzedne okno z grafika

0

Witam.

user image

Mam taki problem. Mam jedno okno główne, a w nim okno podrzędne. Przedstawione poniżej rozwiązanie działa, udaje mi się najpierw rysować scenę w oknie głównym (tutaj akurat na razie tylko ustawiam kolor tła), potem rysuję w drugim oknie. Zamiana rysowania między oknami zachodzi za pomocą wglMakeCurrent i przypisania HDC do odpowiedniego okna. Okna posiadają osobne klasy i procedury okienkowe.

Jednak jest to strasznie nie wydajne rozwiązanie (nie wiem czemu). Na komputerach średniej klasy program się bardzo ścina, grafika i samo okno podczas przesuwania haczy.

Tutaj widać pętle główną:

        /*************************************************************
                 *************     RYSOWANIE W OKNO_GRAFIKI     ***************
                 *************************************************************/   
                 g_HDC = GetDC(okno_grafiki);   
                 g_hRC = wglCreateContext(g_HDC);
                 SetupPixelFormat(g_HDC);
                 wglMakeCurrent(g_HDC, g_hRC);
                 SelectObject(g_HDC, hCzcionka);
                 wglUseFontBitmaps(g_HDC, 32, 96, base);  
                 
                 UstawieniaOknoGrafiki();
                 Kamera();
                 RysujOknoGrafiki();
                 
                 /* **************** Czyszczenie ******************** */
                               wglMakeCurrent(g_HDC, NULL);
                               wglDeleteContext(g_hRC);
                               ReleaseDC(okno_grafiki, g_HDC);
                 
                 
                 /*************************************************************
                 *************     RYSOWANIE W OKNO_GLOWNE     ****************
                 *************************************************************/
                 g_HDC = GetDC(okno_glowne);   
                 g_hRC = wglCreateContext(g_HDC);
                 SetupPixelFormat(g_HDC);
                 wglMakeCurrent(g_HDC, g_hRC);
                 SelectObject(g_HDC, hCzcionka);
                 wglUseFontBitmaps(g_HDC, 32, 96, base);
       
                 RysujOknoGlowne();
                 
                 /* **************** Czyszczenie ******************** */
                               wglMakeCurrent(g_HDC, NULL);
                               wglDeleteContext(g_hRC);
                               ReleaseDC(okno_glowne, g_HDC);
                 
                 TranslateMessage(&msg);
                 DispatchMessage(&msg);
                 Sleep(1);

Teraz pytanie. Co robię źle, że to praktycznie na komputerze Intel Core Duo 2,2, Geforce 8600 GTS, 2GB DDR2 chodzi, a na kompie AMD 2,1, Radeon 9660, 512 DDR ni hu hu.

Obserwacja:
Wylączając rysowanie w oknie głównym program zaczyna działać na słabych komputerach i znacznie polepsza się jego wydajność, co obserwuję ruszając ramionami robota (to żółte :P). Więc coś jest nie tak z tym przełączaniem się po oknach.

Innym pomysłem jest zrobienie tego w 1 oknie, ale nie za bardzo wiem, czy da się/ lub jak to zrobić aby rysować najpierw po całym oknie przyciski(teraz to okno główne), a potem w kawałku okna rysując samą animacje robota.

0

i to wszystko sie kreci w petli komunikatow ?????

Jesli tak to zle, bo tworzysz mnostwo obiektow, nie zwalniasz ich, ciagle ustawiasz setpixel... etc.
Wystarczy wglMakeCurrent i odrysowanie okien. Dodatkowo jesli to w petli komunikatow to tez bez sensu, wystarczy w paint i ewentualne interakcje z klawiszami.

a i jeszcze ten sleep ? Po co? Za szybko Ci to chodzi ?

0

Z tego co wyczytałem na tym forum to Sleep(1) odciąża procesor, w sensie, że nie jest zużywane 100% na program czy coś takiego. Ale to nic nie spowalnia praktycznie, bo co to jest 1ms :P.

Gdy usunę sobie SetPixelFormat to w ogóle nie wyświetla grafiki w tym oknie gdzie to usunę. A to co tworze jest zwalniane w części opatrzonej komunikatem /Czyszcznie/. Samo wglMakeCurrent nie wystarcza, bo musze HDC przypisać do drugiego okna, potem znów mu ustawić format pixeli, a potem go zrobić bieżącym dla OpenGL'a.

Inaczej mi to nie chodzi, chciałem też zrobić to tak, że podczas tworzenia robię dwa HDC i hRC i potem tylko sobie wglMakeCurrentem zmieniam to tu to tam, ale jakoś nie działało na dwóch HDC.

Jak mogę inaczej zrobić obsługę dwóch okien? Skoro to jest totalny kombajn dla procka ? Lub jak w jednym oknie wyświetlać animację OpenGL ale nie na całym obszarze okna, tylko w konkretnym obszarze.

Proszący o pomoc.
Mrowa

0

Wystarczy raz na poczatku utworzyc wszelkie konteksty, uchwyty, wczytac czcionki, bitmapy,....
Potem zmieniasz tylko konteksty (czynic je aktualnym). SetPixelFormata tez wystarczy raz na poczatku (chyba, ze cos go zmienia w trakcie). Kopsnij wiecej kodu (zamiast procedur rysujacych niech tam maluje np kulke, bo nie wtym rzecz). Nie wiem w jakim systemie masz zamiar to odpalac (widac windows), mozna z bibliotek miedzy platformowych kozystac i nie dlubac sie w WinAPI.

0

Zrobiłem teraz to tak, że przy tworzeniu okna (komunikat WM_CREATE) przypisuję globalnym kontekstom to co trzeba, a w głównej pętli zmieniam tylko bieżący za pomocą wglMakeCurrent. Efekt tego jest taki, że tworzy okna, widać je, ale nie ma grafiki OpenGL.

Definicje kontekstów:

HDC g_HDC;                                          // kontekst urzadzenia 
HGLRC g_hRC;                                        // kontekst tworzenia grafiki
HDC g_HDC2;                                          // kontekst urzadzenia 2
HGLRC g_hRC2;                                        // kontekst tworzenia grafiki 2

Potem przy obsłudze w procedurach okienkowych:

  1. WndProc (okno główne)
case WM_CREATE:
                  g_HDC = GetDC(okno_główne);   
                  g_hRC = wglCreateContext(g_HDC);
                  SetupPixelFormat(g_HDC);
                  break;
  1. WndProc2 (okno grafiki)
case WM_CREATE:
                  g_HDC2 = GetDC(okno_grafiki);   
                  g_hRC2 = wglCreateContext(g_HDC2);
                  SetupPixelFormat(g_HDC2);
                  break;

A potem w pętli głównej robie aktywnym pierwsze okno rysuje pierwsze okno, zmieniam wglMakeCurrent'em na drugie, rysuje drugie. Usuwanie kontekstów jest w komunikacie WM_CLOSE.

Lecz nie działa...

Pozdrawiam
Mrowa

P.S Całego kodu jest 1300 wierszy, daje tutaj tylko to co jest związane z tymi zabawami kontekstami, bo jeśli rysuje tylko 1 okno to wszystko gra.

0

Okej, dziękuję ludziom którzy starali się mi pomóc. Znalazłem rozwiązanie na innym forum :), dotyczy ono mojego drugiego pomysłu na rozwiązanie tego problemu.

A więc problem ten można rozwiązać przy pomocy ustawiania różnych glViewport. Co pozwala w jednym oknie, rysować po różnych jego częściach. To tak gdyby ktoś miał problem podobny do mojego.

Pozdrawiam.

1 użytkowników online, w tym zalogowanych: 0, gości: 1