GLSLShader.cpp 29.2 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
276
277
278
279
280

	return flag;
}

bool GLSLShader::loadVertexShaderSourceString( const char *vertex_shader_source )
{
	int		status;
	char	*info_log;

281
	if (*m_vertex_shader_object==0)
Sylvain Thery's avatar
Sylvain Thery committed
282
	{
283
284
		glDeleteShader(*m_vertex_shader_object);
		*m_vertex_shader_object=0;
Sylvain Thery's avatar
Sylvain Thery committed
285
	}
Pierre Kraemer's avatar
Pierre Kraemer committed
286
287

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

290
	if( !*m_vertex_shader_object )
Pierre Kraemer's avatar
Pierre Kraemer committed
291
	{
292
		CGoGNerr << "ERROR - GLSLShader::loadVertexShader() - unable to create shader object." << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
293
294
295
296
297
298
		return false;
	}

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

301
		glDeleteShader(*m_vertex_shader_object );
302
		*m_vertex_shader_object = 0;
Pierre Kraemer's avatar
Pierre Kraemer committed
303
304
305
306

		return false;
	}

307
	glShaderSource( *m_vertex_shader_object, 1, (const char**)&vertex_shader_source, NULL );
Pierre Kraemer's avatar
Pierre Kraemer committed
308
309

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

312
	glGetProgramiv( *m_vertex_shader_object, GL_OBJECT_COMPILE_STATUS_ARB, &status );
Pierre Kraemer's avatar
Pierre Kraemer committed
313
314
	if( !status )
	{
315
		CGoGNerr << "ERROR - GLshader::loadVertexShader() - error occured while compiling shader " << m_nameVS<< CGoGNendl;
316
		info_log = getInfoLog( *m_vertex_shader_object );
317
				CGoGNerr << info_log << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
318
319
		delete [] info_log;

320
		glDeleteShader( *m_vertex_shader_object );
321
		*m_vertex_shader_object = 0;
Pierre Kraemer's avatar
Pierre Kraemer committed
322
323
324
325
326
327
328
329

		return false;
	}

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

330
bool GLSLShader::loadFragmentShaderSourceString( const char *fragment_shader_source )
Pierre Kraemer's avatar
Pierre Kraemer committed
331
332
333
334
{
	int		status;
	char	*info_log;

335
	if (*m_fragment_shader_object==0)
Sylvain Thery's avatar
Sylvain Thery committed
336
	{
337
338
		glDeleteShader(*m_fragment_shader_object);
		*m_fragment_shader_object=0;
Sylvain Thery's avatar
Sylvain Thery committed
339
	}
Pierre Kraemer's avatar
Pierre Kraemer committed
340
341

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

344
	if( !*m_fragment_shader_object )
Pierre Kraemer's avatar
Pierre Kraemer committed
345
	{
346
		CGoGNerr << "ERROR - GLSLShader::loadFragmentShader() - unable to create shader object." << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
347
348
349
350
		return false;
	}

	/*** load source file ***/
351
	if( !fragment_shader_source )
Pierre Kraemer's avatar
Pierre Kraemer committed
352
	{
353
		CGoGNerr << "ERROR - GLSLShader::loadFragmentShader() - source string is empty." << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
354

355
		glDeleteShader( *m_fragment_shader_object );
356
		*m_fragment_shader_object = 0;
Pierre Kraemer's avatar
Pierre Kraemer committed
357
358
359
360

		return false;
	}

361
	glShaderSource( *m_fragment_shader_object, 1, (const char**)&fragment_shader_source, NULL );
Pierre Kraemer's avatar
Pierre Kraemer committed
362
363

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

366
	glGetProgramiv( *m_fragment_shader_object, GL_OBJECT_COMPILE_STATUS_ARB, &status );
Pierre Kraemer's avatar
Pierre Kraemer committed
367
368
	if( !status )
	{
369
		CGoGNerr << "ERROR - GLshader::loadFragmentShader() - error occured while compiling shader " <<  m_nameFS << CGoGNendl;
370
		info_log = getInfoLog( *m_fragment_shader_object );
371
		CGoGNerr << info_log << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
372
373
		delete [] info_log;

374
		glDeleteShader( *m_fragment_shader_object );
375
		*m_fragment_shader_object = 0;
Pierre Kraemer's avatar
Pierre Kraemer committed
376
377
378
379
380
381
382
383
384
385
386
387
388

		return false;
	}

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

bool GLSLShader::loadGeometryShaderSourceString( const char *geom_shader_source )
{
	int		status;
	char	*info_log;

389
	if (*m_geom_shader_object==0)
Sylvain Thery's avatar
Sylvain Thery committed
390
	{
391
392
		glDeleteShader(*m_geom_shader_object);
		*m_geom_shader_object=0;
Sylvain Thery's avatar
Sylvain Thery committed
393
	}
Pierre Kraemer's avatar
Pierre Kraemer committed
394
	/*** create shader object ***/
395
	*m_geom_shader_object = glCreateShader(GL_GEOMETRY_SHADER_EXT);
Pierre Kraemer's avatar
Pierre Kraemer committed
396

397
	if( !*m_geom_shader_object )
Pierre Kraemer's avatar
Pierre Kraemer committed
398
	{
399
		CGoGNerr << "ERROR - GLSLShader::loadGeometryShader() - unable to create shader object." << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
400
401
402
403
404
405
		return false;
	}

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

408
		glDeleteShader( *m_geom_shader_object );
409
		*m_geom_shader_object = 0;
Pierre Kraemer's avatar
Pierre Kraemer committed
410
411
412
413

		return false;
	}

414
	glShaderSource( *m_geom_shader_object, 1, (const char**)&geom_shader_source, NULL );
Pierre Kraemer's avatar
Pierre Kraemer committed
415
416

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

419
	glGetProgramiv( *m_geom_shader_object, GL_OBJECT_COMPILE_STATUS_ARB, &status );
Pierre Kraemer's avatar
Pierre Kraemer committed
420
421
	if( !status )
	{
422
		CGoGNerr << "ERROR - GLshader::loadGeometryShader() - error occured while compiling shader "<< m_nameGS << CGoGNendl;
423
		info_log = getInfoLog( *m_geom_shader_object );
424
		CGoGNerr << info_log << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
425
426
		delete [] info_log;

427
		glDeleteShader( *m_geom_shader_object );
428
		*m_geom_shader_object = 0;
Pierre Kraemer's avatar
Pierre Kraemer committed
429
430
431
432
433
434
435
436

		return false;
	}

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

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

443
	glGetProgramiv( obj, GL_OBJECT_INFO_LOG_LENGTH_ARB, &info_log_length );
Pierre Kraemer's avatar
Pierre Kraemer committed
444
445

	info_log = new char [info_log_length];
446
	glGetProgramInfoLog( obj, info_log_length, &length, info_log );
Pierre Kraemer's avatar
Pierre Kraemer committed
447
448
449
450

	return info_log;
}

Sylvain Thery's avatar
Sylvain Thery committed
451
bool GLSLShader::create(GLint inputGeometryPrimitive,GLint outputGeometryPrimitive, int nb_max_vertices)
Pierre Kraemer's avatar
Pierre Kraemer committed
452
453
454
455
{
	int		status;
	char	*info_log;

456
	if (nb_max_vertices != -1)
Sylvain Thery's avatar
Sylvain Thery committed
457
458
		m_nbMaxVertices = nb_max_vertices;

459
460
	m_geom_inputPrimitives = inputGeometryPrimitive;
	m_geom_outputPrimitives = outputGeometryPrimitive;
Pierre Kraemer's avatar
Pierre Kraemer committed
461
462

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

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

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

	/*** attach shaders to program object ***/
479
480
	glAttachShader( *m_program_object, *m_vertex_shader_object );
	glAttachShader( *m_program_object, *m_fragment_shader_object );
481
	if (*m_geom_shader_object)
Pierre Kraemer's avatar
Pierre Kraemer committed
482
	{
483
		glAttachShader( *m_program_object, *m_geom_shader_object );
Pierre Kraemer's avatar
Pierre Kraemer committed
484

485
486
487
		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
488
489
490
	}

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

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

501
502
		glDetachShader( *m_program_object, *m_vertex_shader_object );
		glDetachShader( *m_program_object, *m_fragment_shader_object );
503
		if (*m_geom_shader_object)
504
505
			glDetachShader( *m_program_object, *m_geom_shader_object );
		glDeleteShader( *m_program_object );
506
		*m_program_object = 0;
Pierre Kraemer's avatar
Pierre Kraemer committed
507
508
509
510

		return false;
	}

511
512
513
514
	*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");
515

Pierre Kraemer's avatar
Pierre Kraemer committed
516
517
518
	return true;
}

Sylvain Thery's avatar
Sylvain Thery committed
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538


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;
}







539
540
541
542
543
544
bool GLSLShader::link()
{
	int		status;
	char	*info_log;

	/*** link program object ***/
545
	glLinkProgram( *m_program_object );
546

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

555
556
		glDetachShader( *m_program_object, *m_vertex_shader_object );
		glDetachShader( *m_program_object, *m_fragment_shader_object );
557
		if (*m_geom_shader_object)
558
559
			glDetachShader( *m_program_object, *m_geom_shader_object );
		glDeleteShader( *m_program_object );
560
		*m_program_object = 0;
561
562
563
564
565
566
567

		return false;
	}

	return true;
}

568
bool GLSLShader::bind() const
Pierre Kraemer's avatar
Pierre Kraemer committed
569
{
570
	if( *m_program_object )
Pierre Kraemer's avatar
Pierre Kraemer committed
571
	{
572
		glUseProgram( *m_program_object );
Pierre Kraemer's avatar
Pierre Kraemer committed
573
574
		return true;
	}
575
576
	else
		return false;
Pierre Kraemer's avatar
Pierre Kraemer committed
577
578
}

579
void GLSLShader::unbind() const
Pierre Kraemer's avatar
Pierre Kraemer committed
580
{
581
	if( *m_program_object )
Pierre Kraemer's avatar
Pierre Kraemer committed
582
	{
583
		glUseProgram( 0 );
Pierre Kraemer's avatar
Pierre Kraemer committed
584
585
586
587
588
	}
}

bool GLSLShader::isBinded()
{
589
590
591
592
593
594
	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
595
596
597
598
}

GLSLShader::~GLSLShader()
{
599
	if( *m_program_object )
Pierre Kraemer's avatar
Pierre Kraemer committed
600
601
602
	{
		unbind();

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

619
		glDeleteShader( *m_program_object );
Pierre Kraemer's avatar
Pierre Kraemer committed
620
	}
621

622
623
624
625
626
627
628
	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
629
//	m_registeredShaders.erase(this);
Pierre Kraemer's avatar
Pierre Kraemer committed
630
631
632
633
}

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

644
645
646
647
648
649
650
651
652
653
654
655
656
657
	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
658
	// LA MACRO SHADERPATH contient le chemin du repertoire qui contient les fichiers textes
Pierre Kraemer's avatar
Pierre Kraemer committed
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
	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()
{
675
#ifndef GLEW_MX
Pierre Kraemer's avatar
Pierre Kraemer committed
676
677
678
	GLenum error = glewInit();

	if (error != GLEW_OK)
679
		CGoGNerr << "Error: " << glewGetErrorString(error) << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
680
	else
681
		CGoGNout << "Status: Using GLEW " << glewGetString(GLEW_VERSION) << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
682
683

	if (!areVBOSupported())
684
		CGoGNout << "VBO not supported !" << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
685
686

	if(!areShadersSupported()) {
687
		CGoGNout << "Shaders not supported !" << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
688
689
		return false;
	}
690
691
692
#endif
	return true;

Pierre Kraemer's avatar
Pierre Kraemer committed
693
694
695
696
}

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

Pierre Kraemer's avatar
Pierre Kraemer committed
700
701
702
703
	std::string vss = findFile(vs);
	if(!loadVertexShader(vss)) return false;
	
	std::string pss = findFile(ps);
704
	if(!loadFragmentShader(pss)) return false;
Pierre Kraemer's avatar
Pierre Kraemer committed
705
706

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

Sylvain Thery's avatar
Sylvain Thery committed
714
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
715
{
Sylvain Thery's avatar
Sylvain Thery committed
716
717
718
719
	m_nameVS = vs;
	m_nameFS = ps;
	m_nameGS = gs;

Pierre Kraemer's avatar
Pierre Kraemer committed
720
721
722
723
	std::string vss = findFile(vs);
	if(!loadVertexShader(vss)) return false;

	std::string pss = findFile(ps);
724
	if(!loadFragmentShader(pss)) return false;
Pierre Kraemer's avatar
Pierre Kraemer committed
725
726
727
728
729
730

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

	if (!geomShaderLoaded)
	{
731
		CGoGNerr << "Error while loading geometry shader" << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
732
733
	}

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

740
	CGoGNout << "Shaders loaded (" << vs << "," << ps << "," << gs <<")" << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
741
742
743
	return true;
}

Sylvain Thery's avatar
Sylvain Thery committed
744
745
bool GLSLShader::loadShadersFromMemory(const char* vs, const char* fs)
{
746
747
	if (m_vertex_shader_source)
		delete [] m_vertex_shader_source;
748
	m_vertex_shader_source = NULL;
749
750
751

	unsigned int sz = strlen(vs);
	m_vertex_shader_source = new char[sz+1];
Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
752
	strcpy(m_vertex_shader_source, vs);
753
754
755
756
757
758

	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
759
	strcpy(m_fragment_shader_source, fs);
760

761
762
	if(!loadVertexShaderSourceString(vs))
		return false;
Sylvain Thery's avatar
Sylvain Thery committed
763

764
765
	if(!loadFragmentShaderSourceString(fs))
		return false;
Sylvain Thery's avatar
Sylvain Thery committed
766
767
768

	if(!create())
	{
769
		CGoGNout << "Unable to create the shaders !" << CGoGNendl;
Sylvain Thery's avatar
Sylvain Thery committed
770
771
772
773
774
		return false;
	}
	return true;
}

Sylvain Thery's avatar
Sylvain Thery committed
775
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
776
{
777
778
	if (m_vertex_shader_source)
		delete [] m_vertex_shader_source;
779
	m_vertex_shader_source = NULL;
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798

	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
799
800
	if(!loadVertexShaderSourceString(vs))
		return false;
Sylvain Thery's avatar
Sylvain Thery committed
801

Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
802
803
	if(!loadFragmentShaderSourceString(fs))
		return false;
Sylvain Thery's avatar
Sylvain Thery committed
804

Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
805
806
	if(!loadGeometryShaderSourceString(gs))
		return false;
Sylvain Thery's avatar
Sylvain Thery committed
807

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

	return true;
}

817
818
819
820
bool GLSLShader::reloadVertexShaderFromMemory(const char* vs)
{
	if (m_vertex_shader_source)
		delete [] m_vertex_shader_source;
821
	m_vertex_shader_source = NULL;
822
823
824

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

826
827
828
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
	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))
	{
866
		CGoGNerr << "Unable to create the shaders !" << CGoGNendl;
867
868
869
		return false;
	}

870
871
872
	*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
873
	*m_uniMat_Normal	= glGetUniformLocation(*m_program_object,"NormalMatrix");
874
875
876

	restoreUniformsAttribs();

877
878
	updateClippingUniforms();

879
880
881
	return true;
}

882
883
bool GLSLShader::validateProgram()
{
884
	if(!*m_program_object)
885
886
		return false;

887
	glValidateProgram(*m_program_object);
888
	GLint Result = GL_FALSE;
889
	glGetProgramiv(*m_program_object, GL_VALIDATE_STATUS, &Result);
890
891
892

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

	return true;
}

bool GLSLShader::checkProgram()
{
	GLint Result = GL_FALSE;
908
	glGetProgramiv(*m_program_object, GL_LINK_STATUS, &Result);
909
910

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

	return Result == GL_TRUE;
}

bool GLSLShader::checkShader(int shaderType)
{
	GLint Result = GL_FALSE;
	int InfoLogLength;
923
	GLuint id;
924
925
926
927

	switch(shaderType)
	{
	case VERTEX_SHADER:
928
		id = *m_vertex_shader_object;
929
930
		break;
	case FRAGMENT_SHADER:
931
		id = *m_fragment_shader_object;
932
933
		break;
	case GEOMETRY_SHADER:
934
		id = *m_geom_shader_object;
935
936
		break;
	default:
937
		CGoGNerr << "Error unkown shader type" << CGoGNendl;
938
939
940
941
942
943
944
945
		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]);
946
	CGoGNout << &Buffer[0] << CGoGNendl;
947
948
949
950

	return Result == GL_TRUE;
}

Sylvain Thery's avatar
Sylvain Thery committed
951
void GLSLShader::bindAttrib(unsigned int att, const char* name) const
952
{
953
	glBindAttribLocation(*m_program_object, att, name);
954
955
}

956
957
958
959
960
void GLSLShader::addPathFileSeach(const std::string& path)
{
	m_pathes.push_back(path);
}

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

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

void GLSLShader::setCurrentOGLVersion(unsigned int version)
{
Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
1018
	CURRENT_OGL_VERSION = version;
Sylvain Thery's avatar
Sylvain Thery committed
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
	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();
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053

	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]);
	}
1054
1055

	this->unbind();
Sylvain Thery's avatar
Sylvain Thery committed
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
}

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]);
1070

Sylvain Thery's avatar
Sylvain Thery committed
1071
1072
	if (*m_uniMat_Normal >= 0)
		glUniformMatrix4fv(*m_uniMat_Normal, 	1 , false, &normalMatrix[0][0]);
1073
1074

	this->unbind();
1075
1076
}

Sylvain Thery's avatar
Sylvain Thery committed
1077
1078
1079



1080
void GLSLShader::enableVertexAttribs(unsigned int stride, unsigned int begin) const
1081
1082
{
	this->bind();
1083
	for (std::vector<Utils::GLSLShader::VAStr>::const_iterator it = m_va_vbo_binding.begin(); it != m_va_vbo_binding.end(); ++it)
1084
1085
1086
	{
		glBindBuffer(GL_ARRAY_BUFFER, it->vbo_ptr->id());
		glEnableVertexAttribArray(it->va_id);
1087
		glVertexAttribPointer(it->va_id, it->vbo_ptr->dataSize(), GL_FLOAT, false, stride, (const GLvoid*)((unsigned long)(begin)));
1088
	}
1089
//	this->unbind();
1090
}
Sylvain Thery's avatar
Sylvain Thery committed
1091

1092
1093
void GLSLShader::disableVertexAttribs() const
{
1094
//	this->bind();
1095
	for (std::vector<Utils::GLSLShader::VAStr>::const_iterator it = m_va_vbo_binding.begin(); it != m_va_vbo_binding.end(); ++it)
1096
1097
1098
1099
		glDisableVertexAttribArray(it->va_id);
	this->unbind();
}

Sylvain Thery's avatar
Sylvain Thery committed
1100

1101
1102
1103
1104
1105
void GLSLShader::updateCurrentMatrices()
{
	glm::mat4 model(currentModelView());
	model *= currentTransfo();

Sylvain Thery's avatar
Sylvain Thery committed
1106
1107
1108
	currentPMV() = currentProjection() * model;
	currentNormalMatrix() = glm::gtx::inverse_transpose::inverseTranspose(model);

1109
	for(std::set< std::pair<void*, GLSLShader*> >::iterator it = m_registeredShaders.begin(); it != m_registeredShaders.end(); ++it)
Sylvain Thery's avatar
Sylvain Thery committed
1110
		it->second->updateMatrices(currentProjection(), model, currentPMV(), currentNormalMatrix());
Sylvain Thery's avatar
Sylvain Thery committed
1111
}
Pierre Kraemer's avatar
Pierre Kraemer committed
1112

1113
1114
1115
1116
1117
1118
1119
void GLSLShader::updateAllFromGLMatrices()
{
	GLdouble modelview[16];
	GLdouble projection[16];
	glGetDoublev( GL_MODELVIEW_MATRIX, modelview );
	glGetDoublev( GL_PROJECTION_MATRIX, projection );

1120
1121
	glm::mat4& model = currentModelView();
	glm::mat4& proj = currentProjection();