Używaj jednolitych buforów (tj. Stałych buforów w języku D3D).
Tak długo, jak wszyscy twoi shadery zgadzają się co do układu i punktu wiązania każdego takiego bufora, aktualizacja staje się bardzo prosta. Modele wcale nie muszą nic wiedzieć o shaderach. Muszą tylko zaktualizować matrycę widoku modelu w swoim stałym buforze, a potok renderujący użyje go automatycznie.
Przynajmniej twierdziłbym, że powinieneś mieć dwa takie bufory. Pierwszy powinien przechowywać macierz projekcji, matrycę kamery, połączoną matrycę projekcji z kamery, informacje o rzutni, szczegóły frustrum i odwrotności matrycy. Musisz zaktualizować ten bufor tylko raz na scenę.
Następnie daj każdemu modelowi kolejny bufor do przechowywania jego matrycy widoku modelu, macierzy normalnej, odwrotności i właściwości materiału. Jest on aktualizowany jeden raz dla każdego modelu i można to zrobić za pomocą innej aktualizacji (jeśli / w razie potrzeby). Informacje o materiale można / należy przenieść do trzeciego bufora specyficznego dla materiału, jeśli masz możliwość współużytkowania materiałów między wieloma obiektami.
W ustawieniu cieniowania do przodu sensowne jest umieszczenie wszystkich świateł w innym buforze, a w przypadku cieniowania odroczonego warto również zastosować bufor światła dla przejścia światła (zamiast bufora modelu / materiału używanego w przejście geometrii).
Pamiętaj, że potrzebujesz umiarkowanie aktualnej wersji GL, aby w ogóle używać jednolitych buforów (3.1 lub rozszerzenia; dość powszechna dzisiaj, z wyjątkiem niektórych starszych, ale wciąż używanych laptopów) i potrzebujesz dość nowej wersji, aby być możliwość powiązania jednolitych buforów z określonymi lokalizacjami powiązań z kodu modułu cieniującego (4.2; wciąż niezbyt często, ale coraz lepiej), w przeciwnym razie musisz wykonać więcej pracy w kodzie po stronie procesora, aby skonfigurować ustawienia (kod procesora musi znać odpowiednie powiązanie wskazuje, więc to raczej zapach API niż poważny problem). OpenGL | ES nie dodał jednolitych buforów do 3.0, co niestety nie jest obsługiwane na większości popularnych platform mobilnych.
Jeśli bufory nie są opcją, będziesz potrzebować globalnego miejsca do przechowywania lokalizacji indeksu dla aktywnego modułu cieniującego. Możesz użyć glGetUniformLocation
po załadowaniu shadera, aby znaleźć indeksy dla dobrze znanych nazw (podobnych ModelViewMatrix
lub podobnych), a następnie zapisać te indeksy. Twój rendering może mapować wartości wyliczeniowe, takie jak MODEL_VIEW
przekazane do SetUniform
funkcji otoki, aby spojrzeć na związany moduł cieniujący, znaleźć indeks i wywołać glUniform
poprawnie. Nie jest to szczególnie duża zmiana w użyciu kodu klienta z buforów innych niż konieczność ustawiania każdego munduru indywidualnie, jeśli wszystko dobrze się zapakuje.
Zobacz bloki interfejsu GLSL i jednolite obiekty buforowe .