2017-3-28缓冲区-在缓冲区中填充及复制数据(buffers)
1、 如果你要放入缓冲的数据是不变的值,那么使用glClearBufferSubData()或者glClearNamedBufferSubData()会更有效率。原型如下:
voidglClearBufferSubData(GLenum target,
GLenuminternalformat,
GLintptr offset,
GLsizeiptr size,
GLenum format,
GLenum type,
const void * data);
voidglClearNamedBuffeSubData(GLuint buffer,
GLenuminternalformat,
GLintptr offset,
GLsizeiptr size,
GLenum format,
GLenum type,
const void *data);
第一个参数不在赘述,data参数即是要写入的数据,format和type是关于data的信息,format可以有GL_RED,GL_RG,GL_RGB,GL_RGBA四种选择,type则是数据类型,包括GL_BYTE,GL_UNSIGNED_BYTE,GL_SHORT,_GL_UNSIGNED_SHORT,GL_INT,GL_UNSIGNED_INT,GL_FLOAT,GL_DOUBLE,依次对应的C语言类型是:GLchar,GLuchar,GLshort,GLushort,Glint,GLuint,GLfloat,GLdouble.
2、 共享数据及复制缓冲区数据的方法:
voidglCopyBufferSubData(GLenumreadtarget,
GLenumwritetarget,
GLintptr readoffset,
GLintptr writeoffset,
GLsizeiptr size);
voidglCopyNamedBufferSubData(GLuintreadBuffer,
GLuint writeBuffer,
GLintptr readOffset,
GLintpt rwriteOffset,
GLsizeiptr size);
对于glCopyBufferSubData(),writetarget和readtarget可以是任何可获取到的缓冲区绑定点目标。然而,因为同一个绑定点一次只能绑定一个缓冲区,所以你不能在两个都绑定到如GL_ARRAY_BUFFER目标上的缓冲区之间进行数据拷贝。因此,当你进行拷贝的时候,你必须指定两个绑定点来绑定这两个缓冲区,但这样就会打断OpenGL状态(state)。
为了解决这个问题,OpenGL提供了GL_COPY_READ_BUFFER和GL_COPY_WRITE_BUFFER来专门允许你可以从一个缓冲区复制数据到另一个缓冲区而不会产生什么副作用。这两个目标在OpenGL中只会在这个地方用到,因此不会影响到其他缓冲区目标。
上面两个函数的后面三个参数指定了拷贝的开始位置及拷贝的大小,应注意确保读写区域均在相应的缓冲区对象中,都则会复制失败。
2017-3-28缓冲区-从缓冲区往顶点着色器中投放数据。
1、 可以通过顶点属性把缓冲区中的数据投递给顶点数组对象(VAO)。为了让顶点属性引用一个缓冲区对象,可以使用glVertexArrayAttribBinding()函数:
VoidglVertexArrayAttribBinding(GLuintv aobj,GLuint attribIndex,GLuint bindingIndex);
参数vaobj制定了顶点数组对象,attribIndex指定的是顶点属性的绑定索引,bindingIndex指的是数据源的绑定点。
2、为了告诉数据源在哪个缓冲区以及在缓冲区内部的哪里,我们可以使用下面这个函数来把一个缓冲区绑定到顶点缓冲区:
voidglVertexArrayVertexBuffer(GLuintvaobj,
GLuint bindingIndex,
GLuint buffer,
GLintptr offset,
GLsize stride);
第一个参数就是要操作的顶点数组对象,第二个参数应与glVertexArrayAttribBinding()的第3个参数一致,buffer即是数据源所在的绑定到bindingIndex上的缓冲区的名字,offset是指数据的起始位置的偏移量,stride是指顶点之间的步长(间隔),如果设为0,那么OpenGL会根据数据类型及size自动计算。
3、在指定完了了数据缓冲区后,需要告诉OpenGL这些数据时如何布局的:
glVerexArrayVertexBufferFormat(GLuintvaobj,
GLuint attribIndex,
Glint size,
GLenum type,
GLboolean normalized,
GLuint relativeOffset
);
需要注意的是size是每一个顶点的组成部分的数目,normalized指定是否在数据传递到shader前把数据归一化。比如假如shader要求输入的是浮点型数据,如果normalized设为true,而type又是GL_UNSIGNED_BYTE或者GL_INT,它就会用255去除这个数据再传递过去。relativeOffset是指从当前顶点起始处到所要的属性的起始处的偏移量。
location = binding[attrib.binding].memory + // Start of datastore in memory
binding[attrib.binding].offset + // Offset of vertexattribute in buffer
binding[attrib.binding].stride * vertex.index + // Start of*this*vertex
vertex.relative_offset; // Start of attribute relative tovertex
3、 最后一步就是调用glEnableVertexAttribArray()使得顶点属性自动从缓冲区中获取顶点信息投递到shader中。在不需要使用缓冲区的数据时,调用glDisableVertexAttribArray()即可。
2017-3-28缓冲区-顶点着色器多输入。
1、 假如shader中有以下输入变量:
layout (location=0) in vec3 position;
layout(location=1) in vec3 color;
2、 GLintglGetAttribLocation(GLuintprogram,constGLchar * name)函数可以获取shader中的输入变量的定位符(location的值)。找不到所要找的变量就返回-1。
3、 有两种连接主程序数据和顶点着色器输入变量的方式。一种是分离式,一种是交叉式。前者属性存储在不同的buffer中,至少是在同一个buffer中不同位置。