Coupure prévue mardi 3 Août au matin pour maintenance du serveur. Nous faisons au mieux pour que celle-ci soit la plus brève possible.

GLSLShader.cpp 29.3 KB
Newer Older
Pierre Kraemer's avatar
Pierre Kraemer committed
1
2
3
/*******************************************************************************
* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps  *
* version 0.1                                                                  *
4
* Copyright (C) 2009-2012, IGG Team, LSIIT, University of Strasbourg           *
Pierre Kraemer's avatar
Pierre Kraemer committed
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
*                                                                              *
* This library is free software; you can redistribute it and/or modify it      *
* under the terms of the GNU Lesser General Public License as published by the *
* Free Software Foundation; either version 2.1 of the License, or (at your     *
* option) any later version.                                                   *
*                                                                              *
* This library is distributed in the hope that it will be useful, but WITHOUT  *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or        *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License  *
* for more details.                                                            *
*                                                                              *
* You should have received a copy of the GNU Lesser General Public License     *
* along with this library; if not, write to the Free Software Foundation,      *
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.           *
*                                                                              *
20
* Web site: http://cgogn.unistra.fr/                                           *
Pierre Kraemer's avatar
Pierre Kraemer committed
21
22
23
* Contact information: cgogn@unistra.fr                                        *
*                                                                              *
*******************************************************************************/
Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
24

Pierre Kraemer's avatar
Pierre Kraemer committed
25
26
27
28
29
#define EXPORTING 1

#include "Utils/GLSLShader.h"
#include <iostream>
#include <fstream>
30
#include <vector>
31
#include "Utils/cgognStream.h"
Pierre Kraemer's avatar
Pierre Kraemer committed
32

Sylvain Thery's avatar
Sylvain Thery committed
33
34
#include "glm/gtx/inverse_transpose.hpp"

Pierre Kraemer's avatar
Pierre Kraemer committed
35
36
37
38
39
namespace CGoGN
{

namespace Utils
{
Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
40
41

unsigned int GLSLShader::CURRENT_OGL_VERSION = 2;
Sylvain Thery's avatar
Sylvain Thery committed
42
43
44

std::string GLSLShader::DEFINES_GL2=\
"#version 110\n"
45
"#define PRECISON float pipo_PRECISION\n"
Sylvain Thery's avatar
Sylvain Thery committed
46
47
48
"#define ATTRIBUTE attribute\n"
"#define VARYING_VERT varying\n"
"#define VARYING_FRAG varying\n"
49
50
"#define FRAG_OUT_DEF float pipo_FRAGDEF\n"
"#define INVARIANT_POS float pipo_INVARIANT\n";
Sylvain Thery's avatar
Sylvain Thery committed
51

Pierre Kraemer's avatar
Pierre Kraemer committed
52

Sylvain Thery's avatar
Sylvain Thery committed
53
std::string GLSLShader::DEFINES_GL3=\
54
"#version 150\n"
55
"#define PRECISON precision highp float\n"
Sylvain Thery's avatar
Sylvain Thery committed
56
57
58
59
"#define ATTRIBUTE in\n"
"#define VARYING_VERT smooth out\n"
"#define VARYING_FRAG smooth in\n"
"#define FRAG_OUT_DEF out vec4 gl_FragColor\n"
60
"#define INVARIANT_POS invariant gl_Position\n";
Sylvain Thery's avatar
Sylvain Thery committed
61

Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
62
63

std::string* GLSLShader::DEFINES_GL = NULL;
64
65
66

std::vector<std::string> GLSLShader::m_pathes;

Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
67
68
69
std::set< std::pair<void*, GLSLShader*> > GLSLShader::m_registeredShaders;


70
71
72
//glm::mat4* GLSLShader::s_current_matrices=NULL;
Utils::GL_Matrices* GLSLShader::s_current_matrices=NULL;

Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
73
74
75
76
GLSLShader::GLSLShader() :
	m_vertex_shader_source(NULL),
	m_fragment_shader_source(NULL),
	m_geom_shader_source(NULL)
Pierre Kraemer's avatar
Pierre Kraemer committed
77
{
78
79
80
81
82
83
84
85
86
	*m_vertex_shader_object = 0;
	*m_fragment_shader_object = 0;
	*m_geom_shader_object = 0;
	*m_program_object = 0;
	*m_uniMat_Proj = -1;
	*m_uniMat_Model = -1;
	*m_uniMat_ModelProj = -1;
	*m_uniMat_Normal = -1;

Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
87
	if (DEFINES_GL == NULL)
88
		DEFINES_GL = &DEFINES_GL2;
Sylvain Thery's avatar
Sylvain Thery committed
89
90

	m_nbMaxVertices = 16;
Pierre Kraemer's avatar
Pierre Kraemer committed
91
92
}

Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
93
void GLSLShader::registerShader(void* ptr, GLSLShader* shader)
94
{
Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
95
	m_registeredShaders.insert(std::pair<void*,GLSLShader*>(ptr, shader));
96
97
}

Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
98
void GLSLShader::unregisterShader(void* ptr, GLSLShader* shader)
99
{
Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
100
	m_registeredShaders.erase(std::pair<void*,GLSLShader*>(ptr, shader));
101
102
103
104
}

std::string GLSLShader::defines_Geom(const std::string& primitivesIn, const std::string& primitivesOut, int maxVert)
{
Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
105
	if (CURRENT_OGL_VERSION == 3)
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
	{
		std::string str("#version 150\n");
		str.append("precision highp float;\n");
		str.append("layout (");
		str.append(primitivesIn);
		str.append(") in;\n");

		str.append("layout (");
		str.append(primitivesOut);
		str.append(", max_vertices = ");
		std::stringstream ss;
		ss << maxVert;
		str.append(ss.str());
		str.append(") out;\n");
		str.append("#define VARYING_IN in\n");
		str.append("#define VARYING_OUT smooth out\n");
		str.append("#define POSITION_IN(X) gl_in[X].gl_Position\n");
123
		str.append("#define NBVERTS_IN gl_in.length()\n");
124
125
126
127
		return str;
	}
	else
	{
Sylvain Thery's avatar
Sylvain Thery committed
128
129
130
		std::string str("#version 110\n");
		str.append("#extension GL_EXT_geometry_shader4 : enable\n");
		str.append("#define PRECISON float pipo_PRECISION\n");
131
132
133
134
		str.append("#define ATTRIBUTE attribute\n");
		str.append("#define VARYING_IN varying in\n");
		str.append("#define VARYING_OUT varying out\n");
		str.append("#define POSITION_IN(X) gl_PositionIn[X]\n");
135
		str.append("#define NBVERTS_IN gl_VerticesIn\n");
136
137
138
139
		return str;
	}
}

Pierre Kraemer's avatar
Pierre Kraemer committed
140
141
bool GLSLShader::areGeometryShadersSupported()
{
Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
142
143
	if (!glewGetExtension("GL_EXT_geometry_shader4"))
		return false;
Pierre Kraemer's avatar
Pierre Kraemer committed
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
	return true;
}

bool GLSLShader::areShadersSupported()
{
	if ( ! glewGetExtension("GL_ARB_vertex_shader")) return false;
	if ( ! glewGetExtension("GL_ARB_fragment_shader")) return false;
	if ( ! glewGetExtension("GL_ARB_shader_objects")) return false;
	if ( ! glewGetExtension("GL_ARB_shading_language_100")) return false;

	return true;
}

bool GLSLShader::areVBOSupported()
{
	if (!glewGetExtension("GL_ARB_vertex_buffer_object"))
		return false;
	return true;
}

Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
164
char* GLSLShader::loadSourceFile(const std::string& filename)
Pierre Kraemer's avatar
Pierre Kraemer committed
165
166
167
168
169
170
171
172
173
174
{
	std::ifstream	file;
	int				file_size;
	char*			shader_source;

	/*** opening file ***/
	file.open( filename.c_str() , std::ios::in | std::ios::binary );

	if( !file.good() )
	{
175
		CGoGNerr << "ERROR - GLSLShader::loadSourceFile() - unable to open the file " << filename << "." << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
		return NULL;
	}

	/*** reading file ***/
	try
	{
		/* get file size */
		file.seekg( 0, std::ios::end );
		file_size = file.tellg();
		file.seekg( 0, std::ios::beg );

		/* allocate shader source table */
		shader_source = new char [ file_size+1 ];

		/* read source file */
		file.read( shader_source, file_size );
		shader_source[ file_size ] = '\0';
	}
	catch( std::exception& io_exception )
	{
196
		CGoGNerr << "ERROR - GLSLShader::loadSourceFile() - " << io_exception.what() << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
197
198
199
200
201
202
203
204
205
206
207
208
		file.close();
		return NULL;
	}

	/*** termination ***/
	file.close();
	return shader_source;
}

bool GLSLShader::loadVertexShader(  const std::string& filename )
{
	bool	flag;
209
//	char	*vertex_shader_source;
Pierre Kraemer's avatar
Pierre Kraemer committed
210

211
212
	if (m_vertex_shader_source)
		delete [] m_vertex_shader_source;
213
	m_vertex_shader_source = NULL;
Pierre Kraemer's avatar
Pierre Kraemer committed
214

215
	m_vertex_shader_source = loadSourceFile( filename );
Pierre Kraemer's avatar
Pierre Kraemer committed
216

217
	if( !m_vertex_shader_source )
Pierre Kraemer's avatar
Pierre Kraemer committed
218
	{
219
		CGoGNerr << "ERROR - GLSLShader::loadVertexShader() - error occured while loading source file." << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
220
221
222
223
		return false;
	}


224
225
	flag = loadVertexShaderSourceString( m_vertex_shader_source );
//	delete [] vertex_shader_source;
Pierre Kraemer's avatar
Pierre Kraemer committed
226
227
228
229

	return flag;
}

230
bool GLSLShader::loadFragmentShader(const std::string& filename )
Pierre Kraemer's avatar
Pierre Kraemer committed
231
232
{
	bool	flag;
233
//	char	*fragment_shader_source;
Pierre Kraemer's avatar
Pierre Kraemer committed
234

235
236
	if (m_fragment_shader_source)
		delete [] m_fragment_shader_source;
237
	m_fragment_shader_source = NULL;
Pierre Kraemer's avatar
Pierre Kraemer committed
238

239
	m_fragment_shader_source = loadSourceFile( filename );
Pierre Kraemer's avatar
Pierre Kraemer committed
240

241
	if( !m_fragment_shader_source )
Pierre Kraemer's avatar
Pierre Kraemer committed
242
	{
243
		CGoGNerr << "ERROR - GLSLShader::loadFragmentShader() - error occured while loading source file." << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
244
245
246
		return false;
	}

247
248
	flag = loadFragmentShaderSourceString( m_fragment_shader_source );
//	delete [] fragment_shader_source;
Pierre Kraemer's avatar
Pierre Kraemer committed
249
250
251
252
253
254
255
256


	return flag;
}

bool GLSLShader::loadGeometryShader(const std::string& filename )
{
	bool	flag;
257
//	char	*geom_shader_source;
Pierre Kraemer's avatar
Pierre Kraemer committed
258

259
260
	if (m_geom_shader_source)
		delete [] m_geom_shader_source;
Pierre Kraemer's avatar
Pierre Kraemer committed
261

262
	m_geom_shader_source = loadSourceFile( filename );
Pierre Kraemer's avatar
Pierre Kraemer committed
263

264
	if( !m_geom_shader_source )
Pierre Kraemer's avatar
Pierre Kraemer committed
265
	{
266
		CGoGNerr << "ERROR - GLSLShader::loadGeometryShader() - error occured while loading source file." << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
267
268
269
		return false;
	}

270
271
	flag = loadGeometryShaderSourceString( m_geom_shader_source );
//	delete [] geom_shader_source;
Pierre Kraemer's avatar
Pierre Kraemer committed
272
273
274
275

	return flag;
}

Sylvain Thery's avatar
Sylvain Thery committed
276
bool GLSLShader::logError(GLuint handle, const std::string& nameSrc, const char *src)
Pierre Kraemer's avatar
Pierre Kraemer committed
277
{
Sylvain Thery's avatar
Sylvain Thery committed
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
	char *info_log;
	info_log = getInfoLog( handle );
	if (info_log!=NULL)
	{
		CGoGNerr << "============================================================================" << CGoGNendl;
		CGoGNerr << "Error in " << nameSrc << CGoGNendl;
		CGoGNerr << "----------------------------------------------------------------------------" << CGoGNendl;
		char line[256];
		int ln=1;
		std::stringstream ss(src);
		do
		{
			ss.getline(line,256);
			std::cout << ln++ << ": "<< line<< std::endl;
		}while (!ss.eof());
		CGoGNerr << "----------------------------------------------------------------------------" << CGoGNendl;
		CGoGNerr << info_log;
		CGoGNerr << "============================================================================" << CGoGNendl;
		delete [] info_log;
		return false;
	}
	return true;
}
Pierre Kraemer's avatar
Pierre Kraemer committed
301

Sylvain Thery's avatar
Sylvain Thery committed
302
303
304

bool GLSLShader::loadVertexShaderSourceString( const char *vertex_shader_source )
{
305
	if (*m_vertex_shader_object==0)
Sylvain Thery's avatar
Sylvain Thery committed
306
	{
307
308
		glDeleteShader(*m_vertex_shader_object);
		*m_vertex_shader_object=0;
Sylvain Thery's avatar
Sylvain Thery committed
309
	}
Pierre Kraemer's avatar
Pierre Kraemer committed
310
311

	/*** create shader object ***/
312
	*m_vertex_shader_object = glCreateShader( GL_VERTEX_SHADER );
Pierre Kraemer's avatar
Pierre Kraemer committed
313

314
	if( !*m_vertex_shader_object )
Pierre Kraemer's avatar
Pierre Kraemer committed
315
	{
316
		CGoGNerr << "ERROR - GLSLShader::loadVertexShader() - unable to create shader object." << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
317
318
319
320
321
322
		return false;
	}

	/*** load source file ***/
	if( !vertex_shader_source )
	{
323
		CGoGNerr << "ERROR - GLSLShader::loadVertexShader() - source string is empty." << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
324

325
		glDeleteShader(*m_vertex_shader_object );
326
		*m_vertex_shader_object = 0;
Pierre Kraemer's avatar
Pierre Kraemer committed
327
328
329
330

		return false;
	}

331
	glShaderSource( *m_vertex_shader_object, 1, (const char**)&vertex_shader_source, NULL );
Pierre Kraemer's avatar
Pierre Kraemer committed
332
333

	/*** compile shader object ***/
334
	glCompileShader( *m_vertex_shader_object );
Pierre Kraemer's avatar
Pierre Kraemer committed
335

Sylvain Thery's avatar
Sylvain Thery committed
336
	if (!logError(*m_vertex_shader_object, m_nameVS, vertex_shader_source))
Pierre Kraemer's avatar
Pierre Kraemer committed
337
	{
338
		glDeleteShader( *m_vertex_shader_object );
339
		*m_vertex_shader_object = 0;
Pierre Kraemer's avatar
Pierre Kraemer committed
340
341
342
343
344
345
346
		return false;
	}

	/*** termination ***/
	return true;
}

347
bool GLSLShader::loadFragmentShaderSourceString( const char *fragment_shader_source )
Pierre Kraemer's avatar
Pierre Kraemer committed
348
{
349
	if (*m_fragment_shader_object==0)
Sylvain Thery's avatar
Sylvain Thery committed
350
	{
351
352
		glDeleteShader(*m_fragment_shader_object);
		*m_fragment_shader_object=0;
Sylvain Thery's avatar
Sylvain Thery committed
353
	}
Pierre Kraemer's avatar
Pierre Kraemer committed
354
355

	/*** create shader object ***/
356
	*m_fragment_shader_object = glCreateShader( GL_FRAGMENT_SHADER );
Pierre Kraemer's avatar
Pierre Kraemer committed
357

358
	if( !*m_fragment_shader_object )
Pierre Kraemer's avatar
Pierre Kraemer committed
359
	{
360
		CGoGNerr << "ERROR - GLSLShader::loadFragmentShader() - unable to create shader object." << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
361
362
363
364
		return false;
	}

	/*** load source file ***/
365
	if( !fragment_shader_source )
Pierre Kraemer's avatar
Pierre Kraemer committed
366
	{
367
		CGoGNerr << "ERROR - GLSLShader::loadFragmentShader() - source string is empty." << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
368

369
		glDeleteShader( *m_fragment_shader_object );
370
		*m_fragment_shader_object = 0;
Pierre Kraemer's avatar
Pierre Kraemer committed
371
372
373
374

		return false;
	}

375
	glShaderSource( *m_fragment_shader_object, 1, (const char**)&fragment_shader_source, NULL );
Pierre Kraemer's avatar
Pierre Kraemer committed
376
377

	/*** compile shader object ***/
378
	glCompileShader( *m_fragment_shader_object );
Pierre Kraemer's avatar
Pierre Kraemer committed
379

Sylvain Thery's avatar
Sylvain Thery committed
380
	if (!logError(*m_fragment_shader_object, m_nameFS, fragment_shader_source))
Pierre Kraemer's avatar
Pierre Kraemer committed
381
	{
382
		glDeleteShader( *m_fragment_shader_object );
383
		*m_fragment_shader_object = 0;
Pierre Kraemer's avatar
Pierre Kraemer committed
384
385
386
		return false;
	}

Sylvain Thery's avatar
Sylvain Thery committed
387

Pierre Kraemer's avatar
Pierre Kraemer committed
388
389
390
391
392
393
	/*** termination ***/
	return true;
}

bool GLSLShader::loadGeometryShaderSourceString( const char *geom_shader_source )
{
394
	if (*m_geom_shader_object==0)
Sylvain Thery's avatar
Sylvain Thery committed
395
	{
396
397
		glDeleteShader(*m_geom_shader_object);
		*m_geom_shader_object=0;
Sylvain Thery's avatar
Sylvain Thery committed
398
	}
Pierre Kraemer's avatar
Pierre Kraemer committed
399
	/*** create shader object ***/
400
	*m_geom_shader_object = glCreateShader(GL_GEOMETRY_SHADER_EXT);
Pierre Kraemer's avatar
Pierre Kraemer committed
401

402
	if( !*m_geom_shader_object )
Pierre Kraemer's avatar
Pierre Kraemer committed
403
	{
404
		CGoGNerr << "ERROR - GLSLShader::loadGeometryShader() - unable to create shader object." << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
405
406
407
408
409
410
		return false;
	}

	/*** load source file ***/
	if( !geom_shader_source )
	{
411
		CGoGNerr << "ERROR - GLSLShader::loadGeometryShader() - source string is empty." << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
412

413
		glDeleteShader( *m_geom_shader_object );
414
		*m_geom_shader_object = 0;
Pierre Kraemer's avatar
Pierre Kraemer committed
415
416
417
418

		return false;
	}

419
	glShaderSource( *m_geom_shader_object, 1, (const char**)&geom_shader_source, NULL );
Pierre Kraemer's avatar
Pierre Kraemer committed
420
421

	/*** compile shader object ***/
422
	glCompileShader( *m_geom_shader_object );
Pierre Kraemer's avatar
Pierre Kraemer committed
423

Sylvain Thery's avatar
Sylvain Thery committed
424
	if (!logError(*m_geom_shader_object, m_nameGS, geom_shader_source))
Pierre Kraemer's avatar
Pierre Kraemer committed
425
	{
426
		glDeleteShader( *m_geom_shader_object );
427
		*m_geom_shader_object = 0;
Pierre Kraemer's avatar
Pierre Kraemer committed
428
429
430
		return false;
	}

Sylvain Thery's avatar
Sylvain Thery committed
431

Pierre Kraemer's avatar
Pierre Kraemer committed
432
433
434
435
	/*** termination ***/
	return true;
}

436
char* GLSLShader::getInfoLog( GLuint obj )
Pierre Kraemer's avatar
Pierre Kraemer committed
437
438
439
440
441
{
	char	*info_log;
	int		info_log_length;
	int		length;

Sylvain Thery's avatar
Sylvain Thery committed
442
443
444
445
	glGetShaderiv(obj, GL_INFO_LOG_LENGTH, &info_log_length);

	if (info_log_length <= 1)
		return NULL;
Pierre Kraemer's avatar
Pierre Kraemer committed
446
447

	info_log = new char [info_log_length];
Sylvain Thery's avatar
Sylvain Thery committed
448
	glGetShaderInfoLog( obj, info_log_length, &length, info_log );
Pierre Kraemer's avatar
Pierre Kraemer committed
449
450
451
452

	return info_log;
}

Sylvain Thery's avatar
Sylvain Thery committed
453
454


Sylvain Thery's avatar
Sylvain Thery committed
455
bool GLSLShader::create(GLint inputGeometryPrimitive,GLint outputGeometryPrimitive, int nb_max_vertices)
Pierre Kraemer's avatar
Pierre Kraemer committed
456
457
458
459
{
	int		status;
	char	*info_log;

460
	if (nb_max_vertices != -1)
Sylvain Thery's avatar
Sylvain Thery committed
461
462
		m_nbMaxVertices = nb_max_vertices;

463
464
	m_geom_inputPrimitives = inputGeometryPrimitive;
	m_geom_outputPrimitives = outputGeometryPrimitive;
Pierre Kraemer's avatar
Pierre Kraemer committed
465
466

	/*** check if shaders are loaded ***/
467
	if( !*m_vertex_shader_object || !*m_fragment_shader_object )
Pierre Kraemer's avatar
Pierre Kraemer committed
468
	{
469
		CGoGNerr << "ERROR - GLSLShader::create() - shaders are not defined." << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
470
471
472
473
		return false;
	}

	/*** create program object ***/
474
	m_program_object = glCreateProgram();
Pierre Kraemer's avatar
Pierre Kraemer committed
475

476
	if( !*m_program_object )
Pierre Kraemer's avatar
Pierre Kraemer committed
477
	{
478
		CGoGNerr << "ERROR - GLSLShader::create() - unable to create program object." << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
479
480
481
482
		return false;
	}

	/*** attach shaders to program object ***/
483
484
	glAttachShader( *m_program_object, *m_vertex_shader_object );
	glAttachShader( *m_program_object, *m_fragment_shader_object );
485
	if (*m_geom_shader_object)
Pierre Kraemer's avatar
Pierre Kraemer committed
486
	{
487
		glAttachShader( *m_program_object, *m_geom_shader_object );
Pierre Kraemer's avatar
Pierre Kraemer committed
488

489
490
491
		glProgramParameteriEXT(*m_program_object, GL_GEOMETRY_INPUT_TYPE_EXT, inputGeometryPrimitive);
		glProgramParameteriEXT(*m_program_object, GL_GEOMETRY_OUTPUT_TYPE_EXT, outputGeometryPrimitive);
		glProgramParameteriEXT(*m_program_object, GL_GEOMETRY_VERTICES_OUT_EXT, m_nbMaxVertices);
Pierre Kraemer's avatar
Pierre Kraemer committed
492
493
494
	}

	/*** link program object ***/
495
	glLinkProgram( *m_program_object );
Pierre Kraemer's avatar
Pierre Kraemer committed
496

497
	glGetProgramiv( *m_program_object, GL_OBJECT_LINK_STATUS_ARB, &status );
Pierre Kraemer's avatar
Pierre Kraemer committed
498
499
	if( !status )
	{
500
		CGoGNerr << "ERROR - GLSLShader::create() - error occured while linking shader program." << CGoGNendl;
501
		info_log = getInfoLog( *m_program_object );
502
		CGoGNerr << "  LINK " << info_log << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
503
504
		delete [] info_log;

505
506
		glDetachShader( *m_program_object, *m_vertex_shader_object );
		glDetachShader( *m_program_object, *m_fragment_shader_object );
507
		if (*m_geom_shader_object)
508
509
			glDetachShader( *m_program_object, *m_geom_shader_object );
		glDeleteShader( *m_program_object );
510
		*m_program_object = 0;
Pierre Kraemer's avatar
Pierre Kraemer committed
511
512
513
514

		return false;
	}

515
516
517
518
	*m_uniMat_Proj		= glGetUniformLocation(*m_program_object, "ProjectionMatrix");
	*m_uniMat_Model		= glGetUniformLocation(*m_program_object, "ModelViewMatrix");
	*m_uniMat_ModelProj	= glGetUniformLocation(*m_program_object, "ModelViewProjectionMatrix");
	*m_uniMat_Normal	= glGetUniformLocation(*m_program_object, "NormalMatrix");
519

Pierre Kraemer's avatar
Pierre Kraemer committed
520
521
522
	return true;
}

Sylvain Thery's avatar
Sylvain Thery committed
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542


bool GLSLShader::changeNbMaxVertices(int nb_max_vertices)
{
	m_nbMaxVertices = nb_max_vertices;
	if (*m_geom_shader_object)
	{
		glProgramParameteriEXT(*m_program_object,GL_GEOMETRY_VERTICES_OUT_EXT,m_nbMaxVertices);
		// need to relink
		return true;
	}
	return false;
}







543
544
545
546
547
548
bool GLSLShader::link()
{
	int		status;
	char	*info_log;

	/*** link program object ***/
549
	glLinkProgram( *m_program_object );
550

551
	glGetProgramiv( *m_program_object, GL_OBJECT_LINK_STATUS_ARB, &status );
552
553
	if( !status )
	{
554
		CGoGNerr << "ERROR - GLSLShader::create() - error occured while linking shader program." << CGoGNendl;
555
		info_log = getInfoLog( *m_program_object );
556
		CGoGNerr << "  LINK " << info_log << CGoGNendl;
557
558
		delete [] info_log;

559
560
		glDetachShader( *m_program_object, *m_vertex_shader_object );
		glDetachShader( *m_program_object, *m_fragment_shader_object );
561
		if (*m_geom_shader_object)
562
563
			glDetachShader( *m_program_object, *m_geom_shader_object );
		glDeleteShader( *m_program_object );
564
		*m_program_object = 0;
565
566
567
568
569
570
571

		return false;
	}

	return true;
}

572
bool GLSLShader::bind() const
Pierre Kraemer's avatar
Pierre Kraemer committed
573
{
574
	if( *m_program_object )
Pierre Kraemer's avatar
Pierre Kraemer committed
575
	{
576
		glUseProgram( *m_program_object );
Pierre Kraemer's avatar
Pierre Kraemer committed
577
578
		return true;
	}
579
580
	else
		return false;
Pierre Kraemer's avatar
Pierre Kraemer committed
581
582
}

583
void GLSLShader::unbind() const
Pierre Kraemer's avatar
Pierre Kraemer committed
584
{
585
	if( *m_program_object )
Pierre Kraemer's avatar
Pierre Kraemer committed
586
	{
587
		glUseProgram( 0 );
Pierre Kraemer's avatar
Pierre Kraemer committed
588
589
590
591
592
	}
}

bool GLSLShader::isBinded()
{
593
594
595
596
597
598
	if (*m_program_object == 0)
		return false;

	GLint po;
	glGetIntegerv(GL_CURRENT_PROGRAM,&po);
	return ( *m_program_object == po );
Pierre Kraemer's avatar
Pierre Kraemer committed
599
600
601
602
}

GLSLShader::~GLSLShader()
{
603
	if( *m_program_object )
Pierre Kraemer's avatar
Pierre Kraemer committed
604
605
606
	{
		unbind();

607
		if( *m_vertex_shader_object )
Pierre Kraemer's avatar
Pierre Kraemer committed
608
		{
609
610
			glDetachShader( *m_program_object, *m_vertex_shader_object );
			glDeleteShader( *m_vertex_shader_object );
Pierre Kraemer's avatar
Pierre Kraemer committed
611
		}
612
		if( *m_fragment_shader_object )
Pierre Kraemer's avatar
Pierre Kraemer committed
613
		{
614
615
			glDetachShader( *m_program_object, *m_fragment_shader_object );
			glDeleteShader( *m_fragment_shader_object );
Pierre Kraemer's avatar
Pierre Kraemer committed
616
		}
617
		if (*m_geom_shader_object)
Pierre Kraemer's avatar
Pierre Kraemer committed
618
		{
619
620
			glDetachShader( *m_program_object, *m_geom_shader_object );
			glDeleteShader( *m_geom_shader_object );
Pierre Kraemer's avatar
Pierre Kraemer committed
621
622
		}

623
		glDeleteShader( *m_program_object );
Pierre Kraemer's avatar
Pierre Kraemer committed
624
	}
625

626
627
628
629
630
631
632
	if (m_vertex_shader_source != NULL)
		delete[] m_vertex_shader_source;
	if (m_fragment_shader_source != NULL)
		delete[] m_fragment_shader_source;
	if (m_geom_shader_source != NULL)
		delete[] m_geom_shader_source;

Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
633
//	m_registeredShaders.erase(this);
Pierre Kraemer's avatar
Pierre Kraemer committed
634
635
636
637
}

std::string GLSLShader::findFile(const std::string filename)
{
Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
638
	// cherche d'abord dans le repertoire courant
Pierre Kraemer's avatar
Pierre Kraemer committed
639
640
641
642
643
644
645
646
647
	std::ifstream file;
	file.open(filename.c_str(),std::ios::in );
	if (!file.fail())
	{
		file.close();
		return filename;
	}
	file.close();

648
649
650
651
652
653
654
655
656
657
658
659
660
661
	for (std::vector<std::string>::const_iterator ipath = m_pathes.begin(); ipath != m_pathes.end(); ++ipath)
	{
		std::string st(*ipath);
		st.append(filename);

		std::ifstream file2;
		file2.open(st.c_str(),std::ios::in);
		if (!file2.fail())
		{
			file2.close();
			return st;
		}
	}

Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
662
	// LA MACRO SHADERPATH contient le chemin du repertoire qui contient les fichiers textes
Pierre Kraemer's avatar
Pierre Kraemer committed
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
	std::string st(SHADERPATH);
	st.append(filename);

	std::ifstream file2; // on ne peut pas réutiliser file ????
	file2.open(st.c_str(),std::ios::in);
	if (!file2.fail())
	{
		file2.close();
		return st;
	}

	return filename;
}

bool GLSLShader::init()
{
679
#ifndef GLEW_MX
Pierre Kraemer's avatar
Pierre Kraemer committed
680
681
682
	GLenum error = glewInit();

	if (error != GLEW_OK)
683
		CGoGNerr << "Error: " << glewGetErrorString(error) << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
684
	else
685
		CGoGNout << "Status: Using GLEW " << glewGetString(GLEW_VERSION) << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
686
687

	if (!areVBOSupported())
688
		CGoGNout << "VBO not supported !" << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
689
690

	if(!areShadersSupported()) {
691
		CGoGNout << "Shaders not supported !" << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
692
693
		return false;
	}
694
695
696
#endif
	return true;

Pierre Kraemer's avatar
Pierre Kraemer committed
697
698
699
700
}

bool GLSLShader::loadShaders(const std::string& vs, const std::string& ps)
{
Sylvain Thery's avatar
Sylvain Thery committed
701
702
	m_nameVS = vs;
	m_nameFS = ps;
703

Pierre Kraemer's avatar
Pierre Kraemer committed
704
705
706
707
	std::string vss = findFile(vs);
	if(!loadVertexShader(vss)) return false;
	
	std::string pss = findFile(ps);
708
	if(!loadFragmentShader(pss)) return false;
Pierre Kraemer's avatar
Pierre Kraemer committed
709
710

	if(!create()) {
711
		CGoGNout << "Unable to create the shaders !" << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
712
713
		return false;
	}
714
	CGoGNout << "Shaders loaded (" << vs << "," << ps << ")" << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
715
716
717
	return true; 
}

Sylvain Thery's avatar
Sylvain Thery committed
718
bool GLSLShader::loadShaders(const std::string& vs, const std::string& ps, const std::string& gs, GLint inputGeometryPrimitive,GLint outputGeometryPrimitive, int nb_max_vertices)
Pierre Kraemer's avatar
Pierre Kraemer committed
719
{
Sylvain Thery's avatar
Sylvain Thery committed
720
721
722
723
	m_nameVS = vs;
	m_nameFS = ps;
	m_nameGS = gs;

Pierre Kraemer's avatar
Pierre Kraemer committed
724
725
726
727
	std::string vss = findFile(vs);
	if(!loadVertexShader(vss)) return false;

	std::string pss = findFile(ps);
728
	if(!loadFragmentShader(pss)) return false;
Pierre Kraemer's avatar
Pierre Kraemer committed
729
730
731
732
733
734

	std::string gss = findFile(gs);
	bool geomShaderLoaded = loadGeometryShader(gss);

	if (!geomShaderLoaded)
	{
735
		CGoGNerr << "Error while loading geometry shader" << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
736
737
	}

Sylvain Thery's avatar
Sylvain Thery committed
738
	if(!create(inputGeometryPrimitive,outputGeometryPrimitive,nb_max_vertices))
Pierre Kraemer's avatar
Pierre Kraemer committed
739
	{
740
		CGoGNout << "Unable to create the shaders !" << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
741
742
743
		return false;
	}

744
	CGoGNout << "Shaders loaded (" << vs << "," << ps << "," << gs <<")" << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
745
746
747
	return true;
}

Sylvain Thery's avatar
Sylvain Thery committed
748
749
bool GLSLShader::loadShadersFromMemory(const char* vs, const char* fs)
{
750
751
	if (m_vertex_shader_source)
		delete [] m_vertex_shader_source;
752
	m_vertex_shader_source = NULL;
753
754
755

	unsigned int sz = strlen(vs);
	m_vertex_shader_source = new char[sz+1];
Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
756
	strcpy(m_vertex_shader_source, vs);
757
758
759
760
761
762

	if (m_fragment_shader_source)
		delete [] m_fragment_shader_source;

	sz = strlen(fs);
	m_fragment_shader_source = new char[sz+1];
Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
763
	strcpy(m_fragment_shader_source, fs);
764

765
766
	if(!loadVertexShaderSourceString(vs))
		return false;
Sylvain Thery's avatar
Sylvain Thery committed
767

768
769
	if(!loadFragmentShaderSourceString(fs))
		return false;
Sylvain Thery's avatar
Sylvain Thery committed
770
771
772

	if(!create())
	{
773
		CGoGNout << "Unable to create the shaders !" << CGoGNendl;
Sylvain Thery's avatar
Sylvain Thery committed
774
775
776
777
778
		return false;
	}
	return true;
}

Sylvain Thery's avatar
Sylvain Thery committed
779
bool GLSLShader::loadShadersFromMemory(const char* vs, const char* fs, const char* gs, GLint inputGeometryPrimitive,GLint outputGeometryPrimitive, int nb_max_vertices)
Sylvain Thery's avatar
Sylvain Thery committed
780
{
781
782
	if (m_vertex_shader_source)
		delete [] m_vertex_shader_source;
783
	m_vertex_shader_source = NULL;
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802

	unsigned int sz = strlen(vs);
	m_vertex_shader_source = new char[sz+1];
	strcpy(m_vertex_shader_source,vs);

	if (m_fragment_shader_source)
		delete [] m_fragment_shader_source;

	sz = strlen(fs);
	m_fragment_shader_source = new char[sz+1];
	strcpy(m_fragment_shader_source,fs);

	if (m_geom_shader_source)
		delete [] m_geom_shader_source;

	sz = strlen(gs);
	m_geom_shader_source = new char[sz+1];
	strcpy(m_geom_shader_source,gs);

Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
803
804
	if(!loadVertexShaderSourceString(vs))
		return false;
Sylvain Thery's avatar
Sylvain Thery committed
805

Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
806
807
	if(!loadFragmentShaderSourceString(fs))
		return false;
Sylvain Thery's avatar
Sylvain Thery committed
808

Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
809
810
	if(!loadGeometryShaderSourceString(gs))
		return false;
Sylvain Thery's avatar
Sylvain Thery committed
811

812
	if(!create(inputGeometryPrimitive, outputGeometryPrimitive, nb_max_vertices))
Sylvain Thery's avatar
Sylvain Thery committed
813
	{
814
		CGoGNout << "Unable to create the shaders !" << CGoGNendl;
Sylvain Thery's avatar
Sylvain Thery committed
815
816
817
818
819
820
		return false;
	}

	return true;
}

821
822
823
824
bool GLSLShader::reloadVertexShaderFromMemory(const char* vs)
{
	if (m_vertex_shader_source)
		delete [] m_vertex_shader_source;
825
	m_vertex_shader_source = NULL;
826
827
828

	unsigned int sz = strlen(vs);
	m_vertex_shader_source = new char[sz+1];
829

830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
	strcpy(m_vertex_shader_source,vs);

	return true;
}

bool GLSLShader::reloadFragmentShaderFromMemory(const char* fs)
{
	if (m_fragment_shader_source)
		delete [] m_fragment_shader_source;

	unsigned int sz = strlen(fs);
	m_fragment_shader_source = new char[sz+1];
	strcpy(m_fragment_shader_source,fs);

	return true;
}

bool GLSLShader::reloadGeometryShaderFromMemory(const char* gs)
{
	if (m_geom_shader_source)
		delete [] m_geom_shader_source;

	unsigned int sz = strlen(gs);
	m_geom_shader_source = new char[sz+1];
	strcpy(m_geom_shader_source,gs);

	return true;
}

bool GLSLShader::recompile()
{
	if (m_vertex_shader_source)
		if(!loadVertexShaderSourceString(m_vertex_shader_source)) return false;
	if (m_fragment_shader_source)
		if(!loadFragmentShaderSourceString(m_fragment_shader_source)) return false;
	if (m_geom_shader_source)
		if(!loadGeometryShaderSourceString(m_geom_shader_source)) return false;

	if(!create(m_geom_inputPrimitives,m_geom_outputPrimitives))
	{
870
		CGoGNerr << "Unable to create the shaders !" << CGoGNendl;
871
872
873
		return false;
	}

874
875
876
	*m_uniMat_Proj		= glGetUniformLocation(*m_program_object,"ProjectionMatrix");
	*m_uniMat_Model		= glGetUniformLocation(*m_program_object,"ModelViewMatrix");
	*m_uniMat_ModelProj	= glGetUniformLocation(*m_program_object,"ModelViewProjectionMatrix");
Sylvain Thery's avatar
Sylvain Thery committed
877
	*m_uniMat_Normal	= glGetUniformLocation(*m_program_object,"NormalMatrix");
878
879
880

	restoreUniformsAttribs();

881
882
	updateClippingUniforms();

883
884
885
	return true;
}

886
887
bool GLSLShader::validateProgram()
{
888
	if(!*m_program_object)
889
890
		return false;

891
	glValidateProgram(*m_program_object);
892
	GLint Result = GL_FALSE;
893
	glGetProgramiv(*m_program_object, GL_VALIDATE_STATUS, &Result);
894
895
896

	if(Result == GL_FALSE)
	{
897
		CGoGNout << "Validate program:" << CGoGNendl;
898
		int InfoLogLength;
899
		glGetProgramiv(*m_program_object, GL_INFO_LOG_LENGTH, &InfoLogLength);
900
		std::vector<char> Buffer(InfoLogLength);
901
		glGetProgramInfoLog(*m_program_object, InfoLogLength, NULL, &Buffer[0]);
902
		CGoGNout <<  &(Buffer[0]) << CGoGNendl;
903
904
905
906
907
908
909
910
911
		return false;
	}

	return true;
}

bool GLSLShader::checkProgram()
{
	GLint Result = GL_FALSE;
912
	glGetProgramiv(*m_program_object, GL_LINK_STATUS, &Result);
913
914

	int InfoLogLength;
915
	glGetProgramiv(*m_program_object, GL_INFO_LOG_LENGTH, &InfoLogLength);
916
	std::vector<char> Buffer(std::max(InfoLogLength, int(1)));
917
	glGetProgramInfoLog(*m_program_object, InfoLogLength, NULL, &Buffer[0]);
918
	CGoGNout << &Buffer[0] << CGoGNendl;
919
920
921
922
923
924
925
926

	return Result == GL_TRUE;
}

bool GLSLShader::checkShader(int shaderType)
{
	GLint Result = GL_FALSE;
	int InfoLogLength;
927
	GLuint id;
928
929
930
931

	switch(shaderType)
	{
	case VERTEX_SHADER:
932
		id = *m_vertex_shader_object;
933
934
		break;
	case FRAGMENT_SHADER:
935
		id = *m_fragment_shader_object;
936
937
		break;
	case GEOMETRY_SHADER:
938
		id = *m_geom_shader_object;
939
940
		break;
	default:
941
		CGoGNerr << "Error unkown shader type" << CGoGNendl;
942
943
944
945
946
947
948
949
		return false;
		break;
	}

	glGetShaderiv(id, GL_COMPILE_STATUS, &Result);
	glGetShaderiv(id, GL_INFO_LOG_LENGTH, &InfoLogLength);
	std::vector<char> Buffer(InfoLogLength);
	glGetShaderInfoLog(id, InfoLogLength, NULL, &Buffer[0]);
950
	CGoGNout << &Buffer[0] << CGoGNendl;
951
952
953
954

	return Result == GL_TRUE;
}

Sylvain Thery's avatar
Sylvain Thery committed
955
void GLSLShader::bindAttrib(unsigned int att, const char* name) const
956
{
957
	glBindAttribLocation(*m_program_object, att, name);
958
959
}

960
961
962
963
964
void GLSLShader::addPathFileSeach(const std::string& path)
{
	m_pathes.push_back(path);
}

965
unsigned int GLSLShader::bindVA_VBO(const std::string& name, VBO* vbo)
Sylvain Thery's avatar
Sylvain Thery committed
966
{
967
	GLint idVA = glGetAttribLocation(*(this->m_program_object), name.c_str());
Sylvain Thery's avatar
Sylvain Thery committed
968
969
970
	//valid ?
	if (idVA < 0)
	{
Pierre Kraemer's avatar
Pierre Kraemer committed
971
		CGoGNerr << "GLSLShader: Attribute " << name << " does not exist in shader" << CGoGNendl;
972
		return idVA;
Sylvain Thery's avatar
Sylvain Thery committed
973
974
975
976
977
978
	}
	// search if name already exist
	for (std::vector<VAStr>::iterator it = m_va_vbo_binding.begin(); it != m_va_vbo_binding.end(); ++it)
	{
		if (it->va_id == idVA)
		{
979
980
			it->vbo_ptr = vbo;
			return (it - m_va_vbo_binding.begin());
Sylvain Thery's avatar
Sylvain Thery committed
981
982
983
984
985
		}
	}
	// new one:
	VAStr temp;
	temp.va_id = idVA;
986
	temp.vbo_ptr = vbo;
Sylvain Thery's avatar
Sylvain Thery committed
987
	m_va_vbo_binding.push_back(temp);
988
989
990
991
992
993
	return (m_va_vbo_binding.size() -1);
}

void GLSLShader::changeVA_VBO(unsigned int id, VBO* vbo)
{
	m_va_vbo_binding[id].vbo_ptr = vbo;
Sylvain Thery's avatar
Sylvain Thery committed
994
995
996
997
}

void GLSLShader::unbindVA(const std::string& name)
{
998
	GLint idVA = glGetAttribLocation(*(this->m_program_object), name.c_str());
Sylvain Thery's avatar
Sylvain Thery committed
999
1000
1001
	//valid ?
	if (idVA < 0)
	{
1002
		CGoGNerr << "GLSLShader: Attribute " << name << " does not exist in shader, not unbinded" << CGoGNendl;
Sylvain Thery's avatar
Sylvain Thery committed
1003
1004
1005
1006
		return;
	}
	// search if name already exist
	unsigned int nb = m_va_vbo_binding.size();
1007
	for (unsigned int i = 0; i < nb; ++i)
Sylvain Thery's avatar
Sylvain Thery committed
1008
1009
1010
1011
1012
1013
1014
1015
1016
	{
		if (m_va_vbo_binding[i].va_id == idVA)
		{
			if (i != (nb-1))
				m_va_vbo_binding[i] = m_va_vbo_binding[nb-1];
			m_va_vbo_binding.pop_back();
			return;
		}
	}
1017
	CGoGNerr << "GLSLShader: Attribute "<<name<< " not binded"<< CGoGNendl;
Sylvain Thery's avatar
Sylvain Thery committed
1018
1019
1020
1021
}

void GLSLShader::setCurrentOGLVersion(unsigned int version)
{
Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
1022
	CURRENT_OGL_VERSION = version;
Sylvain Thery's avatar
Sylvain Thery committed
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
	switch(version)
	{
	case 2:
		DEFINES_GL = &DEFINES_GL2;
		break;
	case 3:
		DEFINES_GL = &DEFINES_GL3;
		break;
	}
}

/**
 * update projection, modelview, ... matrices
 */
void GLSLShader::updateMatrices(const glm::mat4& projection, const glm::mat4& modelview)
{
	this->bind();
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057

	if (*m_uniMat_Proj >= 0)
		glUniformMatrix4fv(*m_uniMat_Proj, 1, false, &projection[0][0]);

	if (*m_uniMat_Model >= 0)
		glUniformMatrix4fv(*m_uniMat_Model,	1, false, &modelview[0][0]);

	if (*m_uniMat_ModelProj >= 0)
	{
		glm::mat4 PMV = projection * modelview;
		glUniformMatrix4fv(*m_uniMat_ModelProj,	1 , false, &PMV[0][0]);
	}

	if (*m_uniMat_Normal >= 0)
	{
		glm::mat4 normalMatrix = glm::gtx::inverse_transpose::inverseTranspose(modelview);
		glUniformMatrix4fv(*m_uniMat_Normal, 	1 , false, &normalMatrix[0][0]);
	}
1058
1059

	this->unbind();
Sylvain Thery's avatar
Sylvain Thery committed
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
}

void GLSLShader::updateMatrices(const glm::mat4& projection, const glm::mat4& modelview, const glm::mat4& PMV, const glm::mat4& normalMatrix)
{
	this->bind();

	if (*m_uniMat_Proj >= 0)
		glUniformMatrix4fv(*m_uniMat_Proj, 1, false, &projection[0][0]);

	if (*m_uniMat_Model >= 0)
		glUniformMatrix4fv(*m_uniMat_Model,	1, false, &modelview[0][0]);

	if (*m_uniMat_ModelProj >= 0)
		glUniformMatrix4fv(*m_uniMat_ModelProj,	1 , false, &PMV[0][0]);
1074

Sylvain Thery's avatar
Sylvain Thery committed
1075
1076
	if (*m_uniMat_Normal >= 0)
		glUniformMatrix4fv(*m_uniMat_Normal, 	1 , false, &normalMatrix[0][0]);
1077
1078

	this->unbind();
1079
1080
}

Sylvain Thery's avatar