gKit2 light
Loading...
Searching...
No Matches
draw.cpp
1
2#include "image_io.h"
3#include "texture.h"
4
5#include "draw.h"
6#include "window.h"
7#include "program.h"
8#include "uniforms.h"
9
10//avec texture
11void draw( Mesh& m, const Transform& model, const Transform& view, const Transform& projection, const GLuint texture )
12{
13 DrawParam param;
14 param.model(model).view(view).projection(projection);
15 param.texture(texture);
16 param.draw(m);
17}
18
19void draw( Mesh& m, const Transform& model, Orbiter& camera, const GLuint texture )
20{
21 // recupere les transformations
22 Transform view= camera.view();
23 Transform projection= camera.projection(window_width(), window_height(), 45);
24
25 // affiche l'objet
26 draw(m, model, view, projection, texture);
27}
28
29void draw( Mesh& m, Orbiter& camera, const GLuint texture )
30{
31 draw(m, Identity(), camera, texture);
32}
33
34
35// sans texture
36void draw( Mesh& m, const Transform& model, const Transform& view, const Transform& projection )
37{
38 DrawParam param;
39 param.model(model).view(view).projection(projection);
40 param.draw(m);
41}
42
43void draw( Mesh& m, const Transform& model, Orbiter& camera )
44{
45 // recupere les transformations
46 Transform view= camera.view();
47 Transform projection= camera.projection(window_width(), window_height(), 45);
48
49 // affiche l'objet
50 draw(m, model, view, projection);
51}
52
53void draw( Mesh& m, Orbiter& camera )
54{
55 // affiche l'objet
56 draw(m, Identity(), camera);
57}
58
59
60// groupe de triangles + matiere, sans texture
61void draw( const TriangleGroup& group, Mesh& m, const Transform& model, const Transform& view, const Transform& projection )
62{
63 DrawParam param;
64 param.model(model).view(view).projection(projection);
65 param.draw(group, m);
66}
67
68void draw( const TriangleGroup& group, Mesh& m, const Transform& model, Orbiter& camera )
69{
70 // recupere les transformations
71 Transform view= camera.view();
72 Transform projection= camera.projection(window_width(), window_height(), 45);
73
74 // dessine les triangles
75 draw(group, m, model, view, projection);
76}
77
78void draw( const TriangleGroup& group, Mesh& m, Orbiter& camera )
79{
80 draw(group, m, Identity(), camera);
81}
82
83
84// groupe de triangles + matiere et texture
85void draw( const TriangleGroup& group, Mesh& m, const Transform& model, const Transform& view, const Transform& projection, const GLuint texture )
86{
87 DrawParam param;
88 param.model(model).view(view).projection(projection);
89 param.texture(texture);
90 param.draw(group, m);
91}
92
93void draw( const TriangleGroup& group, Mesh& m, const Transform& model, Orbiter& camera, const GLuint texture )
94{
95 // recupere les transformations
96 Transform view= camera.view();
97 Transform projection= camera.projection(window_width(), window_height(), 45);
98
99 // dessine les triangles
100 draw(group, m, model, view, projection, texture);
101}
102
103void draw( const TriangleGroup& group, Mesh& m, Orbiter& camera, const GLuint texture )
104{
105 draw(group, m, Identity(), camera, texture);
106}
107
108
109void draw( Mesh& m, DrawParam& param )
110{
111 param.draw(m);
112}
113
114
115GLuint DrawParam::create_program( const GLenum primitives, const unsigned flags )
116{
117 std::string definitions;
118
119 if(flags & USE_TEXCOORD)
120 definitions.append("#define USE_TEXCOORD\n");
121 if(flags & USE_NORMAL)
122 definitions.append("#define USE_NORMAL\n");
123 if(flags & USE_COLOR)
124 definitions.append("#define USE_COLOR\n");
125
126 if((flags & USE_TEXCOORD) && (flags & USE_ALPHATEST))
127 definitions.append("#define USE_ALPHATEST\n");
128
129 if(flags & USE_SHADING)
130 {
131 definitions.append("#define USE_SHADING\n");
132
133 if(flags & USE_MATERIAL)
134 definitions.append("#define USE_MATERIAL\n");
135 if((flags & USE_LIGHT))
136 definitions.append("#define USE_LIGHT\n");
137 if(flags & USE_SUN)
138 definitions.append("#define USE_SUN\n");
139 if(flags & USE_SKY)
140 definitions.append("#define USE_SKY\n");
141 }
142
143 //~ printf("--\n%s", definitions.c_str());
144 const char *filename= smart_path("data/shaders/mesh.glsl");
145 bool use_mesh_color= (primitives == GL_POINTS || primitives == GL_LINES || primitives == GL_LINE_STRIP || primitives == GL_LINE_LOOP);
146 if(use_mesh_color)
147 filename= smart_path("data/shaders/mesh_color.glsl");
148
149 PipelineProgram *cache= PipelineCache::manager().find(filename, definitions.c_str());
150 return cache->program;
151}
152
153GLuint DrawParam::create_debug_normals_program( const GLenum primitives, const unsigned flags )
154{
155 const char *filename= smart_path("data/shaders/normals.glsl");
156 bool use_mesh_color= (primitives == GL_POINTS || primitives == GL_LINES || primitives == GL_LINE_STRIP || primitives == GL_LINE_LOOP);
157 if(use_mesh_color)
158 // pas la peine, les normales ne sont definies que pour les triangles...
159 return 0;
160
161 PipelineProgram *cache= PipelineCache::manager().find(filename);
162 return cache->program;
163}
164
165GLuint DrawParam::create_debug_texcoords_program( const GLenum primitives, const unsigned flags )
166{
167 const char *filename= smart_path("data/shaders/texcoords.glsl");
168 PipelineProgram *cache= PipelineCache::manager().find(filename);
169 return cache->program;
170}
171
172unsigned DrawParam::create_flags( const bool use_texcoord, const bool use_normal, const bool use_color )
173{
174 unsigned options= flags;
175 update(options, USE_TEXCOORD, use_texcoord);
176 update(options, USE_NORMAL, use_normal);
177 update(options, USE_COLOR, use_color);
178
179 return options;
180}
181
182unsigned DrawParam::update( unsigned &flags, const unsigned option, const bool use )
183{
184 if(use)
185 flags= flags | option;
186 else
187 flags= flags & ~option;
188 return flags;
189}
190
191bool DrawParam::flag( const unsigned option )
192{
193 return flags & option;
194}
195
197{
198 if(mesh.index_count())
199 draw(0, mesh.index_count(), mesh);
200 else
201 draw(0, mesh.vertex_count(), mesh);
202}
203
204void DrawParam::draw( Mesh& mesh, const Transform& model )
205{
206 m_model= model;
207 draw(mesh);
208}
209
210void DrawParam::draw( const TriangleGroup& group, Mesh& mesh )
211{
212 draw(group.first, group.n, mesh);
213}
214
215void DrawParam::draw( const unsigned first, const unsigned count, Mesh& mesh )
216{
217 bool use_texture= m_texture;
218 if(flag(USE_MATERIAL))
219 use_texture= use_texture || m_material.diffuse_texture || m_material.specular_texture || m_material.ns_texture;
220 bool use_texcoord= use_texture && mesh.has_texcoord();
221 bool use_normal= mesh.has_normal();
222 bool use_color= mesh.has_color();
223
224 Transform mv= m_view * m_model;
225 Transform mvp= m_projection * mv;
226
227 GLuint program= 0;
228 if(flag(DEBUG_TEXCOORDS))
229 {
230 program= create_debug_texcoords_program( mesh.primitives(), create_flags(use_texcoord, use_normal, use_color) );
231 if(program > 0)
232 {
233 use_color= false;
234 use_normal= false;
235 use_texcoord= true;
236 update(flags, USE_LIGHT | USE_TEXTURE | USE_ALPHATEST, false);
237
238 glUseProgram(program);
239 //~ program_use_texture(program, "diffuse_color", 0, m_debug_texture);
240 program_uniform(program, "mvpMatrix", mvp);
241 program_uniform(program, "mvMatrix", mv);
242
243 mesh.draw(first, count, program);
244 return;
245 }
246 }
247
248 //
249 program= create_program( mesh.primitives(), create_flags(use_texcoord, use_normal, use_color) );
250 assert(program > 0);
251
252 glUseProgram(program);
253 if(!use_color)
254 program_uniform(program, "mesh_color", mesh.default_color());
255
256 program_uniform(program, "mvpMatrix", mvp);
257
258 // utiliser une texture, elle ne sera visible que si le mesh a des texcoords...
259 if(use_texcoord && m_texture > 0)
260 program_use_texture(program, "diffuse_texture", 0, m_texture);
261
262 if(flag(USE_ALPHATEST))
263 program_uniform(program, "alpha_min", m_alpha_min);
264
265 if(flag(USE_SHADING))
266 {
267 if(use_normal)
268 program_uniform(program, "normalMatrix", mv.normal()); // transforme les normales dans le repere camera.
269 if(!use_normal || flag(USE_LIGHT | USE_MATERIAL))
270 program_uniform(program, "mvMatrix", mv);
271
272 if(flag(USE_MATERIAL))
273 {
274 program_uniform(program, "diffuse_color", m_material.diffuse);
275 program_uniform(program, "specular_color", m_material.specular);
276 program_uniform(program, "ns", m_material.ns);
277
278 if(use_texcoord)
279 {
280 // texture blanche uniforme par defaut
281 static GLuint white_texture= 0;
282 if(white_texture == 0)
283 {
284 ImageData data(16, 16, 4);
285 for(unsigned y= 0; y < data.height; y++)
286 for(unsigned x= 0; x < data.width; x++)
287 {
288 unsigned char *pixel= data.pixels.data() + data.offset(x, y);
289 for(unsigned i= 0; i < data.channels; i++)
290 pixel[i]= 255;
291 }
292
293 white_texture= make_texture(0, data);
294 }
295
296 if(m_material.diffuse_texture > 0)
297 program_use_texture(program, "diffuse_texture", 0, m_material.diffuse_texture);
298 else
299 program_use_texture(program, "diffuse_texture", 0, white_texture);
300
301 if(m_material.specular_texture > 0)
302 program_use_texture(program, "specular_texture", 1, m_material.specular_texture);
303 else
304 program_use_texture(program, "specular_texture", 1, white_texture);
305
306 if(m_material.specular_texture > 0)
307 program_use_texture(program, "ns_texture", 2, m_material.specular_texture);
308 else
309 program_use_texture(program, "ns_texture", 2, white_texture);
310 }
311 }
312
313 if(flag(USE_LIGHT))
314 {
315 program_uniform(program, "light", m_view(m_light)); // transforme la position de la source dans le repere camera, comme les normales
316 program_uniform(program, "light_color", m_light_color);
317 }
318 if(flag(USE_SUN))
319 {
320 program_uniform(program, "sun", m_view(m_sun)); // transforme la direction de la source dans le repere camera, comme les normales
321 program_uniform(program, "sun_color", m_sun_color);
322 }
323 if(flag(USE_SKY))
324 {
325 program_uniform(program, "sky", m_view(m_sky)); // transforme la direction de la source dans le repere camera, comme les normales
326 program_uniform(program, "sky_color", m_sky_color);
327 }
328 }
329
330 mesh.draw(first, count, program);
331
332 // dessine les normales par dessus...
333 if(flag(DEBUG_NORMALS))
334 {
335 program= create_debug_normals_program( mesh.primitives(), create_flags(use_texcoord, use_normal, use_color) );
336 if(program > 0)
337 {
338 use_color= false;
339 use_normal= true;
340 use_texcoord= false;
341 update(flags, USE_SHADING | USE_LIGHT | USE_TEXTURE | USE_ALPHATEST, false);
342
343 static float scale= 1;
344 if(key_state('p') || key_state(SDLK_KP_PLUS))
345 scale+= 0.005f;
346 if(key_state('m') || key_state(SDLK_KP_MINUS))
347 scale-= 0.005f;
348 if(scale < 0.1f)
349 scale= 0.1f;
350
351 glUseProgram(program);
352 program_uniform(program, "mvpMatrix", mvp);
353 program_uniform(program, "normalMatrix", mv.normal()); // transforme les normales dans le repere camera.
354 program_uniform(program, "scale", scale * m_normals_scale);
355
356 mesh.draw(first, count, program);
357 }
358 }
359}
GLuint create_program(const GLenum primitives, const unsigned flags)
construit un shader program configure pour l'ensemble d'options.
Definition draw.cpp:115
GLuint create_debug_texcoords_program(const GLenum primitives, const unsigned flags)
construit un shader program / debug des coordonnees de texture.
Definition draw.cpp:165
void draw(Mesh &mesh)
dessine l'objet avec l'ensemble des parametres definis.
Definition draw.cpp:196
GLuint create_debug_normals_program(const GLenum primitives, const unsigned flags)
construit un shader program / debug des normales.
Definition draw.cpp:153
DrawParam & model(const Transform &m)
modifie la transformation model utilisee pour afficher l'objet.
Definition draw.h:82
DrawParam & view(const Transform &m)
modifie la transformation view utilisee pour afficher l'objet.
Definition draw.h:84
DrawParam & projection(const Transform &m)
modifie la transformation projection utilisee pour afficher l'objet.
Definition draw.h:86
DrawParam & texture(const GLuint t)
plaque une texture opaque a la surface de l'objet.
Definition draw.h:107
representation d'un objet / maillage.
Definition mesh.h:121
Color default_color() const
renvoie la couleur par defaut du mesh, utilisee si les sommets n'ont pas de couleur associee.
Definition mesh.h:293
void draw(const GLuint program)
dessine l'objet avec un shader program.
Definition mesh.cpp:757
GLenum primitives() const
renvoie le type de primitives.
Definition mesh.h:345
representation de la camera, type orbiter, placee sur une sphere autour du centre de l'objet.
Definition orbiter.h:17
PipelineProgram * find(const char *filename, const char *definitions="")
renvoie un shader program compile. et l'ajoute dans le cache...
Definition program.h:69
static PipelineCache & manager()
acces au singleton.
Definition program.h:130
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:448
int window_height()
renvoie la hauteur de la fenetre de l'application.
Definition window.cpp:27
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:53
int window_width()
renvoie la largeur de la fenetre de l'application.
Definition window.cpp:23
Transform Identity()
construit la transformation identite.
Definition mat.cpp:187
int first
premier triangle du groupe
Definition mesh.h:105
int n
nombre de triangles du groupe
Definition mesh.h:106
@ USE_COLOR
inclut l'attribut couleur dans les buffers.
Definition mesh.h:115
@ USE_TEXCOORD
inclut l'attribut coordonnees de texture dans les buffers.
Definition mesh.h:113
@ USE_NORMAL
inclut l'attribut normale dans les buffers.
Definition mesh.h:114
representation d'un ensemble de triangles de meme matiere.
Definition mesh.h:103
GLuint make_texture(const int unit, const int width, const int height, const GLenum texel_type, const GLenum data_format, const GLenum data_type)
creation de textures filtrables / mipmaps
Definition texture.cpp:10
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
description d'un shader program compile.
Definition program.h:51
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