在iOS上使用OpenGLES从无符号短*基本绘制像素

时间:2012-09-12 06:29:25

标签: iphone ios opengl-es drawing

对于我的非应用商店应用,我一直在使用私有框架Core Surface直接绘制到iPhone的屏幕。但是,在旧设备上这可能相当慢,因为它大量使用CPU来进行绘制。为了解决这个问题,我决定尝试使用OpenGLES将像素渲染到屏幕上。

目前(我无法更改此内容),我引用了一个名为BaseAddress的无符号short *变量,并且必要的第三方代码访问BaseAddress并使用新的像素数据更新它。

我已经设置了一个GLKViewController,并按如下方式实现了viewDidLoad:

- (void)viewDidLoad {
    [super viewDidLoad];

    self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];

    if (!self.context) {
        NSLog(@"Failed to create ES context");
    }

    [EAGLContext setCurrentContext:self.context];

    GLKView *view = (GLKView *)self.view;
    view.context = self.context;

    glGenBuffers(1, &screenBuffer);
    glBindBuffer(GL_ARRAY_BUFFER, screenBuffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(BaseAddress), BaseAddress, GL_DYNAMIC_DRAW);

}

其中screenBuffer是一个实例变量。在glkView:drawInRect:方法中,我有以下内容:

- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect {
    glDrawElements(GL_ARRAY_BUFFER, sizeof(BaseAddress)/sizeof(BaseAddress[0]), GL_UNSIGNED_SHORT, BaseAddress);
}

不幸的是,我运行应用时只显示黑屏。如果我回到使用Core Surface,该应用程序工作正常。基本上,如何使用OpenGLES将像素绘制到屏幕上?

1 个答案:

答案 0 :(得分:0)

我认为最好使用纹理,对于你的情况,我会尝试为iOS设备找到一些旧的ES1模板。基本上你需要的是一个帧缓冲区和一个由UIView层构成的颜色缓冲区:

    glGenFramebuffers(1, &viewFramebuffer);
    glBindFramebuffer(GL_FRAMEBUFFER, viewFramebuffer);
    glGenRenderbuffers(1, &viewColorBuffer);
    glBindRenderbuffer(GL_RENDERBUFFER, viewColorBuffer);
    [context renderbufferStorage:GL_RENDERBUFFER fromDrawable:(CAEAGLLayer*)self.layer];
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, viewColorBuffer);

    glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &backingWidth);
    glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, & backingHeight);

对于投影矩阵,我建议您使用glOrthof(.0f, backingWidth, backingHeight, .0f, -1.0f, 1.0f);,使您的GL坐标与视图坐标相同。

接下来在一些初始化时生成一个纹理,绑定它并赋予它2的幂的维度(textureWidth = 1; while(textureWidth < backingWidth) textureWidth = textureWidth << 1;)并将其传递给数据指针的NULL(全部在函数“glTexImage2D”中)

然后生成与纹理相同的正方形的顶点数组,从(0,0)到(textureWidth,textureHeight),纹理坐标从(0,0)到(1,1)

当您将数据传递到指针并准备推送到纹理时,使用glTexSubImage2D更新它:如果获取数据或更新整个屏幕,则只能更新纹理的一部分使用rect(0,0,screenWidth,screenHeight)

现在只需用纹理绘制这两个三角形..

  • 请注意,纹理大小有限制:大多数有效iOS设备1&lt; 11(2048)iPad3 1&lt;&lt; 12
  • 创建时不要忘记设置纹理参数:glTexParameteri
  • 检查视网膜显示并根据需要将CAEAGLLayer的内容比例设置为2