Większość czasu tworzę pod ArchLinux. Niedawno postanowiłem wypróbować go na Ubuntu 16.04. Sytuacja, na którą się natknąłem, była naprawdę dziwna:
- Brak
glGetError()
w ogóle. - Brak błędów, ostrzeżeń, nic złego w wynikach debugowania gl.
- Wszystkie potwierdzenia, które zrobiłem dla wszystkich złych sytuacji, nie zostały wyzwolone.
-
glClear
pomyślnie wyczyścił bufory I określone, ale: -
glDraw*
nic nie narysowałem.
Na szczęście znalazłem rozwiązanie który miał ustawić glViewport
. Jednak nie do końca rozumiem, dlaczego jest to konieczne do rysowania w Ubuntu, ale nie jest konieczne w ArchLinux? Różnica jest również między kartami graficznymi: na archlinux używam NVIDIA 1060, na Ubuntu używam zintegrowanej grafiki HD P530 (Skylake GT 2 ).
Jeśli to ważne, używam SDL2 z opengl 4.4.
Komentarze
- It ' jest ważne, abyś zdał sobie sprawę, że system operacyjny nie jest tutaj istotny; OpenGL jest zaimplementowany przez dostawcę twojego GPU w ich sterownikach, więc ważnymi czynnikami są twoje GPU i ich sterowniki. System operacyjny może być interesujący jeśli Twój dostawca GPU ma różne bazy kodów dla różnych systemów operacyjnych, ale poza tym ' nie są przydatne informacje.
- @MaximusMinimus to może być odpowiedź na pytanie.
Odpowiedź
Masz już dwie dobre odpowiedzi, ale mogą być one trudne do zrozumienia dla początkującego, więc „Powiem ci, dlaczego naprawdę potrzebujemy .
W typowym renderowaniu może się to wydawać bez sensu – po prostu tworzysz jakieś okno lub renderujesz cel i rysujesz na nim, prawda? Powiedziałbym, że 95 +% aplikacji działa w ten sposób.
Ale powiedzmy, że piszesz aplikację taką jak 3DS MAX, w której masz okno podzielone na 4 różne renderingi. Pamiętasz bieżącej pozycji podziału i zarządzasz zdarzeniami myszy, więc kiedy najedziesz kursorem na podzielony pasek, możesz zmienić kursor myszy na zmianę rozmiaru itd. Kiedy przeciągasz podzielony pasek, zapamiętujesz jego nową pozycję i tak dalej.
Kiedy chcesz renderować swoje widoki 3D, wywołujesz glViewport z położeniem i rozmiarem pierwszego podokna 3D i uruchamiasz typowe polecenia GL do rysowania tutaj. OpenGL automatycznie przeskaluje renderowanie tak, aby pasowało do danego okienka. Zrobisz to samo dla reszta twoich rzutni i na końcu dostajesz jedno okno z kilkoma różnymi renderingami, każdy z własnymi parametrami. W ten sposób możesz mieć tyle różnych renderingów w jednym oknie / celu renderowania, ile chcesz.
Dlaczego nie działało na jednym komputerze?
Procesory graficzne i ich sterowniki mają dużo szczegóły implementacji i różnice, więc generalnie musisz przyzwyczaić się do takich problemów. Jeden prosty przykład: w module cieniującym GLSL możesz utworzyć wektor zerowy 2D w następujący sposób: vec2(0.0,0.0)
, możesz też spróbować zapisać jedną wartość: vec2(0.0)
iz tym kodem niektóre sterowniki będą traktować go jak poprzednią wersję, podczas gdy inne będą zwracać błąd i nic nie renderują. Pamiętaj, że sterowniki od dwóch dostawców będą się różnić bardziej niż dwiema wersjami tego samego sterownika, więc dobrym pomysłem jest przetestowanie kodu na procesorach graficznych nVidia, ATI i Intel. W tym przypadku podejrzewam, że w sterownikach nVidii, nie ustawiaj widoku samodzielnie, zakładają, że chcesz użyć całego celu renderowania, podczas gdy sterowniki Intela tego nie robią.
Odpowiedz
glViewport pozwala opengl wiedzieć, jak odwzorować współrzędne NDC na współrzędne bufora ramki.
Domyślnie jest ustawiony na pełny rozmiar bufora ekranu. Więc musisz go wywołać tylko wtedy, gdy okno zostanie zmieniony lub faktycznie chcesz go zmienić.
Komentarze
- Lub podczas renderowania do bufora ramki, zakładając, że rozmiar okna jest inny.
Odpowiedź
glViewport określa afiniczną transformację xx i yy ze znormalizowanych współrzędnych urządzenia na współrzędne okna. Niech (xnd , ynd) xndynd być znormalizowaną koordynacją urządzenia inates. Następnie współrzędne okna (xw, yw) xwyw są obliczane w następujący sposób:
- „xw = (xnd + 1) (width2) + xxw = xnd + 1width2 + x”
- „yw = (ynd + 1) (height2) + yyw = ynd + 1height2 + y”
Szerokość i wysokość rzutni są dyskretnie ograniczane do zakresu zależnego od implementacja. Aby zapytać o ten zakres, wywołaj funkcję glGet z argumentem „GL_MAX_VIEWPORT_DIMS”
Parametry xiy określają lewy dolny róg widoku w pikselach, podczas gdy szerokość i wysokość określają szerokość i wysokość rzutni