缩放OpenGL纹理并在CPU内存中返回位图

时间:2018-12-10 13:27:49

标签: macos opengl

我在GPU上有一个由OpenGL TextureID和目标定义的纹理。

我需要进一步处理CPU内存中的300像素位图(宽度300像素,高度取决于源宽度)。

像素格式应为具有浮点分量的RGBA,ARGB或BGRA。

这怎么办?

感谢您的答复。

我尝试了以下方法。但是我只能得到白色像素:

glEnable(GL_TEXTURE_2D);

// create render texture
GLuint renderedTexture;
glGenTextures(1, &renderedTexture);
glBindTexture(GL_TEXTURE_2D, renderedTexture);
glTexImage2D(GL_TEXTURE_2D, 0,GL_RGB, (GLsizei)analyzeWidth, (GLsizei)analyzeHeight, 0,GL_RGBA, GL_FLOAT, 0);

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

glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, renderedTexture, 0);

// draw texture
glBindTexture(GL_TEXTURE_2D, inTextureId);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

// Draw a textured quad
glBegin(GL_QUADS);
glTexCoord2f(0, 0); glVertex3f(0, 0, 0);
glTexCoord2f(0, 1); glVertex3f(0, 1, 0);
glTexCoord2f(1, 1); glVertex3f(1, 1, 0);
glTexCoord2f(1, 0); glVertex3f(1, 0, 0);
glEnd();

GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if(status == GL_FRAMEBUFFER_COMPLETE)
{

}

unsigned char *buffer = CGBitmapContextGetData(mainCtx);
glReadPixels(0, 0, (GLsizei)analyzeWidth, (GLsizei)analyzeHeight, GL_RGBA, GL_FLOAT, buffer);

glDisable(GL_TEXTURE_2D);
glBindFramebuffer(GL_FRAMEBUFFER, 0); //

glDeleteFramebuffers(1, &fbo);

1 个答案:

答案 0 :(得分:1)

  1. 创建第二个纹理,大小为300*width/height x 300
  2. 创建一个Framebuffer Object并将新纹理附加为颜色缓冲区。
  3. 为(未缩放的)源纹理设置适当的纹理过滤器。您可以在点采样(GL_NEAREST)和双线性滤波(GL_LINEAR)之间选择。如果缩小比例超过2倍,则可以考虑同时使用mipmapping,并且可能要先在源纹理上调用glGenerateMipmap,然后使用GL_..._MIPMAP_...缩小过滤器之一。但是,mipmapping的可用性取决于源纹理的创建方式,如果它是不带mipmap金字塔的不可变纹理对象,则此方法将无效。
  4. 将纹理对象(具有原始源纹理)渲染为新纹理。最直观的几何图形是填充视口的矩形,最有效的几何图形是单个三角形。
  5. 使用glReadPixels(通过FBO)或glGetTexImage(直接从纹理)读回缩放的纹理。为了提高性能,您可以考虑通过Pixel Buffer Objects进行异步回读。