使用缓冲区实现此OpenGL ES 2.0代码

时间:2013-01-29 17:02:57

标签: opengl-es-2.0 vbo

此代码绘制了数千个彩色方块的大网格。在每一帧上,它随机选取正方形并将它们设置为新颜色。我想减少CPU负载。设置缓冲区和绘制的理想代码是什么?我对VBO设置和Open GL绘图调用感兴趣。请记住,GPU内存中的顶点颜色总是在变化,但顶点位置永远不会改变。

- (id)initWithBounds:(float)pLeft right:(float)pRight bottom:(float)pBottom top:(float)pTop
{
    if (self = [super init]) {

        effect = [[GLKBaseEffect alloc] init];
        effect.transform.projectionMatrix = GLKMatrix4MakeOrtho(pLeft, pRight, pBottom, pTop, 1, -1);;

        self.left = pLeft;
        self.right = pRight;
        self.bottom = pBottom;
        self.top = pTop;

        GLfloat gridWidth = self.right - self.left;
        GLfloat gridHeight = self.top - self.bottom;
        GLfloat halfWidth = gridWidth / 2;
        GLfloat halfHeight = gridHeight / 2;


        // Create the vertices for each point of the grid
        float cellSize = 8.f;

        CGSize screenSize = [UIApplication currentSize];
        numRows = screenSize.height / cellSize;
        numCols = screenSize.width / cellSize;
        int verticesPerRow = numCols + 1;


        int verticesPerCell = 4;
        int numVertices = numRows * numCols * verticesPerCell;
        GLKVector2 *vertices = malloc(sizeof(GLKVector2) * numVertices);
        int vertexIndex;

        // Note use of <= as there is 1 more vertex row/col than numRows/numCols
        for (int rowIndex = 0; rowIndex <= numRows; rowIndex++) {

            for (int colIndex = 0; colIndex <= numCols; colIndex++) {

                vertexIndex = (verticesPerRow * rowIndex) + colIndex;
                vertices[vertexIndex] = GLKVector2Make((cellSize * colIndex) - halfWidth, (cellSize * rowIndex) - halfHeight);
            }
        }

        // Create vertexIndices array which colours and vertices arrays wil be based on

        int triangleVerticesPerCell = 6; // Define 2 triangles per cell = 2 x 3 vertices
        numTriangleVertices = numRows * numCols * triangleVerticesPerCell;
        NSLog(@"numTriangleVertices %i", numTriangleVertices);
        //        numTriangleVertices = 6;

        int *vertexIndices = malloc(sizeof(int) * numTriangleVertices);
        int i = 0;

        for (int rowIndex = 0; rowIndex < numRows; rowIndex++) {

            for (int colIndex = 0; colIndex < numCols; colIndex++) {

                vertexIndex = (numCols * rowIndex) + colIndex + rowIndex;

                vertexIndices[i++] = vertexIndex;
                vertexIndices[i++] = vertexIndex + 1;
                vertexIndices[i++] = vertexIndex + verticesPerRow + 1;
                vertexIndices[i++] = vertexIndex;
                vertexIndices[i++] = vertexIndex + verticesPerRow + 1;
                vertexIndices[i++] = vertexIndex + verticesPerRow;
            }
        }


        // grid vertices
        //        int numTriangleVertices = 1 * triangleVerticesPerCell; // 1 cell
        triangleVertices = malloc(sizeof(GLKVector2) * numTriangleVertices);
        triangleColours = malloc(sizeof(GLKVector4) * numTriangleVertices);

        // Sets all values of array to 0
        //        memset(triangleVertices,0,sizeof(GLKVector2)*numVertices);

        GLKVector4 currColour;

        for (i = 0; i < numTriangleVertices; i++) {

            // Give a new colour to every new set of 6 vertices
            if(!(i % 6)) {

                currColour = GLKVector4Make(1.0 * arc4random_uniform(101)/100,
                                            1.0 * arc4random_uniform(101)/100,
                                            1.0 * arc4random_uniform(101)/100,
                                            1);
            }
            triangleColours[i] = currColour;

            // Next vertex
            triangleVertices[i] = vertices[vertexIndices[i]];
        }


        // Release memory later
        free(vertices);
        free(vertexIndices);

        [NSTimer scheduledTimerWithTimeInterval:.02
                                         target:self
                                       selector:@selector(timerUpdate:)
                                       userInfo:nil
                                        repeats:YES];

    }
    return self;
}

-(void) timerUpdate:(NSTimer*)timer {

    for(int i = 0; i < 100; i++) {

        int randomCellIndex = ((numRows * numCols)-1) * arc4random_uniform(10001)/10000;
        //        NSLog(@"randomCellIndex %i", randomCellIndex);
        // Loop through the random cell's vertices, setting thier colour
        GLKVector4 currColour = GLKVector4Make(1.0 * arc4random_uniform(101)/100,
                                               1.0 * arc4random_uniform(101)/100,
                                               1.0 * arc4random_uniform(101)/100,
                                               1);

        int startIndex = randomCellIndex * 6;

        for (int i = startIndex; i < startIndex + 6; i++) {

            triangleColours[i] = currColour;
        }
    }

}

-(void)render {
    //  NSLog(@"in EEScene's render");
    glClearColor(clearColor.r, clearColor.g, clearColor.b, clearColor.a);
    glClear(GL_COLOR_BUFFER_BIT);

    [effect prepareToDraw];

    glEnableVertexAttribArray(GLKVertexAttribPosition);
    glVertexAttribPointer(GLKVertexAttribPosition, 2,
                          GL_FLOAT, GL_FALSE, 0, triangleVertices);

    glEnableVertexAttribArray(GLKVertexAttribColor);
    glVertexAttribPointer(GLKVertexAttribColor, 4,
                          GL_FLOAT, GL_FALSE, 0, triangleColours);


    glDrawArrays(GL_TRIANGLES, 0, numTriangleVertices);

    glDisableVertexAttribArray(GLKVertexAttribPosition);
    glDisableVertexAttribArray(GLKVertexAttribColor);
}