2012-02-03 14 views
5

Buduję grę na iOS z OpenGL ES 2.0, która zawiera scenę z około 100 różnymi "obiektami", które muszę móc przekształcać niezależnie od siebie. Jestem nowy w OpenGL ES. W związku z tym początkowo sądziłem, że powinienem zacząć od OpenGL ES 1.1, a następnie przenieść aplikację do wersji 2.0, aby skorzystać z ulepszonych efektów wizualnych.Jak manipulować obiektami niezależnie od siebie w OpenGL ES 2.0?

Jednak, gdy zaczynałem czuć się komfortowo z wersją 1.1, zdałem sobie sprawę, częściowo opartą na bardzo centralnym, 2.0-centrycznym szablonie Xcode dla OpenGL, że będzie to więcej kłopotów niż warto walczyć od razu do wersji 2.0, więc Ugryzłem kulę.

Obecnie trudno mi zrozumieć koncepcje na tyle, aby wykonywać proste transformacje na moich obiektach macierzy wierzchołków niezależnie od siebie. Czytałem w dokumentach OpenGLES 2.0, że najlepszym sposobem na to byłoby użycie wielu VBO, po jednym dla każdej tablicy wierzchołków. Jednak nie mogę zmienić jednego z nich bez wpływu na całą scenę.

zacząłem projekt z szablonu jabłko OpenGL ES i usprawnione go tak, że metoda setupGL wygląda następująco:

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

Wiem, że to bardzo zaniedbany Code I w zasadzie copy-and-wklejane bufor Część do stworzenia, aby ustawić się do eksperymentowania z dwoma różnymi vertextArrays w oddzielnych buforach. Wydaje się, że pracował, jak mogę uczynić obu buforów w metodzie 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); 
} 

Mój problem pojawia się, gdy próbuję zrobić transformacji na jednej tablicy wierzchołków bez wpływu na drugą. Próbowałem dodać transformacje w powyższej metodzie tuż przed wywołaniem glDrawArrays, bez powodzenia - myślę, że to może działać tylko z wersją 1.1. Wydaje się moje transformacje muszą być wykonane w sposób zmiana:

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

Jednak to gdzie mogę dostać naprawdę confused-- to nie jest wcale jasne, w jaki sposób można zmodyfikować tej metody do wykonania transformacji do jednej lub drugiej VBO . Nie jest nawet jasne, że powyższy kod w ogóle odwołuje się do jednego konkretnego bufora.

Ostatecznie chciałbym rozszerzyć moją grę, przenosząc kod każdego obiektu gry do instancji klasy niestandardowej, która poradziłaby sobie z transformacjami itp. Ale chciałabym wiedzieć, czy jestem całkowicie błędna w moim podejście przed tym.

Odpowiedz

4

Jeśli jest to przydatne dla osób mających podobne problemy, znalazłem odpowiedzi, których szukałem na doskonałym blogu Iana Terrella, Games by Ian Terrell.

W szczególności, this tutorial i dołączony do niego przykładowy kod były dokładnie tym, czego potrzebowałem, aby opanować ten bardzo skomplikowany temat. Mam nadzieję że to pomoże!

+0

Więc pomysł jest GLKViewController i używać NSObjects do umieszczania obiektów? Który następnie daje możliwość manipulowania każdym NSObject .. –

+0

Tak, to jest w zasadzie poprawne. Ostatecznie odesłałem wszystkie moje kształty do ładnie zamkniętych NSObjectów, co znacznie ułatwiło mi pracę. Samouczek, do którego dołączyłem, był świetnym początkiem. – todd412

0

GLKMatrix4 _modelViewProjectionMatrix [5]; // Al inicio

En - (void) Aktualizacja utylizacji GLKMatrix4 projectionMatrix = GLKMatrix4MakeOrtho (-1.0f, 1.0f, -1.0f/aspekcie 1.0f/aspektem, -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); 
}