1、从文件中加载顶点数据时,通常获取到的是位置数组、法线数组和纹理坐标数组。使用glBufferSubData函数进行缓冲填充:
2、gl_FragCoord的x和y分量是片段的窗口空间坐标,其原点为窗口的左下角,z分量等于对应片段的深度值。可以根据片段的窗口坐标,计算出不同的颜色。gl_FragCoord的常用于对比不同片段计算的视觉输出效果,如将屏幕分成两部分,在窗口的左侧渲染一种输出,在窗口的右侧渲染另一种输出。
3、需要确定每个变量的大小和偏移量,才能够按顺序将它们放进缓冲中。变量大小对应C++数据类型,其中向量和矩阵都是大的float数组。变量偏移量可以通过std140布局确定,std140布局声明了偏移量的计算规则。
4、之前,通过glVertexAttribPointer函数指定顶点数组缓冲内容的属性布局。在顶点数组缓冲中,对属性进行了交错处理,将每一个顶点的位置、法线和纹理坐标紧密放置在一起。
5、之前一直调用glBufferData函数来填充缓冲对象所管理的内存,这个函数会分配一块内存,并将数据添加到这块内存中。如果data参数设置为NULL,将只会分配内存,但不进行填充。
6、layout(std设置了Uniform块布局,对它的内容使用一个特定的内存布局。Uniform块的内容是储存在一个缓冲对象中的,缓冲对象只是一块预留内存,并不会保存数据的类型,因此需要确定内存的哪一部分对应着着色器中的哪一个uniform变量。
7、在OpenGL上下文中,定义了一些绑定点,将一个Uniform缓冲链接至它,并将着色器中的Uniform块绑定到相同的绑定点,就可以将Uniform缓冲对象和Uniform块对应起来。可以绑定多个Uniform缓冲到不同的绑定点上。因为着色器A和着色器B都有一个链接到绑定点0的Uniform块,它们的Uniform块将会共享相同的uniform数据。
8、首先,调用glGenBuffers创建一个Uniform缓冲对象,将它绑定到GL_UNIFORM_BUFFER目标,并调用glBufferData,分配足够的内存。
9、Uniform缓冲对象是可以在多个着色器中使用的全局Uniform变量,使用glGenBuffers来创建,绑定到GL_UNIFORM_BUFFER缓冲目标,并将所有相关的Uniform数据存入缓冲。Uniform缓冲对象只需创建一次,但每个着色器中不同的uniform需要手动设置。
10、在顶点着色器中使用了3个矩阵:投影、观察和模型矩阵,而只有模型矩阵会频繁变动。如果有多个着色器使用了这同一组矩阵,那么使用Uniform缓冲对象会更好,因此将投影和模型矩阵存储到一个叫做Matrices的Uniform块中。
11、如果想读写数据的两个不同缓冲都为顶点数组缓冲,就不能同时将两个缓冲绑定到同一个缓冲目标上。因此,使用另外两个缓冲目标,GL_COPY_READ_BUFFER和GL_COPY_WRITE_BUFFER,可以将需要的缓冲绑定到这两个缓冲目标上,作为readtarget和writetarget参数。glCopyBufferSubData会从readtarget中读取size大小的数据,并将其写入writetarget缓冲的writeoffset偏移量处。
12、gl_FragCoord能获取片段的深度值,但不能修改。而输出变量gl_FragDepth可用来设置片段的深度值,直接写入一个0到0之间的float值。如果着色器没有写入值到gl_FragDepth,它会自动取用gl_FragCoord.z的值。
13、在每次渲染迭代中绘制物体之前,将观察矩阵更新到缓冲的后半部分:
14、因为修改了模型矩阵,每个立方体都移动到了窗口的一边,并且由于使用了不同的片段着色器,它们的颜色也不同。
15、声明了一个块名为VS_OUT,实例名为vs_out的接口块,将着色器的输入打包为数组。
16、gl_FrontFacing是一个bool变量,如果当前片段是正向面就返回true,否则就是false。如果不使用面剔除,能够对正反面使用不同的颜色(纹理)。
17、glCopyBufferSubData能够从一个缓冲中复制数据到另一个缓冲中,readtarget和writetarget参数需为复制源和复制目标的缓冲目标。如将VERTEX_ARRAY_BUFFER缓冲复制到VERTEX_ELEMENT_ARRAY_BUFFER缓冲,分别将这些缓冲目标设置为读和写的目标。
18、在例子程序中显示4个立方体,每个立方体使用不同的着色器程序渲染的。将顶点着色器的Uniform块设置为绑定点?
19、可使用glBufferSubData函数填充缓冲的特定区域。参数为:缓冲目标、偏移量、数据的大小和数据本身。偏移量指定从何处开始填充这个缓冲,因此可以插入或者更新缓冲内存的某一部分,但缓冲需要有足够的已分配内存,所以对一个缓冲调用glBufferSubData之前必须要先调用glBufferData。
20、根据std140布局的规则,就能使用glBufferSubData的函数将变量数据按照偏移量填充进缓冲中了。虽然std140布局不是最高效的布局,但它保证了内存布局在每个声明了这个Uniform块的程序中是一致的。
21、Uniform缓冲对象比起独立的uniform有很多好处。第一,一次设置很多uniform会比一个一个设置多个uniform要快很多。第二,比起在多个着色器中修改同样的uniform,在Uniform缓冲中修改一次会更容易一些。第三,如果使用Uniform缓冲对象的话,你可以在着色器中使用更多的uniform。
22、填充缓冲。将投影矩阵的视野值保持不变(所以摄像机就没有缩放了),只需要将其在程序中定义一次,使用glBufferSubData在进入渲染循环之前存储投影矩阵:
23、将图元设置为GL_POINTS时,每一个顶点都会被渲染为一个点,可以通过glPointSize函数来设置渲染出来的点的大小。也可以通过gl_PointSize设置点的宽高(像素),能对每个顶点设置不同的值。
24、将数据导入缓冲的另外一种方法是:通过调用glMapBuffer函数,返回当前绑定缓冲的内存指针,直接将数据复制到缓冲当中。该函数用于直接映射数据到缓冲,而不事先将其存储到临时内存中,比如从文件中读取数据,并直接将它们复制到缓冲内存中。
25、使用glBufferSubData函数,用一个字节数组添加所有的数据,或者更新缓冲的一部分。要想更新uniform变量boolean,可以用以下方式更新Uniform缓冲对象:
26、当需要对缓冲更新或者插入数据,都会绑定到uboExampleBlock,并使用glBufferSubData来更新它的内存。只需要更新这个Uniform缓冲一次,所有使用这个缓冲的着色器就都使用的是更新后的数据了。
27、创建Uniform缓冲对象本身,为缓冲分配了足够的内存,它等于glm::mat4大小的两倍。并将缓冲中的特定范围(在这里是整个缓冲)链接到绑定点?
28、gl_VertexID为只读的输入变量,储存了正在绘制顶点的当前ID。当进行索引渲染的时候,这个变量会存储正在绘制顶点的当前索引。当不使用索引进行绘制的时候,这个变量会储存从渲染调用开始的已处理顶点数量。
29、另一种方式是:将每一种属性类型的向量数据打包为一个大的区块。与交错布局123123123123不同,采用分批的方式?
30、在每个渲染迭代中,对每个着色器设置projection和view矩阵,现在只需要存储这些矩阵一次。首先,声明了一个叫做Matrices的Uniform块,将projection和view矩阵存储到Uniform块中,块中的变量可以直接访问。然后,在OpenGL中将这些矩阵值存入缓冲中,每个声明了这个Uniform块的着色器都能够访问这些矩阵。
31、GLSL定义了以gl_为前缀的内建变量,如:顶点着色器的输出向量gl_Position,它是顶点着色器的裁剪空间输出位置向量。
32、当需要从顶点着色器向片段着色器发送数组或结构体时,可以通过GLSL里的接口块组合这些变量。接口块的声明和结构体的声明类似,使用in或out关键字来定义输入输出。
33、在片段着色器中定义一个输入接口块,块名和顶点着色器中一样(VS_OUT),实例名是随意的。