将openGL ES纹理读取到原始数组 [英] Reading a openGL ES texture to a raw array

查看:239
本文介绍了将openGL ES纹理读取到原始数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试从openGL ES中的RGBA纹理获取字节.我想我想模仿香草openGL中的glGetTexImage.到目前为止,从调用到glClear,像素都为零,而不是我要查找的纹理数据.

I'm trying to get the bytes from a RGBA texture in openGL ES. I think I'm trying to imitate glGetTexImage from vanilla openGL. As is right now, the pixels are all nil, from the call to glClear, not the texture data I'm looking for.

这是从Sparrow Framework扩展SPTexture的类别中的一种方法.

This is a method in a category extending SPTexture from Sparrow Framework.

-(NSMutableData *) getPixelsFromTexture
{
    GLsizei width = (GLsizei) self.width;
    GLsizei height = (GLsizei) self.height;
    GLint oldBind = 0;
    glGetIntegerv(GL_TEXTURE_BINDING_2D, &oldBind);
    glBindTexture(GL_TEXTURE_2D, self.textureID);

    GLuint fbo[1];
    glGenFramebuffersOES(1, fbo);
    glBindFramebufferOES(GL_FRAMEBUFFER_OES, fbo[0]);

    GLuint rbo[1];
    glGenRenderbuffersOES(1, rbo);
    glBindRenderbufferOES(GL_RENDERBUFFER_OES, rbo[0]);
    glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_RGBA4_OES, width, height);

    glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, rbo[0]);

    GLenum status = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES);
    if (status != GL_FRAMEBUFFER_COMPLETE_OES) {
        NSLog(@"Incomplete FBO");
    }

    // draw
    static float texCoords[8] = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f };
    static float vertexCoords[8] = { -1.0f, -1.0f, 1-.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f };

    glMatrixMode (GL_PROJECTION);
    glPushMatrix();
    glLoadIdentity ();
    glOrthof(0.0f, self.width, self.height, 0.0f, 0.0f, 1.0f);
    glMatrixMode (GL_MODELVIEW);
    glPushMatrix();
    glLoadIdentity();
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    glClear(GL_COLOR_BUFFER_BIT);

    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    glEnableClientState(GL_VERTEX_ARRAY);

    glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
    glVertexPointer(2, GL_FLOAT, 0, vertexCoords);

    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
    glDisableClientState(GL_VERTEX_ARRAY);

    glPopMatrix();
    glMatrixMode(GL_PROJECTION);
    glPopMatrix();
    // end draw

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

    glBindRenderbufferOES(GL_RENDERBUFFER_OES, 0);
    glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
    glBindTexture(GL_TEXTURE_2D, oldBind);
    glDeleteRenderbuffersOES(1, rbo);
    glDeleteFramebuffersOES(1, fbo);

    return [NSMutableData dataWithBytes:pixels length:count];
}

我在做什么错了?

推荐答案

因此,我最终能够使用

So, I was eventually able to solve this using a variation of the code seen here. My code is:

@interface SPRenderTexture (RenderToImage)

- (NSMutableData *)renderToPixelData;

@end

@implementation SPRenderTexture (RenderToImage)

- (NSMutableData *)renderToPixelData
{
    __block NSMutableData * pixels = nil;

    [self bundleDrawCalls:^() 
    {
    float scale = [SPStage contentScaleFactor];
    int width = scale * self.width;
    int height = scale * self.height;
    int nrOfColorComponents = 4; //RGBA
    int rawImageDataLength = width * height * nrOfColorComponents;
    GLenum pixelDataFormat = GL_RGBA;
    GLenum pixelDataType = GL_UNSIGNED_BYTE;

    GLubyte *rawImageDataBuffer = (GLubyte *) malloc(rawImageDataLength);
    glReadPixels(0, 0, width, height, pixelDataFormat, pixelDataType, rawImageDataBuffer);

    pixels = [[NSMutableData alloc] initWithBytes:rawImageDataBuffer length:rawImageDataLength];

    }];

    return [pixels autorelease];
}

@end

我希望这对其他人有用.

I hope this will be useful to other people.

这篇关于将openGL ES纹理读取到原始数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆