openGL学习<四>、着色器

  1 //
  2 // Created by sry on 2021/7/6.
  3 //
  4 #include <glad/glad.h>
  5 #include <GLFW/glfw3.h>
  6 #include<iostream>
  7 #include<cmath>
  8 using namespace std;
  9 
 10 void framebuffer_size_callback(GLFWwindow* window, int width, int height)
 11 {
 12     glViewport(0, 0, width, height);  // opengl_frame glfw_frame new_frame,知道为啥有这么多JB帧了吧
 13 }
 14 /*
 15  *
 16  * 这里我们检查用户是否按下了返回键(Esc)(如果没有按下,glfwGetKey将会返回GLFW_RELEASE。
 17  * 如果用户的确按下了返回键,我们将通过glfwSetwindowShouldClose使用把WindowShouldClose属性设置为 true的方法关闭GLFW。
 18  *
 19  * */
 20 void processInput(GLFWwindow *window)
 21 {
 22     if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
 23         glfwSetWindowShouldClose(window, true);
 24 }
 25 
 26 // glsl 渲染语言,这和C++调用Matlab差不多
 27 const char *vertexShaderSource = "#version 330 core\n"
 28                                  "layout (location = 0) in vec3 aPos;\n"
 29                                  "void main()\n"
 30                                  "{\n"
 31                                  "   gl_Position = vec4(aPos, 1.0);\n"
 32                                  "}\0";
 33 
 34 const char *fragmentShaderSource = "#version 330 core\n"
 35                                    "out vec4 FragColor;\n"
 36                                    "uniform vec4 ourColor;\n"
 37                                    "void main()\n"
 38                                    "{\n"
 39                                    "   FragColor = ourColor;\n"
 40                                    "}\n\0";
 41 
 42 int main()
 43 {
 44     // <1>、初始化GLFW
 45     glfwInit();
 46     glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); // opengl3.3
 47     glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
 48     glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // 只用核心通用模块
 49 
 50     // <2>、glfw窗口创建
 51     GLFWwindow* window = glfwCreateWindow(800, 600, "shiruiyu", NULL, NULL);
 52     if (window == NULL)
 53     {
 54         cout << "fuck" << endl;
 55         glfwTerminate(); // Release
 56         return -1;
 57     }
 58     glfwMakeContextCurrent(window); // 通知GLFW将我们窗口的上下文设置为当前线程的主上下文了。
 59     /*
 60      * 告诉OpenGL渲染窗口的尺寸大小
 61      * OpenGL坐标范围只为-1到1,因此我们事实上将(-1到1)范围内的坐标映射到(0, 800)和(0, 600)。
 62      * */
 63     // 对窗口注册一个回调函数(Callback Function),它会在每次窗口大小被调整的时候被调用
 64     glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
 65     /*
 66      * <3>、利用glad加载所有OpenGL函数地址
 67      * GLAD是用来管理OpenGL的函数指针的,所以在调用任何OpenGL的函数之前我们需要初始化GLAD
 68      * */
 69     if (!gladLoadGLLoader((GLADloadproc) glfwGetProcAddress))
 70     {
 71         cout << "Failed to init GLAD" << endl;
 72         return -1;
 73     }
 74     // <4>、构建、编译shader program
 75     // 创建顶点渲染器,vertex shader
 76     unsigned int vertexShader = glCreateShader(GL_VERTEX_SHADER);
 77     glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
 78     glCompileShader(vertexShader);
 79     // 验证渲染器是否正常
 80     int success = 0;
 81     char infoLog[512];
 82     glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
 83     if (!success)
 84     {
 85         glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);
 86         std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl;
 87     }
 88     // 创建线段渲染器,fragment shader
 89     unsigned int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
 90     glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
 91     glCompileShader(fragmentShader);
 92     // 验证渲染器是否正常
 93     success = 0;
 94     glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
 95     if (!success)
 96     {
 97         glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog);
 98         std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl;
 99     }
100     // 链接渲染器,link shaders
101     unsigned int shaderProgram = glCreateProgram();
102     glAttachShader(shaderProgram, vertexShader);
103     glAttachShader(shaderProgram, fragmentShader);
104     glLinkProgram(shaderProgram);
105     // 检测链接错误
106     success = 0;
107     glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
108     if (!success)
109     {
110         glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);
111         std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl;
112     }
113     glDeleteShader(vertexShader);
114     glDeleteShader(fragmentShader);
115 
116     // set up vertex data (and buffer(s)) and configure vertex attributes
117     // ------------------------------------------------------------------
118     float vertices[] = {
119             -0.5f, -0.5f, 0.0f, // left
120             0.5f, -0.5f, 0.0f, // right
121             0.0f,  0.5f, 0.0f  // top
122     };
123     unsigned int VBO, VAO; // ???
124     glGenVertexArrays(1, &VAO);
125     glGenBuffers(1, &VBO);
126     // bind the Vertex Array Object first, then bind and set vertex buffer(s), and then configure vertex attributes(s).
127     glBindVertexArray(VAO);
128 
129     glBindBuffer(GL_ARRAY_BUFFER, VBO);
130     glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
131 
132     glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
133     glEnableVertexAttribArray(0);
134 
135     // note that this is allowed, the call to glVertexAttribPointer registered VBO as the vertex attribute's bound vertex buffer object so afterwards we can safely unbind
136     glBindBuffer(GL_ARRAY_BUFFER, 0);
137     // You can unbind the VAO afterwards so other VAO calls won't accidentally modify this VAO, but this rarely happens. Modifying other
138     // VAOs requires a call to glBindVertexArray anyways so we generally don't unbind VAOs (nor VBOs) when it's not directly necessary.
139     glBindVertexArray(0);
140 
141     // 循环渲染
142     while(!glfwWindowShouldClose(window)) // 检查一次GLFW是否被要求退出
143     {
144         // 输入
145         processInput(window);
146 
147         // 渲染指令
148         // 清除颜色缓冲
149         glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
150         glClear(GL_COLOR_BUFFER_BIT);
151         // 激活着色器
152         glUseProgram(shaderProgram);
153 
154         // 更新uniform颜色
155         float timeValue = glfwGetTime();
156         float greenValue = std::sin(timeValue)/2.0f + 0.5f;
157         int vertexColorLocation = glGetUniformLocation(shaderProgram, "ourColor");
158         glUniform4f(vertexColorLocation, 0.0f, greenValue, 0.0f, 1.0f);
159 
160 
161         // 画第一个三角形
162 
163         glBindVertexArray(VAO);
164         glDrawArrays(GL_TRIANGLES, 0, 3);// Primitive:GL_POINTS、GL_TRIANGLES、GL_LINE_STRIP
165 
166 
167 
168 
169 
170         // 检查并调用事件,交换缓冲
171         glfwPollEvents(); // 检查有没有触发什么事件(比如键盘输入、鼠标移动等)、更新窗口状态,并调用对应的回调函数(可以通过回调方法手动设置)。
172         glfwSwapBuffers(window); // 函数会交换颜色缓冲(它是一个储存着GLFW窗口每一个像素颜色值的大缓冲),它在这一迭代中被用来绘制,并且将会作为输出显示在屏幕上。
173 
174     }
175 
176     glDeleteVertexArrays(1, &VAO);
177     glDeleteBuffers(1, &VBO);
178     glDeleteProgram(shaderProgram);
179 
180     // release
181     glfwTerminate();
182 
183     return 0;
184 }

 

posted @ 2023-09-30 09:56  佚名12  阅读(16)  评论(0编辑  收藏  举报