How can I manipulate objects independently in OpenGL ES 2.0?

I am creating an iOS game with OpenGL ES 2.0 that contains a scene with 100 different “objects” that I need so that they can transform independently of each other. I am new to OpenGL ES. Thus, I initially thought that I should start with OpenGL ES 1.1, and then reconfigure the application to 2.0 in order to take advantage of the improved visual effects.

However, as I felt comfortable with 1.1, I realized, partly Apple-based very 2.0-centric Xcode-template for OpenGL, that it will be more problems than it is worth fighting, moving directly to 2.0, so I'm a bit of a bullet.

Now it’s hard for me to understand the concepts enough to make simple transformations on vertex array objects independently of each other. I read in OpenGLES 2.0 docs that the best way to do this is to use multiple VBOs, one for each vertex array. However, I cannot convert one of them without affecting the whole scene.

I started the project with the Apple OpenGL ES template and simplified it so that the setupGL method looks like this:

-(void)setupGL
{
    // Setup
    [EAGLContext setCurrentContext:self.context];        
    [self loadShaders];
    self.effect = [[GLKBaseEffect alloc] init];
    self.effect.light0.enabled = GL_TRUE;
    self.effect.light0.diffuseColor = GLKVector4Make(1.0f, 0.4f, 0.4f, 1.0f);
    glEnable(GL_DEPTH_TEST); // do depth comparisons and update the depth buffer

    // Initialize first buffer
    glGenVertexArraysOES(1, &_vertexArray);
    glBindVertexArrayOES(_vertexArray);    
    glGenBuffers(1, &_vertexBuffer);    
    glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);    
    glBufferData(GL_ARRAY_BUFFER, sizeof(gPyramidVertexData), gPyramidVertexData, GL_DYNAMIC_DRAW);
    glEnableVertexAttribArray(GLKVertexAttribPosition);    
    glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0));
    glEnableVertexAttribArray(GLKVertexAttribNormal);
    glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12));    
    glBindVertexArrayOES(0);

    // Initialize second buffer
    glGenVertexArraysOES(2, &_vertexArray2);
    glBindVertexArrayOES(_vertexArray2);
    glGenBuffers(2, &_vertexBuffer2);
    glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer2);
    glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW);
    glEnableVertexAttribArray(GLKVertexAttribPosition);
    glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0));
    glEnableVertexAttribArray(GLKVertexAttribNormal);
    glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12));
    glBindVertexArrayOES(0);
}

I know the code is incredibly messy - I basically copied and pasted the buffer creation part to set myself up to experiment with two different vertextArrays in separate buffers. It seems to work, as I can display both buffers in the drawInRect method:

-(void)glkView:(GLKView *)view drawInRect:(CGRect)rect
{
    glBindVertexArrayOES(_vertexArray);
    glUseProgram(_program);
    glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m);
    glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m);    
    glDrawArrays(GL_TRIANGLES, 0, numberOfVerteces);

    glBindVertexArrayOES(_vertexArray2);
    glUseProgram(_program);
    glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m);
    glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m);
    glDrawArrays(GL_TRIANGLES, 0, numberOfVerteces2);
}

, , . glDrawArrays - , 1.1. -, :

-(void)update
{
    float aspect = fabsf(self.view.bounds.size.width / self.view.bounds.size.height);
    GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f);        
    self.effect.transform.projectionMatrix = projectionMatrix;

    GLKMatrix4 baseModelViewMatrix = GLKMatrix4MakeTranslation( 0.0f, 0.0f, -4.0f);
    baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, _sceneRotation, 1.0f, 1.0f, 1.0f);

    GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, zoomFactor);
    modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _objectRotation, 0.0f, 1.0f, 0.0f);
    modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix);

    _normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL);
    _modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix);    
}

, , - , , VBO . , .

, , .. , .

+5
2

, , , , , .

, , , . , !

+4

GLKMatrix4 _modelViewProjectionMatrix [5];//Al inicio

En - (void) update utiliza GLKMatrix4 projectionMatrix = GLKMatrix4MakeOrtho (-1.0f, 1.0f, -1.0f/aspect, 1.0f/aspect, -10.0f, 10.0f);

for (int i=0; i<5;i++) {
    GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(i*0.2+ 0.3f, 0.0f, 0.0f);
    modelViewMatrix = GLKMatrix4Multiply(modelViewMatrix, GLKMatrix4MakeZRotation(0.0 - _rotation));
    modelViewMatrix = GLKMatrix4Multiply(modelViewMatrix, GLKMatrix4MakeXRotation(0.0 - _rotation));
    modelViewMatrix = GLKMatrix4Multiply(modelViewMatrix, GLKMatrix4MakeYRotation(0.20 - _rotation));

   _modelViewProjectionMatrix[i] = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix);
}
0

All Articles