gKit2 light
Loading...
Searching...
No Matches
tuto_mdi_elements_count.cpp
1
3
4#include "app_camera.h"
5
6#include "mesh.h"
7#include "wavefront.h"
8
9#include "orbiter.h"
10#include "program.h"
11#include "uniforms.h"
12
13// representation des parametres de multidrawELEMENTSindirect
14struct IndirectParam
15{
16 unsigned index_count;
17 unsigned instance_count;
18 unsigned first_index;
19 unsigned vertex_base;
20 unsigned instance_base;
21};
22
23
24class TP : public AppCamera
25{
26public:
27 TP( ) : AppCamera(1024, 640, 4, 3) {} // openGL version 4.3, ne marchera pas sur mac.
28
29 int init( )
30 {
31 // verifier la presence de l'extension indirect_parameter,
32 // cf la doc https://registry.khronos.org/OpenGL/extensions/ARB/ARB_indirect_parameters.txt
33 if(GLAD_GL_ARB_indirect_parameters == 0)
34 // erreur, extension non disponible
35 return -1;
36
37 // charge un objet indexe
38 m_objet= read_indexed_mesh("data/robot.obj");
39
40 Point pmin, pmax;
41 m_objet.bounds(pmin, pmax);
42 m_camera.lookat(pmin, pmax);
43
44 // trie les triangles de l'objet par matiere.
45 std::vector<TriangleGroup> groups= m_objet.groups();
46
47 /* parcours chaque groupe et construit les parametres du draw correspondant
48 on peut afficher les groupes avec glDrawElememnts, comme d'habitude :
49
50 glBindVertexArray(m_vao);
51 glUseProgram(m_program);
52 glUniform();
53
54 for(unsigned i= 0; i < groups.size(); i++)
55 glDrawElements(GL_TRIANGLES, /count/ groups[i].n, /type/ GL_UNSIGNED_INT, /offset/ groups[i].first * sizeof(unsigned));
56
57 on peut remplir une structure IndirectParam par draw... et utiliser un seul appel a multidrawindirect
58 */
59
60 std::vector<IndirectParam> params;
61 for(unsigned i= 0; i < groups.size(); i++)
62 {
63 params.push_back({
64 unsigned(groups[i].n), // count
65 1, // instance_count
66 unsigned(groups[i].first), // first_index
67 0, // vertex_base, pas la peine de renumeroter les sommets
68 0 // instance_base, pas d'instances
69 });
70 }
71
72 m_draws= params.size();
73
74 // transferer dans un buffer
75 glGenBuffers(1, &m_indirect_buffer);
76 glBindBuffer(GL_DRAW_INDIRECT_BUFFER, m_indirect_buffer);
77 glBufferData(GL_DRAW_INDIRECT_BUFFER, params.size() * sizeof(IndirectParam), params.data(), GL_STATIC_READ);
78
79 // buffer pour le nombre de draw
80 unsigned n= params.size() - 2;
81 glGenBuffers(1, &m_indirect_count_buffer);
82 glBindBuffer(GL_PARAMETER_BUFFER_ARB, m_indirect_count_buffer);
83 glBufferData(GL_PARAMETER_BUFFER_ARB, sizeof(unsigned), &n, GL_STATIC_READ);
84 // remarque : on pourrait aussi ajouter le compteur dans indirect_buffer, mais c'est sans doute plus lisible comme ca...
85
86 // construire les buffers de l'objet
87 m_vao= m_objet.create_buffers(/* use texcoord */ false, /* use normal */ true, /* use color */ false, /* use material index */ false);
88
89 // et charge un shader..
90 m_program= read_program("gkit2_tutos/M2/indirect_elements.glsl");
91 program_print_errors(m_program);
92
93 // etat openGL par defaut
94 glClearColor(0.2f, 0.2f, 0.2f, 1.f); // couleur par defaut de la fenetre
95
96 glClearDepth(1.f); // profondeur par defaut
97 glDepthFunc(GL_LESS); // ztest, conserver l'intersection la plus proche de la camera
98 glEnable(GL_DEPTH_TEST); // activer le ztest
99
100 return 0;
101 }
102
103 int quit( )
104 {
105 // todo
106 return 0;
107 }
108
109 int render( )
110 {
111 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
112
113 // recupere les transformations
114 Transform model;
115 Transform view= camera().view();
116 Transform projection= camera().projection();
117 Transform mv= view * model;
118 Transform mvp= projection * mv;
119
120 // parametre le shader
121 glBindVertexArray(m_vao);
122 glUseProgram(m_program);
123
124 program_uniform(m_program, "mvpMatrix", mvp);
125 program_uniform(m_program, "mvMatrix", mv);
126
127 #if 0
128 // parametre du multidraw indirect
129 glBindBuffer(GL_DRAW_INDIRECT_BUFFER, m_indirect_buffer);
130 glMultiDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, /* indirect */ 0, /* draw count */ m_draws, /* stride */ 0);
131 // on dessine tout
132 #else
133
134 // parametres du multidraw indirect count
135 glBindBuffer(GL_DRAW_INDIRECT_BUFFER, m_indirect_buffer);
136 glBindBuffer(GL_PARAMETER_BUFFER_ARB, m_indirect_count_buffer);
137 glMultiDrawElementsIndirectCountARB(GL_TRIANGLES, GL_UNSIGNED_INT, /* indirect */ 0, /* draw count */ 0, /* max draw count */ m_draws, /* stride */ 0);
138 // on dessine tout, sauf les 2 derniers groupes... cf init du compteur / indirect_count_buffer
139 #endif
140
141 return 1;
142 }
143
144protected:
145 GLuint m_indirect_buffer;
146 GLuint m_indirect_count_buffer;
147 GLuint m_vao;
148 GLuint m_program;
149 Transform m_model;
150
151 Mesh m_objet;
152 int m_draws;
153};
154
155int main( )
156{
157 TP app;
158 app.run();
159
160 return 0;
161}
classe application.
Definition app_camera.h:19
const Orbiter & camera() const
renvoie l'orbiter gere par l'application.
Definition app_camera.h:37
AppCamera(const int width, const int height, const int major=3, const int minor=3, const int samples=0)
constructeur, dimensions de la fenetre et version d'openGL.
Definition app_camera.cpp:5
int run()
execution de l'application.
Definition app.cpp:36
representation d'un objet / maillage.
Definition mesh.h:121
Transform projection(const int width, const int height, const float fov)
fixe la projection reglee pour une image d'aspect width / height, et une demi ouverture de fov degres...
Definition orbiter.cpp:48
Transform view() const
renvoie la transformation vue.
Definition orbiter.cpp:41
Definition alpha.cpp:58
int render()
a deriver pour afficher les objets. renvoie 1 pour continuer, 0 pour fermer l'application.
int quit()
a deriver pour detruire les objets openGL. renvoie -1 pour indiquer une erreur, 0 sinon.
int init()
a deriver pour creer les objets openGL. renvoie -1 pour indiquer une erreur, 0 sinon.
Mesh read_indexed_mesh(const char *filename)
charge un fichier wavefront .obj et renvoie un mesh compose de triangles indexes. utiliser glDrawElem...
GLuint read_program(const char *filename, const char *definitions)
Definition program.cpp:218
int program_print_errors(const GLuint program)
affiche les erreurs de compilation.
Definition program.cpp:446
tuto_mdi_elements.cpp exemple d'utilisation de multidrawindirect pour des triangles indexes.
Definition tuto_mdi.cpp:22
representation d'un point 3d.
Definition vec.h:21
representation d'une transformation, une matrice 4x4, organisee par ligne / row major.
Definition mat.h:21