gKit2 light
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
14 struct 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 
24 class TP : public AppCamera
25 {
26 public:
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(GLEW_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("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 
144 protected:
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 
155 int 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
int run()
execution de l'application.
Definition: app.cpp:36
representation d'un objet / maillage.
Definition: mesh.h:112
GLuint create_buffers(const bool use_texcoord, const bool use_normal, const bool use_color, const bool use_material_index)
construit les buffers et le vertex array object necessaires pour dessiner l'objet avec openGL....
Definition: mesh.cpp:581
std::vector< TriangleGroup > groups()
renvoie les groupes de triangles de meme matiere. re-organise les triangles. permet d'afficher l'obje...
Definition: mesh.cpp:305
void bounds(Point &pmin, Point &pmax) const
renvoie min et max les coordonnees des extremites des positions des sommets de l'objet (boite engloba...
Definition: mesh.cpp:503
void lookat(const Point &center, const float size)
observe le point center a une distance size.
Definition: orbiter.cpp:7
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:47
Transform view() const
renvoie la transformation vue.
Definition: orbiter.cpp:40
Definition: alpha.cpp:59
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...
Definition: wavefront.cpp:197
GLuint read_program(const char *filename, const char *definitions)
Definition: program.cpp:204
void program_uniform(const GLuint program, const char *uniform, const std::vector< unsigned > &v)
affecte un tableau de valeurs a un uniform du shader program.
Definition: uniforms.cpp:94
int program_print_errors(const GLuint program)
affiche les erreurs de compilation.
Definition: program.cpp:432
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