<GeeXLab Rootard Guide/>

Vertex Buffers


Last update: 2018.12.10 by JeGX

>> Back <<



The gh_vb library is used to create and manipulate vertex buffers (vertex buffer) in order to draw a list of vertices in the form of dots, lines or triangles. Each vertex can have any number of attributes depending on the needs of the demo.

The gh_vb library only handles lists (or arrays) of vertices, it does not support the indexed rendering (which involves an index buffer as in the gh_mesh library).

gh_vb is a low-level library, but once mastered and wrapped in a higher level interface in Lua or Python, its use becomes easy.

We will now see how to implement it to draw a simple triangle.

Creation of the vertex buffer.

attrib_size = 16 -- vec4 = 16 bytes
num_vertex_attribs = 2 -- position + color
vertex_size = num_vertex_attribs * attrib_size
num_vertices = 3 -- 3 vertices for a triangle
buffer_size = num_vertices * vertex_size 

vbid = gh_vb.create(buffer_size, num_vertex_attribs)

Until then, nothing wizard. We have created a vertex buffer to store 3 vertices. Each vertex is composed of a position (4 float) and a color (4 float too).

More complicated things are starting now. Each vertex attribute must be associated with its corresponding location in the vertex shader. This is how OpenGL works!

-- Simple vertex color GPU program

local vs_gl3= [[
#version 150
in vec4 Position; 
in vec4 Color; 
out vec4 v_color; 
void main() 
{ 
  gl_Position = vec4(Position.xy, 0.0, 1.0); 
  v_color = Color; 
} 
]]

local ps_gl3= [[
#version 150
in vec4 v_color; 
out vec4 FragColor; 
void main() 
{ 
  FragColor = v_color; 
}
]]


vertex_color_prog = gh_gpu_program.create_v2("vertex_color_prog", vs_gl3, ps_gl3)
gh_gpu_program.bind(vertex_color_prog) -- required for get_vertex_attrib_location()
gh_gpu_program.bind(0)



-- Position attrib
local vertex_attrib_index = 0
local loc = gh_gpu_program.get_vertex_attrib_location(vertex_color_prog, "Position")
local attrib_location = loc
local attrib_type = 1 -- float => 1 ; integer => 2
local dim = 4 -- vec4
local stride = vertex_size -- 16 bytes
local offset = 0 -- position
gh_vb.set_vertex_attrib_data(vbid, vertex_attrib_index, attrib_location, attrib_type, dim, stride, offset)


-- Color attrib
vertex_attrib_index = 1
loc = gh_gpu_program.get_vertex_attrib_location(vertex_color_prog, "Color")
attrib_location = loc
attrib_type = 1 -- float => 1 ; integer => 2
dim = 4 -- vec4
stride = vertex_size
offset = attrib_size -- color
gh_vb.set_vertex_attrib_data(vbid, vertex_attrib_index, attrib_location, attrib_type, dim, stride, offset)

That's it, the most complicated part is over. This part should be hidden in a higher level function (in Lua / Python).

We just have to fill the vertex buffer with positions and colors.

First you have to make the vertex buffer accessible to the CPU (the mapping) so you can write in:

gh_vb.map(vbid, "GL_WRITE_ONLY")


The first vertex (bottom left) with a red color:

-- position vertex 0
local buffer_offset_bytes = 0
gh_vb.set_value_4f(vbid, buffer_offset_bytes, -1, -1, 0, 1)

-- color vertex 0
buffer_offset_bytes = buffer_offset_bytes + attrib_size
gh_vb.set_value_4f(vbid, buffer_offset_bytes, 1.0, 0.0, 0.0, 1.0)


The second vertex (in the middle and at the top) with a green color:

-- position vertex 1
buffer_offset_bytes = buffer_offset_bytes + attrib_size
gh_vb.set_value_4f(vbid, buffer_offset_bytes, 0, 1, 0, 1)

-- color vertex 1
buffer_offset_bytes = buffer_offset_bytes + attrib_size
gh_vb.set_value_4f(vbid, buffer_offset_bytes, 0.0, 1.0, 0.0, 1.0)


The third vertex (bottom right) with a blue color:

-- position vertex 2
buffer_offset_bytes = buffer_offset_bytes + attrib_size
gh_vb.set_value_4f(vbid, buffer_offset_bytes, 1, -1, 0, 1)

-- color vertex 2
buffer_offset_bytes = buffer_offset_bytes + attrib_size
gh_vb.set_value_4f(vbid, buffer_offset_bytes, 0.0, 0.0, 1.0, 1.0)


Now that the data is written, we can disable unmapper the vertex buffer:

gh_vb.unmap(vbid)


That's it, our vertex buffer is created and initialized. We now draw it. We start by activating (or binding) the GPU program:

gh_gpu_program.bind(vertex_color_prog)


Once the GPU program is activated/bound, we can draw the vertex buffer:

gh_vb.bind(vbid)

local LINE_DEFAULT = 0
local LINE_STRIP = 1
local LINE_LOOP = 2
gh_vb.draw_lines(vbid, 3, 0, LINE_LOOP)

gh_vb.unbind(vbid)


The result in GeeXLab:


It is also possible to draw points:

gh_vb.bind(vbid)
gh_vb.draw_points(vbid, 3, 0)
gh_vb.unbind(vbid)


Or triangles:

gh_vb.bind(vbid)
local TRIANGLE = 0
local TRIANGLE_STRIP = 1
local TRIANGLE_FAN = 9
triangle_mode = TRIANGLE_FAN
gh_vb.draw_triangles(vbid, num_vertices, 0, triangle_mode)
gh_vb.unbind(vbid)




GeeXLab Rootard Guide | Downloads | Contact | Newsletter