Я пытаюсь выяснить, как визуализировать мою сцену на карте куба. Я застрял на этом немного и решил, что попросил бы вас, ребята, о помощи. Я новичок в OpenGL и впервые использую FBO.
В настоящее время у меня есть рабочий пример использования bmp-файла cubemap, а тип образца samplerCube в фрагментном шейдере прикреплен к GL_TEXTURE1. Я не изменяю код шейдера вообще. Я просто изменяю тот факт, что я не буду вызывать функцию, которая загружает bmp-файл cubemap, и пытаюсь использовать приведенный ниже код для рендеринга в cubemap.
Ниже вы можете видеть, что я также снова прикрепляю текстуру к GL_TEXTURE1. Это так, когда я устанавливаю форму:
glUniform1i(getUniLoc(myProg, "Cubemap"), 1);
он может получить к нему доступ через мой фрагментный шейдер через uniform samplerCube Cubemap
.
Я вызываю функцию ниже так:
cubeMapTexture = renderToCubeMap(150, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE);
Теперь я понимаю, что в цикле рисования ниже я не изменяю направление просмотра, чтобы смотреть вниз по оси + x, -x, + y, -y, + z, -z. Я действительно просто хотел увидеть что-то работающее, прежде чем реализовать это. Я подумал, что должен хотя бы увидеть что-то на своем объекте, как сейчас код.
Я ничего не вижу, просто прямо черный. Я сделал свой фон белым, но объект черный. Я удалил освещение и раскраску, чтобы просто попробовать текстуру куба и все еще черный.
Я думаю, что проблема может заключаться в типах форматов при настройке моей текстуры, GL_RGB8, GL_RGBA, но я также пытался:
GL_RGBA, GL_RGBA GL_RGB, GL_RGB
Я думал, что это будет стандартно, так как мы рендерим текстуру, присоединенную к кадровому буферу, но я видел разные примеры, которые используют разные значения перечисления.
Я также попытался связать текстуру карты куба при каждом вызове отрисовки, который я хочу использовать карту куба:
glBindTexture(GL_TEXTURE_CUBE_MAP, cubeMapTexture);
Кроме того, я не создаю буфер глубины для FBO, который я видел в большинстве примеров, потому что мне нужен только буфер цвета для моей карты куба. Я фактически добавил один, чтобы видеть, была ли это проблема, и все еще получил те же самые результаты. Я мог бы обмануть это, когда попытался.
Буду признателен за любую помощь, которая может направить меня в правильном направлении.
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
функция на самом деле рисует что-то видимое? Функция на самом деле что-то рисует? Что произойдет, если вы изменитеdrawSpheres
просто очистить фреймбуфер?Ответы:
Ну, я не могу гарантировать, что это поможет вам понять, что происходит. Вы просто не опубликовали достаточно информации о том, что вы делаете, чтобы отследить какие-либо конкретные ошибки. Хотя я могу исправить одну твою вещь очень быстро:
Это будет звонить только
drawSpheres
пять раз. Я предполагаю, что вы хотели назвать это 6 раз.Но я могу опубликовать рабочий ответ. Обратите внимание, что этот код предназначен для запуска вместе с моей учебной серией , поэтому он ссылается на код, которого нет. Но это в основном такие вещи, как создание сеток и т. Д .; ничего действительно важного.
Вот основные моменты. Шейдеры для основного объекта сферы.
Вершинный шейдер:
Фрагмент шейдера:
Создание текстуры кубической карты, которая будет использоваться в качестве цели рендеринга:
Я фактически заполняю текстуру данными (вместо того, чтобы передавать NULL в glTexImage2D) в качестве средства отладки. Это гарантирует, что все работало до начала использования текстуры в качестве цели рендеринга.
Также обратите внимание, что я предоставляю BASE_LEVEL и MAX_LEVEL. Я всегда делаю это с моими текстурами сразу после создания. Это просто хорошая привычка, так как OpenGL иногда требователен к полноте текстуры и пирамиде mipmap. Вместо того, чтобы помнить правила, я просто установил для них правильные значения неукоснительно.
Вот основная функция рисования:
Это указывает на то
DrawFace
, что рисует заданную грань кубической карты. Это реализовано следующим образом:Эта функция ссылается на набор глобальных таблиц, которые я использую, чтобы придать каждому лицу отдельный цвет фона, отдельный цвет сферы и правильно расположить сферу (в пространстве камеры) для этого лица.
Существенные моменты для
DrawFace
этого.Как правило, если у меня нет определенных знаний о том, что состояние установлено, я устанавливаю это состояние. Я устанавливаю окно просмотра каждый раз, когда я звоню
DrawFace
. Я устанавливаю матрицу проекции каждый раз. Это лишнее; Я мог бы установить их обратноdisplay
до цикла, который вызываетDrawFace
, так же, как я делаю с текущим FBO и рендерингом глубины.Но я также очищаю буферы, которые различны для каждого лица (так как каждое лицо имеет свой цвет).
источник