gKit2 light
Loading...
Searching...
No Matches
tuto_mesh_shader.cpp
1
2
3#include <set>
4#include <map>
5#include <random>
6
7#include "app_camera.h"
8
9#include "mesh.h"
10#include "wavefront_fast.h"
11#include "program.h"
12#include "uniforms.h"
13
15{
16 bool operator() ( const vec3& a, const vec3& b ) const
17 {
18 if(a.x != b.x)
19 return a.x < b.x;
20 if(a.y != b.y)
21 return a.y < b.y;
22 if(a.z != b.z)
23 return a.z < b.z;
24 return false;
25 }
26};
27
28struct MeshShader : public AppCamera
29{
30 MeshShader( const char *filename ) : AppCamera( 1024, 640, 4,6 )
31 {
32 {
33 if(!GLAD_GL_EXT_mesh_shader)
34 {
35 printf("no mesh shaders.\n"); // pas d'extension, pas de tuto...
36 exit(1);
37 }
38
39 printf("mesh shaders:\n");
40
41 GLboolean flag;
42 glGetBooleanv(GL_MESH_PREFERS_LOCAL_INVOCATION_VERTEX_OUTPUT_EXT, &flag);
43 if(flag) printf(" prefers local invocation vertex output\n"); else printf(" [no] prefers local invocation vertex output\n");
44 glGetBooleanv(GL_MESH_PREFERS_LOCAL_INVOCATION_PRIMITIVE_OUTPUT_EXT, &flag);
45 if(flag) printf(" prefers local invocation primitive output\n"); else printf(" [no] prefers local invocation primitive output\n");
46 glGetBooleanv(GL_MESH_PREFERS_COMPACT_VERTEX_OUTPUT_EXT, &flag);
47 if(flag) printf(" prefers compact vertex output\n"); else printf(" [no] prefers compact vertex output\n");
48 glGetBooleanv(GL_MESH_PREFERS_COMPACT_PRIMITIVE_OUTPUT_EXT, &flag);
49 if(flag) printf(" prefers compact primitive output\n"); else printf(" [no] prefers compact primitive output\n");
50
51 GLint n;
52 glGetIntegerv(GL_MAX_PREFERRED_TASK_WORK_GROUP_INVOCATIONS_EXT, &n);
53 printf(" max preferred task work group invocations %d\n", n);
54 glGetIntegerv(GL_MAX_PREFERRED_MESH_WORK_GROUP_INVOCATIONS_EXT, &n);
55 printf(" max preferred mesh work group invocations %d\n", n);
56
57 glGetIntegerv(GL_MAX_MESH_OUTPUT_VERTICES_EXT, &n);
58 printf(" max output vertices %d\n", n);
59 glGetIntegerv(GL_MAX_MESH_OUTPUT_PRIMITIVES_EXT, &n);
60 printf(" max output primitives %d\n", n);
61 glGetIntegerv(GL_MAX_MESH_OUTPUT_COMPONENTS_EXT, &n);
62 printf(" max output components %d\n", n);
63 glGetIntegerv(GL_MAX_MESH_OUTPUT_LAYERS_EXT, &n);
64 printf(" max output layers %d\n", n);
65 }
66
67 m_mesh= read_indexed_mesh_fast(filename);
68 }
69
70 int init( )
71 {
72 if(m_mesh.vertex_count() == 0)
73 return 0; // pas de mesh, pas de tuto...
74
75 // mesh
76 const std::vector<vec3>& positions= m_mesh.positions();
77 std::vector<unsigned> indices= m_mesh.indices(); // copie les indices pour les modifier...
78
79 // re-indexation des sommets uniques
80 std::map<vec3, unsigned, vec3_less> vertex;
81 std::vector<unsigned> remap( indices.size() );
82 for(unsigned i= 0; i < positions.size(); i++)
83 {
84 auto v= vertex.insert( { positions[i], i } );
85 remap[i]= v.first->second;
86 }
87
88 for(unsigned i= 0; i < indices.size(); i++)
89 indices[i]= remap[ indices[i] ];
90
91 printf("remap %u/%u vertices...\n", unsigned(vertex.size()), unsigned(remap.size()));
92
93 // construit les groupes de triangles
94 std::set<unsigned> cluster;
95 std::vector<unsigned> cluster_id(indices.size(), -1);
96 std::vector<unsigned> triangle_id;
97 triangle_id.reserve(indices.size()/3);
98
99 unsigned id= 0;
100 for(unsigned i= 0; i < indices.size(); i++)
101 //~ for(unsigned i= 0; i +2< indices.size(); i+= 3)
102 {
103 unsigned a= indices[i];
104 cluster.insert(a);
105 //~ unsigned b= indices[i+1];
106 //~ cluster.insert(b);
107 //~ unsigned c= indices[i+2];
108 //~ cluster.insert(c);
109
110 if(cluster.size() >= 32)
111 {
112 id++;
113 cluster.clear();
114 }
115
116 triangle_id.push_back(id);
117 }
118 unsigned count= id+1;
119 cluster.clear();
120
121 // couleurs aleatoires
122 std::vector<vec3> colors( count );
123
124 std::random_device hwseed;
125 std::default_random_engine rng( hwseed() );
126 std::uniform_real_distribution<float> uniform;
127
128 for(unsigned i= 0; i < colors.size(); i++)
129 colors[i]= { uniform(rng), uniform(rng), uniform(rng) };
130
131 // affecte une couleur a chaque triangle
132 std::vector<vec3> vertex_colors;
133 std::vector<vec3> vertex_positions;
134 vertex_colors.reserve( indices.size() );
135 vertex_positions.reserve( indices.size() );
136 for(unsigned i= 0; i +2 < indices.size(); i+= 3)
137 {
138 unsigned a= indices[i];
139 unsigned b= indices[i+1];
140 unsigned c= indices[i+2];
141
142 vertex_positions.push_back( positions[ a ] );
143 vertex_positions.push_back( positions[ b ] );
144 vertex_positions.push_back( positions[ c ] );
145
146 vertex_colors.push_back( colors[ triangle_id[i/3] ] );
147 vertex_colors.push_back( colors[ triangle_id[i/3] ] );
148 vertex_colors.push_back( colors[ triangle_id[i/3] ] );
149 }
150
151 glGenVertexArrays(1, &vao);
152 glBindVertexArray(vao);
153
154 glGenBuffers(1, &vertex_buffer);
155 glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
156 glBufferData(GL_ARRAY_BUFFER, vertex_positions.size() * sizeof(vec3), vertex_positions.data(), GL_STATIC_DRAW);
157 glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
158 glEnableVertexAttribArray(0);
159
160 glGenBuffers(1, &cluster_buffer);
161 glBindBuffer(GL_ARRAY_BUFFER, cluster_buffer);
162 glBufferData(GL_ARRAY_BUFFER, vertex_colors.size() * sizeof(vec3), vertex_colors.data(), GL_STATIC_DRAW);
163 glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, 0);
164 glEnableVertexAttribArray(1);
165
166 //
167 Point pmin, pmax;
168 m_mesh.bounds(pmin, pmax);
169 camera().lookat(pmin, pmax);
170
171 //
172 m_program= read_program("gkit2_tutos/M2/mesh.glsl");
173 program_print_errors(m_program);
174
175 m_program_display= read_program("gkit2_tutos/M2/mesh_display.glsl");
176 program_print_errors(m_program_display);
177
178 // etat openGL par defaut
179 glClearColor(0.2f, 0.2f, 0.2f, 1.f); // couleur par defaut de la fenetre
180
181 glClearDepth(1.f); // profondeur par defaut
182 glDepthFunc(GL_LESS); // ztest, conserver l'intersection la plus proche de la camera
183 glEnable(GL_DEPTH_TEST); // activer le ztest
184
185 glFrontFace(GL_CCW);
186 glCullFace(GL_BACK);
187 //~ glEnable(GL_CULL_FACE);
188
189 return 1;
190 }
191
192 int quit( )
193 {
194 return 0;
195 }
196
197 int render( )
198 {
199 if(key_state('r'))
200 {
201 clear_key_state('r');
202 reload_program(m_program, "gkit2_tutos/M2/mesh.glsl");
203 program_print_errors(m_program);
204
205 reload_program(m_program_display, "gkit2_tutos/M2/mesh_display.glsl");
206 program_print_errors(m_program_display);
207 }
208
209 glViewport(0, 0, window_width(), window_height());
210 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
211
212 Transform model= RotationZ(global_time() / 100);
213 Transform view= camera().view();
214 Transform projection= camera().projection();
215
216 Transform mvp= projection * view * model;
217
218#if 0
219 glBindVertexArray(vao);
220 glUseProgram(m_program_display);
221 program_uniform(m_program_display, "mvpMatrix", mvp);
222
223 glDrawArrays(GL_TRIANGLES, 0, m_mesh.index_count());
224#else
225
226 float r= float(int(global_time() / 40) % 40) / float(40);
227
228 glBindVertexArray(0);
229 glUseProgram(m_program);
230 program_uniform(m_program, "color", Color(r,0,0));
231 program_uniform(m_program, "mvpMatrix", mvp);
232
233 glDrawMeshTasksEXT(1, 1, 1);
234#endif
235
236 return 1;
237 }
238
239protected:
240 Mesh m_mesh;
241 GLuint m_program;
242 GLuint m_program_display;
243
244 GLuint vertex_buffer;
245 GLuint cluster_buffer;
246 GLuint vao;
247};
248
249
250int main( int argc, char **argv )
251{
252 const char *filename= "data/bigguy.obj";
253 if(argc > 1)
254 filename= argv[1];
255
256 MeshShader app(filename);
257 app.run();
258
259 return 0;
260}
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
representation d'un objet / maillage.
Definition mesh.h:121
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:48
Transform view() const
renvoie la transformation vue.
Definition orbiter.cpp:41
int window_height()
renvoie la hauteur de la fenetre de l'application.
Definition window.cpp:27
void clear_key_state(const SDL_Keycode key)
desactive une touche du clavier.
Definition window.cpp:46
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
int key_state(const SDL_Keycode key)
renvoie l'etat d'une touche du clavier. cf la doc SDL2 pour les codes.
Definition window.cpp:40
int window_width()
renvoie la largeur de la fenetre de l'application.
Definition window.cpp:23
float global_time()
renvoie le temps ecoule depuis le lancement de l'application, en millisecondes.
Definition window.cpp:126
Transform RotationZ(const float a)
renvoie la matrice representation une rotation de angle degree autour de l'axe Z.
Definition mat.cpp:254
Mesh read_indexed_mesh_fast(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
representation d'une couleur (rgba) transparente ou opaque.
Definition color.h:14
int render()
a deriver pour afficher les objets. renvoie 1 pour continuer, 0 pour fermer l'application.
int init()
a deriver pour creer les objets openGL. renvoie -1 pour indiquer une erreur, 0 sinon.
int quit()
a deriver pour detruire les objets openGL. renvoie -1 pour indiquer une erreur, 0 sinon.
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
vecteur generique, utilitaire.
Definition vec.h:169
representation de l'indexation complete d'un sommet