高级OPENGL, 利用uniform块接口

简介: 高级OPENGL, 利用uniform块接口

1.找到需要的uniform块的索引, 将程序对象的该uniform块索引绑定uniform 缓冲对象的绑定点

2.建立uniform缓冲对象,对象绑定GL_UNIFORM_BUFFER缓冲目标,为缓冲分配内存,将缓冲对象绑定到特定的绑定点,定义绑定点的缓冲范围

3.在渲染循环外绑定uniform块内不需更新的uniform,在渲染循环内绑定uniform块中需要更新的uniform

4.按正常思维,在渲染循环外或内,绑定不再uniform块中的uniform

下面是一个例子,将四个立方体平移到窗口的4个角,每个立方体显示不同的颜色

  1 //输入变量gl_FragCoord能让我们读取当前片段的窗口空间坐标,并获取它的深度值,但是它是一个只读(Read-only)变量。
  2 
  3 
  4 #define GLEW_STATIC
  5 
  6 #include <GL/glew.h>
  7 
  8 #include <GLFW/glfw3.h>
  9 #define STB_IMAGE_IMPLEMENTATION
 10 #include "stb_image.h"
 11 
 12 #include <glm/glm.hpp>
 13 #include <glm/gtc/matrix_transform.hpp>
 14 #include <glm/gtc/type_ptr.hpp>
 15 
 16 #include "Shader.h"
 17 #include "camera.h"
 18 //#include "Model.h"
 19 #include <fstream>
 20 #include <iostream>
 21 using namespace std;
 22 void framebuffer_size_callback(GLFWwindow* window, int width, int height);
 23 void mouse_callback(GLFWwindow* window, double xpos, double ypos);
 24 void scroll_callback(GLFWwindow* window, double xoffset, double yoffset);
 25 void processInput(GLFWwindow *window);
 26 unsigned int loadTexture(const char *path);
 27 
 28 // settings
 29 const unsigned int SCR_WIDTH = 800;
 30 const unsigned int SCR_HEIGHT = 600;
 31 
 32 // camera
 33 Camera camera(glm::vec3(0.0f, 0.0f, 3.0f));
 34 float lastX = (float)SCR_WIDTH / 2.0;
 35 float lastY = (float)SCR_HEIGHT / 2.0;
 36 bool firstMouse = true;
 37 
 38 // timing
 39 float deltaTime = 0.0f;
 40 float lastFrame = 0.0f;
 41 
 42 int main()
 43 {
 44     // glfw: initialize and configure
 45     // ------------------------------
 46     glfwInit();
 47     glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
 48     glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
 49     glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
 50 
 51 #ifdef __APPLE__
 52     glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // uncomment this statement to fix compilation on OS X
 53 #endif
 54 
 55                                                          // glfw window creation
 56                                                          // --------------------
 57     GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "LearnOpenGL", NULL, NULL);
 58     if (window == NULL)
 59     {
 60         std::cout << "Failed to create GLFW window" << std::endl;
 61         glfwTerminate();
 62         return -1;
 63     }
 64     glfwMakeContextCurrent(window);
 65     glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
 66     glfwSetCursorPosCallback(window, mouse_callback);
 67     glfwSetScrollCallback(window, scroll_callback);
 68 
 69     // tell GLFW to capture our mouse
 70     glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
 71 
 72     // glad: load all OpenGL function pointers
 73     // ---------------------------------------
 74     glewExperimental = GL_TRUE;
 75     if (glewInit() != GLEW_OK)
 76     {
 77         cout << "Failed to initialize GLEW!" << endl;
 78         return -1;
 79     }
 80     // configure global opengl state
 81     // -----------------------------
 82     glEnable(GL_DEPTH_TEST);
 83     glDepthFunc(GL_LESS);
 84 
 85     
 86 
 87     // build and compile shaders
 88     // -------------------------
 89     Shader shaderRed("E:\\C++\\High_level_GLSL\\1.7ver1.txt", "E:\\C++\\High_level_GLSL\\1.7frag1.txt");
 90     Shader shaderGreen("E:\\C++\\High_level_GLSL\\1.7ver1.txt", "E:\\C++\\High_level_GLSL\\1.7frag2.txt");
 91     Shader shaderBlue("E:\\C++\\High_level_GLSL\\1.7ver1.txt", "E:\\C++\\High_level_GLSL\\1.7frag3.txt");
 92     Shader shaderYellow("E:\\C++\\High_level_GLSL\\1.7ver1.txt", "E:\\C++\\High_level_GLSL\\1.7frag4.txt");
 93 
 94     // set up vertex data (and buffer(s)) and configure vertex attributes
 95     // ------------------------------------------------------------------
 96     float cubeVertices[] = {
 97 
 98         // positions          // texture Coords
 99         -0.5f, -0.5f, -0.5f, 
100         0.5f, -0.5f, -0.5f,  
101         0.5f,  0.5f, -0.5f,  
102         0.5f,  0.5f, -0.5f,  
103         -0.5f,  0.5f, -0.5f, 
104         -0.5f, -0.5f, -0.5f, 
105 
106         -0.5f, -0.5f,  0.5f,
107         0.5f, -0.5f,  0.5f, 
108         0.5f,  0.5f,  0.5f, 
109         0.5f,  0.5f,  0.5f, 
110         -0.5f,  0.5f,  0.5f,
111         -0.5f, -0.5f,  0.5f,
112 
113         -0.5f,  0.5f,  0.5f,
114         -0.5f,  0.5f, -0.5f,
115         -0.5f, -0.5f, -0.5f,
116         -0.5f, -0.5f, -0.5f,
117         -0.5f, -0.5f,  0.5f,
118         -0.5f,  0.5f,  0.5f,
119 
120         0.5f,  0.5f,  0.5f, 
121         0.5f,  0.5f, -0.5f, 
122         0.5f, -0.5f, -0.5f, 
123         0.5f, -0.5f, -0.5f, 
124         0.5f, -0.5f,  0.5f, 
125         0.5f,  0.5f,  0.5f, 
126 
127         -0.5f, -0.5f, -0.5f,
128         0.5f, -0.5f, -0.5f, 
129         0.5f, -0.5f,  0.5f, 
130         0.5f, -0.5f,  0.5f, 
131         -0.5f, -0.5f,  0.5f,
132         -0.5f, -0.5f, -0.5f,
133 
134         -0.5f,  0.5f, -0.5f,
135         0.5f,  0.5f, -0.5f,
136         0.5f,  0.5f,  0.5f,
137         0.5f,  0.5f,  0.5f,
138         -0.5f,  0.5f,  0.5f,
139         -0.5f,  0.5f, -0.5f
140     };
141     
142     float TexVertices[] = {
143 
144         // positions          // texture Coords
145         0.0f, 0.0f,
146         1.0f, 0.0f,
147         1.0f, 1.0f,
148         1.0f, 1.0f,
149         0.0f, 1.0f,
150         0.0f, 0.0f,
151 
152         0.0f, 0.0f,
153         1.0f, 0.0f,
154         1.0f, 1.0f,
155         1.0f, 1.0f,
156         0.0f, 1.0f,
157         0.0f, 0.0f,
158 
159         1.0f, 0.0f,
160         1.0f, 1.0f,
161         0.0f, 1.0f,
162         0.0f, 1.0f,
163         0.0f, 0.0f,
164         1.0f, 0.0f,
165 
166         1.0f, 0.0f,
167         1.0f, 1.0f,
168         0.0f, 1.0f,
169         0.0f, 1.0f,
170         0.0f, 0.0f,
171         1.0f, 0.0f,
172 
173         0.0f, 1.0f,
174         1.0f, 1.0f,
175         1.0f, 0.0f,
176         1.0f, 0.0f,
177         0.0f, 0.0f,
178         0.0f, 1.0f,
179 
180         0.0f, 1.0f,
181         1.0f, 1.0f,
182         1.0f, 0.0f,
183         1.0f, 0.0f,
184         0.0f, 0.0f,
185         0.0f, 1.0f
186     };
187 
188 
189     // cube VAO
190     unsigned int cubeVAO, cubeVBO;
191     glGenVertexArrays(1, &cubeVAO);
192     glGenBuffers(1, &cubeVBO);
193     glBindVertexArray(cubeVAO);
194     glBindBuffer(GL_ARRAY_BUFFER, cubeVBO);
195     glBufferData(GL_ARRAY_BUFFER, sizeof(cubeVertices), NULL, GL_STATIC_DRAW);
196     glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(cubeVertices), &cubeVertices);
197     glEnableVertexAttribArray(0);
198     glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
199     glBindVertexArray(0);
200 
201     //first ,we get the relevant block indices
202     unsigned int uniformBlockIndexRed = glGetUniformBlockIndex(shaderRed.ID, "Matrices");
203     unsigned int uniformBlockIndexGreen = glGetUniformBlockIndex(shaderGreen.ID, "Matrices");
204     unsigned int uniformBlockIndexBlue = glGetUniformBlockIndex(shaderBlue.ID, "Matrices");
205     unsigned int uniformBlockIndexYellow = glGetUniformBlockIndex(shaderYellow.ID, "Matrices");
206 
207     //then we link each uniform block to this uniform binding point
208     glUniformBlockBinding(shaderRed.ID, uniformBlockIndexRed, 0);
209     glUniformBlockBinding(shaderGreen.ID, uniformBlockIndexGreen, 0);
210     glUniformBlockBinding(shaderBlue.ID, uniformBlockIndexBlue, 0);
211     glUniformBlockBinding(shaderYellow.ID, uniformBlockIndexYellow, 0);
212 
213     //Now actually create the buffer
214     unsigned int uboMatrices;
215     glGenBuffers(1, &uboMatrices);
216     glBindBuffer(GL_UNIFORM_BUFFER, uboMatrices);
217     glBufferData(GL_UNIFORM_BUFFER, 2 * sizeof(glm::mat4), NULL, GL_STATIC_DRAW); 
218     glBindBuffer(GL_UNIFORM_BUFFER, 0);
219     //define the range of the buffer that links to a uniform binging point
220     glBindBufferRange(GL_UNIFORM_BUFFER, 0, uboMatrices, 0, 2 * sizeof(glm::mat4));
221 
222     //store the projection matrix (we only do this once now)(note: we're not using Zoom anymore by changeing the FOV)
223     glm::mat4 projection = glm::perspective(45.0f, (float)SCR_WIDTH / (float)SCR_HEIGHT, 0.1f, 100.0f);
224     glBindBuffer(GL_UNIFORM_BUFFER, uboMatrices);
225     glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(glm::mat4), glm::value_ptr(projection));
226     glBindBuffer(GL_UNIFORM_BUFFER, 0);
227 
228     //unsigned int frontTexture = loadTexture("greenWall.jpg");
229     //unsigned int backTexture = loadTexture("greenWall.jpg");
230 
231     //shader.use();
232     //shader.setInt("frontTexture", 0);
233     ////shader.setInt("backTexture", backTexture);
234     //glUniform1i(glGetUniformLocation(shader.ID, "frontTexture"), 1);
235 
236     ////创建一个uniform缓冲对象
237     //unsigned int uboExampleBlock;
238     //glGenBuffers(1, &uboExampleBlock);
239     //glBindBuffer(GL_UNIFORM_BUFFER, uboExampleBlock);
240     //glBufferData(GL_UNIFORM_BUFFER, 152, NULL, GL_STATIC_DRAW);        //分配152字节的缓冲内存
241     //glBindBuffer(GL_UNIFORM_BUFFER, 0);
242     ////为了将Uniform块绑定到一个特定的绑定点中,我们需要调用glUniformBlockBinding函数,
243     ////它的第一个参数是一个程序对象,之后是一个Uniform块索引和链接到的绑定点,
244     ////Uniform块索引(uniform bloack index )是着色器中已定义Uniform块的位置值索引,这可以通过调用glGetUniformBlockIndex来获取
245     ////它接受一个程序对象和uniform块的名称
246     //unsigned int lights_index = glGetUniformBlockIndex(shader.ID, "Light");
247     //glUniformBlockBinding(shader.ID, lights_index, 2);
248     //
249     ////接下来,我们还需要绑定Uniform缓冲对象到相同的绑定点上,这可以使用glBindBufferBase或glBindBufferRange来完成
250     //glBindBufferBase(GL_UNIFORM_BUFFER, 2, uboExampleBlock);    //该函数需要一个目标,一个绑定点索引和一个uniform缓冲对象作为它的参数
251     ////glBindBufferRange(GL_UNIFORM_BUFFER, 2, uboExampleBlock, 0, 152);
252 
253     ////向uniform缓冲中添加数据
254     //glBindBuffer(GL_UNIFORM_BUFFER, uboExampleBlock);
255     //int b = true;    //GLSL中的bool是4字节的,所以我们将它存为一个integer
256     //glBufferSubData(GL_UNIFORM_BUFFER, 144, 4, &b);
257     //glBindBuffer(GL_UNIFORM_BUFFER, 0);
258 
259     // render loop
260     // -----------
261     while (!glfwWindowShouldClose(window))
262     {
263         // per-frame time logic
264         // --------------------
265         float currentFrame = glfwGetTime();
266         deltaTime = currentFrame - lastFrame;
267         lastFrame = currentFrame;
268 
269         processInput(window);
270 
271         glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
272         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); // don't forget to clear the stencil buffer!
273 
274         //set the view and projection matrix in the uniform block
275         glm::mat4 view = camera.GetViewMatrix();
276         glBindBuffer(GL_UNIFORM_BUFFER, uboMatrices);
277         glBufferSubData(GL_UNIFORM_BUFFER, sizeof(glm::mat4), sizeof(glm::mat4), glm::value_ptr(view));
278         glBindBuffer(GL_UNIFORM_BUFFER, 0);
279 
280         //draw 4 cubes
281         //RED
282         glBindVertexArray(cubeVAO);
283         shaderRed.use();
284         glm::mat4 model;
285         model = glm::translate(model, glm::vec3(-0.75f, 0.75f, 0.0f));    //move top-left
286         shaderRed.setMat4("model", model);
287         glDrawArrays(GL_TRIANGLES, 0, 36);
288 
289         //GREEN
290         shaderGreen.use();
291         model = glm::mat4();
292         model = glm::translate(model, glm::vec3(0.75f, 0.75f, 0.0f));    //move top-right
293         shaderGreen.setMat4("model", model);
294         glDrawArrays(GL_TRIANGLES, 0, 36);
295 
296         shaderYellow.use();
297         model = glm::mat4();
298         model = glm::translate(model, glm::vec3(-0.75f, -0.75f, 0.0f));    //move bottom-left
299         shaderYellow.setMat4("model", model);
300         glDrawArrays(GL_TRIANGLES, 0, 36);
301 
302         shaderBlue.use();
303         model = glm::mat4();
304         model = glm::translate(model, glm::vec3(0.75f, -0.75f, 0.0f));    //move bottom-right
305         shaderBlue.setMat4("model", model);
306         glDrawArrays(GL_TRIANGLES, 0, 36);
307         
308 
309         glfwSwapBuffers(window);
310         glfwPollEvents();
311     }
312 
313     // optional: de-allocate all resources once they've outlived their purpose:
314     // ------------------------------------------------------------------------
315     glDeleteVertexArrays(1, &cubeVAO);
316     
317     glDeleteBuffers(1, &cubeVBO);
318     
319 
320     glfwTerminate();
321     return 0;
322 }
323 
324 // process all input: query GLFW whether relevant keys are pressed/released this frame and react accordingly
325 // ---------------------------------------------------------------------------------------------------------
326 void processInput(GLFWwindow *window)
327 {
328     if (glfwGetKey(window, GLFW_KEY_ENTER) == GLFW_PRESS)
329         glfwSetWindowShouldClose(window, true);
330 
331     if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS)
332         camera.ProcessKeyboard(FORWARD, deltaTime);
333     if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS)
334         camera.ProcessKeyboard(BACKWARD, deltaTime);
335     if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS)
336         camera.ProcessKeyboard(LEFT, deltaTime);
337     if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS)
338         camera.ProcessKeyboard(RIGHT, deltaTime);
339 }
340 
341 // glfw: whenever the window size changed (by OS or user resize) this callback function executes
342 // ---------------------------------------------------------------------------------------------
343 void framebuffer_size_callback(GLFWwindow* window, int width, int height)
344 {
345     // make sure the viewport matches the new window dimensions; note that width and 
346     // height will be significantly larger than specified on retina displays.
347     glViewport(0, 0, width, height);
348 }
349 
350 // glfw: whenever the mouse moves, this callback is called
351 // -------------------------------------------------------
352 void mouse_callback(GLFWwindow* window, double xpos, double ypos)
353 {
354     if (firstMouse)
355     {
356         lastX = xpos;
357         lastY = ypos;
358         firstMouse = false;
359     }
360 
361     float xoffset = xpos - lastX;
362     float yoffset = lastY - ypos; // reversed since y-coordinates go from bottom to top
363 
364     lastX = xpos;
365     lastY = ypos;
366 
367 
368 
369 
370     camera.ProcessMouseMovement(xoffset, yoffset);
371 }
372 
373 // glfw: whenever the mouse scroll wheel scrolls, this callback is called
374 // ----------------------------------------------------------------------
375 void scroll_callback(GLFWwindow* window, double xoffset, double yoffset)
376 {
377     camera.ProcessMouseScroll(yoffset);
378 }
379 
380 // utility function for loading a 2D texture from file
381 // ---------------------------------------------------
382 unsigned int loadTexture(char const * path)
383 {
384     unsigned int textureID;
385     glGenTextures(1, &textureID);
386 
387     int width, height, nrComponents;
388     unsigned char *data = stbi_load(path, &width, &height, &nrComponents, 0);
389     if (data)
390     {
391         GLenum format;
392         if (nrComponents == 1)
393             format = GL_RED;
394         else if (nrComponents == 3)
395             format = GL_RGB;
396         else if (nrComponents == 4)
397             format = GL_RGBA;
398 
399         glBindTexture(GL_TEXTURE_2D, textureID);
400         glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format, GL_UNSIGNED_BYTE, data);
401         glGenerateMipmap(GL_TEXTURE_2D);
402 
403         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
404         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
405         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
406         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
407 
408         stbi_image_free(data);
409     }
410     else
411     {
412         std::cout << "Texture failed to load at path: " << path << std::endl;
413         stbi_image_free(data);
414     }
415 
416     return textureID;
417 }
1456655-20180923111741550-352618129.jpg


相关文章
|
索引 存储 Windows
opengl 教程(5) shader(2) uniform变量
原帖地址:http://ogldev.atspace.co.uk/www/tutorial05/tutorial05.html         在这篇教程中,我们将接触到一种新的shader变量uniform variables,这种变量和属性变量的区别:属性变量是指每个顶点shader调用时,都会根据属性的位置从顶点缓冲中装入该顶点的相应属性值,而uniform变量,则对每个draw调用保持不变,这意味着你在draw调用前装入该变量,然后draw中每个顶点shader执行时,都能访问该变量,而且该变量值会保持不变。
965 0
|
6月前
|
XML 小程序 Java
【Android App】三维投影OpenGL ES的讲解及着色器实现(附源码和演示 超详细)
【Android App】三维投影OpenGL ES的讲解及着色器实现(附源码和演示 超详细)
126 0
|
缓存 C++
Opengl ES之FBO
Opengl ES连载系列
152 0
|
存储 编解码 算法
Opengl ES之LUT滤镜(上)
Opengl ES之连载系列
459 0
|
数据安全/隐私保护 开发者
OpenGL ES 多目标渲染(MRT)
Opengl ES连载系列
323 0
|
数据安全/隐私保护 索引
Opengl ES之纹理数组
Opengl ES连载系列
259 0
|
数据安全/隐私保护
Opengl ES之水印贴图
Opengl ES之连载系列
152 0
|
Java 数据安全/隐私保护 Android开发
Opengl ES之矩阵变换(下)
Opengl ES连载系列
132 0
|
Java API 数据安全/隐私保护
Opengl ES之矩阵变换(上)
Opengl ES连载系列
149 0