简体   繁体   English

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

[英]How to apply colour to a triangle with opengl

I am trying to create a simple program with openGL. 我试图用openGL创建一个简单的程序。 The goal is to create a triangle with colours for every vertex. 目标是为每个顶点创建一个带有颜色的三角形。 The problem is that I can not figure out how to apply the colours to the triangle's vertices. 问题是我无法弄清楚如何将颜色应用于三角形的顶点。

My vertex shader: 我的顶点着色器:

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

My fragment shader: 我的片段着色器:

#version 330

smooth in vec4 theColor;
out vec4 outColor;
void main()
{
    outColor = theColor;
}

main code: 主要代码:

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

The array vertices consists of the vertex points (first 3 vectors) and the color values (second 3 vectors). 数组顶点由顶点(前3个矢量)和颜色值(后3个矢量)组成。 You can see my result in the following picture: 您可以在下图中看到我的结果:

简单的三角形

I have been trying to apply the colours with the following code: 我一直在尝试使用以下代码应用颜色:

glEnableVertexAttribArray(1);
glVertexAttribPointer(3,4, GL_UNSIGNED_BYTE, GL_TRUE, 0, (void*)0);

Unfortunately it does not work and I have no idea how to fix that. 不幸的是它不起作用,我不知道如何解决这个问题。 Can anyone help me out here? 有人可以帮我从这里出去吗?

For compiling and loading my shaders I use: 为了编译和加载我的着色器,我使用:

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

First of all, as was revealed in the discussion in comments, you don't link your program. 首先,正如评论中的讨论所揭示的那样,您不会链接您的程序。 A typical shader program setup looks like this: 典型的着色器程序设置如下所示:

GLuint program = glCreateProgram();
glAttachShader(program, shader1);
glAttachShader(program, shader2);
...
glAttachShader(program, shaderN);
glLinkProgram(program); // <<<<<<<<< a-ha!

After that, a good idea is to check if program linkage was OK. 在那之后,一个好主意是检查程序链接是否正常。 A good example of the full shaders & program setup can be found on OpenGL wiki . 可以在OpenGL wiki上找到完整着色器和程序设置的一个很好的例子。

After successful program linkage, you can even detach the shaders from the program ( glDetachShader ) and delete them ( glDeleteShader ) - the program is already linked, shaders are of no use now (unless you intend to attach them to another program, of course). 成功的程序链接后,您甚至可以从程序中分离着色器( glDetachShader )并删除它们( glDeleteShader ) - 程序已经链接,着色器现在没用(除非您打算将它们附加到另一个程序,当然) 。


Secondly, your arguments to glVertexAttribPointer are slightly messed up (which is totally OK - it takes time and effort to get used to them). 其次,你对glVertexAttribPointer的参数有点混乱(这完全没问题 - 需要时间和精力来适应它们)。

void glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized,
    GLsizei stride, const GLvoid * pointer);
  • index is the attribute index - same as location as specified in shader, so for your color attribute it should be 1 . index是属性索引 - 与着色器中指定的location相同,因此对于color属性,它应为1
  • size is the attribute's dimension, ie number of components; size是属性的维度,即组件数量; supposing that you are using 3-float RGB, size should be 3 假设您使用的是3-float RGB,则大小应为3
  • type is the actual type of the components; type是组件的实际类型; in you case these are floating-points too, so GL_FLOAT 在你的情况下,这些也是浮点数,所以GL_FLOAT
  • stride is the distance between attributes of adjacent vertices, which is 3 floats in your case, ie 12 bytes; stride是相邻顶点属性之间的距离,在你的情况下是3个浮点数,即12个字节; since there's nothing in between adjacent attributes in your vertices array, we can actually leave this zero (both for coordinates & colors) 因为vertices数组中的相邻属性之间没有任何内容,我们实际上可以将此为零(对于坐标和颜色)
  • pointer is the pointer to actual attributes data (or, in your case, offset in VBO); pointer是指向实际属性数据的指针(或者,在您的情况下,是VBO中的偏移量); you are passing the same pointer to both glVertexAttribPointer calls, while your color values are 9 floats after the beginning of coordinate values 您将同一指针传递给两个glVertexAttribPointer调用,而您的颜色值在坐标值开始后为9个浮点数

So, it should be 所以,它应该是

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM