Liaison Moderne des Attributs de Sommets (Vertex Attrib Binding)¶
Ce document décrit la modernisation du pipeline de spécification et de liaison des attributs de sommets dans suckless-ogl, passant de l'ancienne API glVertexAttribPointer à l'API moderne d'OpenGL 4.3+ Vertex Attrib Binding (glVertexAttribFormat, glVertexAttribBinding, glBindVertexBuffer).
1. Contexte et Motivation¶
Auparavant, le moteur s'appuyait sur le modèle classique de spécification des sommets d'OpenGL, où la configuration des attributs (taille, type, pas, décalage) était couplée à la liaison du tampon (VBO) via glVertexAttribPointer. Cette approche présentait plusieurs inconvénients :
- Conversion d'Entiers en Pointeurs : Les décalages (offsets) devaient être passés sous forme de const void*, nécessitant des macros comme utils_buffer_offset (qui convertissaient en interne des entiers en void*). Ce modèle déclenchait des avertissements stricts du compilateur et des outils de l'analyse statique (comme performance-no-int-to-ptr de clang-tidy).
- Couplage Fort : Tout changement de tampon nécessitait de spécifier à nouveau le format des attributs, ce qui augmentait le nombre d'appels au pilote OpenGL et le coût de validation des états.
L'Approche Moderne d'OpenGL 4.3+¶
L'API de Vertex Attrib Binding découple le format des attributs de sommets de leurs tampons sources (VBOs) :
1. Spécification du Format : glVertexAttribFormat définit la structure de l'attribut (taille, type, décalage relatif au sein de la structure) et l'associe à un emplacement d'attribut logique (slot).
2. Liaison Logique : glVertexAttribBinding relie cet emplacement d'attribut à un point de liaison (binding point) logique.
3. Liaison du Tampon : glBindVertexBuffer associe un tampon physique de la carte graphique (VBO) à un point de liaison logique, en indiquant le décalage de départ et le pas (stride).
graph TD
classDef buffer fill:#1a1b26,stroke:#7aa2f7,color:#7aa2f7,stroke-width:2
classDef slot fill:#1a1b26,stroke:#bb9af7,color:#bb9af7
classDef bindpoint fill:#1a1b26,stroke:#e0af68,color:#e0af68
VBO_Geom[VBO Géométrie]:::buffer
VBO_Inst[VBO Instance]:::buffer
BP_0[Point de liaison 0<br/>Pas: 3*sizeof(float)]:::bindpoint
BP_1[Point de liaison 1<br/>Pas: sizeof(SphereInstance)]:::bindpoint
Attr_0[Attribut 0 : Position]:::slot
Attr_1[Attribut 1 : Normales]:::slot
Attr_2[Attribut 2 : Albedo]:::slot
Attr_3[Attribut 3 : Métallique]:::slot
VBO_Geom -->|glBindVertexBuffer| BP_0
VBO_Inst -->|glBindVertexBuffer| BP_1
Attr_0 -->|glVertexAttribBinding| BP_0
Attr_1 -->|glVertexAttribBinding| BP_0
Attr_2 -->|glVertexAttribBinding| BP_1
Attr_3 -->|glVertexAttribBinding| BP_1
2. Détails du Refactoring¶
Le refactoring a impacté les composants suivants :
A. Suppression de utils_buffer_offset¶
La fonction utilitaire utils_buffer_offset a été complètement retirée de include/utils.h et src/utils.c. La spécification des décalages utilise désormais directement des valeurs GLuint simples, éliminant les casts en void*.
B. Standardisation des Points de Liaison¶
Le moteur adopte une convention claire pour les points de liaison au sein des VAO : - Points de liaison 0 & 1 : Données géométriques des sommets (positions, normales, coordonnées de texture). - Point de liaison 2 : Données d'instance (paramètres PBR des sphères, matrices d'instance, etc.).
C. Modules Refactorisés¶
- Utilitaires de Rendu (
src/render_utils.c) : render_utils_create_fullscreen_quadconfigure l'attribut de position avecglVertexAttribFormatet lie le VBO du quad viaglBindVertexBuffersur le point 0.render_utils_setup_sphere_instance_attributesprend maintenant un paramètreGLuint binding_pointet configure les attributs d'instance des sphères sur ce point de liaison logique.- Rendu Instancié (
src/instanced_rendering.c) : - Refactorisation de
instanced_group_bind_meshpour lier la géométrie du mesh (positions sur le point 0, normales sur le point 1) et les données d'instance (matrices/couleurs) sur le point 2. - Rendu Standard & SSBO (
src/scene_render.c,src/ssbo_rendering.c) : - Refactorisation de
scene_update_gpu_buffers(VAO icosphère) etssbo_group_bind_mesh(VAO géométrie SSBO) pour utiliser le modèle de liaison moderne découplé. - Interface Utilisateur (
src/ui.c) : setup_vertex_buffersmappe le flux de sommets d'ImGui (positions, uv, couleurs) avecglVertexAttribFormatsur le point de liaison 0.- Rendu de Traînées (
src/trail_renderer.c) : - Configuration des positions et couleurs des traînées sur le point de liaison 0.
- Rendu de Billboards & Shockwaves (
src/billboard_rendering.c,src/shockwave.c) : - Configuration de la géométrie du quad sur les points 0 et 1, et des données d'instance sur le point 2.
- Refactorisation de
shockwave_renderer_initpour le quad de billboard de l'onde de choc. - Débogage & Visualisation (
src/light_probes.c,src/effects/fx_lut_viz.c) : - Refactorisation de
light_probe_grid_init(VAO de la boîte englobante wireframe d'aide au débogage) pour utiliser VAB. - Refactorisation de
fx_lut_viz_init(VAO de la grille de points pour la LUT 3D) pour utiliser VAB.
3. Avantages¶
- Conformité aux Lints Stricts : Élimine la conversion d'entiers en pointeurs, résolvant tous les avertissements de type
performance-no-int-to-ptr. - Performances : La liaison des tampons indépendamment des formats réduit le coût de validation des états par le pilote GPU.
- Clarity : Séparation nette de la structure des données (format) et de l'emplacement physique en mémoire (tampons).