gKit2 light
draw.cpp
1 
2 #include "draw.h"
3 #include "window.h"
4 #include "program.h"
5 #include "uniforms.h"
6 
7 //avec texture
8 void draw( Mesh& m, const Transform& model, const Transform& view, const Transform& projection, const GLuint texture )
9 {
10  DrawParam param;
11  param.model(model).view(view).projection(projection);
12  param.texture(texture);
13  param.draw(m);
14 }
15 
16 void draw( Mesh& m, const Transform& model, Orbiter& camera, const GLuint texture )
17 {
18  // recupere les transformations
19  Transform view= camera.view();
20  Transform projection= camera.projection(window_width(), window_height(), 45);
21 
22  // affiche l'objet
23  draw(m, model, view, projection, texture);
24 }
25 
26 void draw( Mesh& m, Orbiter& camera, const GLuint texture )
27 {
28  draw(m, Identity(), camera, texture);
29 }
30 
31 
32 // sans texture
33 void draw( Mesh& m, const Transform& model, const Transform& view, const Transform& projection )
34 {
35  DrawParam param;
36  param.model(model).view(view).projection(projection);
37  param.draw(m);
38 }
39 
40 void draw( Mesh& m, const Transform& model, Orbiter& camera )
41 {
42  // recupere les transformations
43  Transform view= camera.view();
44  Transform projection= camera.projection(window_width(), window_height(), 45);
45 
46  // affiche l'objet
47  draw(m, model, view, projection);
48 }
49 
50 void draw( Mesh& m, Orbiter& camera )
51 {
52  // affiche l'objet
53  draw(m, Identity(), camera);
54 }
55 
56 
57 // groupe de triangles + matiere, sans texture
58 void draw( const TriangleGroup& group, Mesh& m, const Transform& model, const Transform& view, const Transform& projection )
59 {
60  DrawParam param;
61  param.model(model).view(view).projection(projection);
62  param.draw(group, m);
63 }
64 
65 void draw( const TriangleGroup& group, Mesh& m, const Transform& model, Orbiter& camera )
66 {
67  // recupere les transformations
68  Transform view= camera.view();
69  Transform projection= camera.projection(window_width(), window_height(), 45);
70 
71  // dessine les triangles
72  draw(group, m, model, view, projection);
73 }
74 
75 void draw( const TriangleGroup& group, Mesh& m, Orbiter& camera )
76 {
77  draw(group, m, Identity(), camera);
78 }
79 
80 
81 // groupe de triangles + matiere et texture
82 void draw( const TriangleGroup& group, Mesh& m, const Transform& model, const Transform& view, const Transform& projection, const GLuint texture )
83 {
84  DrawParam param;
85  param.model(model).view(view).projection(projection);
86  param.texture(texture);
87  param.draw(group, m);
88 }
89 
90 void draw( const TriangleGroup& group, Mesh& m, const Transform& model, Orbiter& camera, const GLuint texture )
91 {
92  // recupere les transformations
93  Transform view= camera.view();
94  Transform projection= camera.projection(window_width(), window_height(), 45);
95 
96  // dessine les triangles
97  draw(group, m, model, view, projection, texture);
98 }
99 
100 void draw( const TriangleGroup& group, Mesh& m, Orbiter& camera, const GLuint texture )
101 {
102  draw(group, m, Identity(), camera, texture);
103 }
104 
105 
106 void draw( Mesh& m, DrawParam& param )
107 {
108  param.draw(m);
109 }
110 
111 
112 GLuint DrawParam::create_program( const GLenum primitives, const bool use_texcoord, const bool use_normal, const bool use_color, const bool use_light, const bool use_alpha_test )
113 {
114  std::string definitions;
115 
116  if(use_texcoord)
117  definitions.append("#define USE_TEXCOORD\n");
118  if(use_normal)
119  definitions.append("#define USE_NORMAL\n");
120  if(use_color)
121  definitions.append("#define USE_COLOR\n");
122  if(use_light)
123  definitions.append("#define USE_LIGHT\n");
124  if(use_texcoord && use_alpha_test)
125  definitions.append("#define USE_ALPHATEST\n");
126 
127  //~ printf("--\n%s", definitions.c_str());
128  const char *filename= smart_path("data/shaders/mesh.glsl");
129  bool use_mesh_color= (primitives == GL_POINTS || primitives == GL_LINES || primitives == GL_LINE_STRIP || primitives == GL_LINE_LOOP);
130  if(use_mesh_color)
131  filename= smart_path("data/shaders/mesh_color.glsl");
132 
133  PipelineProgram *program= PipelineCache::manager().find(filename, definitions.c_str());
134  return program->program;
135 }
136 
137 GLuint DrawParam::create_debug_normals_program( const GLenum primitives, const bool use_texcoord, const bool use_normal, const bool use_color, const bool use_light, const bool use_alpha_test )
138 {
139  const char *filename= smart_path("data/shaders/normals.glsl");
140  bool use_mesh_color= (primitives == GL_POINTS || primitives == GL_LINES || primitives == GL_LINE_STRIP || primitives == GL_LINE_LOOP);
141  if(use_mesh_color)
142  // pas la peine, les normales ne sont definies que pour les triangles...
143  return 0;
144 
145  PipelineProgram *program= PipelineCache::manager().find(filename);
146  return program->program;
147 }
148 
149 GLuint DrawParam::create_debug_texcoords_program( const GLenum primitives, const bool use_texcoord, const bool use_normal, const bool use_color, const bool use_light, const bool use_alpha_test )
150 {
151  const char *filename= smart_path("data/shaders/texcoords.glsl");
152  PipelineProgram *program= PipelineCache::manager().find(filename);
153  return program->program;
154 }
155 
156 
157 void DrawParam::draw( Mesh& mesh )
158 {
159  bool use_texcoord= m_use_texture && m_texture > 0 && mesh.has_texcoord();
160  bool use_normal= mesh.has_normal();
161  bool use_color= mesh.has_color();
162 
163  Transform mv= m_view * m_model;
164  Transform mvp= m_projection * mv;
165 
166  GLuint program= 0;
167  if(m_debug_texcoords)
168  {
169  program= create_debug_texcoords_program(mesh.primitives(), use_texcoord, use_normal, use_color, m_use_light, m_use_alpha_test);
170  m_use_light= false;
171  m_use_texture= false;
172  m_use_alpha_test= false;
173  use_color= false;
174  use_normal= false;
175  use_texcoord= true;
176 
177  glUseProgram(program);
178  //~ program_use_texture(program, "diffuse_color", 0, m_debug_texture);
179  program_uniform(program, "mvpMatrix", mvp);
180  program_uniform(program, "mvMatrix", mv);
181 
182  mesh.draw(program, /* position */ true, use_texcoord, false, false, /* material_index */ false);
183  return;
184  }
185 
186  program= create_program(mesh.primitives(), use_texcoord, use_normal, use_color, m_use_light, m_use_alpha_test);
187 
188  glUseProgram(program);
189  if(!use_color)
190  program_uniform(program, "mesh_color", mesh.default_color());
191 
192  program_uniform(program, "mvpMatrix", mvp);
193  if(use_normal)
194  program_uniform(program, "normalMatrix", mv.normal()); // transforme les normales dans le repere camera.
195  else
196  program_uniform(program, "mvMatrix", mv);
197 
198  // utiliser une texture, elle ne sera visible que si le mesh a des texcoords...
199  if(use_texcoord && m_texture > 0)
200  program_use_texture(program, "diffuse_color", 0, m_texture);
201 
202  if(m_use_light)
203  {
204  program_uniform(program, "light", m_view(m_light)); // transforme la position de la source dans le repere camera, comme les normales
205  program_uniform(program, "light_color", m_light_color);
206  program_uniform(program, "mvMatrix", mv);
207  }
208 
209  if(m_use_alpha_test)
210  program_uniform(program, "alpha_min", m_alpha_min);
211 
212  mesh.draw(program, /* position */ true, use_texcoord, use_normal, use_color, /* material_index */ false);
213 
214  // dessine les normales par dessus...
215  if(m_debug_normals)
216  {
217  program= create_debug_normals_program(mesh.primitives(), use_texcoord, use_normal, use_color, m_use_light, m_use_alpha_test);
218  m_use_light= false;
219  m_use_texture= false;
220  m_use_alpha_test= false;
221  use_color= false;
222  use_normal= true;
223  use_texcoord= false;
224 
225  static float scale= 1;
226  if(key_state('p') || key_state(SDLK_KP_PLUS))
227  scale+= 0.02f;
228  if(key_state('m') || key_state(SDLK_KP_MINUS))
229  scale-= 0.02f;
230  if(scale < 0.1f)
231  scale= 0.1f;
232 
233  glUseProgram(program);
234  program_uniform(program, "mvpMatrix", mvp);
235  program_uniform(program, "normalMatrix", mv.normal()); // transforme les normales dans le repere camera.
236  program_uniform(program, "scale", scale * m_normals_scale);
237 
238  mesh.draw(program, /* position */ true, false, use_normal, false, /* material_index */ false);
239  }
240 }
241 
242 void DrawParam::draw( const TriangleGroup& group, Mesh& mesh )
243 {
244  bool use_texcoord= m_use_texture && m_texture > 0 && mesh.has_texcoord();
245  bool use_normal= mesh.has_normal();
246  bool use_color= mesh.has_color();
247 
248  // etape 1 : construit le program en fonction des attributs du mesh et des options choisies
249  GLuint program= create_program(mesh.primitives(), use_texcoord, use_normal, use_color, m_use_light, m_use_alpha_test);
250 
251  glUseProgram(program);
252  if(group.index != -1 && group.index < mesh.materials().count())
253  program_uniform(program, "mesh_color", mesh.materials().material(group.index).diffuse);
254  else
255  program_uniform(program, "mesh_color", mesh.materials().default_material().diffuse);
256 
257  Transform mv= m_view * m_model;
258  Transform mvp= m_projection * mv;
259 
260  program_uniform(program, "mvpMatrix", mvp);
261  if(use_normal)
262  program_uniform(program, "normalMatrix", mv.normal()); // transforme les normales dans le repere camera.
263  else
264  program_uniform(program, "mvMatrix", mv);
265 
266  // utiliser une texture, elle ne sera visible que si le mesh a des texcoords...
267  if(use_texcoord && m_texture > 0)
268  program_use_texture(program, "diffuse_color", 0, m_texture);
269 
270  if(m_use_light)
271  {
272  program_uniform(program, "light", m_view(m_light)); // transforme la position de la source dans le repere camera, comme les normales
273  program_uniform(program, "light_color", m_light_color);
274  program_uniform(program, "mvMatrix", mv);
275  }
276 
277  if(m_use_alpha_test)
278  program_uniform(program, "alpha_min", m_alpha_min);
279 
280  mesh.draw(group.first, group.n, program, /* position */ true, use_texcoord, use_normal, use_color, /* material_index */ false);
281 }
Definition: draw.h:67
DrawParam & view(const Transform &m)
modifie la transformation view utilisee pour afficher l'objet.
Definition: draw.h:81
DrawParam & model(const Transform &m)
modifie la transformation model utilisee pour afficher l'objet.
Definition: draw.h:79
void draw(Mesh &mesh)
dessine l'objet avec l'ensemble des parametres definis.
Definition: draw.cpp:157
DrawParam & projection(const Transform &m)
modifie la transformation projection utilisee pour afficher l'objet.
Definition: draw.h:83
GLuint create_program(const GLenum primitives, const bool use_texcoord, const bool use_normal, const bool use_color, const bool use_light, const bool use_alpha_test)
Definition: draw.cpp:112
DrawParam & texture(const GLuint t)
plaque une texture opaque a la surface de l'objet.
Definition: draw.h:92
representation d'un objet / maillage.
Definition: mesh.h:112
Color default_color() const
renvoie la couleur par defaut du mesh, utilisee si les sommets n'ont pas de couleur associee.
Definition: mesh.h:284
void draw(const GLuint program, const bool use_position, const bool use_texcoord, const bool use_normal, const bool use_color, const bool use_material_index)
dessine l'objet avec un shader program.
Definition: mesh.cpp:768
GLenum primitives() const
renvoie le type de primitives.
Definition: mesh.h:336
const Materials & materials() const
renvoie la description des matieres.
Definition: mesh.cpp:265
representation de la camera, type orbiter, placee sur une sphere autour du centre de l'objet.
Definition: orbiter.h:17
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
static PipelineCache & manager()
access au singleton.
Definition: draw.h:188
PipelineProgram * find(const char *filename, const char *definitions="")
renvoie un shader program compile.
Definition: draw.h:169
description d'un shader program compile.
Definition: draw.h:151
int window_height()
renvoie la hauteur de la fenetre de l'application.
Definition: window.cpp:29
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:42
int window_width()
renvoie la largeur de la fenetre de l'application.
Definition: window.cpp:25
const char * smart_path(const char *filename)
renvoie le chemin(path) vers le fichier 'filename' apres l'avoir cherche dans un repertoire standard....
Definition: window.cpp:431
Transform Identity()
construit la transformation identite.
Definition: mat.cpp:187
int first
premier triangle du groupe
Definition: mesh.h:105
int index
indice de la "propriete"du groupe de triangles, par defaut : indice de la matiere
Definition: mesh.h:104
int n
nombre de triangles du groupe
Definition: mesh.h:106
representation d'un ensemble de triangles de meme matiere.
Definition: mesh.h:103
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
void program_use_texture(const GLuint program, const char *uniform, const int unit, const GLuint texture, const GLuint sampler)
configure le pipeline et le shader program pour utiliser une texture, et des parametres de filtrage,...
Definition: uniforms.cpp:198
Color diffuse
couleur diffuse / de base.
Definition: materials.h:17
const Material & material(const int id) const
renvoie la ieme matiere.
Definition: materials.h:102
int count() const
nombre de matieres.
Definition: materials.h:94
const Material & default_material()
renvoie une matiere par defaut.
Definition: materials.h:124
representation d'une transformation, une matrice 4x4, organisee par ligne / row major.
Definition: mat.h:21
Transform normal() const
renvoie la transformation a appliquer aux normales d'un objet transforme par la matrice m.
Definition: mat.cpp:181