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

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

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

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

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

 //输入变量gl_FragCoord能让我们读取当前片段的窗口空间坐标,并获取它的深度值,但是它是一个只读(Read-only)变量。

 #define GLEW_STATIC

 #include <GL/glew.h>

 #include <GLFW/glfw3.h>
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h" #include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp> #include "Shader.h"
#include "camera.h"
//#include "Model.h"
#include <fstream>
#include <iostream>
using namespace std;
void framebuffer_size_callback(GLFWwindow* window, int width, int height);
void mouse_callback(GLFWwindow* window, double xpos, double ypos);
void scroll_callback(GLFWwindow* window, double xoffset, double yoffset);
void processInput(GLFWwindow *window);
unsigned int loadTexture(const char *path); // settings
const unsigned int SCR_WIDTH = ;
const unsigned int SCR_HEIGHT = ; // camera
Camera camera(glm::vec3(0.0f, 0.0f, 3.0f));
float lastX = (float)SCR_WIDTH / 2.0;
float lastY = (float)SCR_HEIGHT / 2.0;
bool firstMouse = true; // timing
float deltaTime = 0.0f;
float lastFrame = 0.0f; int main()
{
// glfw: initialize and configure
// ------------------------------
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, );
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, );
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); #ifdef __APPLE__
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // uncomment this statement to fix compilation on OS X
#endif // glfw window creation
// --------------------
GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "LearnOpenGL", NULL, NULL);
if (window == NULL)
{
std::cout << "Failed to create GLFW window" << std::endl;
glfwTerminate();
return -;
}
glfwMakeContextCurrent(window);
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
glfwSetCursorPosCallback(window, mouse_callback);
glfwSetScrollCallback(window, scroll_callback); // tell GLFW to capture our mouse
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); // glad: load all OpenGL function pointers
// ---------------------------------------
glewExperimental = GL_TRUE;
if (glewInit() != GLEW_OK)
{
cout << "Failed to initialize GLEW!" << endl;
return -;
}
// configure global opengl state
// -----------------------------
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS); // build and compile shaders
// -------------------------
Shader shaderRed("E:\\C++\\High_level_GLSL\\1.7ver1.txt", "E:\\C++\\High_level_GLSL\\1.7frag1.txt");
Shader shaderGreen("E:\\C++\\High_level_GLSL\\1.7ver1.txt", "E:\\C++\\High_level_GLSL\\1.7frag2.txt");
Shader shaderBlue("E:\\C++\\High_level_GLSL\\1.7ver1.txt", "E:\\C++\\High_level_GLSL\\1.7frag3.txt");
Shader shaderYellow("E:\\C++\\High_level_GLSL\\1.7ver1.txt", "E:\\C++\\High_level_GLSL\\1.7frag4.txt"); // set up vertex data (and buffer(s)) and configure vertex attributes
// ------------------------------------------------------------------
float cubeVertices[] = { // positions // texture Coords
-0.5f, -0.5f, -0.5f,
0.5f, -0.5f, -0.5f,
0.5f, 0.5f, -0.5f,
0.5f, 0.5f, -0.5f,
-0.5f, 0.5f, -0.5f,
-0.5f, -0.5f, -0.5f, -0.5f, -0.5f, 0.5f,
0.5f, -0.5f, 0.5f,
0.5f, 0.5f, 0.5f,
0.5f, 0.5f, 0.5f,
-0.5f, 0.5f, 0.5f,
-0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f,
-0.5f, 0.5f, -0.5f,
-0.5f, -0.5f, -0.5f,
-0.5f, -0.5f, -0.5f,
-0.5f, -0.5f, 0.5f,
-0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f,
0.5f, 0.5f, -0.5f,
0.5f, -0.5f, -0.5f,
0.5f, -0.5f, -0.5f,
0.5f, -0.5f, 0.5f,
0.5f, 0.5f, 0.5f, -0.5f, -0.5f, -0.5f,
0.5f, -0.5f, -0.5f,
0.5f, -0.5f, 0.5f,
0.5f, -0.5f, 0.5f,
-0.5f, -0.5f, 0.5f,
-0.5f, -0.5f, -0.5f, -0.5f, 0.5f, -0.5f,
0.5f, 0.5f, -0.5f,
0.5f, 0.5f, 0.5f,
0.5f, 0.5f, 0.5f,
-0.5f, 0.5f, 0.5f,
-0.5f, 0.5f, -0.5f
}; float TexVertices[] = { // positions // texture Coords
0.0f, 0.0f,
1.0f, 0.0f,
1.0f, 1.0f,
1.0f, 1.0f,
0.0f, 1.0f,
0.0f, 0.0f, 0.0f, 0.0f,
1.0f, 0.0f,
1.0f, 1.0f,
1.0f, 1.0f,
0.0f, 1.0f,
0.0f, 0.0f, 1.0f, 0.0f,
1.0f, 1.0f,
0.0f, 1.0f,
0.0f, 1.0f,
0.0f, 0.0f,
1.0f, 0.0f, 1.0f, 0.0f,
1.0f, 1.0f,
0.0f, 1.0f,
0.0f, 1.0f,
0.0f, 0.0f,
1.0f, 0.0f, 0.0f, 1.0f,
1.0f, 1.0f,
1.0f, 0.0f,
1.0f, 0.0f,
0.0f, 0.0f,
0.0f, 1.0f, 0.0f, 1.0f,
1.0f, 1.0f,
1.0f, 0.0f,
1.0f, 0.0f,
0.0f, 0.0f,
0.0f, 1.0f
}; // cube VAO
unsigned int cubeVAO, cubeVBO;
glGenVertexArrays(, &cubeVAO);
glGenBuffers(, &cubeVBO);
glBindVertexArray(cubeVAO);
glBindBuffer(GL_ARRAY_BUFFER, cubeVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(cubeVertices), NULL, GL_STATIC_DRAW);
glBufferSubData(GL_ARRAY_BUFFER, , sizeof(cubeVertices), &cubeVertices);
glEnableVertexAttribArray();
glVertexAttribPointer(, , GL_FLOAT, GL_FALSE, * sizeof(float), (void*));
glBindVertexArray(); //first ,we get the relevant block indices
unsigned int uniformBlockIndexRed = glGetUniformBlockIndex(shaderRed.ID, "Matrices");
unsigned int uniformBlockIndexGreen = glGetUniformBlockIndex(shaderGreen.ID, "Matrices");
unsigned int uniformBlockIndexBlue = glGetUniformBlockIndex(shaderBlue.ID, "Matrices");
unsigned int uniformBlockIndexYellow = glGetUniformBlockIndex(shaderYellow.ID, "Matrices"); //then we link each uniform block to this uniform binding point
glUniformBlockBinding(shaderRed.ID, uniformBlockIndexRed, );
glUniformBlockBinding(shaderGreen.ID, uniformBlockIndexGreen, );
glUniformBlockBinding(shaderBlue.ID, uniformBlockIndexBlue, );
glUniformBlockBinding(shaderYellow.ID, uniformBlockIndexYellow, ); //Now actually create the buffer
unsigned int uboMatrices;
glGenBuffers(, &uboMatrices);
glBindBuffer(GL_UNIFORM_BUFFER, uboMatrices);
glBufferData(GL_UNIFORM_BUFFER, * sizeof(glm::mat4), NULL, GL_STATIC_DRAW);
glBindBuffer(GL_UNIFORM_BUFFER, );
//define the range of the buffer that links to a uniform binging point
glBindBufferRange(GL_UNIFORM_BUFFER, , uboMatrices, , * sizeof(glm::mat4)); //store the projection matrix (we only do this once now)(note: we're not using Zoom anymore by changeing the FOV)
glm::mat4 projection = glm::perspective(45.0f, (float)SCR_WIDTH / (float)SCR_HEIGHT, 0.1f, 100.0f);
glBindBuffer(GL_UNIFORM_BUFFER, uboMatrices);
glBufferSubData(GL_UNIFORM_BUFFER, , sizeof(glm::mat4), glm::value_ptr(projection));
glBindBuffer(GL_UNIFORM_BUFFER, ); //unsigned int frontTexture = loadTexture("greenWall.jpg");
//unsigned int backTexture = loadTexture("greenWall.jpg"); //shader.use();
//shader.setInt("frontTexture", 0);
////shader.setInt("backTexture", backTexture);
//glUniform1i(glGetUniformLocation(shader.ID, "frontTexture"), 1); ////创建一个uniform缓冲对象
//unsigned int uboExampleBlock;
//glGenBuffers(1, &uboExampleBlock);
//glBindBuffer(GL_UNIFORM_BUFFER, uboExampleBlock);
//glBufferData(GL_UNIFORM_BUFFER, 152, NULL, GL_STATIC_DRAW); //分配152字节的缓冲内存
//glBindBuffer(GL_UNIFORM_BUFFER, 0);
////为了将Uniform块绑定到一个特定的绑定点中,我们需要调用glUniformBlockBinding函数,
////它的第一个参数是一个程序对象,之后是一个Uniform块索引和链接到的绑定点,
////Uniform块索引(uniform bloack index )是着色器中已定义Uniform块的位置值索引,这可以通过调用glGetUniformBlockIndex来获取
////它接受一个程序对象和uniform块的名称
//unsigned int lights_index = glGetUniformBlockIndex(shader.ID, "Light");
//glUniformBlockBinding(shader.ID, lights_index, 2);
//
////接下来,我们还需要绑定Uniform缓冲对象到相同的绑定点上,这可以使用glBindBufferBase或glBindBufferRange来完成
//glBindBufferBase(GL_UNIFORM_BUFFER, 2, uboExampleBlock); //该函数需要一个目标,一个绑定点索引和一个uniform缓冲对象作为它的参数
////glBindBufferRange(GL_UNIFORM_BUFFER, 2, uboExampleBlock, 0, 152); ////向uniform缓冲中添加数据
//glBindBuffer(GL_UNIFORM_BUFFER, uboExampleBlock);
//int b = true; //GLSL中的bool是4字节的,所以我们将它存为一个integer
//glBufferSubData(GL_UNIFORM_BUFFER, 144, 4, &b);
//glBindBuffer(GL_UNIFORM_BUFFER, 0); // render loop
// -----------
while (!glfwWindowShouldClose(window))
{
// per-frame time logic
// --------------------
float currentFrame = glfwGetTime();
deltaTime = currentFrame - lastFrame;
lastFrame = currentFrame; processInput(window); glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); // don't forget to clear the stencil buffer! //set the view and projection matrix in the uniform block
glm::mat4 view = camera.GetViewMatrix();
glBindBuffer(GL_UNIFORM_BUFFER, uboMatrices);
glBufferSubData(GL_UNIFORM_BUFFER, sizeof(glm::mat4), sizeof(glm::mat4), glm::value_ptr(view));
glBindBuffer(GL_UNIFORM_BUFFER, ); //draw 4 cubes
//RED
glBindVertexArray(cubeVAO);
shaderRed.use();
glm::mat4 model;
model = glm::translate(model, glm::vec3(-0.75f, 0.75f, 0.0f)); //move top-left
shaderRed.setMat4("model", model);
glDrawArrays(GL_TRIANGLES, , ); //GREEN
shaderGreen.use();
model = glm::mat4();
model = glm::translate(model, glm::vec3(0.75f, 0.75f, 0.0f)); //move top-right
shaderGreen.setMat4("model", model);
glDrawArrays(GL_TRIANGLES, , ); shaderYellow.use();
model = glm::mat4();
model = glm::translate(model, glm::vec3(-0.75f, -0.75f, 0.0f)); //move bottom-left
shaderYellow.setMat4("model", model);
glDrawArrays(GL_TRIANGLES, , ); shaderBlue.use();
model = glm::mat4();
model = glm::translate(model, glm::vec3(0.75f, -0.75f, 0.0f)); //move bottom-right
shaderBlue.setMat4("model", model);
glDrawArrays(GL_TRIANGLES, , ); glfwSwapBuffers(window);
glfwPollEvents();
} // optional: de-allocate all resources once they've outlived their purpose:
// ------------------------------------------------------------------------
glDeleteVertexArrays(, &cubeVAO); glDeleteBuffers(, &cubeVBO); glfwTerminate();
return ;
} // process all input: query GLFW whether relevant keys are pressed/released this frame and react accordingly
// ---------------------------------------------------------------------------------------------------------
void processInput(GLFWwindow *window)
{
if (glfwGetKey(window, GLFW_KEY_ENTER) == GLFW_PRESS)
glfwSetWindowShouldClose(window, true); if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS)
camera.ProcessKeyboard(FORWARD, deltaTime);
if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS)
camera.ProcessKeyboard(BACKWARD, deltaTime);
if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS)
camera.ProcessKeyboard(LEFT, deltaTime);
if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS)
camera.ProcessKeyboard(RIGHT, deltaTime);
} // glfw: whenever the window size changed (by OS or user resize) this callback function executes
// ---------------------------------------------------------------------------------------------
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{
// make sure the viewport matches the new window dimensions; note that width and
// height will be significantly larger than specified on retina displays.
glViewport(, , width, height);
} // glfw: whenever the mouse moves, this callback is called
// -------------------------------------------------------
void mouse_callback(GLFWwindow* window, double xpos, double ypos)
{
if (firstMouse)
{
lastX = xpos;
lastY = ypos;
firstMouse = false;
} float xoffset = xpos - lastX;
float yoffset = lastY - ypos; // reversed since y-coordinates go from bottom to top lastX = xpos;
lastY = ypos; camera.ProcessMouseMovement(xoffset, yoffset);
} // glfw: whenever the mouse scroll wheel scrolls, this callback is called
// ----------------------------------------------------------------------
void scroll_callback(GLFWwindow* window, double xoffset, double yoffset)
{
camera.ProcessMouseScroll(yoffset);
} // utility function for loading a 2D texture from file
// ---------------------------------------------------
unsigned int loadTexture(char const * path)
{
unsigned int textureID;
glGenTextures(, &textureID); int width, height, nrComponents;
unsigned char *data = stbi_load(path, &width, &height, &nrComponents, );
if (data)
{
GLenum format;
if (nrComponents == )
format = GL_RED;
else if (nrComponents == )
format = GL_RGB;
else if (nrComponents == )
format = GL_RGBA; glBindTexture(GL_TEXTURE_2D, textureID);
glTexImage2D(GL_TEXTURE_2D, , format, width, height, , format, GL_UNSIGNED_BYTE, data);
glGenerateMipmap(GL_TEXTURE_2D); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); stbi_image_free(data);
}
else
{
std::cout << "Texture failed to load at path: " << path << std::endl;
stbi_image_free(data);
} return textureID;
}

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

高级OPENGL, 利用uniform块接口的更多相关文章

  1. OpenGL ES 中Uniform块

    1.采用uniform Block的原因如果你的程序中包含了多个着色器,而且这些着色器使用了相同的Uniform变量,你就不得不为每个着色器分别管理这些变量.Uniform变量的location是在程 ...

  2. CSharpGL(33)使用uniform块来优化对uniform变量的读写

    CSharpGL(33)使用uniform块来优化对uniform变量的读写 +BIT祝威+悄悄在此留下版了个权的信息说: Uniform块 如果shader程序变得比较复杂,那么其中用到的unifo ...

  3. 利用jQuery扩展接口为jQuery框架定义了两个自定义函数,然后调用这两个函数

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  4. 利用阿里大于接口发短信(Delphi版)

    阿里大于是阿里通信旗下产品,融合了三大运营商的通信能力,提供包括短信.语音.流量直充.私密专线.店铺手机号等个性化服务.每条四分五,价钱还算公道,经老农测试,响应速度非常快,基本上是秒到.官方文档提供 ...

  5. 第三百三十五节,web爬虫讲解2—Scrapy框架爬虫—豆瓣登录与利用打码接口实现自动识别验证码

    第三百三十五节,web爬虫讲解2—Scrapy框架爬虫—豆瓣登录与利用打码接口实现自动识别验证码 打码接口文件 # -*- coding: cp936 -*- import sys import os ...

  6. java实现利用httpclient访问接口

    HTTP协议时Internet上使用的很多也很重要的一个协议,越来越多的java应用程序需要通过HTTP协议来访问网络资源. HTTPClient提供的主要功能: 1.实现了所有HTTP的方法(GET ...

  7. 利用Fiddler拦截接口请求并篡改数据

    近期在测试一个下单的项目,出于安全角度考虑,测试了一个场景,那就是利用工具对接口进行拦截并篡改数据.将接口一拦截并篡改数据后,发现收货满满.开发默默接受了我的建议,并对代码进行了修改. 对于fiddl ...

  8. 利用Kettle转储接口数据

    1.     项目背景 1.1.  项目背景 数据接口 API:应用程序接口(Application Program Interface)的简称,是实现计算机软件之间数据通信的工具.同时API也是一种 ...

  9. UVa 1103 (利用连通块来判断字符) Ancient Messages

    本题就是灵活运用DFS来求连通块来求解的. 题意: 给出一幅黑白图像,每行相邻的四个点压缩成一个十六进制的字符.然后还有题中图示的6中古老的字符,按字母表顺序输出这些字符的标号. 分析: 首先图像是被 ...

随机推荐

  1. <YaRN><Official doc><RM REST API's>

    Overview ... YARN Architecture The fundamental idea of YARN is to split up the functionalities of re ...

  2. L296 EST 科技英语翻译-美学取向 (上)

    tips:对语言进行恰如其分的润饰,讲究词法.句法及篇章的粘连,增加可读性. 1 Accuracy 精确性 科技文章用词要求准确,尽量避免含糊不清和一词多义 dead air静空气 2 Paralle ...

  3. L265 - 5 questions to ask yourself before you ask for a raise or promotion

    You’ve been in your role for a while now, giving 110% to every assignment your manager hands out. Yo ...

  4. RAD Studio August 2018 Roadmap

    路线图: https://community.embarcadero.com/article/news/16638-rad-studio-august-2018-roadmap 路线图评论: http ...

  5. robotframework·RIDE基础

    date:2018520 day09 一.学习环境 1.安装python27 2.安装robotframework(cmd→[pip install robotframework]) 3.安装WxPy ...

  6. elk的安装部署

    Elk日志安装文档 需要用到有三个软件包 和redis 分布式部署:已上图就是分布式部署的架构图 Logstash :    是部署在前台的应用上,收集数据的 和部署在redis和elasticsea ...

  7. Android.mk使用第三方库方法

    /********************************************************************** * Android.mk使用第三方库方法 * 说明: * ...

  8. [LeetCode&Python] Problem 706. Design HashMap

    Design a HashMap without using any built-in hash table libraries. To be specific, your design should ...

  9. HPU第四次积分赛-K :方框(水题,打印图形)

    方框 描述 用'*'打印出一个nxn的字符图形(1<=n<=100). 输入 多组输入.每行输入一个n,输入EOF结束文件. 输出 输出一个满足题意的图形. 输入样例 1  1 2 5 6 ...

  10. java中事件驱动

    在java语言中,事件不是由事件源自己来处理的,而是交给事件监听者来处理,要将事件源(如按钮)和对事件的具体处理分离开来.这就是所谓的事件委托处理模型. 事件委托处理模型由产生事件的事件源.封装事件相 ...