Próbuję wymyślić, jak renderować moją scenę do mapy kostki. Utknąłem na tym trochę i pomyślałem, że poproszę was o pomoc. Jestem nowy w OpenGL i po raz pierwszy korzystam z FBO.
Obecnie mam działający przykład użycia pliku bmp z mapą Cubemap, a typ próbki samplerCube w module cieniującym fragmenty jest dołączony do GL_TEXTURE1. W ogóle nie zmieniam kodu modułu cieniującego. Zmieniam tylko fakt, że nie będę wywoływał funkcji, która ładowała plik bmp Cubemap i próbowała użyć poniższego kodu do renderowania mapy Cubemap.
Poniżej możesz zobaczyć, że ponownie dołączam teksturę do GL_TEXTURE1. Dzieje się tak, gdy ustawiam mundur:
glUniform1i(getUniLoc(myProg, "Cubemap"), 1);
może uzyskać do niego dostęp za pośrednictwem mojego modułu cieniującego fragmenty uniform samplerCube Cubemap
.
Nazywam poniższą funkcję tak:
cubeMapTexture = renderToCubeMap(150, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE);
Teraz zdaję sobie sprawę w poniższej pętli rysowania, że nie zmieniam kierunku widoku, aby spojrzeć w dół osi + x, -x, + y, -y, + z, -z. Naprawdę chciałem tylko zobaczyć, jak coś działa, zanim to zaimplementuję. Uznałem, że powinienem przynajmniej zobaczyć coś na swoim obiekcie takim, jak jest teraz w kodzie.
Nic nie widzę, tylko prosta czerń. Moje tło jest białe, a obiekt jest czarny. Usunąłem oświetlenie i kolory, aby po prostu próbkować teksturę mapy kubka i nadal czarny.
Myślę, że problemem mogą być typy formatów podczas ustawiania mojej tekstury, którą jest GL_RGB8, GL_RGBA, ale próbowałem też:
GL_RGBA, GL_RGBA GL_RGB, GL_RGB
Myślałem, że będzie to standard, ponieważ renderujemy teksturę dołączoną do bufora ramki, ale widziałem różne przykłady, które używają różnych wartości wyliczania.
Próbowałem również powiązać teksturę mapy kostki w każdym wywołaniu losowania, którego chcę użyć mapy kostki:
glBindTexture(GL_TEXTURE_CUBE_MAP, cubeMapTexture);
Ponadto nie tworzę bufora głębokości dla FBO, co widziałem w większości przykładów, ponieważ chcę tylko bufor kolorów dla mojej mapy kostki. Dodałem jeden, aby sprawdzić, czy to jest problem i nadal mam takie same wyniki. Mógłbym to zrobić, gdy próbowałem.
Doceniam każdą pomoc, która może skierować mnie w dobrym kierunku.
GLuint renderToCubeMap(int size, GLenum InternalFormat, GLenum Format, GLenum Type)
{
// color cube map
GLuint textureObject;
int face;
GLenum status;
//glEnable(GL_TEXTURE_2D);
glActiveTexture(GL_TEXTURE1);
glGenTextures(1, &textureObject);
glBindTexture(GL_TEXTURE_CUBE_MAP, textureObject);
glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
for (face = 0; face < 6; face++) {
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, 0, InternalFormat, size, size, 0, Format, Type, NULL);
}
// framebuffer object
glGenFramebuffers(1, &fbo);
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X, textureObject, 0);
status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
printf("%d\"\n", status);
printf("%d\n", GL_FRAMEBUFFER_COMPLETE);
glViewport(0,0,size, size);
for (face = 1; face < 6; face++) {
drawSpheres();
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, textureObject, 0);
}
//Bind 0, which means render to back buffer, as a result, fb is unbound
glBindFramebuffer(GL_FRAMEBUFFER, 0);
return textureObject;
}
drawSpheres
funkcja rzeczywiście rysuje coś widocznego? Czy funkcja rzeczywiście coś rysuje? Co się stanie, jeśli zmienisz się,drawSpheres
aby po prostu wyczyścić bufor ramki?Odpowiedzi:
Nie mogę zagwarantować, że to pomoże ci dowiedzieć się, co się dzieje. Po prostu nie opublikowałeś wystarczającej ilości informacji o tym, co robisz, aby wyśledzić jakieś konkretne błędy. Chociaż mogę bardzo szybko poprawić jedną z twoich rzeczy:
To zadzwoni tylko
drawSpheres
pięć razy. Zgaduję, że chciałeś to nazwać 6 razy.Ale mogę opublikować działającą odpowiedź. Zauważ, że ten kod jest przeznaczony do uruchamiania razem z moją serią samouczków , więc zawiera odniesienie do kodu, który nie jest obecny. Ale chodzi przede wszystkim o tworzenie siatek i tak dalej; nic naprawdę ważnego.
Oto najważniejsze punkty. Shadery dla głównego obiektu kuli.
Moduł cieniujący wierzchołek:
Moduł cieniujący fragmenty:
Tworzenie tekstury mapy kubaturowej, która będzie używana jako cel renderowania:
Faktycznie wypełniam teksturę danymi (zamiast przekazywać NULL do glTexImage2D) jako pomoc w debugowaniu. Zapewnia to, że wszystko działało przed użyciem tekstury jako celu renderowania.
Zauważ też, że dostarczam BASE_LEVEL i MAX_LEVEL. I zawsze zrobić z moich tekstur bezpośrednio po stworzeniu. To po prostu dobry nawyk, ponieważ OpenGL bywa czasem wybredny pod względem kompletności tekstur i piramidy mipmap. Zamiast zapamiętywać reguły, po prostu ustawiłem je zgodnie z religijnymi wartościami.
Oto główna funkcja rysowania:
Odnosi się to do
DrawFace
, który rysuje dane oblicze mapy cubemap. Jest to realizowane w następujący sposób:Ta funkcja odnosi się do zestawu globalnych tabel, których używam, aby nadać każdej twarzy odrębny kolor tła, odrębny kolor kuli i odpowiednio ustawić kulę (w przestrzeni kamery) dla tej twarzy.
Najważniejsze z
DrawFace
nich to:Zasadniczo, o ile nie mam pewności, że stan jest ustawiony, ustawiam ten stan. Ustawiam rzutnię za każdym razem, gdy dzwonię
DrawFace
. Za każdym razem ustawiam macierz projekcji. Te są zbyteczne; Mógłbym ustawić je z powrotemdisplay
przed pętlą, która wywołujeDrawFace
, tak jak robię to z obecnym buforem renderowania głębokości i FBO.Ale usuwam również bufory, które są różne dla każdej twarzy (ponieważ każda twarz ma inny kolor).
źródło