21#include "M2/meshoptimizer/meshoptimizer.h"
22#include "M2/meshoptimizer/indexanalyzer.cpp"
23#include "M2/meshoptimizer/vcacheoptimizer.cpp"
24#include "M2/meshoptimizer/vfetchoptimizer.cpp"
27void vcache(
const Mesh& mesh )
29 meshopt_VertexCacheStatistics stats= meshopt_analyzeVertexCache( mesh.indices().data(), mesh.indices().size(), mesh.positions().size(),
33 printf(
"[vertex cache]\n");
34 printf(
" transformed vertices %u\n", stats.vertices_transformed);
35 printf(
" warps %u\n", stats.warps_executed);
36 printf(
" acmr transformed vertices / triangle %f\n", stats.acmr);
37 printf(
" atvr transformed vertices / vertex %f\n", stats.atvr);
43void vfetch(
const Mesh& mesh )
45 unsigned vertex_size=
sizeof(
vec3);
46 meshopt_VertexFetchStatistics stats= meshopt_analyzeVertexFetch( mesh.indices().data(), mesh.indices().size(), mesh.positions().size(), vertex_size );
48 printf(
"[vertex fetch]\n");
49 printf(
" bytes %u, %uMB\n", stats.bytes_fetched, stats.bytes_fetched / 1024 / 1024);
50 printf(
" overfetch %f\n", stats.overfetch);
62 std::vector<triangle> triangles;
63 triangles.reserve(data.triangle_count());
65 std::vector<unsigned> indices= data.indices();
66 for(
unsigned i= 0; i +2 < indices.size(); i+= 3)
68 triangle t= { indices[i], indices[i+1], indices[i+2] };
69 triangles.push_back( t );
72 std::random_device hwseed;
73 std::default_random_engine rng( hwseed() );
74 std::shuffle(triangles.begin(), triangles.end(), rng);
76 indices.resize(triangles.size() * 3);
77 for(
unsigned i= 0; i < triangles.size(); i++)
79 triangle t= triangles[i];
85 return Mesh( data.primitives(), data.positions(), indices );
89Mesh optimize_vcache(
const Mesh& mesh )
91 std::vector<unsigned> indices( mesh.index_count() );
92 meshopt_optimizeVertexCache( indices.data(), mesh.indices().data(), mesh.indices().size(), mesh.positions().size() );
94 return Mesh( mesh.primitives(), mesh.positions(), indices );
97Mesh optimize_vfetch(
const Mesh& mesh )
99 std::vector<vec3> positions( mesh.vertex_count() );
100 std::vector<unsigned> indices= mesh.indices();
101 meshopt_optimizeVertexFetch( positions.data(), indices.data(), indices.size(), mesh.positions().data(), mesh.positions().size(),
sizeof(
vec3) );
103 return Mesh( mesh.primitives(), positions, indices );
111 TP(
const char *filename ) :
AppTime(1024, 576, 4,4)
118 if(m_objet.vertex_count() == 0)
122 m_objet_reference= m_objet;
129 m_objet.bounds(pmin, pmax);
130 m_camera.lookat(pmin, pmax);
136 m_display_program=
read_program(
"gkit2_tutos/M2/vertex_display.glsl");
140 glClearColor(0.2, 0.2, 0.2, 1);
143 glDepthFunc(GL_LEQUAL);
144 glEnable(GL_DEPTH_TEST);
145 glEnable(GL_CULL_FACE);
147 glGenQueries(1, &m_query_vertex_shaders);
149 glGenBuffers(1, &m_buffer);
150 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_buffer);
151 glBufferData(GL_SHADER_STORAGE_BUFFER,
sizeof(
unsigned) * m_objet.vertex_count(),
nullptr, GL_STREAM_DRAW);
154 const std::vector<unsigned> &indices= m_objet.indices();
155 m_shared.resize( m_objet.vertex_count() );
157 for(
unsigned i= 0; i < indices.size(); i++)
158 m_shared[ indices[i] ]++;
174 update_camera( m_camera );
177 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
179 static int optimize= 0;
181 static const char *export_filename=
"export.obj";
186 optimize= (optimize +1) % 4;
192 m_objet= m_objet_reference;
193 export_filename=
"reference.obj";
200 m_objet= optimize_vcache(m_objet_reference);
201 m_objet= optimize_vfetch(m_objet);
202 export_filename=
"optimize.obj";
209 m_objet= shuffle(m_objet_reference);
210 export_filename=
"shuffle.obj";
217 m_objet= m_objet_reference;
219 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_buffer);
220 glBufferData(GL_SHADER_STORAGE_BUFFER,
sizeof(
unsigned) * m_shared.size(), m_shared.data(), GL_STREAM_DRAW);
221 export_filename=
"reference.obj";
242 reload_program(m_program);
245 reload_program(m_display_program);
249 static bool rotate=
false;
270 int zeros[4]= { 0, 0, 0, 0 };
271 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_buffer);
272 glClearBufferData(GL_SHADER_STORAGE_BUFFER, GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT, zeros);
274 glBeginQuery(GL_VERTEX_SHADER_INVOCATIONS, m_query_vertex_shaders);
276 glUseProgram(m_program);
277 program_uniform(m_program,
"mvpMatrix", mvp);
279 m_objet.draw(m_program);
281 glEndQuery(GL_VERTEX_SHADER_INVOCATIONS);
283 GLuint64
vertices= m_objet.vertex_count();
284 GLuint64 vertex_shaders= 0; glGetQueryObjectui64v(m_query_vertex_shaders, GL_QUERY_RESULT, &vertex_shaders);
285 printf(
"%lu transformed vertices / %lu vertex atvr %f\n", vertex_shaders,
vertices,
float(vertex_shaders) /
float(
vertices));
287 glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
288 glClear(GL_COLOR_BUFFER_BIT);
293 glUseProgram(m_display_program);
294 program_uniform(m_display_program,
"mvpMatrix", mvp);
295 program_uniform(m_display_program,
"mvMatrix", mv);
297 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_buffer);
299 m_objet.draw( m_display_program);
309 Mesh m_objet_reference;
311 std::vector<unsigned> m_shared;
314 GLuint m_display_program;
317 GLuint m_query_vertices;
318 GLuint m_query_vertex_shaders;
319 GLuint m_query_fragment_shaders;
323int main(
int argc,
char **argv )
325 const char *filename=
"data/bigguy.obj";
AppTime(const int width, const int height, const int major=3, const int minor=3)
constructeur, dimensions de la fenetre et version d'openGL.
representation d'un objet / maillage.
representation de la camera, type orbiter, placee sur une sphere autour du centre de l'objet.
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.
int window_height()
renvoie la hauteur de la fenetre de l'application.
void clear_key_state(const SDL_Keycode key)
desactive une touche du clavier.
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().
int key_state(const SDL_Keycode key)
renvoie l'etat d'une touche du clavier. cf la doc SDL2 pour les codes.
int window_width()
renvoie la largeur de la fenetre de l'application.
float global_time()
renvoie le temps ecoule depuis le lancement de l'application, en millisecondes.
Transform Identity()
construit la transformation identite.
Transform RotationY(const float a)
renvoie la matrice representation une rotation de a degree autour de l'axe Y.
Mesh read_indexed_mesh_fast(const char *filename)
charge un fichier wavefront .obj et renvoie un mesh compose de triangles indexes. utiliser glDrawElem...
int write_mesh(const Mesh &mesh, const char *filename, const char *materials_filename)
enregistre un mesh dans un fichier .obj.
int capture(const char *prefix)
GLuint read_program(const char *filename, const char *definitions)
int program_print_errors(const GLuint program, const char *filename)
affiche les erreurs de compilation.
int release_program(const GLuint program)
MeshData vertices(MeshData &data)
construit les sommets. prepare l'affichage openGL, avec glDrawArrays().
representation d'un point 3d.
vecteur generique, utilitaire.