OpenGL-探路篇
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OpenGL-探路篇相关的知识,希望对你有一定的参考价值。
一、渲染
1)含义:从模型创建最终图像的过程
二、着色器(shader) :同一时刻只能有一个着色器起作用
1)含义:专为图形处理单元(GPU)编写的一种小程序(用GLSL/OpenGL Shading Language 编写)
2)包括:顶点着色器(vertex)-> 细分着色器(增加图元) -> 几何着色器(调整图元) -> 片元着色器(主要处理光栅化后的片元数据)
*顶点着色器的输出必须与片元着色器的输入匹配
——补充:
顶点 -> 图元(点、线段、多边形) -> 片元 -> 像素(需经过测试,包括所有权测试、裁剪测试、深度测试、alpha测试、模板测试)-> 帧缓冲区 -> 映射到显示
片元:比像素多一些颜色、深度、纹理信息(候选像素)
光栅化:图元转换为片元的过程,片元为二维图像,每个点包含颜色、深度、纹理信息,该点和相关信息为一个片元。
3)创建着色器对象(glCreateShader)-> 关联着色器代码(glShaderSource)-> 编译(glCompileShader)-> 创建多个着色器。。。-> 创建着色器程序(glCreateProgram)-> 关联着色器到着色器程序(glAttachShader)-> 连接着色器程序(glLinkProgram)-> 启用着色器程序(glUseProgram)
三、三个函数前缀:
1)glGen*:生成引用名称,类似指针
2)glBind*:分配内存
例如:glBindVertexArray(GLuint array) -> 如果array是glGen*创建的引用,则生成一个新的顶点数组与引用关联,或者激活已存在的顶点数组对象。-》作为当前对象。
绑定时间:创建对象并初始化时、再次使用未被绑定的对象时
3)glDelete*:删除对象
注:通过gllsVertexArray(GLuint array)判断某一名称是否已经被保留为一个顶点数组对象
四、将数据载入缓存对象
例:glBufferData(GLenum target,GLsizeiptr size, const GLvoid *data, GLenum usage)
-> 1、分配顶点数据所需要的储存空间
2、将数据从应用程序的数组拷贝到OpenGL服务端的内存中
参数说明:target -> 数据类型
usage -> 分配数据之后的读写方式。
函数说明:将size大小的数据从客户端拷贝到服务端
五、着色器编写
// 传递着色器
#version 430 core
/*
layout 布局限定符,目的为变量提供元数据
in 数据流入
out 数据流出
*/
layout(location = 0) in vec4 vPosition; // 着色器变量是着色器与外部世界的联系所在
void main() {
gl_position = vPosition;
}
#version 430 core
out vec4 fColor;
void main() {
fColor = vec4(0.0,0.0,1.0,1.0);
}
六、将应用程序与着色器之间,以及不同着色阶段之间的数据通道连接起来 -> 着色管线装配过程。
2017-02-23
七、uniform(始终如一)变量:从应用程序接收数据,不会随着顶点或片元的改变而改变。对于给定的图元而言是个常量。着色器无法改变该类型的值。
1)在应用程序中改变该类型的值,需先获取其在uniform索引列表中的索引 -> glGetUniformLocation(GLuint program,const char* name),获得索引之后,需要将uniform块与缓冲对象关联,(ps:glUniformBlockBinding手动绑定)
2)uniform位置是在着色器链接的时候产生的(glLinkProgram())
3)uniform块中只能包含透明类型的变量
4)布局限定符
shared:多个程序共享
packed:设置uniform占最小内存空间,但会禁止程序间共享
row(column)_major:行/列主序存储方式
5)uniform块名称不能作为uniform变量的父名称,因此两个uniform变量不能同名
八、GLSL:
1)类型修饰符:const \ in \ out \ uniform \ shared \ buffer(共享)
2)discard语句会让片元着色器立即终止,从而丢弃片元。
3)invariant和precise关键字可以保证在图形设备计算的不变性。
可通过预编译将着色器中的所有变量设置为invariant -> #pragma STDGL invariant(all)
区别:如果数值发生变化,但数学上并不影响结果,则用precise,如交换律
2017-02-24 09:23:55
九、子程序池
1)步骤:
1.定义子程序类型 -> subroutine returnType funcPoolName ( type1 param1...);
2.声明子程序 -> subroutine (funcPoolName) returnType func1()..
3.函数指针 -> subroutine uniform funcPoolName funcPointer;
2)指定所用的子程序:glUniformSubroutinesuiv(GLenum shaderType , GLsizei count , const GLuint* indices) -> 设置所有count个子程序uniform使用indices数组中的值。
粒子:如indices[n](n为函数指针uniform的location)为func1的索引(通过glGetSubroutineIndex获得)
以上是关于OpenGL-探路篇的主要内容,如果未能解决你的问题,请参考以下文章