1. 程式人生 > >OpenGL超級寶典第七版學習筆記-緩衝區-在緩衝區中填充及複製資料(buffers)

OpenGL超級寶典第七版學習筆記-緩衝區-在緩衝區中填充及複製資料(buffers)

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中不同位置。