如何在OpenGL ES中从渲染纹理中读取像素

时间:2012-09-26 10:48:47

标签: opengl-es

我正在尝试从动态生成的纹理中读取像素(RTT,渲染到纹理)。我通过实施列出here列出的Apple建议方法来拍摄此快照。

这适用于“默认”颜色缓冲区,它会显示在屏幕上,但我无法使其适用于写入纹理的像素。

我遇到这些问题:

// Bind the color renderbuffer used to render the OpenGL ES view
// If your application only creates a single color renderbuffer which is already bound at this point,
// this call is redundant, but it is needed if you're dealing with multiple renderbuffers.
// Note, replace "_colorRenderbuffer" with the actual name of the renderbuffer object defined in your class.
glBindRenderbufferOES(GL_RENDERBUFFER_OES, _colorRenderbuffer);

// Get the size of the backing CAEAGLLayer
glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth);
glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight);

问题在于我没有色彩缓冲,因为我正在渲染纹理。

以下是我创建纹理的方法:

void Texture::generate()
{
    // Create texture to render into
    glActiveTexture(unit);
    glGenTextures(1, &handle);
    glBindTexture(GL_TEXTURE_2D, handle);

    // Configure texture
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minFilter);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magFilter);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
}

以下是我如何将其链接到用于渲染的FBO:

void Texture::attachToFrameBuffer(GLuint framebuffer)
{
    this->framebuffer = framebuffer;

    // Attach texture to the color attachment of the provided framebuffer
    glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, handle, 0);
}

正如你所看到的,我真的没有一个_colorRenderbuffer,我可以在那里绑定到它。我首先想到绑定到帧缓冲区然后执行Apple的代码就可以了,但是backingWidth和backingHeight并没有给我纹理的分辨率(2048x2048),而是我场景的分辨率(320x320)。所以我想我在这里错过了一些东西。

1 个答案:

答案 0 :(得分:1)

因为你可以渲染成纹理,它需要有一些内部存储,所以你需要在渲染之前在某个时刻调用glTexImage2D(可能会将NULL作为图像数据传递,因此只需分配纹理图像)。

  

但是backingWidth和backingHeight并没有给我分辨率   质地

为什么你想要检索那些值(当然这些检索函数不起作用,因为它们的名称就像它们的名字一样在渲染缓冲区上工作)。你已经知道了,因为谁创建了纹理(见上文)。

一旦你渲染到纹理中,你可以像捕捉普通屏幕一样调用glReadPixels,因为你的纹理现在是帧缓冲区,所以从帧缓冲区读取像素会从纹理中读取像素(当然,在调用glReadPixels)时,FBO仍然必须受到约束。

这实际上是回读ES中没有glGetTexImage的任何纹理数据的唯一方法,但是因为你刚刚渲染到它中,这绝对没有问题。