C++ 如何使用opengl将颜色应用于三角形

C++ 如何使用opengl将颜色应用于三角形,c++,opengl,fragment-shader,vertex-shader,C++,Opengl,Fragment Shader,Vertex Shader,我正在尝试用openGL创建一个简单的程序。目标是为每个顶点创建一个带有颜色的三角形。问题是我不知道如何将颜色应用于三角形的顶点 我的顶点着色器: #version 330 layout(location = 0) in vec4 vertex_position; layout(location = 1) in vec4 vertex_color; smooth out vec4 theColor; void main() { gl_Position = vec4(vertex_p

我正在尝试用openGL创建一个简单的程序。目标是为每个顶点创建一个带有颜色的三角形。问题是我不知道如何将颜色应用于三角形的顶点

我的顶点着色器:

#version 330

layout(location = 0) in vec4 vertex_position;
layout(location = 1) in vec4 vertex_color;

smooth out vec4 theColor;

void main()
{
    gl_Position = vec4(vertex_position.x, vertex_position.y, vertex_position.z, 1.0);
    theColor = vertex_color;
}
我的片段着色器:

#version 330

smooth in vec4 theColor;
out vec4 outColor;
void main()
{
    outColor = theColor;
}
主要代码:

    float vertices[] = {
                -0.5f, -0.5f, 0.0f,
                0.5f, -0.5f, 0.0f,
                0.0f, 0.5f, 0.0f,
                0.5f, 0.6f, 0.1f,
                0.2f, 0.6, 0.3f,
                0.1f, 0.23f, 0.78f
            };

        GLuint my_vao, my_vbo;
                glGenVertexArrays(1, &my_vao);
                glBindVertexArray(my_vao);
                glGenBuffers(1, &my_vbo);
                glBindBuffer(GL_ARRAY_BUFFER, my_vbo);
                glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
                glEnableVertexAttribArray(0);
            //  glEnableVertexAttribArray(1);
                glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3*sizeof(float), (void*)0);
            //  glVertexAttribPointer(3,4, GL_UNSIGNED_BYTE, GL_TRUE, 0, (void*)0);

    glClear(GL_COLOR_BUFFER_BIT);
    glUseProgram(shaderProgram);
    glBindVertexArray(vao);
    glViewport(0, 0, viewport_width, viewport_height);
    glDrawArrays(GL_TRIANGLES, 0, 3);
    swapBuffers();
阵列顶点由顶点(前3个向量)和颜色值(后3个向量)组成。您可以在下图中看到我的结果:

我一直在尝试使用以下代码应用颜色:

glEnableVertexAttribArray(1);
glVertexAttribPointer(3,4, GL_UNSIGNED_BYTE, GL_TRUE, 0, (void*)0);
不幸的是,它不起作用,我不知道如何修复它。有人能帮我吗

对于编译和加载我的着色器,我使用:

    std::string loadVertexShader(const char* vertexPath)
    {
        std::string vertexCode;
        std::ifstream vShaderFile;
        vShaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);
        try
        {
            vShaderFile.open(vertexPath);
            std::stringstream vShaderStream;
            vShaderStream << vShaderFile.rdbuf();
            vShaderFile.close();
            vertexCode = vShaderStream.str();
        }
        catch (std::ifstream::failure e)
        {
            std::cout << "ERROR::VERTEXSHADER::FILE_NOT_SUCCESFULLY_READ" << std::endl;
        }
        return vertexCode;
    }

int vertexShader = glCreateShader(GL_VERTEX_SHADER);
        int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
        std::string vertexVal = loadVertexShader("shader/vertexshader.shader");
        const char* vShaderCode = vertexVal.c_str();
        std::string fragmentVal = loadFragmentShader("shader/fragmentshader.shader");
        const char* fShaderCode = fragmentVal.c_str();
        glShaderSource(vertexShader, 1, &vShaderCode, NULL);
        glCompileShader(vertexShader);
        glShaderSource(fragmentShader, 1, &fShaderCode, NULL);
        glCompileShader(fragmentShader);

GLint vertexStatus;
        char vertexInfoLog[512];
        char fragmentInfoLog[512];
        glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &vertexStatus);
        GLint fragmentStatus;
        glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &fragmentStatus);

        if (!vertexStatus)
        {
            glGetShaderInfoLog(vertexShader, 512, NULL, fragmentInfoLog);
            std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << fragmentInfoLog << std::endl;
        }

        if (!fragmentStatus)
        {
            glGetShaderInfoLog(fragmentShader, 512, NULL, vertexInfoLog);
            std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << vertexInfoLog << std::endl;
        }
std::string loadVertexShader(const char*vertexPath)
{
字符串顶点编码;
std::ifstream-vShaderFile;
异常(std::ifstream::failbit | std::ifstream::badbit);
尝试
{
vShaderFile.open(垂直);
std::stringstream-vShaderStream;

vShaderStream首先,正如评论中的讨论所揭示的,您不链接程序。典型的着色器程序设置如下所示:

GLuint program = glCreateProgram();
glAttachShader(program, shader1);
glAttachShader(program, shader2);
...
glAttachShader(program, shaderN);
glLinkProgram(program); // <<<<<<<<< a-ha!
  • index
    是属性索引-与着色器中指定的
    location
    相同,因此对于颜色属性,它应该是
    1
  • size
    是属性的维度,即组件的数量;假设您使用的是3-float RGB,那么大小应该是
    3
  • type
    是组件的实际类型;在您的情况下,这些也是浮点,因此
    GL\u FLOAT
  • stride
    是相邻顶点属性之间的距离,在您的情况下是3个浮点数,即12个字节;因为在
    顶点
    数组中相邻属性之间没有任何内容,所以我们实际上可以将该值保留为零(坐标和颜色)
  • pointer
    是指向实际属性数据的指针(或者,在您的情况下,是VBO中的偏移);您将同一指针传递给两个
    glvertexattributepointer
    调用,而颜色值在坐标值开始后是9个浮点数
所以,应该是这样

glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, (float const *)(nullptr) + 9);

glvertexattributepointer
的第一个参数应该是1而不是3,以匹配
布局(位置=1)
。您还应该添加带有颜色数据的VBO。感谢您的快速回复。将参数更改为1不会改变任何事情。VBO my_VBO不是已经有了颜色数据,因为它获取了数组顶点,其中包含顶点和顶点颜色吗?哦,抱歉,覆盖了该部分。假设您的数据包含3*3个浮点数属性和指针3个3浮点数为颜色,属性指针应该是:<代码> GLVICTATTURBIONTIONT(1, 3,GLASTIFY,GLUX FALSE,0,(空虚*)3×3×sieof(浮点))< />代码。我不知道为什么您使用了无符号字节,因为数据是浮动的。NB:用数值捕获C++异常通常是个坏主意,最好是<代码> catch(STD::IFSTRO::失败const & e)
。好的,谢谢。你认为我的loadVertexShader函数可能有问题吗?我对片段着色器的操作完全相同。不幸的是,这也不起作用。我的代码:GlenableVertexAttributeArray(0);GlenableVertexAttributeArray(1);GlVertexAttributePointer(0,3,GL_FLOAT,GL_FALSE,3*sizeof(FLOAT),(void*)0);glvertexattributepointer(1,3,GL_FLOAT,GL_FALSE,0,(void*)(3*3**sizeof(FLOAT));@coderof力以什么确切方式不起作用?三角形仍然是黑色的吗?如果将片段着色器
main
更改为例如
outColor=vec4(1.0,0.0,1.0),会发生什么情况
?三角形仍然是黑色的。如果我像你说的那样更改片段着色器,则什么也不会发生。它仍然是黑色的。@CoderoftForce现在这很奇怪。你确定你已经重新编译了项目等吗?你如何编译你的着色器?你检查着色器编译是否成功了吗?是的,我已经重新编译了所有内容。我刚刚编辑了我的问题。您可以在那里看到我的着色器处理。我从glGetShaderInfoLog()中没有得到任何错误
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, (float const *)(nullptr) + 9);