Manage multiple grids in Open GL ES 2.0 (iOS GLKit)?

I managed to create a single grid in Open GL ES 2.0 using iOS GLKit. I cannot figure out how to create a second grid that looks identical to the first, except for a different position.

I think it would be very helpful if someone could just provide some sample code that draws multiple grids, since I think I'm going to do it completely wrong. However, here is a list of what I did to try to make this work.

  • I created two C-arrays of vertex information. The first is my template (hard-coded coordinates with the center at 0,0,0), and the second is what I would like to display (initially empty).
  • I created two C-arrays of index information. Same as vertex information.
  • I have two global variables ints, vertexCount and indiceCount, initially 0.
  • I have a function c, createAt (float x, float y, float z). This function copies my vertex pattern to my vertex mapping array and then applies the passed in offsets to each vertex. It also copies the indices and applies the offset so that they point to the new displayed vertices.

This does not work. Only one object is displayed on the screen.

Looking through other people's questions and answers, does it sound like I should have several vertex buffers? I dont know; I'm terribly confused.

+4
source share
3 answers

Because of the GLKBaseEffect class, rendering multiple cells with the same geometry but with different positions or orientations is pretty simple with GLKit. Take a look at the β€œOpenGL Game” template provided by Xcode, which displays a cube with GLKit and another cube with OpenGL ES 2.0.

Here is a modification of the OpenGL Game sample, which adds a new cube over two rotating ones:

- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect { glClearColor(0.65f, 0.65f, 0.65f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glBindVertexArrayOES(_vertexArray); // Render the object with GLKit [self.effect prepareToDraw]; glDrawArrays(GL_TRIANGLES, 0, 36); // Render another version of the object with GLKit // First put it in a different place (you would normally // do this in the update loop): GLKMatrix4 baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -4.0f); baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, _rotation, 0.0f, 1.0f, 0.0f); GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 1.5, -0.0f); modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); self.effect.transform.modelviewMatrix = modelViewMatrix; // Now render it: [self.effect prepareToDraw]; glDrawArrays(GL_TRIANGLES, 0, 36); // Render the object again with ES2 glUseProgram(_program); glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m); glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m); glDrawArrays(GL_TRIANGLES, 0, 36); } 

The code between the comments "Render another version" and "Render the object again" is new. The first thing he needs to do is create a new model model for an additional cube; this is based on the code in update: (not shown). Normally I would put the code there, but I would like to keep the sample short.

Then it displays a cube, which is pretty simple with GLKit. Yay GLKit!

Screenshot of three cubes in Apple's GLKit / OpenGL Game sample

Hope this helps. It looks like you are barking the wrong tree with extra vertex and index arrays; this is necessary if you want to visualize different geometries, but you said the same model in different places. That GLKit is perfect.

+5
source

Since there is only 1 base effect, I suppose you would do matrix calculations in the update and just assign it to the base modelviewmatrix effect before you draw again?

0
source

John Riselvato comments above that he really wants him to see the update: the contents of the method. I really wanted to see this myself, because it was difficult for me to wrap my head around placing several objects on the screen using the same GLKBaseEffect object. Here is how I did it:

 // update method where I create 3 different modelViewMatrices to use with my GLKBaseEffect object later in the draw method - (void)updateWithDeltaTime:(NSTimeInterval)deltaTime { _rotation1 += 120.0 * deltaTime; _rotation2 += 150.0 * deltaTime; _rotation3 += 180.0 * deltaTime; GLKMatrix4 modelViewMatrix = GLKMatrix4Identity; modelViewMatrix = GLKMatrix4Translate(modelViewMatrix, -1.0f, 0.0f, -4.0f); modelViewMatrix = GLKMatrix4RotateY(modelViewMatrix, GLKMathDegreesToRadians(90.0f)); modelViewMatrix = GLKMatrix4RotateZ(modelViewMatrix, GLKMathDegreesToRadians(_rotation1)); _modelViewMatrix1 = modelViewMatrix; modelViewMatrix = GLKMatrix4Identity; modelViewMatrix = GLKMatrix4Translate(modelViewMatrix, 0.0f, 0.0f, -4.0f); modelViewMatrix = GLKMatrix4RotateY(modelViewMatrix, GLKMathDegreesToRadians(90.0f)); modelViewMatrix = GLKMatrix4RotateZ(modelViewMatrix, GLKMathDegreesToRadians(_rotation2)); _modelViewMatrix2 = modelViewMatrix; modelViewMatrix = GLKMatrix4Identity; modelViewMatrix = GLKMatrix4Translate(modelViewMatrix, 1.0f, 0.0f, -4.0f); modelViewMatrix = GLKMatrix4RotateY(modelViewMatrix, GLKMathDegreesToRadians(90.0f)); modelViewMatrix = GLKMatrix4RotateZ(modelViewMatrix, GLKMathDegreesToRadians(_rotation3)); _modelViewMatrix3 = modelViewMatrix; } // draw method where I re-use my GLKBaseEffect object, applying the 3 modelViewMatrices I set in the update: method above - (void)glkView:(GLKView *)view drawInRect:(CGRect)rect { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); _effect.transform.modelviewMatrix = _modelViewMatrix1; [_effect prepareToDraw]; glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer1); glDrawArrays(GL_TRIANGLES, 0, cylinderVertices); _effect.transform.modelviewMatrix = _modelViewMatrix2; [_effect prepareToDraw]; glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer2); glDrawArrays(GL_TRIANGLES, 0, cylinderVertices); _effect.transform.modelviewMatrix = _modelViewMatrix3; [_effect prepareToDraw]; glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer3); glDrawArrays(GL_TRIANGLES, 0, cylinderVertices); } // how i initially setup my GLKBaseEffect object and my opengl buffers - (void)_setupGL { [EAGLContext setCurrentContext:_context]; //glEnable(GL_CULL_FACE); glEnable(GL_DEPTH_TEST); glClearColor(0.5f, 0.5f, 0.5f, 1.0f); _effect = [[GLKBaseEffect alloc] init]; [self _createEffect]; [_effect prepareToDraw]; glGenBuffers(1, &_vertexBuffer1); glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer1); glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW); glGenBuffers(1, &_vertexBuffer2); glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer2); glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW); glGenBuffers(1, &_vertexBuffer3); glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer3); glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW); glEnableVertexAttribArray(GLKVertexAttribPosition); glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid *)offsetof(Vertex, Position)); glEnableVertexAttribArray(GLKVertexAttribTexCoord0); glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid *)offsetof(Vertex, Texel)); glEnableVertexAttribArray(GLKVertexAttribNormal); glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid *)offsetof(Vertex, Normal)); } 

Hope this helps someone.

0
source

Source: https://habr.com/ru/post/1394776/


All Articles