Вопрос по iphone, framebuffer, opengl-es – Рисование в OpenGL ES framebuffer и получение UIImage от него на iPhone

3

Я пытаюсь сделать закадровый рендеринг некоторых примитивов в OpenGL ES на iOS. Код выглядит следующим образом:

// 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 возвращает полностью голубое изображение, без красной линии. Что это может быть? Я пропустил некоторые действия до рисования линии?

Нету ((это не проблема medvedNick
Меняет ли флажкиCGImageCreate() вkCGBitmapByteOrderDefault | kCGImageAlphaLast Помогите? Я забыл все упорядочения байтов цветового пространства, но это то, что у меня есть в моемglReadPixels() - & GT; UIImage рутина здесь. Brad Larson♦

Ваш Ответ

1   ответ
3

что я создавал EAGLContext для OpenGL ES 2.0, но функции, которые я использовал, были для 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);

после этого все работает)

Не могли бы вы вставить весь рабочий код или помогите по этому вопросу:stackoverflow.com/questions/18275545/…

Похожие вопросы