【问题标题】:glReadPixels directly to a textureglReadPixels 直接到纹理
【发布时间】:2013-08-15 17:49:15
【问题描述】:
  • 我渲染了一个场景(到默认渲染缓冲区)
  • 我想从这个场景中抓取一个矩形并用它创建一个纹理
  • 我不希望 glReadPixels() 向下传输到 CPU,然后将数据上传回 GPU
  • 这可以使用 OpenGL ES 2.0 吗?
  • 附注- 我想使用屏幕的 POT 区域,而不是一些奇怪的形状

我已经工作的 GPU->CPU->GPU 实现的伪代码:

// Render stuff here

byte *magData = glReadPixels();

// Bind the already-generated texture object
BindTexture(GL_TEXTURE0, GL_TEXTURE_2D, alias);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, MAGWIDTH, MAGHEIGHT, 0, GL_RGB, GL_UNSIGNED_BYTE, magData);

【问题讨论】:

  • 只是为了澄清,您的意思是“如果我改用 OpenGL ES 2.0,这可能吗?”因为您现在使用的代码看起来不像 2.0(据我所知,2.0 会使用着色器来绑定纹理)。
  • 为什么不将您的场景渲染为纹理,然后使用该纹理切出您感兴趣的特定区域并显示到屏幕上?
  • @BradLarson 但他似乎无论如何都需要一份副本,那么为什么不立即从默认帧缓冲区复制呢?使您免于显示纹理。还是您的意思是选择不首先复制感兴趣的区域(并通过其他方式进行复制,例如调整 texcoords 或其他方式)?

标签: ios opengl-es


【解决方案1】:

您可以使用glCopyTexImage2D 从后台缓冲区复制:

glBindTexture(GL_TEXTURE_2D, textureID);
glCopyTexImage2D(GL_TEXTURE_2D, level, internalFormat, x, y, width, height, border);

OpenGL ES 2.0 总是从后台缓冲区(或单缓冲配置的前台缓冲区)复制。使用 OpenGL ES 3.0,您可以指定副本的来源:

glReadBuffer(GL_BACK);

鉴于 ClayMontgomery 的回答(glCopyTexImage2D 很慢) - 您可能会发现使用具有正确大小和格式的纹理的 glCopyTexSubImage2D 更快,因为它写入预分配的纹理而不是每次都分配一个新缓冲区。如果这仍然太慢,您应该尝试按照他的建议进行操作并渲染到帧缓冲区(尽管您还需要使用帧缓冲区的纹理在屏幕上绘制一个四边形以获得相同的结果)。

【讨论】:

  • 这是正确的,但 OpenGL ES 2.0 不支持 glReadBuffer()(3.0 支持)。我需要做的就是glBindTexture,然后调用glCopyTexImage2D,它总是从默认的渲染缓冲区中读取。谢谢!
  • 啊抱歉 - 我正在查看 ES 3.0 页面,尽管我在 ES 2.0 中使用它。我会编辑答案。
【解决方案2】:

你会发现 glCopyTexImage2D() 真的很慢。做你想做的事的快速方法是直接渲染到纹理作为 FBO 的附件。这可以通过 OpenGL ES 2.0 或 1.1(带有扩展)来完成。本文详细讲解:

http://processors.wiki.ti.com/index.php/Render_to_Texture_with_OpenGL_ES

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-08-05
    • 2012-09-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-31
    • 2014-07-12
    • 1970-01-01
    相关资源
    最近更新 更多