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-探路篇的主要内容,如果未能解决你的问题,请参考以下文章

工具向IntelliJ IDEA 探路

OpenGL3:高级篇 GLSL

OpenGL片段着色器不照亮场景

片段着色器中未使用纹理数据 - OpenGL

带有顶点/片段着色器的光。使用不同的变量。 (openGL)

OpenGL、GLSL 片段着色器无法读取 Sampler2D 纹理