gKit2 light
Loading...
Searching...
No Matches
tuto_mdi.cpp
Go to the documentation of this file.
1
3
4#include <chrono>
5
6#include "mat.h"
7#include "program.h"
8#include "uniforms.h"
9
10#include "wavefront.h"
11#include "texture.h"
12
13#include "orbiter.h"
14#include "draw.h"
15
16#include "app.h"
17#include "text.h"
18
19
20// representation des parametres de multidrawARRAYS
22{
23 unsigned vertex_count;
24 unsigned instance_count;
25 unsigned first_vertex;
26 unsigned first_instance;
27};
28
29
30
31class TP : public App
32{
33public:
34 TP( ) : App(1024, 640, 4, 6) {} // openGL version 4.6, ne marchera pas sur mac.
35
36 int init( )
37 {
38 if(!GLAD_GL_ARB_indirect_parameters)
39 return -1;
40 printf("GL_ARB_indirect_parameters ON\n");
41
42 m_objet= read_mesh("data/bigguy.obj");
43 Point pmin, pmax;
44 m_objet.bounds(pmin, pmax);
45
46 m_camera.lookat(pmin - Vector(200, 200, 0), pmax + Vector(200, 200, 0));
47
48 // genere les parametres des draws et les transformations
49 for(int y= -15; y <= 15; y++)
50 for(int x= -15; x <= 15; x++)
51 {
52 m_multi_model.push_back( Translation(x *20, y *20, 0) );
53 m_multi_indirect.push_back( { unsigned(m_objet.vertex_count()), 1, 0, 0} );
54 }
55 // oui c'est la meme chose qu'un draw instancie, mais c'est juste pour comparer les 2 solutions...
56
57 // stockage des parametres du multi draw indirect
58 glGenBuffers(1, &m_indirect_buffer);
59 glBindBuffer(GL_DRAW_INDIRECT_BUFFER, m_indirect_buffer);
60 glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(IndirectParam) * m_multi_indirect.size(), &m_multi_indirect.front(), GL_DYNAMIC_DRAW);
61
62 // stockage des matrices des objets
63 glGenBuffers(1, &m_model_buffer);
64 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_model_buffer);
65 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(Transform) * m_multi_model.size(), &m_multi_model.front(), GL_DYNAMIC_DRAW);
66
67 // creation des vertex buffer, uniquement les positions
68 m_vao= m_objet.create_buffers(/* texcoord */ false, /* normal */ false, /* color */ false, /* material */ false);
69
70 // shader programs
71 m_program_direct= read_program("gkit2_tutos/M2/indirect_direct.glsl"); // affichage classique N draws
72 program_print_errors(m_program_direct);
73
74 m_program= read_program("gkit2_tutos/M2/indirect.glsl"); // affichage indirect 1 multi draw
75 program_print_errors(m_program);
76
77 // affichage du temps cpu / gpu
78 m_console= create_text();
79
80 // mesure du temps gpu de glDraw
81 glGenQueries(1, &m_time_query);
82
83 // etat openGL par defaut
84 glClearColor(0.2f, 0.2f, 0.2f, 1.f); // couleur par defaut de la fenetre
85
86 glClearDepth(1.f); // profondeur par defaut
87 glDepthFunc(GL_LESS); // ztest, conserver l'intersection la plus proche de la camera
88 glEnable(GL_DEPTH_TEST); // activer le ztest
89
90 return 0; // ras, pas d'erreur
91 }
92
93 int quit( )
94 {
95 glDeleteQueries(1, &m_time_query);
96 release_text(m_console);
97
98 release_program(m_program);
99 m_objet.release();
100 glDeleteBuffers(1, &m_indirect_buffer);
101
102 return 0;
103 }
104
105 int update( const float time, const float delta )
106 {
107 m_model= RotationY(time / 20);
108 return 0;
109 }
110
111 int render( )
112 {
113 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
114
115 // deplace la camera
116 int mx, my;
117 unsigned int mb= SDL_GetRelativeMouseState(&mx, &my);
118 if(mb & SDL_BUTTON(1)) // le bouton gauche est enfonce
119 m_camera.rotation(mx, my);
120 else if(mb & SDL_BUTTON(3)) // le bouton droit est enfonce
121 m_camera.move(mx);
122 else if(mb & SDL_BUTTON(2)) // le bouton du milieu est enfonce
123 m_camera.translation((float) mx / (float) window_width(), (float) my / (float) window_height());
124
125 // mesure le temps d'execution du draw
126 glBeginQuery(GL_TIME_ELAPSED, m_time_query); // pour le gpu
127 std::chrono::high_resolution_clock::time_point cpu_start= std::chrono::high_resolution_clock::now(); // pour le cpu
128
129 #if 0
130 // dessine n copies de l'objet avec 1 glDrawArrays par copie
131 glBindVertexArray(m_vao);
132 glUseProgram(m_program_direct);
133
134 program_uniform(m_program_direct, "modelMatrix", m_model);
135 program_uniform(m_program_direct, "vpMatrix", m_camera.projection(window_width(), window_height(), 45) * m_camera.view());
136 program_uniform(m_program_direct, "viewMatrix", m_camera.view());
137
138 // dessine l'objet avec 1 draw par copie
139 for(int i= 0; i < int(m_multi_model.size()); i++)
140 {
141 program_uniform(m_program_direct, "objectMatrix", m_multi_model[i]);
142 glDrawArrays(GL_TRIANGLES, 0, m_objet.vertex_count());
143 }
144 // dans ce cas particulier, on pourrait utiliser un draw instancie, mais ce n'est pas le but du tuto...
145
146 #else
147 // dessine n copies de l'objet avec 1 seul appel a glMultiDrawArraysIndirect
148 glBindVertexArray(m_vao);
149 glUseProgram(m_program);
150
151 // uniforms...
152 program_uniform(m_program, "modelMatrix", m_model);
153 program_uniform(m_program, "vpMatrix", m_camera.projection(window_width(), window_height(), 45) * m_camera.view());
154 program_uniform(m_program, "viewMatrix", m_camera.view());
155
156 // buffers...
157 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_model_buffer);
158 glBindBuffer(GL_DRAW_INDIRECT_BUFFER, m_indirect_buffer);
159
160 glMultiDrawArraysIndirect(m_objet.primitives(), 0, m_multi_indirect.size(), 0);
161 #endif
162
163
164 // affiche le temps
165 std::chrono::high_resolution_clock::time_point cpu_stop= std::chrono::high_resolution_clock::now();
166 long long int cpu_time= std::chrono::duration_cast<std::chrono::nanoseconds>(cpu_stop - cpu_start).count();
167
168 glEndQuery(GL_TIME_ELAPSED);
169
170 // recupere le resultat de la requete gpu
171 GLint64 gpu_time= 0;
172 glGetQueryObjecti64v(m_time_query, GL_QUERY_RESULT, &gpu_time);
173
174 clear(m_console);
175 printf(m_console, 0, 0, "cpu %02dms %03dus", (int) (cpu_time / 1000000), (int) ((cpu_time / 1000) % 1000));
176 printf(m_console, 0, 1, "gpu %02dms %03dus", (int) (gpu_time / 1000000), (int) ((gpu_time / 1000) % 1000));
177
178 draw(m_console, window_width(), window_height());
179
180 printf("cpu %02dms %03dus ", (int) (cpu_time / 1000000), (int) ((cpu_time / 1000) % 1000));
181 printf("gpu %02dms %03dus\n", (int) (gpu_time / 1000000), (int) ((gpu_time / 1000) % 1000));
182
183 return 1;
184 }
185
186protected:
187 GLuint m_indirect_buffer;
188 GLuint m_model_buffer;
189 GLuint m_time_query;
190
191 GLuint m_vao;
192 GLuint m_program;
193 GLuint m_program_direct;
194
195 Text m_console;
196
197 Transform m_model;
198 Mesh m_objet;
199 Orbiter m_camera;
200
201 std::vector<IndirectParam> m_multi_indirect;
202 std::vector<Transform> m_multi_model;
203
204};
205
206
207int main( int argc, char **argv )
208{
209 TP tp;
210 tp.run();
211
212 return 0;
213}
classe application.
Definition app.h:20
int run()
execution de l'application.
Definition app.cpp:36
representation d'un objet / maillage.
Definition mesh.h:121
representation de la camera, type orbiter, placee sur une sphere autour du centre de l'objet.
Definition orbiter.h:17
Definition alpha.cpp:58
int render()
a deriver pour afficher les objets. renvoie 1 pour continuer, 0 pour fermer l'application.
Definition tuto_mdi.cpp:111
int quit()
a deriver pour detruire les objets openGL. renvoie -1 pour indiquer une erreur, 0 sinon.
Definition tuto_mdi.cpp:93
int update(const float time, const float delta)
a deriver et redefinir pour animer les objets en fonction du temps.
Definition tuto_mdi.cpp:105
int init()
a deriver pour creer les objets openGL. renvoie -1 pour indiquer une erreur, 0 sinon.
Definition tuto_mdi.cpp:36
void clear(Text &text)
efface le contenu de la console.
Definition text.cpp:72
int window_height()
renvoie la hauteur de la fenetre de l'application.
Definition window.cpp:27
void printf(Text &text, const int px, const int py, const char *format,...)
affiche un texte a la position x, y. meme utilisation que printf().
Definition text.cpp:140
Text create_text()
cree une console. a detruire avec release_text( ).
Definition text.cpp:14
void release_text(Text &text)
detruit une console.
Definition text.cpp:64
int window_width()
renvoie la largeur de la fenetre de l'application.
Definition window.cpp:23
Transform RotationY(const float a)
renvoie la matrice representation une rotation de a degree autour de l'axe Y.
Definition mat.cpp:242
Transform Translation(const Vector &v)
renvoie la matrice representant une translation par un vecteur.
Definition mat.cpp:216
Mesh read_mesh(const char *filename)
charge un fichier wavefront .obj et renvoie un mesh compose de triangles non indexes....
Definition wavefront.cpp:14
GLuint read_program(const char *filename, const char *definitions)
Definition program.cpp:217
int program_print_errors(const GLuint program, const char *filename)
affiche les erreurs de compilation.
Definition program.cpp:461
int release_program(const GLuint program)
detruit les shaders et le program.
Definition program.cpp:240
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
Definition text.h:62
representation d'une transformation, une matrice 4x4, organisee par ligne / row major.
Definition mat.h:21
representation d'un vecteur 3d.
Definition vec.h:67