简介

Uniform是一种从CPU中的应用向GPU中的着色器发送数据的方式,但uniform和顶点属性有些不同。

首先,uniform是全局的(Global)。全局意味着uniform变量必须在每个着色器程序对象中都是独一无二的,而且它可以被着色器程序的任意着色器在任意阶段访问。
第二,无论你把uniform值设置成什么,uniform会一直保存它们的数据,直到它们被重置或更新。

单独统一变量

声明

uniform vec3 color

赋值

//获取指定统一变量的location
int vertexColorLocation = glGetUniformLocation(_program, "test"); //为vec3 的统一变量 赋值
glUniform3f(vertexColorLocation, 0.0f, 1.0f, 0.0f);

赋值函数是根据 统一变量类型的不同而调整的.其中函数名中包含数字(1、2、3、4)表示接受这个数字个用于更改uniform变量的值,i表示32位整形,f表示32位浮点型,ub表示8位无符号byte,ui表示32位无符号整形,v表示接受相应的指针类型(或者就是传入的是数组)。

glUniform1f(GLint locaation,GLFloat x) 表示 float类型
glUniform2f(GLint locaation,GLFloat x,GLFloat y) 表示 二位向量 分量类型为float
glUniform1fv(GLint locaation,GLSize count,const GLfloat* value) float类型指针
glUniformMatrix4x3(Glint location,GLsizei count,GLboolean transpose,const GLfloat* value) 表示为 4x3矩阵. 参数: transpose 表示是否采用 行优先顺序(GL_TRUE)

UBO

UBO(Uniform Buffer Object)是用来存储着色语言中Uniform类型变量的缓冲区对象,使用UBO可以让uniform变量在不同的着色语言程序中实现共用,也可以在着色语言程序中实现uniform类型变量的设置与更新。

提到UBO就必须要提到着色语言GLSL中的Uniform Blocks,它将众多的Uniform类型的变量集中在一起进行统一的管理,对于需要大量Uniform类型变量的程序可以显著地提高性能。(有点像全局版的VBO)

原理

原理示意图.png

在显存中创建缓存对象(Buffer),在buffer中存储统一变量数据, 将Buffer与 指定的point绑定, 将统一变量缓冲区的索引 和 point绑定. 这样通过point 将变量 和 缓存 连接.

设置UBO

//统一变量块
layout (std140) uniform colorBlock{
vec4 cc;
};
        GLuint blockid,bufferid;
GLint blocksize;
GLint point = 1; // 统一变量数据
GLfloat blockData[] = {
1.0f,1.0f,1.0f,1.0f
}; //获取统一变量块索引
blockid = glGetUniformBlockIndex(_program, "colorBlock"); //获取统一变量块大小
glGetActiveUniformBlockiv(_program, blockid, GL_UNIFORM_BLOCK_DATA_SIZE, &blocksize); //将变量索引 和 point 绑定
glUniformBlockBinding(_program, blockid, point); //创建与绑定缓冲区
glGenBuffers(1, &bufferid);
glBindBuffer(GL_UNIFORM_BUFFER, bufferid); //向缓冲区中赋值
glBufferData(GL_UNIFORM_BUFFER, blocksize, blockData, GL_DYNAMIC_DRAW); //将UBO 和 point 绑定
glBindBufferBase(GL_UNIFORM_BUFFER, point, bufferid);

修改UBO

        GLfloat uploadData[] = {
0.0f,0.0f,1.0f,1.0f
}; // 绑定当然统一变量块的 buffer
glBindBuffer(GL_UNIFORM_BUFFER, bufferid); //获取统一变量块 中 指定变量的 偏移量
const GLchar *names[] = {"cc"};
GLuint indices[1];
glGetUniformIndices(_program, 1, names, indices);
GLint offset[1];
glGetActiveUniformsiv(_program, 1, indices, GL_UNIFORM_OFFSET, offset);
glBufferSubData(GL_UNIFORM_BUFFER, offset[0], blocksize, uploadData);

函数补充

1, glGetUniformIndices (GLuint program, GLsizei uniformCount, const GLchar* const *uniformNames, GLuint* uniformIndices)
该函数用于获取统一变量块中 变量们的索引 参数:

program 程序对象
uniformCount 变量名称数组的元素数量
uniformNames 变量名称数组
uniformIndices 用于接受变量索引的数组

2,glGetActiveUniformsiv (GLuint program, GLsizei uniformCount, const GLuint* uniformIndices, GLenum pname, GLint* params)
该函数用于 通过变量索引 查询变量信息. 参数:

program 程序对象
uniformCount 变量数量
uniformIndices 变量索引数组
pname 表示要查询变量的那个属性 GL_UNIFORM_OFFSET(变量偏移量) GL_UNIFORM_SIZE(变量大小) GL_UNIFORM_NAME_LENGTH(变量名长度) GL_UNIFORM_TYPE(变量类型)....
params 接受查询结果的数组

注意

着色语言编译优化

如果你声明了一个uniform却在GLSL代码中没用过,编译器会静默移除这个变量,导致最后编译出的版本中并不会包含它.

UBO限定符

在UBO中,针对不同的限定符 还存在不同的字节补齐的情况.所以获取偏移量,大小最好还是通过查询进行,避免自己计算出现错误.

这是 std140(标准统一变量块布局)限定符的内存分配情况:

std140布局.png

OpenGL ES on iOS --- 统一变量(Uniform)和统一变量块(UBO)的更多相关文章

  1. WebGL 在 OpenGL ES 指令 iOS 在 C 分歧版指令分析

    WebGL 中 OpenGL ES 指令与 iOS 中 C 版指令的差异简析 太阳火神的漂亮人生 (http://blog.csdn.net/opengl_es) 本文遵循"署名-非商业用途 ...

  2. 通过OpenGL ES在iOS平台实践增强现实

    http://www.cnblogs.com/elvisyzhao/p/3398250.html 本文采用OpenGL ES 1固定渲染管线实现,目标为在设备拍摄到的现实世界中,绘制世界坐标轴,并根据 ...

  3. 通过OpenGL ES在iOS平台实践增强现实(一)

    http://ios.9tech.cn/news/2013/1108/38495.html 1.本文采用OpenGL ES 1固定渲染管线实现,目标为在设备拍摄到的现实世界中,绘制世界坐标轴,并根据设 ...

  4. 通过OpenGL ES在iOS平台实践增强现实(二)

    上一篇讲到如何使用OpenGL ES绘制一个3D场景,这一篇我们会配合使用iOS提供的CoreMotion框架把虚拟世界中的摄像机的位置朝向和设备实际的位置朝向绑定起来.本文还对防抖做了处理. 首先说 ...

  5. 【转载】OpenGL ES 三种类型修饰 uniform attribute varying

    其实attribute varying已经被in和out代替了,但是有些工程代码里面仍然还在,所以权当笔记好了. 1.uniform变量uniform变量是外部application程序传递给(ver ...

  6. OpenGL ES着色器语言之变量和数据类型(一)(官方文档第四章)和varying,uniform,attribute修饰范围

    OpenGL ES着色器语言之变量和数据类型(一)(官方文档第四章)   所有变量和函数在使用前必须声明.变量和函数名是标识符. 没有默认类型,所有变量和函数声明必须包含一个声明类型以及可选的修饰符. ...

  7. iOS 中OpenGL ES 优化 笔记 1

    1,避免同步和Flushing操作 OpenGL ES的命令执行通常是在command buffer中积累一定量的命令后,再做批处理执行,这样效率会更高:但是一些OpenGL ES命令必须flush ...

  8. OpenGL ES应用开发实践指南:iOS卷

    <OpenGL ES应用开发实践指南:iOS卷> 基本信息 原书名:Learning OpenGL ES for iOS:A Hands-On Guide to Modern 3D Gra ...

  9. OpenGL ES for Android

    经过半年的准备OpenGL ES for Android系列文章终于要和大家见面了,在这里定一个小目标-先吸引1000个粉丝,万一实现了呢.写关于OpenGL ES的文章开始是有一些犹豫的,因为Ope ...

随机推荐

  1. 红绿灯 promise和原始方式实现

    Promise 方式 async+await function sleep(duration){ return new Promise(function(resolve){ setTimeout(re ...

  2. Egret入门学习日记 --- 第十二篇(书中 5.1节 内容)

    第十二篇(书中 5.1节 内容) 昨天把 第4章完成了. 今天来看第5章. 接下来是 5.1节 的内容. 总结一下 5.1节 的重点: 1.如何制作一个公用按钮皮肤. 跟着做: 重点1:如何制作一个公 ...

  3. Java面试 - static 修饰的变量和方法有哪些特点?

    1.static修饰的变量和方法,在类加载时即被初始化,可直接通过类名.变量名和类型.方法名进行调用. 2.static修饰的变量,在类加载时会被分配到数据区的方法区.类的实例可共享方法区中的变量.如 ...

  4. Webpack配置开发环境总结

    本文主要讲解webpack.config.js文件的配置,不会讲解webpack是什么,默认你会安装webpack及其它npm包,并对webpack有一些了解. 下面将从webpack.config. ...

  5. VLAN之间通信-三层交换机实现

    1.打开三层交换机的命令行,配置VLAN和设置端口IP enable //进入特权模式 configure terminal //进入全局配置模式 ip routing //启动交换机的路由功能 vl ...

  6. linux awk和sed工具

    慕课网链接:https://www.imooc.com/video/14508 部分示例命令 #替换passwd中的用户名和userid和gid gsed 's/\(^[a-z_-]\+\):\*:\ ...

  7. pandas数据结构之基础运算笔记

    import pandas as pd import numpy as np s = pd.Series([1,3,5,6,8],index=list('acefh')) s.index # 读取行索 ...

  8. windows通过gcc编译代码

    1.将gcc添加到环境变量 2.检查gcc是否安装成功 cmd下输入gcc –v 3.cd进入需要编译源文件的目录 4.dir查看当前目录下是否有需要编译的文件(linux下用ls) 5.编译文件(H ...

  9. 【搜索+set去重】Balance Scale

    Balance Scale 题目描述 You, an experimental chemist, have a balance scale and a kit of weights for measu ...

  10. Crossword Expert CodeForces - 1194F (期望)

    大意: $n$个题, 按照第$i$题随机$t_i$或$t_i+1$秒钟完成, 最多做$T$秒, 求做题数期望. 期望转为做题数$\ge x$的方案数之和最后再除以总方案数 这是因为$\sum\limi ...