4

我已经设法使用 iOS 的 GLKit 在 Open GL ES 2.0 中创建了一个网格。我想不通的是如何创建第二个网格,它看起来与第一个网格相同,只是位置不同。

我认为如果有人可以简单地提供一些绘制多个网格的示例代码,那将是最有帮助的,因为我认为我这样做完全错误。尽管如此,这里列出了我为尝试完成这项工作所做的工作。

  • 我创建了两个顶点信息的 C 数组。第一个是我的模板(以 0,0,0 为中心的硬编码坐标),第二个是我想要显示的模板(最初为空)。
  • 我创建了两个索引信息的 C 数组。与顶点信息的处理相同。
  • 我有两个全局变量 int,vertexCount 和 indiceCount,最初都是 0。
  • 我有 ac 函数 createAt(float x, float y, float z)。此函数将我的顶点模板复制到我的顶点显示数组中,然后将传入的偏移量应用于每个顶点。它还复制索引并应用偏移量,以便它们指向新的显示顶点。

但这不起作用。只有一个对象被绘制在屏幕上。

查看其他人的问题和答案,听起来可能我应该有多个顶点缓冲区?我不知道; 我非常困惑。

4

3 回答 3

5

借助 GLKBaseEffect 类,使用 GLKit 渲染具有相同几何形状但不同位置或方向的多个网格非常容易。看看 Xcode 提供的“OpenGL Game”模板,它用 GLKit 渲染一个立方体,另一个用 OpenGL ES 2.0 渲染一个立方体。

这是对 OpenGL 游戏示例的修改,它在两个旋转的立方体上方添加了一个新立方体:

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

“渲染另一个版本”和“再次渲染对象”注释之间的代码是新的。它需要做的第一件事是为额外的立方体提出一个新的模型视图矩阵;这是基于update:(未显示)中的代码。通常我会把代码放在那里,但我想保持样本简短。

接下来它渲染立方体,这对于 GLKit 来说非常简单。耶 GLKit!

Apple 的 GLKit / OpenGL 游戏示例中三个立方体的屏幕截图

我希望这有帮助。听起来您在使用额外的顶点和索引数组来查找错误的树;如果您想渲染不同的几何图形,这是必要的,但是您在不同的地方说相同的模型。这是 GLKit 的理想选择。

于 2012-02-06T14:49:47.077 回答
0

由于只有1个基本效果,我认为您会在更新中进行矩阵计算,然后在再次绘制之前将其分配给基本效果模型视图矩阵?

于 2012-06-12T21:54:18.637 回答
0

上面的 John Riselvato 评论说他真的希望他能看到更新:方法内容。我真的很希望自己能看到这一点,因为在使用相同的 GLKBaseEffect 对象时,我很难将头绕在屏幕上放置多个对象。这是我最终做到的方式:

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

希望这可以帮助某人。

于 2014-10-15T10:51:11.857 回答