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. <Web Crawler><Java><thread-safe queue>

    Basic Solution The simplest way is to build a web crawler that runs on a single machine with single ...

  2. 字符界面的贪吃蛇--链表--C++

    前天看了下链表,由于平时对链表的使用不多,所以对链表的应用也没什么了解,所以想来想去,就想用链表实现一下贪吃蛇. 下面言归正传,先看效果图,再看代码,其他没有了! 图1: 图2: 代码: #inclu ...

  3. 某关于数位DP的一节课后的感受

    题目 求给定区间[x,y]中满足下列条件的整数个数,这个数恰好等于k个互不相等的B的整数次幂之和 Input 15 20 2 2 Out 17 18 20 示例:17=24+20 18=24+21 2 ...

  4. maven 细节 —— scope、坐标

    对于 idea 开发环境,测试代码便是在 src/test/java(该java目录会在创建时标注为测试文件夹) 目录下的 .java 代码为测试代码: 1. scope scope的分类 compi ...

  5. dblogin userid ogg ERROR: Unable to connect to database using user ogg

    测试环境,初步配置ogg,添加ogg用户连接数据库,提示无权限报错. 1.0 报错信息 GGSCI (enmo) > dblogin userid ogg,password ogg ERROR: ...

  6. Anaconda canda 安装 Python3 配置

    链接: 1.安装Python 3.5以及tensorflow 以前用virtualenv觉得挺好用了,但是用多python版本下安装tensorflow,出现问题: pip is configured ...

  7. flask的安装

    1.查看已安装的Flask版本 在 python 的交互模式中 : 1. import flask 没报错:已经安装了Flask,可以继续查看版本 报错:没安装Flask 2. flask.__ver ...

  8. Js中的判空

    1.JS 中判断 undefined JavaScript 中有两个特殊数据类型:undefined 和 null var test= undefined; if (typeof(test) == u ...

  9. indexedDB为何物

    https://developer.mozilla.org/zh-CN/docs/Web/API/IndexedDB_API 在前一个阶段的工作中,项目组要开发一个平台,为了做出更好的用户体验,实现快 ...

  10. rsync命令 续集 、linux系统日志、screen工具

    1.rsync 通过服务进行监听同步: 开启服务:rsync --daemon  (默认开启873端口) 需要编辑配制文件:/etc/rsyncd.conf port=873log file=/var ...