2

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

这是我现在拥有的代码:

- (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;
}
4

3 回答 3

1

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

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

即使您不使用点,首先计算您需要的所有三角形几何图形仍然是一个好主意,然后在一个绘图调用中发送所有这些。这将显着减少您的 OpenGL ES API 调用开销。

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

于 2012-07-12T17:15:36.170 回答
0

你不能尝试以某种方式优化它吗?我对图形类型的东西不是很熟悉,但我想如果你正在绘制 200,000 个方块,那么所有这些方块实际上都是可见的似乎不太可能。您不能为您的 mySquare 类添加某种 isVisible 标记,以确定您要绘制的正方形是否实际可见?然后显而易见的下一步是修改您的绘图函数,以便如果正方形不可见,则不要绘制它。

或者您是否要求有人尝试改进您现有的代码,因为如果您的性能像您说的那样糟糕,我认为对上述代码进行小的更改不会解决您的问题。您将不得不重新考虑如何进行绘图。

于 2012-07-12T16:00:32.743 回答
0

看起来您的代码实际上试图做的是拍摄一张_model.rows× _model.columns2D 图像并将其放大_model.pixelSize. 如果-[ColorModel getColorAtRow:andColumn:]一次从颜色值数组中检索 3 个字节,那么您可能需要考虑将该颜色值数组作为GL_RGB/GL_UNSIGNED_BYTE数据上传到 OpenGL 纹理中,并让 GPU 一次放大所有像素。

或者,如果放大内容是ColorModel您使用 OpenGL ES 和 GLKit 的唯一原因,您最好将颜色值包装到 CGImage 中并允许 UIKit 和 Core Animation 为您绘制。多久ColorModel更新一次颜色值?

于 2012-07-15T03:05:57.073 回答