4

私はopenGLが初めてです。私は私の主なレファレンスとしてアップルのドキュメントを使用してい ます http://developer.apple.com/library/ios/#documentation/3DDrawing/Conceptual/OpenGLES_ProgrammingGuide/TechniquesforWorkingwithVertexData/TechniquesforWorkingwithVertexData.html#//apple_ref/doc/uid/TP40008793-CH107-SW6

私の問題は、2ではなくopenGL ES 1.1を使用しているため、リスト 9-3 で使用されているglVertexAttribPointerglEnableVertexAttribArrayなどの関数が認識されないことです ... :)

このドキュメントで説明されている最適化を試みています: インデックスと頂点を構造体として保持し、そのすべてのデータ: 位置、色 (リスト 9-1)

typedef struct _vertexStruct
{
  GLfloat position[3];
  GLubyte color[4];
} VertexStruct;

const VertexStruct vertices[] = {...};
const GLushort indices[] = {...};

リスト9-2、9-3のようなVBOを使用する

前述したように、そこで使用されている関数のいくつかは、openGL ES 1.1 には存在しません。ES 1.1 で同じことを行う方法があるかどうか疑問に思っています。おそらく他のコードを使用しますか?

ありがとう、アレックス


クリスチャンの答えに従って編集し、glVertexPointer、glColorPointerを使用しようとしました。コードは次のとおりです。立方体は印刷されますが、色は印刷されません... :(。誰でも、ES 1.1を使用してそのような方法でVBOを使用することは可能ですか

typedef struct {
    GLubyte red;
    GLubyte green;
    GLubyte blue;
    GLubyte alpha;
} Color3D;

typedef struct {
    GLfloat x;
    GLfloat y;
    GLfloat z;
} Vertex3D;

typedef struct{
   Vector3D position;
   Color3D color;
} MeshVertex;

キューブ データ:

static const MeshVertex meshVertices [] =
{

    { { 0.0, 1.0, 0.0 } , { 1.0, 0.0, 0.0 ,1.0 } },
    { { 0.0, 1.0, 1.0 } , { 0.0, 1.0, 0.0 ,1.0 } },
    { { 0.0, 0.0, 0.0 } , { 0.0, 0.0, 1.0 ,1.0 } },
    { { 0.0, 0.0, 1.0 } , { 1.0, 0.0, 0.0, 1.0 } },
    { { 1.0, 0.0, 0.0 } , { 0.0, 1.0, 0.0, 1.0 } },
    { { 1.0, 0.0, 1.0 } , { 0.0, 0.0, 1.0, 1.0 } },
    { { 1.0, 1.0, 0.0 } , { 1.0, 0.0, 0.0, 1.0 } },
    { { 1.0, 1.0, 1.0 } , { 0.0, 1.0, 0.0, 1.0 } }

};

static const GLushort meshIndices [] =
{   0, 1, 2 , 
    2, 1, 3 , 
    2, 3, 4 ,
    3, 5, 4 ,
    0, 2, 6 ,
    6, 2, 4 ,
    1, 7, 3 ,
    7, 5, 3 ,
    0, 6, 1 ,
    1, 6, 7 , 
    6, 4, 7 , 
    4, 5, 7 
};

関数

GLuint vertexBuffer;
GLuint indexBuffer;

- (void) CreateVertexBuffers 
{ 
    glGenBuffers(1, &vertexBuffer);
    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(meshVertices), meshVertices, GL_STATIC_DRAW);

    glGenBuffers(1, &indexBuffer);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(meshIndices), meshIndices, GL_STATIC_DRAW);

}

- (void) DrawModelUsingVertexBuffers
{
    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
    glVertexPointer(3, GL_FLOAT, sizeof(MeshVertex), (void*)offsetof(MeshVertex,position));
    glEnableClientState(GL_VERTEX_ARRAY);


    glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(MeshVertex), (void*)offsetof(MeshVertex,color));
    glEnableClientState(GL_COLOR_ARRAY);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);  
    glDrawElements(GL_TRIANGLE_STRIP, sizeof(meshIndices)/sizeof(GLushort), GL_UNSIGNED_SHORT,    (void*)0);

    glDisableClientState(GL_VERTEX_ARRAY);
    glDisableClientState(GL_COLOR_ARRAY);
}
4

1 に答える 1

4

glVertexAttribPointerおよびのような関数glEnableVertexAttribArrayは、一般的なカスタム頂点属性に使用されます (これは、OpenGL ES 2.0 で頂点データを送信するためにサポートされている唯一の方法です)。

固定関数パイプラインを使用する場合 (OpenGL ES 1.1 で必要な場合)、組み込みの属性を使用するだけです (頂点配列に切り替える前に使用していた可能性のあるglVertexand呼び出しを考えてください)。または(の代わりに) のglColorように、対応する即時モードと同様に呼び出される各属性の関数があります。これらの配列は、または(の代わりに) のような定数を使用して呼び出すことで有効/無効になります。glVertexPointerglColorPointerglVertexAttribPointergl(En/Dis)ableClientStateGL_VERTEX_ARRAYGL_COLOR_ARRAYgl(En/Dis)ableVertexAttribArray

しかし、原則として、OpenGL ES 1.1 プログラミングを 2.0 のリソースで学習するべきではありません。その情報の多くは役に立たないからです (少なくとも OpenGL を初めて使用する場合)。たとえば、リンクされたサイトで説明されている一部のメソッドは、VBO や VAO など、1.1 ではサポートされていない場合があります。しかし、私は ES の経験がまったくないことも認めなければならないので、それについて完全には確信が持てません。

編集:更新されたコードについて:色がないということは、キューブが単色、おそらく白であることを意味すると思います。あなたが使用した最初のコード例GLubyte color[4]では、現在はそのいくつかのColor3Dタイプですが、これは呼び出しに適合しない可能性がありglColorPointer(4, GL_UNSIGNED_BYTE, ...)ます (最初の引数はコンポーネントの数で、2 番目の引数はタイプです)。

タイプに 3 色または浮動小数点色しか含まれていない場合Color3Dは、とにかく 4-ubyte 色を使用することをお勧めします。これは、位置の 3 つの float と一緒に、完全に 16 バイトに整列された頂点を取得する必要があるためです。提供されたリンクで提案してください。

ところで、あなたのCreateVertexBuffers関数でインデックス バッファの作成を繰り返しているのは、むしろタイプミスですね。

編集:色には ubytes (0 (黒) から 255 (フルカラー) の範囲) が含まれており、浮動小数点数で初期化します。したがって、float 値 1.0 (これはフル カラーを意味するはずです) は ubyte に変換され、[0,255] の範囲全体と比較してまだ非常に小さいため、すべてが黒である 1 になります。ubytes を使用する場合は、それらも ubytes で初期化する必要があるため、カラー データのすべての 0.0 を 0 に、すべての 1.0 を 255 に置き換えるだけです。

ところで、ES 1.1 で VBO を使用していて、少なくとも何かが描画されているので、ES 1.1 は VBO をサポートしているようです。私はそれを知りませんでした。ただし、VAO もサポートしているかどうかはわかりません。

glBindBuffer(GL_ARRAY_BUFFER, 0)ところで、これら 2 つの関数の最後で、要素配列バッファーの使用が終了したら、同様に andを呼び出す必要があります。そうしないと、バッファーを想定していない他の関数で問題が発生する可能性がありますが、バッファーはまだバインドされています。OpenGL はステート マシンであり、設定したすべてのステートは、再度変更されるか、コンテキストが破棄されるまで維持されることを常に覚えておいてください。

于 2011-09-01T17:56:55.520 に答える