0

Xcode で Apple が提供する iOS OpenGL ゲーム テンプレートから始めて、OpenGL VBO で使用しようとしている構造体の配列 (必要に応じて、構造体の構造体の配列の多く) を持っています。ただし、エラーは発生しませんが、画面には何も描画されません。

まず、VecAttributeType 型のこの配列を作成して入力します。これは、vPosition、vTCoordinates、および vNormal の 3 つの他の構造体を持つ構造体です。次に、配列を VBO にコピーし、位置と法線 (オフセットに関しては VecAttributeType.vPosition と VecAttributeType.vNormal を意味します) を glVertexAttribPointer を介して頂点シェーダーの適切な / 属性にバインドします。それではレンダリングしてみます。

そして、何も描かれていません:/

arrayOfStructs には、モデルの描画に必要なすべての頂点が含まれています。つまり、頂点へのインデックスを使用していません。むしろ、このテストでは、obj と各インデックスの面定義を調べて、適切な頂点、テクスチャ、法線を取得し、arraOfStructures にコピーします。

たとえば、obj 形式の古典的な立方体の場合、ファイルには 8 つの頂点がリストされますが、最終的な arrayOfStructs の長さは 12 で、その中には 12 の VecAttributeType 構造体があり、インデックスから派生したその頂点の正しい位置、テクスチャ座標、および法線がそれぞれ含まれています。 obj ファイルの面定義で。はい、obj ファイルのインデックスが 1 から始まるという事実を考慮して、f 定義のインデックスを -1 オフセットしています。

私の推測では、位置と法線の VBO へのオフセットを間違って計算しているだけです。arrayOfStructures の最初の VecAttributeType の最初の位置 x 座標を次のように出力しようとしたため、そう思います。

NSLog(@"\nTEST:\nfirst vertex X = %f", arrayOfStructs[0].vPosition.x);

そして、次のように印刷しようとしているときに、期待値を取得します。

char* address = (char*)arrayOfStructs+offsetof(VecAttributeType, vPosition.x);
    float b = *address;
    NSLog(@"\nTEST:\nfirst vertex X = %f",  b);

代わりに 0 を出力します (正しい値は 1 である必要があります)。

コードの関連セクションは次のとおりです。

//Inside a c++ class I'm parsing an Obj and creating the vertex attribute array:
typedef struct
{
    float x;
    float y;
    float z;

} Vec3fType;

typedef struct
{
    float s;
    float t;

} Vec2fType;

typedef struct
{
    int p;
    int n;
    int t;

} Vec3iType;

typedef struct
{
    Vec3fType vPosition;
    Vec3fType vNormal;
    Vec2fType vTCoordinates;

} VecAttributeType;

int arrayLength = // Some number;
VecAttributeType* arrayOfStructs = new VecAttributeType[arrayLength];

//  Populate the array.

// . . .

// Then, in the ViewController (Objective-C) class, I try binding to the VBO and getting the offsets right:


[EAGLContext setCurrentContext:self.context];

[self loadShaders];

glEnable(GL_DEPTH_TEST);

GLuint _vertexBuffer;
glGenBuffers(1, &_vertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(VecAttributeType)*arrayLength, arrayOfStructs, GL_STATIC_DRAW);
glEnableVertexAttribArray(GLKVertexAttribPosition);
glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, sizeof(VecAttributeType), BUFFER_OFFSET(0) + offsetof(VecAttributeType, vPosition) + offsetof(Vec3fType, x));
glEnableVertexAttribArray(GLKVertexAttribNormal);
glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, sizeof(VecAttributeType), BUFFER_OFFSET(0) + offsetof(VecAttributeType, vNormal) + offsetof(Vec3fType, x));

最後に、描画コードは次のとおりです。

- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
{
    glClearColor(1.f, 0.f, 0.f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glBindVertexArrayOES(_vertexArray);

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

何か案は?

4

1 に答える 1

0

わかりました... ある時点で、 VAO拡張機能 ( )を使用していたことを忘れていたことが判明glBindVertexArrayOESし、VBO セットアップの最後に無効にした後、glkView:draInRect:

上記の私のコードは有効になっていることを示していますが、SO に投稿する前にコードの関連セクションをコピーする新しいプロジェクトを作成しただけです。

また、glVertexAttribPointer行は次のようにもう少しコンパクトに書き直すことができます。

glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, sizeof(VecAttributeType),(void*)offsetof(VecAttributeType, vPosition.x));
glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, sizeof(VecAttributeType), (void*)offsetof(VecAttributeType, vNormal.x));
于 2012-10-11T09:18:33.677 に答える