OpenGL_9:着色器之uniform变量

来源:互联网 发布:分级阅读 知乎 编辑:程序博客网 时间:2024/06/05 13:28
#include <stdio.h>#include <GLAD/glad.h>#include <GLFW/glfw3.h>#include <math.h>const char *vertexShaderSource =        "#version 330 core\n"                "layout (location = 0) in vec3 aPos;\n"                "void main(){\n"                    "gl_Position = vec4(aPos, 1.0f);\n"                "}\n\0";/** * Uniform是一种从CPU中的应用向GPU中的着色器发送数据的方式,但uniform和顶点属性有些不同。 * 首先,uniform是全局的(Global)。全局意味着uniform变量必须在每个着色器程序对象中 * 都是独一无二的,而且它可以被着色器程序的任意着色器在任意阶段访问。 * 第二,无论你把uniform值设置成什么,uniform会一直保存它们的数据,直到它们被重置或更新。 * */const char *fragmentShaderSource =        "#version 330 core\n"                "out vec4 FragColor;\n"                "uniform vec4 myColor;"                "void main(){\n"                    "FragColor = myColor;\n"                "}\n\0";const unsigned int SCR_WIDTH = 800;const unsigned int SCR_HEIGHT = 600;void framebuffer_size_callback(GLFWwindow* glfWwindow, int width, int height);int main() {    glfwInit();    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);    GLFWwindow *glfWwindow = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "shader", NULL, NULL);    if (NULL == glfWwindow){        printf("Failed to create window\n");        glfwTerminate();        return -1;    }    glfwMakeContextCurrent(glfWwindow);    glfwSetFramebufferSizeCallback(glfWwindow, framebuffer_size_callback);    if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)){        printf("Failed to initialize GLAD\n");    }    int success;    char infoLog[512];    unsigned int vertexShader = glCreateShader(GL_VERTEX_SHADER);    glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);    glCompileShader(vertexShader);    glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);    if (!success){        glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);        printf("Failed to compile vertexShader:%s\n", infoLog);    }    unsigned int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);    glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);    glCompileShader(fragmentShader);    glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);    if (!success){        glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog);        printf("Failed to compile fragmentShader:%s\n", infoLog);    }    unsigned int shaderProgram = glCreateProgram();    glAttachShader(shaderProgram, vertexShader);    glAttachShader(shaderProgram, fragmentShader);    glLinkProgram(shaderProgram);    glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);    if (!success){        glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);        printf("Failed to linkProgram:%s\n", infoLog);    }    glDeleteShader(vertexShader);    glDeleteShader(fragmentShader);    float vertices[] = {            -0.5f, -0.5f, 0.0f,            0.0f,  0.5f, 0.0f,            0.5f, -0.5f, 0.0f    };    unsigned int VBO, VAO;    glGenBuffers(1, &VBO);    glGenVertexArrays(1, &VAO);    glBindVertexArray(VAO);    glBindBuffer(GL_ARRAY_BUFFER, VBO);    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);    glEnableVertexAttribArray(0);//    glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);    while (!glfwWindowShouldClose(glfWwindow)){        glUseProgram(shaderProgram);        // 渲染        // 清除颜色缓冲        glClearColor(0.2f, 0.3f, 0.3f, 1.0f);        glClear(GL_COLOR_BUFFER_BIT);        //更换uniform颜色        /**         * 首先我们通过glfwGetTime()获取运行的秒数。然后我们使用sin函数让颜色在0.0到1.0之间改变,         * 最后将结果储存到greenValue里。         * 接着,我们用glGetUniformLocation查询uniform ourColor的位置值。         * 我们为查询函数提供着色器程序和uniform的名字(这是我们希望获得的位置值的来源)。         * 如果glGetUniformLocation返回-1就代表没有找到这个位置值。         * 最后,我们可以通过glUniform4f函数设置uniform值。         * 注意,查询uniform地址不要求你之前使用过着色器程序,但是更新一个uniform之前你必须先         * 使用程序(调用glUseProgram),因为它是在当前激活的着色器程序中设置uniform的。         * */        double timeValue = glfwGetTime();        double greenValue = sin(timeValue);        int vertexColorLocation = glGetUniformLocation(shaderProgram, "myColor");        glUniform4f(vertexColorLocation, 0.0f, greenValue, 0.0f, 1.0f);        glBindVertexArray(VAO);        glDrawArrays(GL_TRIANGLES, 0, 3);        glfwSwapBuffers(glfWwindow);        glfwPollEvents();    }    return 0;}void framebuffer_size_callback(GLFWwindow* glfWwindow, int width, int height){    glViewport(0, 0, width, height);}

运行结果:




阅读全文
1 0
原创粉丝点击