2010-12-03 5 views
5

頂点バッファオブジェクトを使用して幾何学的図形の描画に問題があります。私は点の平面を描くつもりだから、基本的には私の空間のすべての離散した位置に1つの頂点を描くつもりです。しかし、私はglDrawElements(...)を呼び出すたびにアクセス違反例外を返すアプリケーションがクラッシュするため、そのプレーンをレンダリングできません。初期化中は間違いがあります。OpenGL 3.x:頂点バッファオブジェクトとglDrawElements(...)を使用するとアクセス違反が発生する

これは私がこれまで持っているものです。このページの2番目の例で


#define SPACE_X 512 
#define SPACE_Z 512 

typedef struct{ 
    GLfloat x, y, z; // position 
    GLfloat nx, ny, nz; // normals 
    GLfloat r, g, b, a; // colors 
} Vertex; 

typedef struct{ 
    GLuint i; // index 
} Index; 

// create vertex buffer 
GLuint vertexBufferObject; 
glGenBuffers(1, &vertexBufferObject); 

// create index buffer 
GLuint indexBufferObject; 
glGenBuffers(1, &indexBufferObject); 

// determine number of vertices/primitives 
const int numberOfVertices = SPACE_X * SPACE_Z; 
const int numberOfPrimitives = numberOfVertices; // As I'm going to render GL_POINTS, number of primitives is the same as number of vertices 

// create vertex array 
Vertex* vertexArray = new Vertex[numberOfVertices]; 

// create index array 
Index* indexArray = new Index[numberOfPrimitives]; 

// create planes (vertex array) 
// color of the vertices is red for now 
int index = -1; 
for(GLfloat x = -SPACE_X/2; x < SPACE_X/2; x++) { 
    for(GLfloat z = -SPACE_Z/2; z < SPACE_Z/2; z++) { 
     index++; 
     vertexArray[index].x = x; 
     vertexArray[index].y = 0.0f; 
     vertexArray[index].z = z; 
     vertexArray[index].nx = 0.0f; 
     vertexArray[index].ny = 0.0f; 
     vertexArray[index].nz = 1.0f; 
     vertexArray[index].r = 1.0; 
     vertexArray[index].g = 0.0; 
     vertexArray[index].b = 0.0; 
     vertexArray[index].a = 1.0; 
    } 
} 

// bind vertex buffer 
glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObject); 

// buffer vertex array 
glBufferData(GL_ARRAY_BUFFER, numberOfVertices * sizeof(Vertex), vertexArray, GL_DTREAM_DRAW); 

// bind vertex buffer again 
glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObject); 

// enable attrib index 0 (positions) 
glEnableVertexAttribArray(0); 

// pass positions in 
glVertexAttribPointer((GLuint)0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), vertexArray); 

// enable attribute index 1 (normals) 
glEnableVertexAttribArray(1); 

// pass normals in 
glVertexAttribPointer((GLuint)1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), &vertexArray[0].nx); 

// enable attribute index 2 (colors) 
glEnableVertexAttribArray(2); 

// pass colors in 
glVertexAttribPointer((GLuint)2, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), &vertexArray[0].r); 

// create index array 
for(GLunit i = 0; i < numberOfPrimitives; i++) { 
    indexArray[i].i = i; 
} 

// bind buffer 
glBindBuffer(GL_ELEMENET_ARRAY_BUFFER, indexBufferObject); 

// buffer indices 
glBufferData(GL_ELEMENET_ARRAY_BUFFER, numberOfPrimitives * sizeof(Index), indexArray, GL_STREAM_DRAW); 

// bind buffer again 
glBindBuffer(GL_ELEMENET_ARRAY_BUFFER, indexBufferObject); 

// AND HERE IT CRASHES! 
// draw plane of GL_POINTS 
glDrawElements(GL_POINTS, numberOfPrimitives, GL_UNSIGNED_INT, indexArray); 

// bind default buffers 
glBindBuffer(GL_ARRAY_BUFFER, 0); 
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); 

// delete vertex/index buffers 
glDeleteBuffers(1, &vertexBufferObject); 
glDeleteBuffers(1, &indexBufferObject); 

delete[] vertexArray; 
vertexArray = NULL; 

delete[] indexArray; 
indexArray = NULL; 
+0

ターゲットとしているOpenGLのバージョンを明記してください。3.xは少し曖昧です。ところで、 'glVertexAttribPointer'または' glEnableVertexAttribArray'の前に頂点配列オブジェクトを作成してバインドすることをお勧めします。あなたはおそらくOpenGL互換性プロファイルを使用しているので、そのためにエラーは表示されませんでした。 – Kos

+0

十分に公正。 3.xはやや曖昧だと思います。 GLのマイナーバージョンでも大きな違いがあると思いました。だから、現在私はOpenGL 3.3を使用しています。 – Walter

答えて

0

見て、あなたが何をしたかと比較:http://www.opengl.org/wiki/VBO_-_just_examples

そして、あなたは1つのタイプミスがありますGL_DTREAM_DRAWを。

+0

私は木の木が見えなかったようです。私はそのページを知っていましたが、何らかの理由で私は "glEnableClientState(...)"が廃止されたという事実を監督しました!それはちょっと恥ずかしいです。お邪魔になってすみません。 – Walter

+0

それは唯一の問題でしたか?あなたのコードは今正しく動作していますか? – Bojan

+0

さて、それはやや働いています。私は今いくつかの他の問題があります。 glEnableClientState(...)を削除した後、私は実際に初めてアプリケーションを実行することができました。ただし、しばらくするとクラッシュするため、期待どおりに動作しません。だから、私は正確に何がクラッシュの原因を把握しようとします。頂点バッファオブジェクトの作成とその頂点の描画を省略すると、アプリケーションは適切な速度で正常に動作します。しかし、上記のコードを追加するとすぐに15秒かかり、アプリケーションがクラッシュします。 – Walter

0

メソッドglEnableClientState(...)は非推奨です!申し訳ありませんが、何らかの理由で私はその事実を監督しました。

+1

glEnableClientStateは推奨されていませんが、ここでは間違っています。つまり、VBOの頂点を指していることを覚えておいてください(GPUのメモリではなくクライアントのメモリ上)。それがVBOであれば、もはやクライアントの状態ではありません。 :) – Kos

6

バッファオブジェクトを使用している場合、glDelementsのgl * Pointerおよび4番目のパラメータの最後のパラメータは、もはや主メモリ内のアドレスではなくなりますが、あなたのバッファメモリはまだバッファオブジェクトにオフセットされています。これらのオフセットをバイト単位で計算してください! "offsetof"マクロはとても役に立ちます。

+0

これは正しいことです.VBOが 'GL_ELEMENT_ARRAY_BUFFER'にバインドされている場合、最後の引数はバッファの相対位置をアドレッシングベースとして使用します。値「0」は「現在バインドされているVBOの先頭」を意味します。演算子 'offsetof'が本当にあなたを助けるでしょう。 – Kos

+0

これは興味深い点です。だから私はそれを理解する場合は、色のためにこのようにする必要があります:glVertexAttribPoint(1、4、GL_FLOAT、GL_FALSE、sizeof(Vertex)、(GLvoid *)(offsetof(Vertex、r)))); これは間違いありませんか? – Walter

+0

あなたは正しいです!それが私の問題の解決です!私が間違ってglEnableClientState(...)を使用しただけでなく、あなたが言及したパラメータも誤解していました。そのヒントをありがとう。私のアプリケーションは現在正常に動作しています... – Walter

関連する問題