【问题标题】:Read texture bytes with glReadPixels?用 glReadPixels 读取纹理字节?
【发布时间】:2012-08-05 11:57:09
【问题描述】:

我想将原始纹理数据转储到磁盘(以便稍后读回),但我不确定 glReadPixel 是否会从当前绑定的纹理中读取。

如何从纹理中读取缓冲区?

【问题讨论】:

  • 嘿@Geri,我的回答对你有帮助吗?

标签: ios opengl-es textures glreadpixels


【解决方案1】:

glReadPixels 函数从帧缓冲区读取,而不是从纹理读取。要读取纹理对象,您必须使用 glGetTexImage它在 OpenGL ES 中不可用 :(

如果您想从纹理中读取缓冲区,那么您可以将其绑定到 FBO(FrameBuffer 对象)并使用 glReadPixels

//Generate a new FBO. It will contain your texture.
glGenFramebuffersOES(1, &offscreen_framebuffer);
glBindFramebufferOES(GL_FRAMEBUFFER_OES, offscreen_framebuffer);

//Create the texture 
glGenTextures(1, &my_texture);
glBindTexture(GL_TEXTURE_2D, my_texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,  width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);

//Bind the texture to your FBO
glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, my_texture, 0);

//Test if everything failed    
GLenum status = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES);
if(status != GL_FRAMEBUFFER_COMPLETE_OES) {
    printf("failed to make complete framebuffer object %x", status);
}

然后,您只需要在要从纹理中读取数据时调用 glReadPixels:

//Bind the FBO
glBindFramebufferOES(GL_FRAMEBUFFER_OES, offscreen_framebuffer);
// set the viewport as the FBO won't be the same dimension as the screen
glViewport(0, 0, width, height);

GLubyte* pixels = (GLubyte*) malloc(width * height * sizeof(GLubyte) * 4);
glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels);

//Bind your main FBO again
glBindFramebufferOES(GL_FRAMEBUFFER_OES, screen_framebuffer);
// set the viewport as the FBO won't be the same dimension as the screen
glViewport(0, 0, screen_width, screen_height);

【讨论】:

  • 删除所有 OES 后缀后,我可以确认它在 Mac 上也能正常工作
  • GLuint screen_framebuffer; glGetIntegerv(GL_FRAMEBUFFER_BINDING, &screen_framebuffer); 开头获取主FBO id。
【解决方案2】:

感谢 Gergonzale 的回答。今天早上我花了一些时间试图弄清楚如何让它与 16 位纹理一起工作,这段代码 sn-p 可能对将 GL_UNSIGNED_SHORT_5_6_5 转换为 GL_UNSIGNED_BYTE 的其他人有用

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,  tSizeW, tSizeH, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, NULL);
GLubyte* pixels = (GLubyte*) malloc(tSizeW * tSizeH * sizeof(GLubyte) * 2);
glReadPixels(0, 0, tSizeW, tSizeH, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, pixels);

int index = (x*tSizeH + y)*2;
unsigned int rgb = pixels[index + 1]*256 + pixels[index + 0];
unsigned int r = rgb;
r &= 0xF800;    // 1111 1000 0000 0000
r >>= 11;       // 0001 1111
r *= (255/31.); // Convert from 31 max to 255 max

unsigned int g = rgb;
g &= 0x7E0;     // 0000 0111 1110 0000
g >>= 5;        // 0011 1111
g *= (255/63.); // Convert from 63 max to 255 max

unsigned int b = rgb;
b &= 0x1F;      // 0000 0000 0001 1111
//g >>= 0;      // 0001 1111
b *= (255/31.); // Convert from 31 max to 255 max

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多