2010-12-03 11 views
5

Bir köşe nesnesi kullanarak bazı geometri oluşturmada sorun yaşıyorum. Ben bir nokta düzlemi çizmeyi planlıyorum, bu yüzden temelde boşluktaki her ayrık pozisyonda bir köşe. Ancak, glDrawElements (...) dediğim her zaman, bir erişim ihlali istisnası döndüren uygulama çöker. Başlatma sırasında bir hata olmalı, sanırım. Bu sayfadaki ikinci örneğeOpenGL 3.x: Verttex arabellek nesnesini ve glDrawElements kullanırken erişim ihlali (...)


#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

Lütfen her zaman hangi OpenGL sürümünü hedeflediğinizi belirtin - 3.x biraz belirsiz. BTW- herhangi bir "glVertexAttribPointer" veya "glEnableVertexAttribArray" önce bir köşe nesnesi nesnesi oluşturmak ve bağlamak için iyi bir uygulamadır. Muhtemelen OpenGL uyumluluk profilini kullanıyorsunuz, bu nedenle bunun için bir hata almadınız. – Kos

+0

Yeterince adil. Sanırım 3.x biraz belirsiz. GL'nin küçük versiyonları arasında büyük farklılıklar olduğunu düşündüm. Yani şu anda OpenGL 3.3 kullanıyorum. – Walter

cevap

0

bak ve ne yaptığını karşılaştırmak: http://www.opengl.org/wiki/VBO_-_just_examples

Ve bir yazım hatası vardır:

Bu

Ben bugüne kadar ne olduğunu GL_DTREAM_DRAW .

+0

Ağaçlar için odun görmediğim gibi görünüyor. Bu sayfayı biliyordum, ama bir nedenden dolayı "glEnableClientState (...)" in kullanımdan kaldırıldığını gördüm. Bu çok utanç verici. Seni rahatsız ettiğim için özür dilerim. – Walter

+0

Tek sorun bu muydu? Kodunuz şimdi düzgün çalışıyor mu? – Bojan

+0

Eh, biraz çalışıyor. Şimdi başka problemlerim var. GlEnableClientState'den (...) kurtulduktan sonra, uygulamayı ilk kez çalıştırmayı başardım. Ancak, bir süre sonra çöktüğü için beklendiği gibi çalışmaz. Yani, çarpışmaya tam olarak neyin sebep olduğunu anlamaya çalışıyorum. Köşe tamponu nesnesinin oluşturulmasını ve köşelerinin çizilmesini ihmal edersem, uygulama iyi bir hızda iyi çalışır. Ancak yukarıdaki kodu eklediğimde, belki 15 saniye sürüyor ve uygulama çöküyor. – Walter

0

glEnableClientState (...) yöntemi kullanımdan kaldırılmıştır! Üzgünüz, bir sebepten dolayı bu gerçeği gözlemledim.

+1

glEnableClientState yalnızca kullanımdan kaldırılmamış, aynı zamanda yanlış bir şekilde, bir VBO'daki köşelere işaret etmek istediğinizi unutmayın (GPU'nun belleğinde değil, istemcinin belleğinde). VBO'daysa artık müşteri durumu değil. :) – Kos

6

Arabellek nesnelerini kullandığınızda, glDrawElements öğesindeki gl * Pointer ve 4. parametresindeki son parametreler artık ana bellekte (sizin aygıtınız) değildir, ancak arabellek nesnelerine kaydırılır. Bu ofsetleri bayt cinsinden hesapladığınızdan emin olun! "Offsetof" makrosu orada çok yararlı.

+0

Doğru - eğer herhangi bir VBO 'GL_ELEMENT_ARRAY_BUFFER''a bağlıysa, son argüman tamponun adresleme tabanı olarak göreceli konumunu kullanır. '0' değeri," şu anda bağlı olan VBO’nun başlangıcı "anlamına gelir. Operatör 'offsetof' gerçekten size yardımcı olacaktır. – Kos

+0

Bu ilginç bir nokta. Bu yüzden eğer doğru anlarsam, renkler için şu şekilde görünmelidir: glVertexAttribPoint (1, 4, GL_FLOAT, GL_FALSE, sizeof (Vertex), (GLvoid *) (offsetof (Vertex, r))); Bu doğru mu? – Walter

+0

Haklısınız! Bu benim sorunumun çözümü! Sadece yanlış bir şekilde glEnableClientState (...) kullandığım değil, aynı zamanda bahsettiğiniz parametreleri yanlış anladım. Bu ipucu için teşekkürler. Uygulamam şimdi iyi çalışıyor ... – Walter

İlgili konular