Opengl着色器vec3未更新

时间:2017-01-02 19:39:24

标签: c++ opengl colors shader

我试图每帧都更新三角形的颜色。我没有运气,我无法弄清楚为什么有人可以帮助我。我已经尝试了多次,改变了我每次尝试更新数据的方式。任何帮助将不胜感激。

#include <glew.h>
#include <glfw3.h>
#include <iostream>
#include <fstream>
#include <time.h>
using namespace std;

GLuint compileshaders() {
    GLuint vshader, fshader, program;

    static const GLchar * vshadersource[] = {
        "#version 450 core                \n"
        " layout (location=0) in vec3 position;\n"
        " layout (location=1) in vec3 color;\n"
        " out vec3 color_out               ;\n"
        "void main()                  \n"
        "{                                \n"
        "color_out = color;               \n"
        "gl_Position = vec4(position,1.0);\n"
        "}                                \n"
    };

    static const GLchar * fshadersource[] = {
        "#version 450 core                \n"
        "in vec3 color_out;               \n"
        "out vec4 colorO;                  \n"
        "void main()                       \n"
        "{                                \n"
        " colorO = vec4(color_out,1.0);   \n"
        "}                                \n"
    };

    vshader = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vshader, 1, vshadersource, NULL);
    glCompileShader(vshader);

    fshader = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fshader, 1, fshadersource, NULL);
    glCompileShader(fshader);

    GLint vCompiled = 0;
    glGetShaderiv(vshader, GL_COMPILE_STATUS, &vCompiled);
    GLint fCompiled = 0;
    glGetShaderiv(fshader, GL_COMPILE_STATUS, &fCompiled);

    if (vCompiled && fCompiled != GL_FALSE) {
        program = glCreateProgram();
        glAttachShader(program, vshader);
        glAttachShader(program, fshader);
        glLinkProgram(program);
        glDeleteShader(vshader);
        glDeleteShader(fshader);
        return program;
    }
    else {
        cout << "Shader Error!" << endl;
    }

    glDeleteShader(vshader);
    glDeleteShader(fshader);

    return NULL;
}

int main(void)
{
    srand(time(0));
    GLFWwindow* window;
    GLuint program;
    GLuint vertex_array_object;
    GLuint buffers[2];

    if (!glfwInit())
        return -1;

    window = glfwCreateWindow(640, 480, "Hello World", NULL, NULL);
    if (!window)
    {
        glfwTerminate();
        return -1;
    }

    glfwMakeContextCurrent(window);

    glewInit();

    static const GLfloat positions[] =  {0.25,-0.25,0.5,0.25,0.25,0.5,-0.25,-0.25,0.5};
    static GLfloat color[] = {1.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,1.0};

    program = compileshaders();
    glUseProgram(program);
    glCreateVertexArrays(1, &vertex_array_object);
    glCreateBuffers(2, &buffers[0]);
    glNamedBufferStorage(buffers[0], sizeof(positions), positions, 0);
    glVertexArrayVertexBuffer(vertex_array_object, 0, buffers[0], 0,  sizeof(GLfloat) * 3);
    glVertexArrayAttribFormat(vertex_array_object, 0, 3, GL_FLOAT, GL_FALSE, 0);
    glVertexArrayAttribBinding(vertex_array_object, 0, 0);
    glEnableVertexArrayAttrib(vertex_array_object, 0);
    glNamedBufferStorage(buffers[1], sizeof(color), color, 0);
    glVertexArrayVertexBuffer(vertex_array_object, 1, buffers[1], 0,   sizeof(GLfloat) * 3);
    glVertexArrayAttribFormat(vertex_array_object, 1, 3, GL_FLOAT, GL_FALSE, 0);
    glVertexArrayAttribBinding(vertex_array_object, 1, 1);
    glEnableVertexArrayAttrib(vertex_array_object, 1);
    glBindVertexArray(vertex_array_object);

    GLfloat clearcolor[4] = { 0.0,0.0,0.0,1.0 };
    glPointSize(40);

    int width, height;
    while (!glfwWindowShouldClose(window))
    {
        glfwGetWindowSize(window, &width, &height);
        glViewport(0, 0, width, height);
        glClearBufferfv(GL_COLOR, 0, clearcolor);

        for (int i = 0; i < 9; i++) {
            color[i] = (rand() % 2);
        }
        glVertexAttrib3fv(1, color);

        glDrawArrays(GL_TRIANGLES, 0, 3);

        glfwSwapBuffers(window);
        glfwPollEvents();
    }

    glDeleteVertexArrays(1,&vertex_array_object);
    glDeleteProgram(program);

    glfwTerminate();
    return 0;
}

1 个答案:

答案 0 :(得分:1)

glNamedBufferStorage(buffers[1], sizeof(color), color, 0);

这告诉OpenGL将给定数组中当前存储的 复制到给定的buffer object中。它不会在color和存储的缓冲区数据之间创建一些链接。在处理完此命令后,OpenGL无法知道您正在修改color

并且glVertexAttrib3fv并没有按照您的想法行事。

如果要更改OpenGL缓冲区对象中的数据,则必须进行OpenGL调用以将不同的数据上传到缓冲区。

此外,您创建了一个静态缓冲区(usage参数为0)。静态缓冲区的重点是 static :它的内容在创建时固定。因此任何上传命令,如glNamedBufferSubData都不起作用。

因此,您需要决定如何更新缓冲区的数据。您想映射它并通过指针更改数据吗?你想坚持映射它吗?您想使用glNamedBufferSubData进行更新吗?您想在更新之前使缓冲区无效吗?有许多更新OpenGL缓冲区对象的策略。

最简单的方法是使glNamedBufferSubData无效并使用,但您需要一个适当的使用参数:

glNamedBufferStorage(buffers[1], sizeof(color), color, GL_DYNAMIC_STORAGE_BIT);

...

while (!glfwWindowShouldClose(window))
{
    glfwGetWindowSize(window, &width, &height);
    glViewport(0, 0, width, height);
    glClearBufferfv(GL_COLOR, 0, clearcolor);

    for (int i = 0; i < 9; i++) {
        color[i] = (rand() % 2);
    }

    glInvalidateBufferData(buffer[1]);
    glNamedBufferSubData(buffer[1], 0, sizeof(color), color);

    glDrawArrays(GL_TRIANGLES, 0, 3);

    glfwSwapBuffers(window);
    glfwPollEvents();
}