Uniform是变量类型的一种修饰符,是OpenGL ES  中被着色器中的常量值,使用存储各种着色器需要的数据,例如:转换矩阵、光照参数或者颜色。

  uniform 的空间被顶点着色器和片段着色器分享。也就是说顶点着色器和片段着色器被链接到一起进入项目,它们分享同样的uniform。因此一个在顶点着色器中声明的uniform,相当于在片段着色器中也声明过了。当应用程序装载uniform 时,它的值在顶点着色器和片段着色器都可用。在链接阶段,链接器将分配常量在项目里的实际地址,那个地址是被应用程序使用和加载的标识。

  另一个需要注意的是,uniform 被存储在硬件被称为常量存储,这是一种分配在硬件上的存储常量值的空间。因为这种存储需要的空间是固定的,在程序中这种uniform 的数量是受限的。这个限制能通过读gl_MaxVertexUniformVectors 和gl_MaxFragmentUniformVectors编译变量得出。( 或者用GL_MAX_VERTEX_UNIFORM_VECTORS 或GL_MAX_FRAGMENT_UNIFORM_ VECTORS 为参数调用glGetIntegerv)OpenGL ES 2.0必须至少提供256 个顶点着色器uniform 和224个片段着色器uniform。

  

  获取和设置Uniform

  在程序中使用glGetProgramiv函数,将GL_ACTIVE_UNIFORMS作为参数来查询Uniforms,可以获取程序中Uniform的数量,,如果常量处于active,说明它正在被程序使用。另外你可以只声明Uniform而不使用它,链接器将会优化掉这些Uniform,不将它存储到实际使用的常量列表中。你能使用GL_ACTIVE_UNIFORM_MAX_LENGTH 为参数调用glGetProgramiv,找出在程序里最大的常量列表名字(甚至是空的)。一旦我们知道实际使用的常量数目和描述的数目,我们可以使用glGetActiveUniform 和glGetActiveUniformsiv查找常量:

  

  

  

  使用glGetActiveUniform函数你可以确定Uniform几乎所有的属性。你可以通过它的类型来确定它的名称。另外如果变量是一个数组,你可以找出数组中的最大值。我们可以通过glGetUniformLocation函数来获取Uniform的位置,位置值是一个整型数据,用来标识Uniform在程序中的位置。注意:不在uniform 块中指定位置。这个位置值用于后面函数使用这个Uniform。

  

  glGetUniformLocation将根据Uniform名称获取Uniform的位置,通过下列函数根据位置来装载uniform

  

  

  

  装载uniforms函数大部分是自动完成的。使用哪个函数装载uniforms取决于glGetActiveUniform函数返回的类型。例如类型如果是GL_FLOAT_VEC4,glUniform4f 或glUniform4fv 被使用。如果返回的类型大于一个,glUniform4fv 将被使用一次装载整个数组。如果uniform不是一个数组类型,glUniform4f 或glUniform4fv 被使用。一个值得注意的地方是glUniform*调用不使用程序对象句柄做参数。原因是因为glUniform*调用总是在当前的程序中绑定glUseProgram 执行。uniform值在程序对象中总是保持一致。也就是说,一旦你在项目里设定一个uniform值,这个值将保持不变,甚至你激活另一个程序。

  

GLint maxUniformLen;
GLint numUniforms;
char *uniformName;
GLint index;
glGetProgramiv ( progObj, GL_ACTIVE_UNIFORMS, &numUniforms );
glGetProgramiv ( progObj, GL_ACTIVE_UNIFORM_MAX_LENGTH,
&maxUniformLen );
uniformName = malloc ( sizeof ( char ) * maxUniformLen );
for ( index = ; index < numUniforms; index++ )
{
  GLint size;
  GLenum type;
  GLint location;
  // Get the uniform info
  glGetActiveUniform ( progObj, index, maxUniformLen, NULL,
  &size, &type, uniformName );
  // Get the uniform location
  location = glGetUniformLocation ( progObj, uniformName );
  switch ( type )
  {
    case GL_FLOAT:
    //
    break;
    case GL_FLOAT_VEC2:
    //
    break;
    case GL_FLOAT_VEC3:
    //
    break;
    case GL_FLOAT_VEC4:
    //
    break;
    case GL_INT:
    //
    break;
    // ... Check for all the types ...
    default:
    // Unknown type
    break;
  }
}

  

OpenGL ES 3.0之Uniform详解的更多相关文章

  1. 【Android 应用开发】OpenGL ES 2.0 -- 制作 3D 彩色旋转三角形 - 顶点着色器 片元着色器 使用详解

    最近开始关注OpenGL ES 2.0 这是真正意义上的理解的第一个3D程序 , 从零开始学习 . 案例下载地址 : http://download.csdn.net/detail/han120201 ...

  2. OpenGL ES 2.0 -- 制作 3D 彩色旋转三角形 - 顶点着色器 片元着色器 使用详解

    最近开始关注OpenGL ES 2.0 这是真正意义上的理解的第一个3D程序 , 从零开始学习 . 案例下载地址 : http://download.csdn.net/detail/han120201 ...

  3. (OpenGL ES 2.0 Shading Language) attribute 、uniform 和 varying

    一:attribute .uniform 和 varying 都是glsl的变量的内存指示器(storage qualifiers),指明变量的内存特性 二:attribute attribute 是 ...

  4. 【AR实验室】OpenGL ES绘制相机(OpenGL ES 1.0版本)

    0x00 - 前言 之前做一些移动端的AR应用以及目前看到的一些AR应用,基本上都是这样一个套路:手机背景显示现实场景,然后在该背景上进行图形学绘制.至于图形学绘制时,相机外参的解算使用的是V-SLA ...

  5. 在 OpenGL ES 2.0 上实现视差贴图(Parallax Mapping)

    在 OpenGL ES 2.0 上实现视差贴图(Parallax Mapping) 视差贴图 最近一直在研究如何在我的 iPad 2(只支持 OpenGL ES 2.0, 不支持 3.0) 上实现 视 ...

  6. OpenGL ES 3.0 基础知识

    首先要了解OpenGL的图形管线有哪些内容,再分别去了解其中的相关的关系: 管线分别包括了顶点缓冲区/数组对象,定点着色器,纹理,片段着色器,变换反馈,图元装配,光栅化,逐片段操作,帧缓冲区.其中顶点 ...

  7. OpenGL ES 3.0 点,线,三角形绘制形式总结

    OpenGL ES 3.0 顶点     -1,  1, 0, -0.5f,  0, 0,     0, -1, 0,    -1,  0, 0, 0.5f,   0, 0,     1, -1,   ...

  8. Android OpenGL ES 3.0 纹理应用

    本文主要演示OpenGL ES 3.0 纹理演示.接口大部分和2.0没什么区别,脚本稍微有了点变化而已. 扩展GLSurfaceView package com.example.gles300; im ...

  9. OpenGL ES 2.0 Shader 调试新思路(二): 做一个可用的原型

    OpenGL ES 2.0 Shader 调试新思路(二): 做一个可用的原型 目录 背景介绍 请参考前文OpenGL ES 2.0 Shader 调试新思路(一): 改变提问方式 优化 ledCha ...

随机推荐

  1. [Deepin 15] 编译安装 PHP-5.6.30

    先看下历史笔记: Ubuntu 14 编译安装 PHP 5.4.45 + Nginx 1.4.7 + MySQL 5.6.26 笔记 ################################# ...

  2. 【教程】新手如何制作简单MAD和AMV,学不会那都是时辰

    [教程]新手如何制作简单MAD和AMV,学不会那都是时 http://tieba.baidu.com/p/2303522172 [菜鸟教你做MAD]Vegas制作MAD入门教程 http://tieb ...

  3. 为什要使用预编译SQL?(转)

    本文转自https://www.cnblogs.com/zouqin/p/5314827.html 今天在研发部技术大牛的指点下,我终于明白了为什么要使用SQL预编译的形式执行数据库JDBC:

  4. Spring boot配置多个Redis数据源操作实例

    原文:https://www.jianshu.com/p/c79b65b253fa Spring boot配置多个Redis数据源操作实例 在SpringBoot是项目中整合了两个Redis的操作实例 ...

  5. GPG入门教程

    原文地址:http://www.ruanyifeng.com/blog/2013/07/gpg.html 作者: 阮一峰 日期: 2013年7月12日 前两篇文章,我介绍了RSA算法. 今天,就接着来 ...

  6. iOS6新特征:UICollectionView介绍-非常棒 -转

    传送门:http://www.devdiv.com/forum.php?mod=viewthread&tid=128378

  7. Java删除List和Set集合中元素

    今天在做项目时,需要删除List和Set中的某些元素,当时使用边遍历,边删除的方法,却报了以下异常: ConcurrentModificationException 为了以后不忘记,使用烂笔头把它记录 ...

  8. Java ArrayList、string、string[]之间的转换

    1.ArrarList 转换为 string[] : ArrayList list = new ArrayList(); list.Add("aaa"); list.Add(&qu ...

  9. window.opener()方法

    <!DOCTYPE html><html><head><meta charset="GBK"><title>菜鸟教程(r ...

  10. 架构模式逻辑层模式之:表模块(Table Model)

    表模块和领域模型比,有两个显著区别: 1:表模块中的类和数据库表基本一一对应,而领域模型则无此要求: 2:表模块中的类的对象处理表中的所有记录,而领域模型的一个对象代表表中的一行记录: 一般情况下,我 ...