OpenGL ES 2.x:如何在 glDiscardFramebufferEXT 之后读取像素?

Posted

技术标签:

【中文标题】OpenGL ES 2.x:如何在 glDiscardFramebufferEXT 之后读取像素?【英文标题】:OpenGL ES 2.x: How to read pixels after glDiscardFramebufferEXT? 【发布时间】:2012-03-02 06:19:15 【问题描述】:

我阅读了EXT_discard_framebuffer,它导致命名的帧缓冲区可附加图像的内容变得未定义。在丢弃帧缓冲区之后,来自 glReadPixels 的像素值与丢弃帧缓冲区之前相同。为什么?并且,通过这个扩展,OpenGL ES 实现如何在渲染帧后优化掉帧缓冲区内容的存储?

//
// create a texture object
//
GLuint tex;
glGenTextures(1, &tex);
glBindTexture(GL_TEXTURE_2D, tex);

glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
glBindTexture(GL_TEXTURE_2D, 0);

//
// create a framebuffer object
//
GLuint fbo;
GLboolean check;

glGenFramebuffers(1, &fbo);
glBindFramebuffer(GL_FRAMEBUFFER, fbo);

check = glIsFramebuffer(fbo1);
if (!check) 
    __android_log_print(ANDROID_LOG_ERROR, "debug",
            "------ check Framebuffer object failed ------\n");
    return EGL_FALSE;


glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) 
    __android_log_print(ANDROID_LOG_ERROR, "debug",
            "------ fbo not set completely!------\n");
    return EGL_FALSE;


draw_texture(fbo);

GLubyte sampledColor[4] = 0, 0, 0, 0;
int randX = 128, randY = 128;

GLenum attachments[] =  GL_COLOR_ATTACHMENT0, GL_DEPTH_ATTACHMENT ;
glBindFramebuffer(GL_FRAMEBUFFER, fbo);

glReadPixels(randX, randY, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, sampledColor);
__android_log_print(ANDROID_LOG_INFO, "debug",
    "[LINE: %d] coordinate(%d, %d) color is (%d, %d, %d, %d)\n",
    __LINE__, randX, randY, sampledColor[0], sampledColor[1],
    sampledColor[2], sampledColor[3]);

glDiscardFramebufferEXT(GL_FRAMEBUFFER, 2, attachments);

glReadPixels(randX, randY, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, sampledColor);
__android_log_print(ANDROID_LOG_INFO, "debug",
    "[LINE: %d] coordinate(%d, %d) color is (%d, %d, %d, %d)\n",
    __LINE__, randX, randY, sampledColor[0], sampledColor[1],
    sampledColor[2], sampledColor[3]);

【问题讨论】:

【参考方案1】:

glDiscardFramebufferEXT 的作用是通知驱动程序你不关心帧缓冲区的内容。什么驱动程序(或 GPU)决定用它做什么 - 这不取决于你。驱动程序可以将所有内容重置为 0,或者它可以保持原样,或者它可能会在您下次调用 glClear 时使用此信息并更有效地执行它(例如,通过为内容分配新内存,而不是执行 memset 0 值)。不用担心它会做什么。

【讨论】:

嗨,Mārtiņš Možeiko 我想测试 glDiscardFramebufferEXT(),但我不知道调用 glDiscardFramebufferEXT 后的下一步是什么。你可以向我展示?非常感谢。 什么意思 - 下一步? 我想在Opengl ES2中测试glDiscardFramebufferEXT func,如何检查函数使用是否正确,如何验证? 尝试在有无丢弃的情况下测量性能。使用 Discard 的性能不应低于没有(但不一定更高)。 好的,非常感谢,我会试试的。顺便说一句,你能给我一些示例代码吗?

以上是关于OpenGL ES 2.x:如何在 glDiscardFramebufferEXT 之后读取像素?的主要内容,如果未能解决你的问题,请参考以下文章

OpenGL ES几个概念-顶点着色器片元着色器EGL

如何在Android上使用OpenGL ES 2.0绘制点

如何在Android上将OpenGL ES 1.0代码转换为OpenGL Es 2.0?

如何在Android上使用OpenGL ES 2.0绘制点

如何在 UIView 中绘制 opengl es

如何让 OpenGL-ES 在带有 SDL2 的 Raspberry Pi 上工作?