[英]Writing OpenEXR 16bit image file in C++
我試圖按照文檔第4頁中的示例,使用OpenEXR編寫使用OpenGL渲染的16位紋理,但是由於某些原因,在執行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);
您是否只是復制並粘貼了該代碼(還有該代碼)? 那么它失敗的原因是:
改為這樣做:
首先是一個助手,清理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操作之后立即被映射,這使整個過程變得同步。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.