Запись 16-битного файла изображения OpenEXR в стеке переполнения

Я пытаюсь написать 16-битную текстуру с OpenGL, используя OpenEXR, следуя пример на странице 4 из документации, но по какой-то причине мой код падает при выполнении file_exr.writePixels(512), Есть ли что-то, что я здесь скучаю?

Обновить: Я проверял это fboId а также pboId хорошо инициализированы и ошибок OpenGL не существует до этого момента.

const Imf::Rgba * dest;
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboId);
glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, pboId);
glReadPixels(0, 0, 512, 512,  GL_BGRA, GL_HALF_FLOAT_NV, 0);
dest = (const Imf::Rgba *)glMapBuffer(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY_ARB);

Imf::RgbaOutputFile file_exr("/tmp/file.exr", 512, 512, Imf::WRITE_RGBA);
file_exr.setFrameBuffer(dest, 1, 512);
file_exr.writePixels(512);

glUnmapBufferARB(GL_PIXEL_PACK_BUFFER_ARB);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0);

0

Решение

Вы только что скопировали и вставили этот код (и только этот код)? Тогда причина этого заключается в том, что:

  • Буферный объект, в который вы хотите прочитать пиксели из OpenGL, не существует; следовательно, его отображение не будет выполнено, что означает, что вы указываете OpenEXR на нулевой указатель
  • В приведенном выше коде нет ни одной проверки состояния ошибки.

Сделайте это вместо этого:

Сначала помощник, чтобы очистить стек ошибок OpenGL (который может накапливать многократные ошибки):

int check_gl_errors()
{
int errors = 0;
while( GL_NO_ERROR != glGetError() ) { errors++; }
return errors;
}

Тогда это

int const width  = 512;
int const height = 512;
size_t const sizeof_half_float = 2;

glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboId);
glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, pboId);
glBufferDataARB(GL_PIXEL_PACK_BUFFER_ARB,
width * height * sizeof_half_float,
NULL,
GL_STATIC_READ_ARB);

if( !check_gl_errors() ) {
glPixelStorei(GL_PACK_ALIGNMENT, 1);
glPixelStorei(GL_PACK_ROW_LENGTH, 0);
glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
glPixelStorei(GL_PACK_SKIP_ROWS, 0);

/* BTW: You have to check that your system actually supports the
GL_HALF_FLOAT_NV format extension at all. */
glReadPixels(0, 0, width, width,  GL_BGRA, GL_HALF_FLOAT_NV, 0);

if( !check_gl_errors() ) {
Imf::Rgba const * const dest = (Imf::Rgba const*)
glMapBufferARB(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY_ARB);
if( !check_gl_errors() && nullptr != dest ) {
Imf::RgbaOutputFile file_exr(
"/tmp/file.exr",
width, height,
Imf::WRITE_RGBA);
file_exr.setFrameBuffer(dest, 1, width);
file_exr.writePixels(height);

glUnmapBufferARB(GL_PIXEL_PACK_BUFFER_ARB);
}
else {
/* glMapBuffer failed */
}
}
else {
/* glReadPixels failed */
}
}
else {
/* glBufferDataARB failed => no valid buffer object
to work with in the first place */
}

Все эти проверки ошибок важны. Они делают вашу программу не сбойной, но дают диагностику, что пошло не так.

В любом случае, использование PBO в самом порядке операций в любом случае не помогает, потому что оно отображается сразу после операции glReadPixels, что делает все это синхронным.

0

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


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