{"id":52,"date":"2021-11-01T19:42:56","date_gmt":"2021-11-01T19:42:56","guid":{"rendered":"https:\/\/blogs.oregonstate.edu\/learnfromscratch\/?p=52"},"modified":"2021-11-01T19:42:56","modified_gmt":"2021-11-01T19:42:56","slug":"vertex-buffer-object","status":"publish","type":"post","link":"https:\/\/blogs.oregonstate.edu\/learnfromscratch\/2021\/11\/01\/vertex-buffer-object\/","title":{"rendered":"Vertex buffer object"},"content":{"rendered":"\n<p>1.0 <strong>Introduction<\/strong><\/p>\n\n\n\n<p>As a starter for graphic design, learners sometimes confuse where they should put objects\u2019 information such as vertex coordinate, texture coordinate, and surface normal coordinate. We learn to use<em> display lists<\/em> for static graphic designs in order to improve the overall performance. As the graphic program gets bigger, learners might see the need to further improve the program\u2019s performance. <em>Vertex buffer object (VBO) <\/em>is a good way to store vertex coordinates and vertex attributes on graphic cards. Then, every time an object is redrawn, its coordinates get pulled from the GPU instead of the CPU.\u00a0<\/p>\n\n\n\n<p>2.0<strong> Steps to create and use a vertex buffer object<\/strong><\/p>\n\n\n\n<p>Breaking down the process into small steps, I hope that this could help learners have a better understanding of the purpose of each steps and how to implement it. <\/p>\n\n\n\n<p>2.1: <strong><em>Create the vertex coordinates and vertex attributes<\/em><\/strong><\/p>\n\n\n\n<p>2.2: <strong><em>Create\/delet<\/em>e <em>a VBO with three steps<\/em><\/strong> [1]<\/p>\n\n\n\n<p>2.2.1 <strong>void glGenBuffers(GLsizei n, GLuint* ids) <\/strong>to create a new buffer object. N is the number of buffer objects to create; ids is the address of a GLuint variable.<\/p>\n\n\n\n<p>2.2.2 <strong>void glBindBuffer(GLenum target, GLuint id)<\/strong> to bind the buffer object to the corresponding ID. For vertex attributes including vertex coordinates, texture coordinates, surface normal coordinates and color arrays, target is <strong>GL_ARRAY_BUFFER<\/strong>. For vertex connection indices, the target is <strong>GL_ELEMENT_ARRAY_BUFFER<\/strong>.\u00a0<\/p>\n\n\n\n<p>2.2.3 <em><strong>copying vertex coordinates and vertex attributes into buffer objects.<\/strong><\/em><\/p>\n\n\n\n<p><strong>void glBufferData(GLenum target, GLsizei size, const void* data, GLenum usage) <\/strong><\/p>\n\n\n\n<p><em>Size<\/em> is the amount of bytes of data to be transferred. data is the memory address of the data to be transferred. If <em>data <\/em>is a NULL pointer, VPO will reserve the memory space for the given data size.\u00a0Usage flag specify how the VBO is used as following:\u00a0<\/p>\n\n\n\n<p class=\"has-text-align-left\">GL_STATIC_DRAW, GL_STATIC_READ, GL_STATIC_COPY<\/p>\n\n\n\n<p class=\"has-text-align-left\">GL_DYNAMIC_DRAW, GL_DYNAMIC_READ,GL_DYNAMIC_COPY<\/p>\n\n\n\n<p class=\"has-text-align-left\">GL_STREAM_DRAW, GL_STREAM_READ, GL_STREAM_COPY.&nbsp;<\/p>\n\n\n\n<p>If VBO does not change, we use &#8220;<em>Static<\/em>&#8221; . If data frequently changes, we use &#8220;dynamic&#8221;. If data changes for each frame, we use &#8220;stream&#8221;. \u201c<em>Draw<\/em>\u201d specifies data to draw, \u201c<em>read<\/em>\u201d specifies data to read by the client\u2019s application, and \u201c<em>copy<\/em>\u201d specifies data to both read and draw.\u00a0<\/p>\n\n\n\n<p>void <strong>glDeleteBuffers<\/strong>(GLsizei n, const GLuint* ids) is used to delete the VBO when users finish using the buffer object.<\/p>\n\n\n\n<p>2.3 <strong><em>Activate\/ deactivate the drawing data<\/em><\/strong><\/p>\n\n\n\n<p>\u00a0<strong>glEnableClientState<\/strong>(type) is used to activate the drawing data. <\/p>\n\n\n\n<p>The type could be <strong>GL_VERTEX_ARRAY, GL_COLOR_ARRAY, GL_NORMAL_ARRAY. Or GL_TEXTURE_COORD_ARRAY.\u00a0<\/strong><\/p>\n\n\n\n<p>To deactivating the client state, using the function <strong>glDisableClientState(type)<\/strong><\/p>\n\n\n\n<p>2.4<strong> <em>Getting each Data Type from Buffer<\/em><\/strong><\/p>\n\n\n\n<p><strong>glVertexPointer<\/strong>( size, type, stride, offset);<\/p>\n\n\n\n<p><strong>glColorPointer<\/strong>( size, type, stride, offset)<strong>;<\/strong><\/p>\n\n\n\n<p><strong>glNormalPointer<\/strong>( type, stride, offset);<\/p>\n\n\n\n<p><strong>glTexCoordPointer<\/strong>( size, type, stride, offset);<\/p>\n\n\n\n<p>Size specifies numbers per vertex (2, 3, or 4. Type specifies GL_SHORT, GL_INT, GL_FLOAT, or GL_DOUBLE. Stride is the byte offset between consecutive data. Offset is the byte offset from the beginning of the data array buffer to the first element of the data type. Depending on how data is stored in the array buffer (packed or interleaved arrangement, stride and offset can be set differently.&nbsp;<\/p>\n\n\n\n<p>2.5 <strong><em>Drawing using glDrawArrays() or glDrawElements()<\/em><\/strong><\/p>\n\n\n\n<p><strong>void glDrawArrays(<\/strong>GLenum mode, GLint first, GLsizei, count<strong>)<\/strong><\/p>\n\n\n\n<p>glDrawArrays() is used if the enabled arrays are arranged in the order of vertices. Mode defines which topology is used, it accepts GL_POINTS, GL_LINE_STRIP, GL_LINE_LOOP, GL_LINES, GL_LINE_STRIP_ADJACENCY, GL_LINES_ADJACENCY, GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN, GL_TRIANGLES, GL_TRIANGLE_STRIP_ADJACENCY, GL_TRIANGLES_ADJACENCY, GL_PATCHES. <\/p>\n\n\n\n<p><em>First<\/em> is the starting index in the enabled arrays and count is the number of indices to be rendered [2].\u00a0<\/p>\n\n\n\n<p>void <strong>glDrawElements<\/strong>(GLenum mode, GLsizei count, GLenum type, const void * indices).\u00a0<\/p>\n\n\n\n<p>The glDrawElements() requires four arguments, but it allows the reuse of the same vertices. Mode is similar as in glDrawArrays(). Count specifies the number of elements needed to render. Type specifies the data type (GL_UNSIGNED_BYTE, GL_UNSIGNED_SHORT, or GL_UNSIGNED_INT). Indices specify a pointer to the address of the indices array [3].\u00a0<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"385\" src=\"https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/4779\/files\/2021\/11\/1-1024x385.png\" alt=\"\" class=\"wp-image-53\" srcset=\"https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/4779\/files\/2021\/11\/1-1024x385.png 1024w, https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/4779\/files\/2021\/11\/1-300x113.png 300w, https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/4779\/files\/2021\/11\/1-768x289.png 768w, https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/4779\/files\/2021\/11\/1.png 1272w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><figcaption>Figure 1: Drawing a cube using glDrawArrays() and glDrawElements()<br>Source: https:\/\/www.khronos.org\/registry\/OpenGL-Refpages\/gl4\/.[4]<br><\/figcaption><\/figure>\n\n\n\n<p>2.6<strong> <em>Mapping data from buffer object to the client&#8217;s address space<\/em><\/strong><\/p>\n\n\n\n<p><strong>void *glMapBuffer(<\/strong>GLenum target, GLenum access<strong>);<\/strong><\/p>\n\n\n\n<p>This function returns a pointer to the stored data; users can directly\u00a0 read and\/or write to the buffer object&#8217;s mapped data store. <em>Target<\/em> could be GL_ARRAY_BUFFER, GL_TEXTURE_BUFFER, etc. <em>Access<\/em> can be one of the following GL_READ_ONLY, GL_WRITE_ONLY, or GL_READ_WRITE.\u00a0<\/p>\n\n\n\n<p>The function GLboolean <strong>glUnmapBuffer<\/strong>(GLenum target)is used to cancel the buffer object&#8217;s data store from the client&#8217;s address space<\/p>\n\n\n\n<p>3.0 <strong>Indexed Vertex Buffer Object C++ Class\u00a0<\/strong><\/p>\n\n\n\n<p>Figure 2 shows methods supported by the indexed VBO C++ Class, and an example is shown in Figure 3 to demonstrate how the class is used.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1224\" height=\"564\" src=\"https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/4779\/files\/2021\/11\/2-1024x472.png\" alt=\"\" class=\"wp-image-54\" srcset=\"https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/4779\/files\/2021\/11\/2-1024x472.png 1024w, https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/4779\/files\/2021\/11\/2-300x138.png 300w, https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/4779\/files\/2021\/11\/2-768x354.png 768w, https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/4779\/files\/2021\/11\/2.png 1224w\" sizes=\"auto, (max-width: 1224px) 100vw, 1224px\" \/><figcaption>Figure 2 shows methods are supported by the indexed Vertex Buffer Object C++ Class. Source: <a href=\"https:\/\/doc.lagout.org\/programmation\/OpenGL\/OpenGL%20Insights_%20OpenGL%2C%20OpenGL%20ES%2C%20and%20WebGL%20Community%20Experiences%20%5BCozzi%20%26%20Riccio%202012-07-23%5D.pdf\">https:\/\/doc.lagout.org\/programmation\/OpenGL\/OpenGL%20Insights_%20OpenGL%2C%20OpenGL%20ES%2C%20and%20WebGL%20Community%20Experiences%20%5BCozzi%20%26%20Riccio%202012-07-23%5D.pdf<\/a> [5]\u00a0<br><\/figcaption><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"931\" height=\"1024\" src=\"https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/4779\/files\/2021\/11\/3-931x1024.png\" alt=\"\" class=\"wp-image-55\" srcset=\"https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/4779\/files\/2021\/11\/3-931x1024.png 931w, https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/4779\/files\/2021\/11\/3-273x300.png 273w, https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/4779\/files\/2021\/11\/3-768x845.png 768w, https:\/\/osu-wams-blogs-uploads.s3.amazonaws.com\/blogs.dir\/4779\/files\/2021\/11\/3.png 936w\" sizes=\"auto, (max-width: 931px) 100vw, 931px\" \/><figcaption>Figure 3: Example of using the VBO class to draw a colored cube. <br>Source:  <a href=\"https:\/\/doc.lagout.org\/programmation\/OpenGL\/OpenGL%20Insights_%20OpenGL%2C%20OpenGL%20ES%2C%20and%20WebGL%20Community%20Experiences%20%5BCozzi%20%26%20Riccio%202012-07-23%5D.pdf\">https:\/\/doc.lagout.org\/programmation\/OpenGL\/OpenGL%20Insights_%20OpenGL%2C%20OpenGL%20ES%2C%20and%20WebGL%20Community%20Experiences%20%5BCozzi%20%26%20Riccio%202012-07-23%5D.pdf<\/a> [5]\u00a0 <\/figcaption><\/figure>\n\n\n\n<p>4.0 <strong>Conclusion<\/strong><\/p>\n\n\n\n<p>The Vertex Buffer Object provides a great tool for graphic design\u2019s learners to improve the efficiency of data transferring by storing the vertex coordinates and vertex attributes on the GPU. With VBO, vertex data will be transferred from client memory once instead of for every frame.\u00a0<\/p>\n\n\n\n<p class=\"has-text-align-center\"><strong>Reference<\/strong><\/p>\n\n\n\n<p>[1]Song Ho Ahn. (2018). <em>OpenGL Vertex Buffer Object(VBO)<\/em>. [Online]. Available: <a href=\"http:\/\/www.songho.ca\/opengl\/gl_vbo.html\">http:\/\/www.songho.ca\/opengl\/gl_vbo.html<\/a>. Accessed Oct 31, 2021.\u00a0<\/p>\n\n\n\n<p>[2] OpenGL4.5.<em> glDrawArrays<\/em>.docs.gl. [Online]. Available:\u00a0 <a href=\"https:\/\/docs.gl\/gl4\/glDrawArrays\">https:\/\/docs.gl\/gl4\/glDrawArrays<\/a>. Accessed Oct 31, 2021.\u00a0<\/p>\n\n\n\n<p>[3] OpenGL\u00ae 4.5 Reference Pages. <em>glDrawElements<\/em>. Kronos.org.<strong> <\/strong>[Online]. Available: https:\/\/www.khronos.org\/registry\/OpenGL-Refpages\/gl4\/. Accessed Oct 31, 2021.\u00a0<\/p>\n\n\n\n<p>[4] Song Ho Ahn. (2018). <em>OpenGL Vertex Array<\/em>. [Online]. Available: <a href=\"http:\/\/www.songho.ca\/opengl\/gl_vertexarray_quad.html\">http:\/\/www.songho.ca\/opengl\/gl_vertexarray_quad.html<\/a>. Accessed Oct 31, 2021<\/p>\n\n\n\n<p>[5] Patrick Cozzi and Christophe Riccio.(2012). OpenGL Insights. CRC press. [Online]. Available: <a href=\"https:\/\/doc.lagout.org\/programmation\/OpenGL\/OpenGL%20Insights_%20OpenGL%2C%20OpenGL%20ES%2C%20and%20WebGL%20Community%20Experiences%20%5BCozzi%20%26%20Riccio%202012-07-23%5D.pdf\">https:\/\/doc.lagout.org\/programmation\/OpenGL\/OpenGL%20Insights_%20OpenGL%2C%20OpenGL%20ES%2C%20and%20WebGL%20Community%20Experiences%20%5BCozzi%20%26%20Riccio%202012-07-23%5D.pdf<\/a>. Access Oct 31, 2021<\/p>\n","protected":false},"excerpt":{"rendered":"<p>1.0 Introduction As a starter for graphic design, learners sometimes confuse where they should put objects\u2019 information such as vertex coordinate, texture coordinate, and surface normal coordinate. We learn to use display lists for static graphic designs in order to improve the overall performance. As the graphic program gets bigger, learners might see the need&hellip; <a class=\"more-link\" href=\"https:\/\/blogs.oregonstate.edu\/learnfromscratch\/2021\/11\/01\/vertex-buffer-object\/\">Continue reading <span class=\"screen-reader-text\">Vertex buffer object<\/span><\/a><\/p>\n","protected":false},"author":11550,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-52","post","type-post","status-publish","format-standard","hentry","category-uncategorized","entry"],"_links":{"self":[{"href":"https:\/\/blogs.oregonstate.edu\/learnfromscratch\/wp-json\/wp\/v2\/posts\/52","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blogs.oregonstate.edu\/learnfromscratch\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.oregonstate.edu\/learnfromscratch\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.oregonstate.edu\/learnfromscratch\/wp-json\/wp\/v2\/users\/11550"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.oregonstate.edu\/learnfromscratch\/wp-json\/wp\/v2\/comments?post=52"}],"version-history":[{"count":2,"href":"https:\/\/blogs.oregonstate.edu\/learnfromscratch\/wp-json\/wp\/v2\/posts\/52\/revisions"}],"predecessor-version":[{"id":57,"href":"https:\/\/blogs.oregonstate.edu\/learnfromscratch\/wp-json\/wp\/v2\/posts\/52\/revisions\/57"}],"wp:attachment":[{"href":"https:\/\/blogs.oregonstate.edu\/learnfromscratch\/wp-json\/wp\/v2\/media?parent=52"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.oregonstate.edu\/learnfromscratch\/wp-json\/wp\/v2\/categories?post=52"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.oregonstate.edu\/learnfromscratch\/wp-json\/wp\/v2\/tags?post=52"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}