OpenGL网格类VertexColor

时间:2016-11-01 14:13:02

标签: opengl colors shader mesh vertex

我想创建一个动态网格类但是当我启用顶点颜色时我必须做错事。 在我的例子中,我有2个片段着色器(fragment.glsl - > solid red color / fragmentExp.glsl - > vertexColor)。接下来,我创建两个基元,一个三角形和一个立方体,并将这些数据放在两个网格中。

因此,当我使用纯色片段着色器并且不设置顶点颜色时,它可以正常工作。

以下是我的工作示例:

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

当我更改以下行时出现问题: 所以现在网格中有vertexColors并使用了vertexColor片段着色器。

结果我得到了黑屏。 我究竟做错了什么?它已经对我的网格类做了一些事情......

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

最后是我的通用网格类:

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

这是我的顶点着色器和我的片段着色器:

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

1 个答案:

答案 0 :(得分:0)

glVertexAttribPointer始终在当前绑定的GL_ARRAY_BUFFER上运行。在你的初始化函数中,如果没有颜色,这是VBO,当有颜色时,这是CBO。要解决此问题,您必须在设置顶点属性之前绑定正确的缓冲区。 (请注意,只有在颜色可用时才应设置颜色属性绑定。)

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