-1

I wanna create a dynamic mesh class but i must do something wrong when I enable vertex colors. In my example I have 2 fragment shaders (fragment.glsl -> solid red color / fragmentExp.glsl -> vertexColor). Next I create two primitives one triangle and one cube and put this data in two meshes.

So when i use the solid color fragment shader and don't set the vertex colors it works just fine.

Here is my working example:

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);
}

The problem appears when i change the following lines: So now the meshes have vertexColors in them and are using the vertexColor fragment shader.

And as result I got a black screen. What am I doing wrong? It has do do something with my mesh class...

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();

And finally my generic mesh class:

#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);
}

Here is my vertex shader and my 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;
};
Michael
  • 177
  • 2
  • 15

1 Answers1

0

The glVertexAttribPointer always operate on the currently bound GL_ARRAY_BUFFER. In your init function, this is VBO if there are no colors present and CBO when there are colors. To solve this you have to bind the correct buffer before setting the vertex attributes. (Note that you should only set the color attribute bindings when colors are available.)

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);
}
BDL
  • 21,052
  • 22
  • 49
  • 55