2012-08-08 207 views
11

我想將原始紋理數據轉儲到磁盤(稍後回讀),並且我不確定glReadPixel是否會從當前綁定的紋理中讀取。使用glReadPixels讀取紋理字節?

如何從紋理中讀取緩衝區?

+0

嘿@Geri,我的回答幫助你的? – gergonzalez 2013-11-06 14:52:23

回答

30

glReadPixels函數從幀緩衝區讀取,而不是紋理。要讀取紋理對象必須使用glGetTexImage它不可在OpenGL ES :(

如果你想讀你的紋理緩衝,然後您可以將其綁定到一個FBO(幀緩衝區對象)和使用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); 
+1

我可以確認這個工作在Mac上,一旦所有的OES後綴都被刪除 – nuclearnova 2014-08-18 19:10:46

2

謝謝你的答案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