2014-09-11 3 views
0

Я пытаюсь написать 16-битную текстуру, визуализированную с помощью OpenGL, используя OpenEXR, следуя the example in page 4 from the documentation, но по какой-то причине мой код падает при выполнении file_exr.writePixels(512). Здесь что-то не хватает?Запись файла изображения OpenEXR 16bit в C++

Update: Я проверить, что 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

Конечно, я правильно установил 'fboId' и' pboId', и я также проверяю ошибки, когда создаю и заполняю их, хотя я должен был четко прояснить мой вопрос. Я думаю, что это, вероятно, связано с поддержкой 'GL_HALF_FLOAT_NV' ... Я дважды проверю это позже сегодня. Благодаря! – Dan

Смежные вопросы