GLSL初探

OpenGL ES错误处理

如果不正确使用OpenGL ES命令,应用程序就会产生一个错误编码,这个错误编码将被记录,可以用glGetError查询。在应用程序用glGetError查第一个错误代码之前,不会记录其它错误代码,一旦查询到错误代码,当前错误代码便复位为GL_NO_ERROR。
GLenum glGetError(void)

image.png

OpenGL ES的版本

OpenGL ES 1.X :针对固定功能流⽔水管线硬件
OpenGL ES 2.X :针对可编程流⽔水管线硬件
OpenGL ES 3.X :OpenGL ES 2.0的扩展

着色器与程序

  • 需要创建2个基本对象才能用着色器进行渲染:着色器对象和程序对象
  • 获取链接后着色器对象的一般过程包括6个步骤:
  1. 创建一个顶点着色器对象和一个片段着色器对象
  2. 将源代码链接到每个着色器对象
  3. 编译着色器对象
  4. 创建一个程序对象
  5. 将编译后的着色器对象连接到程序对象
  6. 链接程序对象

关于GLSL编译

在OpenGL ES中,每个program对象有且仅有一个Vertex shader对象和一个Fragment Shader对象连接到它。

  • Shader:类似于C编译器
  • Program:类似于C链接器
  • glLInkProgram:操作产生最后的可执行程序,它包含最后可以在硬件上执行的硬件指令。

Shader和Program编程概述

  1. 创建Shader
  • 编写Vertex ShaderFragment Shader源码
  • 创建两个shader实例:glCreateShader
  • shader实例指定源码:glShaderSource
  • 编译shader源码:glCompileShader
  1. 创建Program
  • 创建programglCreateProgram
  • 绑定shaderprogramglAttachShader(GLuint program, GLuint shader);每个program必须绑定一个Vertex Shader和一个Fragment Shader
  • 链接programglLinkProgram(GLuint program)
  • 使用programglUseProgram(GLuint program)

创建与编译一个着色器相关接口

GLuint glCreateShader(GLenum type);
type - 创建着色器的类型,GL_VERTEX_SHADER或者GL_FRAGMENT_SHADER
返回值 - 是指向新着色器对象的句柄,可以调用glDeleteShader删除

void glDeleteShader(GLuint shader);
shader - 要删除的着色器对象句柄

void glShaderSource(GLuint shader, GLSizei count, const GLChar * const *string, const GLint *length);
shader - 指向着色器对象的句柄
count - 着色器源字符串的数量,着色器可以由多个源字符串组成,但是每个着色器只有一个main函数
string - 指向保存数量的count着色器源字符串的数组指针
length - 指向保存每个着色器字符串大小且元素数量为count的整数数组指针
复制代码
void glCompileShader(GLuint shader);
shader - 需要编译的着色器对象句柄

void glGetShaderiv(GLuint shader, GLenum pname, GLint *params);
shader - 需要编译的着色器对象句柄
pname - 获取的信息参数,可以为GL_COMPLLE_STATUS/GL_DELETE_STATUS/GL_INFO_LOG_LENGTH/GL_SHADER_SOURCE_LENGTH/GL_SHADER_TYPE
params - 指向查询结果的整数存储位置的指针

void glGetShaderInfoLog(GLunit Shader, GLSizei maxLength, GLSizei *length, GLChar *infoLog);
shader - 需要获取信息日志的着色器对象句柄
maxLength - 保存信息日志的缓存区大小
length - 写入的信息日志的长度(减去null终止符),如果不需要知道长度,这个参数可以为Null
info - 指向保存信息日志的字符缓存区的指针
复制代码

创建与链接程序相关接口

// 创建一个程序对象
GLUint glCreateProgram()
返回值 - 返回一个执行新程序对象的句柄

void glDeleteProgram(GLuint program)
program - 指向需要删除的程序对象句柄

// 着色器与程序连接/附着
void glAttachShader(GLuint program, GLuint shader);
program - 指向程序对象的句柄
shader - 指向程序连接的着色器对象的句柄

// 断开连接
void glDetachShader(GLuint program);
program - 指向程序对象的句柄
shader - 指向程序断开连接的着色器对象句柄
复制代码
glLinkProgram(GLuint program)
program - 指向程序对象句柄

// 链接程序之后,需要检查链接是否成功,可以使用glGetProgramiv检查链接状态:
void glGetProgramiv(GLuint program, GLenum pname, GLint *params);
program - 需要获取信息的程序对象句柄
pname - 获取信息的参数,可以是:
GL_ACTIVE_ATTRIBUTES
GL_ACTIVE_ATTRIBUTES_MAX_LENGTH 
GL_ACTIVE_UNIFORM_BLOCK
GL_ACTIVE_UNIFORM_BLOCK_MAX_LENGTH
GL_ACTIVE_UNIFROMS 
GL_ACTIVE_UNIFORM_MAX_LENGTH
GL_ATTACHED_SHADERS 
GL_DELETE_STATUS
GL_INFO_LOG_LENGTH
GL_LINK_STATUS
GL_PROGRAM_BINARY_RETRIEVABLE_HINT 
GL_TRANSFORM_FEEDBACK_BUFFER_MODE
GL_TRANSFORM_FEEDBACK_VARYINGS 
GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH
GL_VALIDATE_STATUS
params - 指向查询结果整数存储位置的指针

// 从程序信息日志中获取信息
void glGetProgramInfoLog(GLuint program, GLSizei maxLength, GLSizei *length, GLChar *infoLog)
program - 指向需要获取信息的程序对象句柄
maxLength - 存储信息日志的缓存区大小
length - 写入的信息日志的长度(减去null终止符),如果不需要知道长度,这个参数可以为Null
info - 指向保存信息日志的字符缓存区的指针

void glUseProgram(GLuint program)
program - 设置为活动程序的程序对象句柄
复制代码

关于GLSL精度限定符解析

image.png

Satisfies the minimum requirements for the vertex language described above.Optional in the fragment language
满足上面描述的顶点语言的最低要求。在片段语言中是可选的。

Satisfies the minimum requirements above for the fragment language . Its range and precision has to be greater than or the same as provided by lowp and less than of the same as provided by highp.
满足上述片段语言的最低要求。其范围和精度必须大于或等于lowp提供的范围和精度,小于highp提供的范围和精度。

Range and precision that can be less than mediump , but still intended to represent all color values for any color channel.
范围和精度可以小于mediump,但仍用于表示任何颜色通道的所有颜色值。

例如:

lowp float color;
varying mediump vec2 Coord;
highp mat4 m;
复制代码

精度范围

Floating Point Range 浮点数范围

  • highp (-2^62^, 2^62^)
  • mediump (-2^14^, 2^14^)
  • lowp (-2, 2)

Integer Range 整数范围

  • hightp (-2^16^, 2^16^)
  • mediump (-2^10^, 2^10^)
  • lowp (-2^8^, 2^8^)

对于高精度和中精度,整型范围必须可以准确地转化成相应的相同精度修饰符所表示的float型。

例如,highp int 可以被转换成highp floatmediump int 可以被转换成mediump float,但是lowp int不能转换成相应的lowp float

字符常量和布尔型没有精度修饰符,当浮点数和整数构造器不含带有精度修饰符的参数时也不需要精度修饰符。

指定变量精度(放在数据类型之前)

highp vec4 position;
varying lowp vec4 color;
mediump float specularExp;
复制代码

指定默认精度(放在Vertex和Fragment Shader源码开始处)

precision precision-qualifier type;

* precision可以用来确定默认精度修饰符
* precision-qualifier可以是lowp, mediump, 或者highp,任何其它类型和修饰符都会引起错误
复制代码

如果typefloat类型,那么该精度(precision-qualifier)将适用于所有无精度修饰符的浮点数声明(标量、向量、矩阵)

如果typeint类型,那么该精度(precision-qualifier)将适用于所有无精度修饰符的整数型声明(标量、向量)

包括全局变量声明,函数返回值声明,函数参数声明,和本地变量声明等。没有声明精度修饰符的变量将使用和它最近的precision语句中的精度。

precision highp float;
precision mediump int;
复制代码

Vertex Shader中,如果没有默认的精度,则floatint精度都为highp
Fragment Shader中,float没有默认的精度,所以必须在Fragment Shader中为float指定一个默认精度或为每个float变量指定精度。

预定义精度

在顶点着色器中有如下预定义的全局默认精度语句:

precision highp float; 
precision highp int;
precision lowp sampler2D;
precision lowp samplerCube;
复制代码

在片元着色器中有如下预定义的全局默认精度语句:

precision mediump int;
precision lowp sampler2D;
precision lowp samplerCube;
复制代码

片元着色器没有默认的浮点数精度修饰符。因此,对于浮点数,浮点数向量和矩阵变量声明,要么声明必须包含一个精度修饰符,要不默认的精度修饰符在之前已经被声明过了。

矩阵数据类型

image.png
mat列x行

向量数据类型

image.png

变量存储限定符

image.png
质心插值学术文献:www.ixueshu.com/document/f2…

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享