• 高级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 }

    学习网址:https://learnopengl-cn.github.io/04%20Advanced%20OpenGL/08%20Advanced%20GLSL/

  • 相关阅读:
    新的开始!
    find命令之mtime
    glances服务器监控工具
    centos7最小化安装改为图形界面
    ansible笔记(3)-文件操作模块(上)
    php-fpm参数详解
    ansible笔记(2)-模块简介
    centos创建交换分区
    等保测评三级整改-身份鉴别
    vsftp安装配置
  • 原文地址:https://www.cnblogs.com/hi3254014978/p/9692250.html
Copyright © 2020-2023  润新知