2016-11-01 8 views
-1

Ich möchte eine dynamische Mesh-Klasse erstellen, aber ich muss etwas falsch machen, wenn ich Vertex-Farben aktiviere. In meinem Beispiel habe ich 2 Fragment-Shader (fragment.glsl -> rote Farbe/fragmentExp.glsl -> vertexColor). Als nächstes erstelle ich zwei Grundelemente, ein Dreieck und einen Würfel und lege diese Daten in zwei Netze.OpenGL Mesh Klasse VertexColor

Also, wenn ich den Solid-Color-Fragment-Shader verwenden und nicht die Vertex-Farben festlegen, funktioniert es gut.

Hier ist mein Arbeitsbeispiel:

Program program; 
program.LoadShader("Vertex", GL_VERTEX_SHADER, "shaders/vertex.glsl"); 
program.LoadShader("Fragment", GL_FRAGMENT_SHADER, "shaders/fragment.glsl"); 
program.AttachToProgram(); 

Program programExp; 
programExp.LoadShader("Vertex", GL_VERTEX_SHADER, "shaders/vertex.glsl"); 
programExp.LoadShader("Fragment", GL_FRAGMENT_SHADER, "shaders/fragmentExp.glsl"); 
programExp.AttachToProgram(); 

GLfloat verticesTri[] = { 
    -0.1f, -0.5f, 0.0f, 
    -0.9f, -0.5f, 0.0f, 
    -0.5f, 0.5f, 0.0f 
}; 

GLfloat verticesCube[] = { 
    0.1f, -0.5f, 0.0f, 
    0.9f, -0.5f, 0.0f, 
    0.1f, 0.5f, 0.0f, 
    0.9f, 0.5f, 0.0f 
}; 

GLuint indicesTri[] = { 
    0, 1, 2 
}; 

GLuint indicesCube[] = { 
    0, 1, 2, 
    2, 3, 1 
}; 

GLfloat colorsTri[] = { 
    1.0f, 0.0f, 0.0f, 
    0.0f, 1.0f, 0.0f, 
    0.0f, 0.0f, 1.0f 
}; 

GLfloat colorsCube[] = { 
    1.0f, 0.0f, 0.0f, 
    0.0f, 1.0f, 0.0f, 
    0.0f, 0.0f, 1.0f, 
    1.0f, 1.0f, 1.0f 
}; 

Mesh tri(program.GetProgram()); 
tri.SetVertices(verticesTri, sizeof(verticesTri)); 
tri.SetIndices(indicesTri, sizeof(indicesTri)); 
//tri.SetColors(colorsTri, sizeof(colorsTri)); 
tri.Init(); 

Mesh cube(program.GetProgram()); 
cube.SetVertices(verticesCube, sizeof(verticesCube)); 
cube.SetIndices(indicesCube, sizeof(indicesCube)); 
//cube.SetColors(colorsCube, sizeof(colorsCube)); 
cube.Init(); 

while (!glfwWindowShouldClose(window)) 
{ 
    glfwPollEvents(); 

    glClearColor(0.0, 0.0, 0.0, 1.0); 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

    tri.Draw(); 
    cube.Draw(); 

    glfwSwapBuffers(window); 
} 

Das Problem erscheint, wenn ich die folgenden Zeilen ändern: So, jetzt die Maschen haben vertexColors in ihnen und werden mit den VERTEX Fragment-Shader.

Und als Ergebnis bekam ich einen schwarzen Bildschirm. Was mache ich falsch? Es hat etwas mit meiner Mesh-Klasse do do ...

Mesh tri(programExp.GetProgram()); 
tri.SetVertices(verticesTri, sizeof(verticesTri)); 
tri.SetIndices(indicesTri, sizeof(indicesTri)); 
tri.SetColors(colorsTri, sizeof(colorsTri)); 
tri.Init(); 

Mesh cube(programExp.GetProgram()); 
cube.SetVertices(verticesCube, sizeof(verticesCube)); 
cube.SetIndices(indicesCube, sizeof(indicesCube)); 
cube.SetColors(colorsCube, sizeof(colorsCube)); 
cube.Init(); 

Und schließlich meine generische Masche Klasse:

#include "header\mesh.h" 

Mesh::Mesh(GLuint program) 
{ 
    this->program = program; 

    glGenVertexArrays(1, &VAO); 
    glBindVertexArray(VAO); 
} 

Mesh::~Mesh() 
{ 
    glDeleteVertexArrays(1, &VAO); 

    glDeleteBuffers(1, &VBO); 
    glDeleteBuffers(1, &EBO); 
    glDeleteBuffers(1, &CBO); 
} 

void Mesh::SetVertices(GLfloat* vertices, unsigned long long size) 
{ 
    numVetices = size; 
    glGenBuffers(1, &VBO); 
    glBindBuffer(GL_ARRAY_BUFFER, VBO); 
    glBufferData(GL_ARRAY_BUFFER, size, vertices, GL_STATIC_DRAW); 
} 

void Mesh::SetIndices(GLuint* indices, unsigned long long size) 
{ 
    numIndices = size; 
    glGenBuffers(1, &EBO); 
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); 
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, size, indices, GL_STATIC_DRAW); 
} 

void Mesh::SetColors(GLfloat* colors, unsigned long long size) 
{ 
    numColors = size; 
    glGenBuffers(1, &CBO); 
    glBindBuffer(GL_ARRAY_BUFFER, CBO); 
    glBufferData(GL_ARRAY_BUFFER, size, colors, GL_STATIC_DRAW); 
} 

void Mesh::Init() 
{ 
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid*)0); 
    glEnableVertexAttribArray(0); 

    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid*)0); 
    glEnableVertexAttribArray(1); 
} 

void Mesh::Draw() 
{ 
    glUseProgram(program); 

    glBindVertexArray(VAO); 
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); 
    //glDrawArrays(GL_TRIANGLES, 0, 6); 
    glBindVertexArray(0); 
} 

Hier ist meine Vertex-Shader und meine Fragment-Shader:

#version 400 

layout(location = 0) in vec3 pos; 
layout(location = 1) in vec3 col; 

out vec3 color; 

void main() 
{ 
    gl_Position = vec4(pos, 1.0); 
    color = col; 
}; 


#version 400 

in vec3 col; 

out vec3 color; 

void main() 
{ 
    color = col; 
}; 

Antwort

0

Die glVertexAttribPointer arbeiten immer an der aktuell gebundenen GL_ARRAY_BUFFER. In Ihrer Init-Funktion ist dies VBO, wenn keine Farben vorhanden sind, und CBO, wenn Farben vorhanden sind. Um dies zu lösen, müssen Sie den richtigen Puffer binden, bevor Sie die Vertex-Attribute setzen. (Beachten Sie, dass Sie die Farbattributbindungen nur festlegen sollten, wenn Farben verfügbar sind.)

void Mesh::Init() 
{ 
    glBindBuffer(GL_ARRAY_BUFFER, VBO); 
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid*)0); 
    glEnableVertexAttribArray(0); 

    glBindBuffer(GL_ARRAY_BUFFER, CBO); 
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid*)0); 
    glEnableVertexAttribArray(1); 
}