4

iOS の GLKit を使用して、Open GL ES 2.0 で単一のメッシュを作成することができました。私が理解できないのは、位置が異なることを除いて最初のメッシュと同じように見える2番目のメッシュを作成する方法です。

私がこれについて完全に間違っていると思うので、誰かが複数のメッシュを描画するサンプルコードを単純に提供できれば、最も役立つと思います。それにもかかわらず、これを機能させるために私が行ったことのリストを次に示します。

  • 頂点情報の C 配列を 2 つ作成しました。1 つ目はテンプレート (0,0,0 を中心とするハードコードされた座標) で、2 つ目は表示したいもの (最初は空) です。
  • インデックス情報の 2 つの C 配列を作成しました。頂点情報と同じ扱いです。
  • vertexCount と indiceCount の 2 つのグローバル変数 int があり、どちらも最初は 0 です。
  • 私はac関数createAt(float x、float y、float z)を持っています。この関数は、頂点テンプレートを頂点表示配列にコピーし、渡されたオフセットを各頂点に適用します。また、インデックスをコピーしてオフセットを適用し、新しい表示頂点を指すようにします。

しかし、これはうまくいきません。画面に描画されるオブジェクトは 1 つだけです。

他の人の質問と回答を見ると、複数の頂点バッファーが必要なように思えますか? 知らない; 私はひどく混乱しています。

4

3 に答える 3

5

GLKBaseEffect クラスのおかげで、GLKit を使用すると、ジオメトリが同じで位置や向きが異なる複数のメッシュを非常に簡単にレンダリングできます。Xcode が提供する「OpenGL Game」テンプレートを見てみましょう。これは、GLKit でキューブをレンダリングし、OpenGL ES 2.0 で別のキューブをレンダリングします。

以下は、回転する 2 つの立方体の上に新しい立方体を追加する 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);
}

「Render another version」と「Render the object again」コメントの間のコードは新しいものです。最初に行う必要があるのは、追加のキューブ用の新しいモデルビュー マトリックスを考え出すことです。これは (表示されていない) のコードに基づいていますupdate:。通常はコードをそこに置きますが、サンプルを短くしたかったのです。

次に、立方体をレンダリングしますが、これは GLKit を使用すると非常に簡単です。イェイGLKit!

Apple の GLKit / OpenGL ゲーム サンプルの 3 つのキューブのスクリーンショット

これが役立つことを願っています。追加の頂点とインデックス配列で間違ったツリーを吠えているようです。これは、異なるジオメトリをレンダリングしたい場合に必要ですが、同じモデルを異なる場所で言っています。それはGLKitが理想的なものです。

于 2012-02-06T14:49:47.077 に答える
0

ベース エフェクトは 1 つしかないので、アップデートでマトリックス計算を行い、それをベース エフェクトの modelviewmatrix に割り当ててから再度描画すると思いますか?

于 2012-06-12T21:54:18.637 に答える
0

John Riselvato は上記のコメントで、update: メソッドの内容を確認できることを本当に望んでいると述べています。同じ 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 に答える