ios - 如何用 glkit、opengl es2 绘制数千个正方形?

标签 ios opengl-es opengl-es-2.0 glkit

我正在尝试在屏幕上绘制多达 200,000 个正方形。或者基本上有很多方 block 。我相信我只是在调用许多绘制调用,这会削弱应用程序的性能。方 block 只会在我按下按钮时更新,所以我不必每一帧都更新它。

这是我现在的代码:

- (void)glkViewControllerUpdate:(GLKViewController *)controller
{

//static float transY = 0.0f;
//float y = sinf(transY)/2.0f;
//transY += 0.175f;

GLKMatrix4 modelview = GLKMatrix4MakeTranslation(0, 0, -5.f);
effect.transform.modelviewMatrix = modelview;

//GLfloat ratio = self.view.bounds.size.width/self.view.bounds.size.height;
GLKMatrix4 projection = GLKMatrix4MakeOrtho(0, 768, 1024, 0, 0.1f, 20.0f);    
effect.transform.projectionMatrix = projection;
_isOpenGLViewReady = YES;
}

- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
{
if(_model.updateView && _isOpenGLViewReady)
{

    glClear(GL_COLOR_BUFFER_BIT);
    [effect prepareToDraw];
    int pixelSize = _model.pixelSize;
    if(!_model.isReady)
        return;
    //NSLog(@"UPDATING: %d, %d", _model.rows, _model.columns);
    for(int i = 0; i < _model.rows; i++)
    {
        for(int ii = 0; ii < _model.columns; ii++)
        {
            ColorModel *color = [_model getColorAtRow:i andColumn:ii];
            CGRect rect = CGRectMake(ii * pixelSize, i*pixelSize, pixelSize, pixelSize);
            //[self drawRectWithRect:rect withColor:c];
            GLubyte squareColors[] = {
                color.red, color.green, color.blue, 255,
                color.red, color.green, color.blue, 255,
                color.red, color.green, color.blue, 255,
                color.red, color.green, color.blue, 255
            };

            // NSLog(@"Drawing color with red: %d", color.red);


            int xVal = rect.origin.x;
            int yVal = rect.origin.y;
            int width = rect.size.width;
            int height = rect.size.height;
            GLfloat squareVertices[] = {
                xVal, yVal, 1,
                xVal + width, yVal, 1,
                xVal,  yVal + height, 1,
                xVal + width,  yVal + height, 1
            };    

            glEnableVertexAttribArray(GLKVertexAttribPosition);
            glEnableVertexAttribArray(GLKVertexAttribColor);

            glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 0, squareVertices);
            glVertexAttribPointer(GLKVertexAttribColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, squareColors);

            glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

            glDisableVertexAttribArray(GLKVertexAttribPosition);
            glDisableVertexAttribArray(GLKVertexAttribColor);


        }
    }   
    _model.updateView = YES;
}

最佳答案

首先,你真的需要画20万个正方形吗?您的视口(viewport)总共只有 786,000 个像素。您可以减少绘制对象的数量,而不会显着影响场景的整体质量。

也就是说,如果这些是较小的正方形,您可以将它们绘制为像素大小足以覆盖正方形区域的点。这需要将顶点着色器中的 gl_PointSize 设置为适当的像素宽度。然后您可以生成您的坐标并将它们全部发送以作为 GL_POINTS 立即绘制。这应该消除三角形的额外几何体和您在此处使用的各个绘制调用的开销。

即使您不使用点,也最好先计算您需要的所有三角形几何体,然后在一次绘制调用中发送所有这些几何体。这将显着减少您的 OpenGL ES API 调用开销。

您可以研究的另一件事是使用顶点缓冲区对象来存储此几何体。如果几何图形是静态的,您可以避免在每个绘制的帧上发送它,或者只更新其中发生变化的部分。即使您只是更改每一帧的数据,我相信将 VBO 用于动态几何在现代 iOS 设备上具有性能优势。

关于ios - 如何用 glkit、opengl es2 绘制数千个正方形?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11454859/

相关文章:

ios - iPhone:sqlite3 blob字段未正确反序列化

ios - 无法在 opengl es 2.0 中加载多个纹理

android - 是否保证 OpenGLES2.0 android 设备支持模板缓冲区?

ios - 根据不同的图像类型获取正确的图像高度的问题

javascript - 如何使用cocos2d-js加载原生IOS xib?

ios - armv8 和 arm64 一样吗?

android - OpenGL ES 3.0 中的多重采样 FBO

c++ - opengl glDrawArray 抛出异常

javascript - WebGL - 使用多个纹理时的条纹

iOS OpenGL ES 2.0 VBO 顶点计数限制 : Once exceeded, CPU 绑定(bind)