<Guide du Rootard GeeXLab/>
Vertex Buffers
Dernière mise à jour: 2018.12.10 par JeGX
>> Retour <<
La librairie
gh_vb permet de créer et manipuler des vertex buffers (vertex buffer = liste de vertices) afin de
rendre une liste de vertices sous la forme de points, de lignes ou de triangles. Chaque vertex peut avoir un nombre quelconque
d'attributs en fonction des besoin de la demo.
La librairie
gh_vb ne gère que des listes (ou tableaux) de vertices, elle ne gère pas le rendu indéxé (qui fait intervenir un
index buffer comme dans la librairie
gh_mesh).
gh_vb est une librairie de
bas niveau, mais une fois maitrisée et wrappée dans une interface de plus haut niveau en Lua ou Python,
son utilisation devient aisée.
Nous allons maintenant voir comment la mettre en oeuvre pour dessiner un simple triangle.
Creation du 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)
Jusqu'à là, rien de sorcier. Nous avons créé un vertex buffer pour stocker 3 vertices. Chaque vertex étant composé d'une position (4 float)
et d'une couleur (4 float aussi).
Les choses plus compliquées commencent maintenant. Il faut associer chaque attribut de vertex avec sa location correcpondante dans le
vertex shader. C'est le fonctionnement d'OpenGL!
-- 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)
Voilà, la partie la plus compliquée est terminée. Cette partie devrait être cachée dans une fonction de plus haut niveau (en Lua / Python).
Il ne nous reste qu'à remplir le vertex buffer avec les positions et les couleurs.
Il faut d'abord rendre le vertex buffer accessible au CPU (le mapping) afin de pouvoir écrire dedans:
gh_vb.map(vbid, "GL_WRITE_ONLY")
Le permier vertex (en bas et à gauche) avec une couleur rouge:
-- 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)
Le second vertex (au milieu et en haut) avec une couleur verte:
-- 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)
Le troisième vertex (en bas et à droite) avec une couleur bleue:
-- 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)
Maintenant que les données sont écrites, on peut désactiver unmapper le vertex buffer:
gh_vb.unmap(vbid)
Voilà, notre vertex buffer est créé et initialisé. On maintenant le dessiner.
On commence par activer le GPU program:
gh_gpu_program.bind(vertex_color_prog)
Une fois le GPU programme activé, on peut dessiner le 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)
Le résultat dans GeeXLab:
Il est également possible de rendre des points:
gh_vb.bind(vbid)
gh_vb.draw_points(vbid, 3, 0)
gh_vb.unbind(vbid)
Ou encore des 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)