在iPhone上将图形绘制到OpenGL ES帧缓冲区并获取UIImage

3

我正在尝试在iOS上使用OpenGL ES对一些图元进行离屏渲染。以下是代码:

// context and neccesary buffers
@interface RendererGL
{
   EAGLContext* myContext;
   GLuint framebuffer;
   GLuint colorRenderbuffer;
   GLuint depthRenderbuffer;
}

.m文件:

- (id) init
{
    self = [super init];
    if (self)
    {
            // initializing context
        myContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
        [EAGLContext setCurrentContext:myContext];
        [self setupOpenGL]; // creating buffers
    }
    return self;
}

-(void) setupOpenGL
{
    int width = 256;
    int height = 256;

    // generating buffers and binding them as Apple,s tutorial says

    glGenFramebuffersOES(1, &framebuffer);
    glBindFramebufferOES(GL_FRAMEBUFFER_OES, framebuffer);

    glGenRenderbuffersOES(1, &colorRenderbuffer);
    glBindRenderbufferOES(GL_RENDERBUFFER_OES, colorRenderbuffer);
    glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_RGBA8_OES, width, height);
    glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, colorRenderbuffer);

    glGenRenderbuffersOES(1, &depthRenderbuffer);
    glBindRenderbufferOES(GL_RENDERBUFFER_OES, depthRenderbuffer);
    glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_DEPTH_COMPONENT16_OES, width, height);
    glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, depthRenderbuffer);

    GLenum status = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) ;
    if(status != GL_FRAMEBUFFER_COMPLETE_OES) {
        NSLog(@"failed to make complete framebuffer object %x", status);
    }
}

- (UIImage *) renderImage
{
        int width = 256;
        int height = 256;

        [EAGLContext setCurrentContext:myContext];
        glEnable(GL_DEPTH_TEST);

// clear color - cyan       
        glClearColor(0.0f, 1.0f, 1.0f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

// trying to draw some primitive - red line
        float line[] = {-0.5f, -0.5f, 0.5f, 0.5f};

        glBindRenderbufferOES(GL_RENDERBUFFER_OES, colorRenderbuffer); //should I do this?

        glEnableClientState(GL_VERTEX_ARRAY);
        glVertexPointer(2, GL_FLOAT, 0, line);

        glColor4f(1.0, 0.0, 0.0, 1.0);
        glLineWidth(10);

        glDrawArrays(GL_LINES, 0, 2); // draw line with two points

        [myContext presentRenderbuffer:GL_RENDERBUFFER_OES]; // and this?

// then I grab image from _frameBuffer and return it as UIImage - this part is working
        NSInteger x = 0, y = 0;
        NSInteger dataLength = width * height * 4;
        GLubyte *data = (GLubyte*)malloc(dataLength * sizeof(GLubyte));

        glPixelStorei(GL_PACK_ALIGNMENT, 4);
        glReadPixels(x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, data);

        CGDataProviderRef ref = CGDataProviderCreateWithData(NULL, data, dataLength, NULL);
        CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();
        CGImageRef iref = CGImageCreate(width, height, 8, 32, width * 4, colorspace, kCGBitmapByteOrder32Big | kCGImageAlphaPremultipliedLast,
                                        ref, NULL, true, kCGRenderingIntentDefault);


        UIGraphicsBeginImageContext(CGSizeMake(width, height));
        CGContextRef cgcontext = UIGraphicsGetCurrentContext();
        CGContextSetBlendMode(cgcontext, kCGBlendModeCopy);
        CGContextDrawImage(cgcontext, CGRectMake(0.0, 0.0, width, height), iref);
        UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();

        free(data);
        CFRelease(ref);
        CFRelease(colorspace);
        CGImageRelease(iref);

        return image;
    }

问题在于-renderImage返回完全青色图像,没有红线。这是什么原因?我在绘制线条之前是否漏掉了某些操作?


CGImageCreate()的标志更改为kCGBitmapByteOrderDefault | kCGImageAlphaLast是否有帮助?我忘记了所有颜色空间字节顺序,但这就是我在这里的glReadPixels()-> UIImage例程中所拥有的。 - Brad Larson
不是这个问题。 - medvedNick
1个回答

3

第一个问题是我为OpenGL ES 2.0创建了EAGLContext,但我使用的函数是针对OpenGL ES 1.1的。解决方案是将常量设置为kEAGLRenderingAPIOpenGLES1。

第二个问题是如果我使用1.1版本,则没有设置模型和投影矩阵。

glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrthof(-1.0f, 1.0f, -1.5f, 1.5f, -1.0f, 1.0f);
glMatrixMode(GL_MODELVIEW);

在这一切都能正常工作之后,请执行以下操作。

请问您能否提供完整的代码或者帮忙解决这个问题:https://dev59.com/HXXYa4cB1Zd3GeqP98Sy - CarmeloS

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接