4 Stimmen

OpenGL 3.x: Zugriffsverletzung bei Verwendung von Vertex-Buffer-Objekt und glDrawElements(...)

Ich habe Probleme beim Rendern einiger Geometrie unter Verwendung eines Vertex-Buffer-Objekts. Ich beabsichtige, eine Ebene von Punkten zu zeichnen, also im Grunde genommen einen Vertex an jeder diskreten Position in meinem Raum. Allerdings kann ich diese Ebene nicht rendern, da die Anwendung jedes Mal abstürzt, wenn ich glDrawElements(...) aufrufe und eine Zugriffsverletzungsausnahme zurückgibt. Es muss einen Fehler bei der Initialisierung geben, denke ich.

Das ist, was ich bisher habe:


#define SPACE_X 512
#define SPACE_Z 512

typedef struct{
    GLfloat x, y, z; // Position
    GLfloat nx, ny, nz; // Normale
    GLfloat r, g, b, a; // Farben
} Vertex;

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

// Vertex-Buffer erstellen
GLuint vertexBufferObject;
glGenBuffers(1, &vertexBufferObject);

// Index-Buffer erstellen
GLuint indexBufferObject;
glGenBuffers(1, &indexBufferObject);

// Anzahl der Vertices / Primitiven bestimmen
const int numberOfVertices = SPACE_X * SPACE_Z;
const int numberOfPrimitives = numberOfVertices; // Da ich GL_POINTS rendern werde, ist die Anzahl der Primitiven gleich der Anzahl der Vertices

// Vertex-Array erstellen
Vertex* vertexArray = new Vertex[numberOfVertices];

// Index-Array erstellen
Index* indexArray = new Index[numberOfPrimitives];

// Ebenen erstellen (Vertex-Array)
// Farbe der Vertices ist im Moment rot
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;
    }
}

// Vertex-Buffer binden
glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObject);

// Vertex-Array puffern
glBufferData(GL_ARRAY_BUFFER, numberOfVertices * sizeof(Vertex), vertexArray, GL_DYNAMIC_DRAW);

// Vertex-Buffer erneut binden
glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObject);

// Attributindex 0 (Positionen) aktivieren
glEnableVertexAttribArray(0);

// Positionen übergeben
glVertexAttribPointer((GLuint)0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), vertexArray);

// Attributindex 1 (Normalen) aktivieren
glEnableVertexAttribArray(1);

// Normalen übergeben
glVertexAttribPointer((GLuint)1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), &vertexArray[0].nx);

// Attributindex 2 (Farben) aktivieren
glEnableVertexAttribArray(2);

// Farben übergeben
glVertexAttribPointer((GLuint)2, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), &vertexArray[0].r);

// Index-Array erstellen
for(GLuint i = 0; i < numberOfPrimitives; i++) {
    indexArray[i].i = i;
}

// Buffer binden
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferObject);

// Indizes puffern
glBufferData(GL_ELEMENT_ARRAY_BUFFER, numberOfPrimitives * sizeof(Index), indexArray, GL_STREAM_DRAW);

// Buffer erneut binden
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferObject);

// UND HIER STÜRZT ES AB!
// Ebenen von GL_POINTS zeichnen
glDrawElements(GL_POINTS, numberOfPrimitives, GL_UNSIGNED_INT, indexArray);

// Standard-Buffer binden
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

// Vertex- / Index-Buffer löschen
glDeleteBuffers(1, &vertexBufferObject);
glDeleteBuffers(1, &indexBufferObject);

delete[] vertexArray;
vertexArray = NULL;

delete[] indexArray;
indexArray = NULL;

6voto

ltjax Punkte 15481

Wenn Sie Pufferobjekte verwenden, sind die letzten Parameter in den gl*Pointer- und der vierte Parameter in glDrawElements nicht mehr Adressen im Hauptspeicher (Ihre noch immer!), sondern Offsets in die Pufferobjekte. Stellen Sie sicher, dass diese Offsets in Bytes berechnet werden! Das Makro "offsetof" ist dabei sehr hilfreich.

0voto

Bojan Punkte 726

Schauen Sie sich das zweite Beispiel auf dieser Seite an und vergleichen Sie es mit dem, was Sie gemacht haben: http://www.opengl.org/wiki/VBO_-_just_examples

Und Sie haben einen Tippfehler: GL_DTREAM_DRAW.

0voto

Walter Punkte 396

Die Methode glEnableClientState(...) ist veraltet! Entschuldigung, aus irgendeinem Grund hatte ich das übersehen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X