Что не так с моим кадровым буфером?

Я создаю объект framebuffer, который будет моим gbuffer для отложенного затенения. Я в основном учился у http://ogldev.atspace.co.uk/, и модифицированный, чтобы быть немного более … вменяемым. Вот исходный код, где я создаю фреймбуфер:

/* Create the FBO */
glGenFramebuffers(1, &fbo);
glBindFramebuffer(GL_FRAMEBUFFER, fbo);

/* Create the gbuffer textures */
glGenTextures(GBUFFER_NUM_TEXTURES, tex);

/* Create the color buffer */
glBindTexture(GL_TEXTURE_2D, tex[GBUFFER_COLOR]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex[GBUFFER_COLOR], 0);

/* Create the normal buffer */
glBindTexture(GL_TEXTURE_2D, tex[GBUFFER_NORMAL]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RG16F, width, height, 0, GL_RG, GL_FLOAT, NULL);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, tex[GBUFFER_NORMAL], 0);

/* Create the depth-stencil buffer */
glBindTexture(GL_TEXTURE_2D, tex[GBUFFER_DEPTH_STENCIL]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, width, height, 0, GL_DEPTH_STENCIL, GL_FLOAT, NULL);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, tex[GBUFFER_DEPTH_STENCIL], 0);

GLenum drawBuffers[] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1};
glDrawBuffers(2, drawBuffers);
glReadBuffer(GL_NONE);

/* Check for errors */
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (status != GL_FRAMEBUFFER_COMPLETE)
{
error("In GBuffer::init():\n");
errormore("Failed to create Framebuffer, status: 0x%x\n", status);
fbo = 0;
return;
}

// restore default FBO
glBindFramebuffer(GL_FRAMEBUFFER, 0);

Когда я запускаю это, однако, статус возвращается GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT, Если не понятно, я пытаюсь создать 3 gbuffers:

  • 32-битный цветовой буфер RGBA (я бы использовал 24-битный, но я боюсь штрафов за выравнивание),
  • 32-разрядный нормальный буфер RG (каждый компонент использует 16-разрядное число с плавающей запятой, но я мог бы избежать короткого замыкания со знаком?)
  • 24-битный буфер глубины, упакованный 8-битным буфером трафарета
  • (всего 96 бит или 12 байт)

Возможные проблемные области, которые я вижу, могут использовать GL_FLOAT для обычного буфера и GL_FLOAT для буфера глубины трафарета. Я полагаю, что GL_HALF_FLOAT будет более подходящим для нормалей, но этого нет в списке типов, которые я могу использовать с glTexImage2D. Точно так же я понятия не имею, какой тип наиболее подходит для буфера глубины трафарета.

Что я делаю неправильно?

1

Решение

Ваше использование GL_FLOAT является в основном не имеет значения, так как передача пикселя на самом деле не происходит.

Вы можете указать там все, что захотите, если это значимый тип данных. Хотя при передаче не происходит передача пикселей NULL для данных GL все еще проверяет тип данных передачи пикселей по набору допустимых типов и выдает ошибку, если вы делаете что-то не так. С этой целью, если возникнет ошибка, текстура будет неполной и, следовательно, не может быть использована в качестве вложения FBO.

Вот в чем проблема, GL_FLOAT не является значимым типом данных для переноса пикселей в упакованный GL_DEPTH_STENCIL формат изображения … он ожидает упакованный тип данных, такой как GL_UNSIGED_INT_24_8 или что-то действительно экзотическое, как GL_FLOAT_32_UNSIGNED_INT_24_8_REV​ (64-битный формат с плавающей запятой + формат трафарета).

В любом случае, на самом деле есть два компонента, которые должны быть упакованы в ваш тип данных. GL_FLOAT можно описать только один из двух компонентов, потому что буферы с плавающей точкой трафарета не имеют смысла.


Кстати, всего этого запутанного беспорядка о типе данных передачи пикселей можно полностью избежать, если вы используете что-то вроде glTexStorage2D (...) в только выделить память для текстуры. glTexImage2D (...) выполняет двойную функцию, выделяя хранилище для текстуры LOD и предоставляя механизм для его инициализации данными. Вы действительно не заботитесь о более поздней части, если вы рисуете в текстуру с FBO, так как это единственное место, откуда она получает какие-либо данные.

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]