用glReadPixels读纹理字节?
我想将原始纹理数据转储到磁盘(稍后回读),我不确定glReadPixel会从当前绑定的纹理中读取。
我怎样才能从我的纹理读取缓冲区?
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);
感谢Gergonzale的回答。 今天早上我花了一些时间试图弄清楚如何让这个工作与16位纹理,这个代码片段可能会有用的人转换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