17-VBO+VAO posted.pptx

advertisement
VertexArray
EECS487:Interactive
ComputerGraphics
Lecture17:
•  VertexBufferObject(VBO)
•  Vertex-ArrayObject(VAO)
•  Samplecodeat
http://web.eecs.umich.edu/~sugih/courses/eecs487/common/notes/gl3+webgl.tgz
Vertexarraymustbecopiedoneverydraw
VBOallowsdatatobestoredinGPUmemorybutstill
clientread/write-able
1.  GenerateandbindVBOdescriptor(s)
glGenBuffers(),glBindBuffer()
2.  AllocatespaceforVBOandpopulateitwithvertex
attribute(s)data
glBufferData(),glBufferSubData()
3.  TelltheGPUwhichattributeiswhereontheVBO
glEnableClientState(),glVertexPointer()
vertices[]
OpenGLstate
GL_COLOR_ARRAY
App/ClientMemory
systembus/network
VertexBufferObject(VBO)
StepstosetupanduseaVBO:
GL_VERTEX_ARRAY
GraphicsCard/
ServerMemory
color[]
Vertexattributedata
readfromclient
memorytoserver
memorywhenever
glDraw*()iscalled
Seeva.cpp
BufferObjectDescriptor
First,generatebufferobjectdescriptor(s)*:
int vbods[N];
glGenBuffers(GLsizei N, GLuint *vbods);
forexample,ifonly1bufferobjectisneeded:
int vbod;
glGenBuffers(1, &vbod);
*descriptor==handle==name==id
VertexBufferObject
App/ClientMemory
CurrentBufferObject
OpenGLstate
glGenBuffers()
vbod
Nextbindeachdescriptortoatypeofbuffer
glBindBuffer(GLenum target, GLuint vbod);
// target: GL_ARRAY_BUFFER,
// GL_ELEMENT_ARRAY_BUFFER (for indices)
vbo
objectholders
forexample:
glBindBuffer(GL_ARRAY_BUFFER, vbod);
systembus/network
Thisalsomakesthevbodbufferobjectthe
“current/in-use”bufferobject:allsubsequent
bufferobjectoperationsapplytothisbufferobject
GraphicsCard/
ServerMemory
IfvbodisNULL,disableBufferObject
VertexBufferObject
App/ClientMemory
vbod
GL_ARRAY_BUFFER
vbo
objectholders
systembus/network
OpenGLstate
glGenBuffers()
glBindBuffer()
BufferObjectData
Allocated(andinitialize)spaceforbufferobject:
glBufferData(GLenum target, GLsizei size,
GLvoid* data, GLenum usage);
// target:asbefore, size:sizeofdata,
// data:pointertosourcedataarray,NULLtoallocate
//
memorywithoutcontentinitialization
// usage:willdatabemodified?HelpsOpenGLdetermine
//
memorylocationtooptimizeperformance
forexample:
GraphicsCard/
ServerMemory
float vertices[3][2] =
{ {0.0, 0.0}, {0.0, 1.0}, {1.0, 0.0} };
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices),
vertices, GL_STATIC_DRAW);
VertexBufferObject
OpenGLstate
App/ClientMemory
vbod
GL_ARRAY_BUFFER
vbo
vertices[]
glGenBuffers()
glBindBuffer()
glBufferData()
MultipleVertexAttributes
Iftherearemultiplevertexattributes,wecanputthem
backtobackinthebufferobjectusing:
glBufferSubData(GLenum target, GLint
offset, GLsizei size, GLvoid* data);
objectholders
systembus/network
vertices[]
GraphicsCard/
ServerMemory
Vertexattributedata
copiedfromclientmemory
toservermemoryusing
glBufferData()or
glBufferSubData()
WhenglDraw*()iscalled,
dataisalreadyresident
MultipleVertexAttributesExample
float vertices[3][2] =
{ {0.0, 0.0}, {0.0, 1.0}, {1.0, 0.0} };
float color[3][3]= { {1.0, 0.0, 0.0},
{0.0, 1.0, 0.0}, {0.0, 0.0, 1.0} };
glBufferData(GL_ARRAY_BUFFER,
sizeof(vertices)+sizeof(color), NULL,
GL_STATIC_DRAW); // allocate space only
glBufferSubData(GL_ARRAY_BUFFER, 0,
sizeof(vertices), vertices); // copy data
glBufferSubData(GL_ARRAY_BUFFER,
sizeof(vertices), sizeof(color), color);
// copy data
// target:asbefore,offset:byteoffsetfromthe
// startofbufferascopytarget,size:sizeofdata,
// data:pointertosourcedataarray
Toavoidhavingtwocopiesofdata,clientcan
shareservermemoryusingglMapBuffer()/
glUnmapBuffer()afterthecalltoglBufferData()
(seePixelBufferObject(PBO)later)
VertexBufferObject
OpenGLstate
App/ClientMemory
vbod
GL_ARRAY_BUFFER
vbo
vertices[]
color[]
glGenBuffers()
glBindBuffer()
glBufferData()
glBufferSubData()
objectholders
systembus/network
vertices[] color[]
GraphicsCard/
ServerMemory
Vertexattributedata
copiedfromclientmemory
toservermemoryusing
glBufferData()or
glBufferSubData()
WhenglDraw*()iscalled,
dataisalreadyresident
CommonError
glGenBuffers()notcalledbeforeglBindBuffer()
Offsetisgivenincount,notinbytes,e.g.,ifthefirst
array(atoffset0)isofNelementsofclassVertex,
thecorrectoffsettothesecondarrayis:
N*sizeof(Vertex),notjustN
Ifoffsetiswrong,especiallywhenusing
glMapBuffer,GPUcanlockupand
systemmustberebooted
VertexBufferObjectUse
Totellthegraphicspipelinethatwe’repassingitan
arrayofvertices,aswithvertexarray,enable
GL_VERTEX_ARRAYinclientmemory:
•  glEnableClientState(GL_VERTEX_ARRAY)
Next,passthearray,specifyingthedataformat
used(differentfromvertexarray,thelastargument
isabyteoffsetfromthestartofbuffer)
•  glVertexPointer(GLint size, GLenum type,
GLsizei stride, const GLvoid *offset);
// size:#coordinatespervertex,type:datatype,
// stride=0meanscoordinatesarebacktoback,
// offset:byteoffsetfromthestartofbufferobject
Finally,drawaswithvertexarray
VertexBufferObjectUse
Allwehavedonesofariscopiedthevertices[]
andcolor[]arraystoabufferobject
Thegraphicspipelinehasnoideaoftheexistenceof
thebufferobjectnorwhatiscontainedinit
Weneedto:
1. tellthegraphicspipelinewhatisinthebufferobject
2. passthebufferobjecttothegraphicspipeline
VertexBufferObjectUseExample
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(2, GL_FLOAT, 0, 0);
glEnableClientState(GL_COLOR_ARRAY);
glColorPointer(3, GL_FLOAT, 0,
sizeof(vertices));
glDrawArrays(GL_TRIANGLES, 0, 3);
// start index: 0
// number of elements: 3
Withvertexbufferobject,client-sidedataarray
(vertices[]andcolor[])donotneedtobein
scopewhenglDraw*()iscalled
VertexBufferObject
Seevbo.cpp
OpenGLstate
App/ClientMemory
vbod
vbo
objectholders
GL_ARRAY_BUFFER
GL_VERTEX_ARRAY
GL_COLOR_ARRAY
systembus/network
vertices[] color[]
GraphicsCard/
ServerMemory
glGenBuffers()
vertices[]
color[]
glBindBuffer()
glBuffer[Sub]Data()
glEnableClientState()
glVertexPointer()
glColorPointer()
Vertexattributedata
copiedfromclientmemory
toservermemoryusing
glBufferData()or
glBufferSubData()
WhenglDraw*()iscalled,
dataisalreadyresident
VariousOpenGLObjects
BufferObjects:unformattedlinearmemory
•  VertexBufferObjects
•  PixelBufferObjects
•  UniformBufferObjects
VertexArrayObjects:encapsulatesetsofvertex
arraystatesincludingvbobindings
TextureObjects:anOpenGLobjectthatcontains
oneormoreimageswiththesameimageformat
FramebufferObjects
•  RenderbufferObjects
OpenGLObjectInGeneral
OpenGLisastatemachine
AnOpenGLobjectisacontainerthatencapsulatesa
particularsetofstates
ThesetofstatesanOpenGLobjectcontaindependsonthe
contextitisboundto:thestatesthatanobjectcontainsare
mappedintoandbecomethecontext’sstates,e.g.,
glBindBuffer(GL_ARRAY_BUFFER, vbod);
Toreadmore:
http://www.opengl.org/wiki/OpenGL_Objects
http://www.opengl.org/wiki/Buffer_Objects
http://www.opengl.org/wiki/Vertex_Buffer_Object
OpenGLObjectsManagement
AllOpenGLobjectsaremanagedthesameway:
•  glGen*()
•  glBind*()
•  use
•  glDelete*()
•  assoonasobjectusageisdone,alwayscallglBind*()with
objecthandle0tounbindobjectandcallglDelete*()to
deleteobject[I’llassumeyouknowthisalreadyandwon’tbe
mentioningitagain]
DrawingMultipleShapes
Todrawdifferentshapes,e.g.,cube,sphere,cone,
etc.multipletimes,wanttostorethevertex
attributesofeachshapeonceONLY,withre-use
Eventhen,withVBOalone,mustmakeseveralAPI
callstochangeOpenGLstateforeachshape,each
draw:
glBindBuffer(GL_ARRAY_BUFFER, vbods[i]);
glVertexPointer(2, GL_FLOAT, 0, vertex_offset);
glColorPointer(3, GL_FLOAT, 0, color_offset);
Vertex-ArrayObject
Vertex-ArrayObject(VAO)encapsulates
vertexattributestates
•  format,type,stride,storageinfo,and
•  attachedvertexbufferobjectifvboisused
Enablesrapidswitchingbetweensetsof
vertexarraystatesandvbobindingswith
asingleAPIcall,changingoneOpenGLstate:
glBindVertexArray(vaods[i]);
RequiresOpenGL3.0+
Vertex-ArrayObject
AswithotherOpenGLobjects,firstgenerate
vertex-arrayobjectdescriptor(s)/handle(s):
VertexArrayObjectwithoutVBO
vaods cone
cone
vao
GLuint vaods[N];
glGenVertexArrays(GLsizei N, GLuint *vaods);
forexample,ifonly2vertex-arrayobjectsareneeded:
App/ClientMemory
GLuint vaods[2];
glGenVertexArrays(2, vaods);
Nextbindandmakecurrenteachdescriptor
glBindVertexArray(GLuint vaods[int i]);
IfvaodsisNULL,disableVertex-ArrayObject
GraphicsCard/
ServerMemory
vertices[]
VAOw/oVBOis
supportedbyMacOSX,
butnotbyallother
graphicscarddrivers
OpenGLstate
current/
bound
SetupClient-SideVertexArray
Forcurrent/boundvertex-arrayobject,
populateVAObyenablingclient-sideaccess:
glEnableClientState(GL_VERTEX_ARRAY);
thenspecifyvertexarraylocation:
glVertexPointer(2, GL_FLOAT, 0, vertices);
Bothclientstateandvertexarraylocation
abovearesetwithinthecontextofaVAO
VAOw/oVBOissupportedbyMacOSX,
Thendraw:
butnotbyallothergraphicscarddrivers
VertexArrayObjectwithoutVBO
vaods cone
cone
vertices[]
vao
GL_VERTEX_ARRAY
VAOw/oVBOis
supportedbyMacOSX,
butnotbyallother
graphicscarddrivers
GL_COLOR_ARRAY
App/ClientMemory
Vertexattributedataread
fromclientmemoryto
servermemorywhenever
glDraw*()iscalled
GraphicsCard/
ServerMemory
glDrawArrays(GL_TRIANGLES, 0, 3);
VAOsSwitchingExample
float cone[N][3], ccolors[N][3];
float cube[M][3], bcolors[M][3];
vaods cone cube
// set up: assuming vaods[] have been generated
glBindVertexArray(vaods[CONE]);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, cone);
glEnableClientState(GL_COLOR_ARRAY);
glColorPointer(3, GL_FLOAT, 0, ccolors);
glBindVertexArray(vaods[CUBE]);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, cube);
glEnableClientState(GL_COLOR_ARRAY);
glColorPointer(3, GL_FLOAT, 0, bcolors);
// use: cone[], ccolors[], cube[],
glBindVertexArray(vaods[CONE]);
glDrawArrays(GL_TRIANGLE_STRIP, 0,
glBindVertexArray(vaods[CUBE]);
glDrawArrays(GL_TRIANGLE_STRIP, 0,
glBindVertexArray(vaods[CONE]);
glDrawArrays(GL_TRIANGLE_STRIP, 0,
VertexArrayObjectwithoutVBO
VAOw/oVBOis
supportedbyMac
OSX,butnotbyall
othergraphicscard
drivers
and bcolors[] must be in scope
N);
M);
N);
cone
vao
vao
GL_VERTEX_ARRAY
GL_VERTEX_ARRAY
GL_COLOR_ARRAY
GL_COLOR_ARRAY
App/ClientMemory
VAOw/oVBOis
GraphicsCard/
supportedbyMacOSX,
ServerMemory
butnotbyallother
graphicscarddrivers
vertices[]
color[]
cube
vertices[]
color[]
Vertexattributedataread
fromclientmemoryto
servermemorywhenever
glDraw*()iscalled
Seevao-va.cpp
VAOwithVBO
First,SetupVBO
Vertex-ArrayObjectwithVBO
float cone[N][3], ccolors[N][3];
float cube[M][3], bcolors[M][3];
enum {CONE=0, CUBE, NSHAPES};
cone
vertices[]
color[]
GLuint vbods[NSHAPES];
glGenBuffers(NSHAPES, vbods);
// set up the two vertex buffer objects
glBindBuffer(GL_ARRAY_BUFFER, vbods[CONE]);
glBufferData(GL_ARRAY_BUFFER, sizeof(cones)+sizeof(ccolors),
0, GL_STATIC_DRAW));
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(cone), cone);
glBufferSubData(GL_ARRAY_BUFFER,
sizeof(cone), sizeof(ccolors), ccolors);
glBindBuffer(GL_ARRAY_BUFFER, vbods[CUBE]);
glBufferData(GL_ARRAY_BUFFER, sizeof(cube)+sizeof(bcolors),
0, GL_STATIC_DRAW));
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(cube), cube);
glBufferSubData(GL_ARRAY_BUFFER,
sizeof(cube), sizeof(bcolors), bcolors);
Next,SetupVAOs
GLuint vaods[NSHAPES];
glGenVertexArrays(NSHAPES, vaods);
// set up the two vertex-array objects
glBindVertexArray(vaods[CONE]);
glBindBuffer(GL_ARRAY_BUFFER, vbods[CONE]);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, 0 /* buffer byte offset */);
glEnableClientState(GL_COLOR_ARRAY);
glColorPointer(3, GL_FLOAT, 0, sizeof(cone) /* byte offset */);
glBindVertexArray(vaods[CUBE]);
glBindBuffer(GL_ARRAY_BUFFER, vbods[CONE]);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, 0 /* byte offset */);
glEnableClientState(GL_COLOR_ARRAY);
glColorPointer(3, GL_FLOAT, 0, sizeof(cube) /* byte offset */);
cube
vbods cone cube
vertices[]
App/ClientMemory
color[]
vertices[] color[]
vertices[] color[]
GraphicsCard/ServerMemory
Vertex-ArrayObjectwithVBO
vaods cone cube
GL_ARRAY_BUFFER
GL_VERTEX_ARRAY
GL_COLOR_ARRAY
cone
GL_ARRAY_BUFFER
GL_VERTEX_ARRAY
GL_COLOR_ARRAY
vertices[]
color[]
cube
vbods cone cube
vertices[]
App/ClientMemory
vertices[] color[]
GraphicsCard/ServerMemory
color[]
vertices[] color[]
Finally,UseVAOstoSwitchShapes
// use, same as client-side, but cone[], ccolors[],
// cube[], and bcolors[] don’t need to be in scope
glBindVertexArray(vaods[CONE]);
glDrawArrays(GL_TRIANGLE_STRIP, 0, N);
glBindVertexArray(vaods[CUBE]);
glDrawArrays(GL_TRIANGLE_STRIP, 0, M);
glBindVertexArray(vaods[CONE]);
glDrawArrays(GL_TRIANGLE_STRIP, 0, N);
Seevao-vbo.cpp
Next:VBOandVAOwithshaders
Download