2012-02-03 13 views
5

Estoy construyendo un juego para iOS con OpenGL ES 2.0 que contiene una escena con alrededor de 100 'objetos' diferentes que necesito poder transformar independientemente el uno del otro. Soy nuevo en OpenGL ES. Como tal, inicialmente pensé que debería comenzar con OpenGL ES 1.1, luego migrar la aplicación a 2.0 para aprovechar los efectos visuales mejorados.¿Cómo manipulo objetos independientemente uno del otro en OpenGL ES 2.0?

Sin embargo, justo cuando me estaba acomodando con 1.1, me di cuenta, en parte basado en la plantilla de Xcode 2.0 muy centrada de Apple para OpenGL, que iba a ser más problemas de lo que vale pelear moviéndome directamente a 2.0, entonces Mordí la bala.

Ahora, me resulta difícil comprender los conceptos lo suficiente como para hacer transformaciones simples en mis objetos de matriz de vértices de forma independiente el uno del otro. Leí en los documentos de OpenGLES 2.0 que la mejor manera de hacerlo sería usar múltiples VBO, una para cada matriz de vértices. Sin embargo, parece que no puedo transformar uno de ellos sin afectar toda la escena.

Empecé el proyecto con la plantilla de Apple OpenGL ES y aerodinámico que, de tal manera que el método setupGL se ve así:

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

Sé que es código- increíblemente descuidada Yo, básicamente, copiar y pegar el buffer porción de creación para prepararme para experimentar con dos vertextArays diferentes en buffers separados. Parece haber funcionado, como puedo hacer que ambas memorias intermedias en el método drawInRect:

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

Mi problema viene cuando intento hacer transforma en una matriz de vértices sin afectar a la otra. Traté de agregar transformaciones en el método anterior justo antes de las llamadas glDrawArrays, sin éxito, creo que solo puede funcionar con 1.1. Parece mis transformaciones se deben hacer dentro del método de actualización:

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

Sin embargo, aquí es donde me pongo muy confused-- no está del todo claro cómo podría modificar este método para hacer transformaciones para uno u otro VBO . Ni siquiera está claro que el código anterior hace referencia a un búfer en particular.

Eventualmente me gustaría expandir mi juego moviendo el código para cada objeto del juego a una instancia de una clase personalizada, que manejaría las transformaciones, etc. Pero me gustaría saber si estoy completamente equivocado en mi enfoque antes de hacerlo.

Respuesta

4

En caso de que esto sea útil para cualquiera que tenga problemas similares, encontré las respuestas que estaba buscando en el excelente blog de Ian Terrell, Games by Ian Terrell.

En particular, this tutorial y su código de muestra acompañante eran exactamente lo que necesitaba para controlar este tema tan complicado. ¡Espero que esto ayude!

+0

¿Entonces la idea es tener un GLKViewController y utilizar NSObjects para colocar objetos? Que luego le da la capacidad de manipular cada NSObject .. –

+0

Sí, eso es básicamente correcto. Eventualmente refactoreé todas mis formas en NSObjects encapsulados, lo que los hizo mucho más fáciles de trabajar. El tutorial al que he vinculado anteriormente fue un gran comienzo. – todd412

0

GLKMatrix4 _modelViewProjectionMatrix [5]; // Al inicio

En - (void) actualización utilizació GLKMatrix4 projectionMatrix = GLKMatrix4MakeOrtho (-1.0f, 1.0f, -1.0f/aspecto, 1.0f/aspecto, -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); 
} 
Cuestiones relacionadas