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
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
302
		glDeleteObjectARB(*m_vertex_shader_object );
		*m_vertex_shader_object = 0;
Pierre Kraemer's avatar
Pierre Kraemer committed
303
304
305
306

		return false;
	}

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

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

312
	glGetObjectParameterivARB( *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
321
		glDeleteObjectARB( *m_vertex_shader_object );
		*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
356
		glDeleteObjectARB( *m_fragment_shader_object );
		*m_fragment_shader_object = 0;
Pierre Kraemer's avatar
Pierre Kraemer committed
357
358
359
360

		return false;
	}

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

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

366
	glGetObjectParameterivARB( *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
375
		glDeleteObjectARB( *m_fragment_shader_object );
		*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
409
		glDeleteObjectARB( *m_geom_shader_object );
		*m_geom_shader_object = 0;
Pierre Kraemer's avatar
Pierre Kraemer committed
410
411
412
413

		return false;
	}

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

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

419
	glGetObjectParameterivARB( *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
428
		glDeleteObjectARB( *m_geom_shader_object );
		*m_geom_shader_object = 0;
Pierre Kraemer's avatar
Pierre Kraemer committed
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450

		return false;
	}

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

char* GLSLShader::getInfoLog( GLhandleARB obj )
{
	char	*info_log;
	int		info_log_length;
	int		length;

	glGetObjectParameterivARB( obj, GL_OBJECT_INFO_LOG_LENGTH_ARB, &info_log_length );

	info_log = new char [info_log_length];
	glGetInfoLogARB( obj, info_log_length, &length, info_log );

	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 = glCreateProgramObjectARB();
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
481
	glAttachObjectARB( *m_program_object, *m_vertex_shader_object );
	glAttachObjectARB( *m_program_object, *m_fragment_shader_object );
	if (*m_geom_shader_object)
Pierre Kraemer's avatar
Pierre Kraemer committed
482
	{
483
		glAttachObjectARB( *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
	glLinkProgramARB( *m_program_object );
Pierre Kraemer's avatar
Pierre Kraemer committed
492

493
	glGetObjectParameterivARB( *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
503
504
505
506
		glDetachObjectARB( *m_program_object, *m_vertex_shader_object );
		glDetachObjectARB( *m_program_object, *m_fragment_shader_object );
		if (*m_geom_shader_object)
			glDetachObjectARB( *m_program_object, *m_geom_shader_object );
		glDeleteObjectARB( *m_program_object );
		*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
	glLinkProgramARB( *m_program_object );
546

547
	glGetObjectParameterivARB( *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
557
558
559
560
		glDetachObjectARB( *m_program_object, *m_vertex_shader_object );
		glDetachObjectARB( *m_program_object, *m_fragment_shader_object );
		if (*m_geom_shader_object)
			glDetachObjectARB( *m_program_object, *m_geom_shader_object );
		glDeleteObjectARB( *m_program_object );
		*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
		glUseProgramObjectARB( *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
584
585
586
587
588
	{
		glUseProgramObjectARB( 0 );
	}
}

bool GLSLShader::isBinded()
{
589
	return ( *m_program_object && *m_program_object == glGetHandleARB(GL_PROGRAM_OBJECT_ARB) );
Pierre Kraemer's avatar
Pierre Kraemer committed
590
591
592
593
}

GLSLShader::~GLSLShader()
{
594
	if( *m_program_object )
Pierre Kraemer's avatar
Pierre Kraemer committed
595
596
597
	{
		unbind();

598
		if( *m_vertex_shader_object )
Pierre Kraemer's avatar
Pierre Kraemer committed
599
		{
600
601
			glDetachObjectARB( *m_program_object, *m_vertex_shader_object );
			glDeleteObjectARB( *m_vertex_shader_object );
Pierre Kraemer's avatar
Pierre Kraemer committed
602
		}
603
		if( *m_fragment_shader_object )
Pierre Kraemer's avatar
Pierre Kraemer committed
604
		{
605
606
			glDetachObjectARB( *m_program_object, *m_fragment_shader_object );
			glDeleteObjectARB( *m_fragment_shader_object );
Pierre Kraemer's avatar
Pierre Kraemer committed
607
		}
608
		if (*m_geom_shader_object)
Pierre Kraemer's avatar
Pierre Kraemer committed
609
		{
610
611
			glDetachObjectARB( *m_program_object, *m_geom_shader_object );
			glDeleteObjectARB( *m_geom_shader_object );
Pierre Kraemer's avatar
Pierre Kraemer committed
612
613
		}

614
		glDeleteObjectARB( *m_program_object );
Pierre Kraemer's avatar
Pierre Kraemer committed
615
	}
616

617
618
619
620
621
622
623
	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
624
//	m_registeredShaders.erase(this);
Pierre Kraemer's avatar
Pierre Kraemer committed
625
626
627
628
}

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

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

	if (error != GLEW_OK)
674
		CGoGNerr << "Error: " << glewGetErrorString(error) << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
675
	else
676
		CGoGNout << "Status: Using GLEW " << glewGetString(GLEW_VERSION) << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
677
678

	if (!areVBOSupported())
679
		CGoGNout << "VBO not supported !" << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
680
681

	if(!areShadersSupported()) {
682
		CGoGNout << "Shaders not supported !" << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
683
684
		return false;
	}
685
686
687
#endif
	return true;

Pierre Kraemer's avatar
Pierre Kraemer committed
688
689
690
691
}

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

Pierre Kraemer's avatar
Pierre Kraemer committed
695
696
697
698
	std::string vss = findFile(vs);
	if(!loadVertexShader(vss)) return false;
	
	std::string pss = findFile(ps);
699
	if(!loadFragmentShader(pss)) return false;
Pierre Kraemer's avatar
Pierre Kraemer committed
700
701

	if(!create()) {
702
		CGoGNout << "Unable to create the shaders !" << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
703
704
		return false;
	}
705
	CGoGNout << "Shaders loaded (" << vs << "," << ps << ")" << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
706
707
708
	return true; 
}

Sylvain Thery's avatar
Sylvain Thery committed
709
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
710
{
Sylvain Thery's avatar
Sylvain Thery committed
711
712
713
714
	m_nameVS = vs;
	m_nameFS = ps;
	m_nameGS = gs;

Pierre Kraemer's avatar
Pierre Kraemer committed
715
716
717
718
	std::string vss = findFile(vs);
	if(!loadVertexShader(vss)) return false;

	std::string pss = findFile(ps);
719
	if(!loadFragmentShader(pss)) return false;
Pierre Kraemer's avatar
Pierre Kraemer committed
720
721
722
723
724
725

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

	if (!geomShaderLoaded)
	{
726
		CGoGNerr << "Error while loading geometry shader" << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
727
728
	}

Sylvain Thery's avatar
Sylvain Thery committed
729
	if(!create(inputGeometryPrimitive,outputGeometryPrimitive,nb_max_vertices))
Pierre Kraemer's avatar
Pierre Kraemer committed
730
	{
731
		CGoGNout << "Unable to create the shaders !" << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
732
733
734
		return false;
	}

735
	CGoGNout << "Shaders loaded (" << vs << "," << ps << "," << gs <<")" << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
736
737
738
	return true;
}

Sylvain Thery's avatar
Sylvain Thery committed
739
740
bool GLSLShader::loadShadersFromMemory(const char* vs, const char* fs)
{
741
742
	if (m_vertex_shader_source)
		delete [] m_vertex_shader_source;
743
	m_vertex_shader_source = NULL;
744
745
746

	unsigned int sz = strlen(vs);
	m_vertex_shader_source = new char[sz+1];
Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
747
	strcpy(m_vertex_shader_source, vs);
748
749
750
751
752
753

	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
754
	strcpy(m_fragment_shader_source, fs);
755

756
757
	if(!loadVertexShaderSourceString(vs))
		return false;
Sylvain Thery's avatar
Sylvain Thery committed
758

759
760
	if(!loadFragmentShaderSourceString(fs))
		return false;
Sylvain Thery's avatar
Sylvain Thery committed
761
762
763

	if(!create())
	{
764
		CGoGNout << "Unable to create the shaders !" << CGoGNendl;
Sylvain Thery's avatar
Sylvain Thery committed
765
766
767
768
769
		return false;
	}
	return true;
}

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

	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
794
795
	if(!loadVertexShaderSourceString(vs))
		return false;
Sylvain Thery's avatar
Sylvain Thery committed
796

Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
797
798
	if(!loadFragmentShaderSourceString(fs))
		return false;
Sylvain Thery's avatar
Sylvain Thery committed
799

Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
800
801
	if(!loadGeometryShaderSourceString(gs))
		return false;
Sylvain Thery's avatar
Sylvain Thery committed
802

803
	if(!create(inputGeometryPrimitive, outputGeometryPrimitive, nb_max_vertices))
Sylvain Thery's avatar
Sylvain Thery committed
804
	{
805
		CGoGNout << "Unable to create the shaders !" << CGoGNendl;
Sylvain Thery's avatar
Sylvain Thery committed
806
807
808
809
810
811
		return false;
	}

	return true;
}

812
813
814
815
bool GLSLShader::reloadVertexShaderFromMemory(const char* vs)
{
	if (m_vertex_shader_source)
		delete [] m_vertex_shader_source;
816
	m_vertex_shader_source = NULL;
817
818
819

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

821
822
823
824
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
	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))
	{
861
		CGoGNerr << "Unable to create the shaders !" << CGoGNendl;
862
863
864
		return false;
	}

865
866
867
	*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
868
	*m_uniMat_Normal	= glGetUniformLocation(*m_program_object,"NormalMatrix");
869
870
871

	restoreUniformsAttribs();

872
873
	updateClippingUniforms();

874
875
876
	return true;
}

877
878
bool GLSLShader::validateProgram()
{
879
	if(!*m_program_object)
880
881
		return false;

882
	glValidateProgram(*m_program_object);
883
	GLint Result = GL_FALSE;
884
	glGetProgramiv(*m_program_object, GL_VALIDATE_STATUS, &Result);
885
886
887

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

	return true;
}

bool GLSLShader::checkProgram()
{
	GLint Result = GL_FALSE;
903
	glGetProgramiv(*m_program_object, GL_LINK_STATUS, &Result);
904
905

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

	return Result == GL_TRUE;
}

bool GLSLShader::checkShader(int shaderType)
{
	GLint Result = GL_FALSE;
	int InfoLogLength;
	GLhandleARB id;

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

	return Result == GL_TRUE;
}

Sylvain Thery's avatar
Sylvain Thery committed
946
void GLSLShader::bindAttrib(unsigned int att, const char* name) const
947
{
948
	glBindAttribLocation(*m_program_object, att, name);
949
950
}

951
952
953
954
955
void GLSLShader::addPathFileSeach(const std::string& path)
{
	m_pathes.push_back(path);
}

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

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

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

	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]);
	}
1049
1050

	this->unbind();
Sylvain Thery's avatar
Sylvain Thery committed
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
}

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

Sylvain Thery's avatar
Sylvain Thery committed
1066
1067
	if (*m_uniMat_Normal >= 0)
		glUniformMatrix4fv(*m_uniMat_Normal, 	1 , false, &normalMatrix[0][0]);
1068
1069

	this->unbind();
1070
1071
}

Sylvain Thery's avatar
Sylvain Thery committed
1072
1073
1074



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

1087
1088
void GLSLShader::disableVertexAttribs() const
{
1089
//	this->bind();
1090
	for (std::vector<Utils::GLSLShader::VAStr>::const_iterator it = m_va_vbo_binding.begin(); it != m_va_vbo_binding.end(); ++it)
1091
1092
1093
1094
		glDisableVertexAttribArray(it->va_id);
	this->unbind();
}

Sylvain Thery's avatar
Sylvain Thery committed
1095

1096
1097
1098
1099
1100
void GLSLShader::updateCurrentMatrices()
{
	glm::mat4 model(currentModelView());
	model *= currentTransfo();

Sylvain Thery's avatar
Sylvain Thery committed
1101
1102
1103
	currentPMV() = currentProjection() * model;
	currentNormalMatrix() = glm::gtx::inverse_transpose::inverseTranspose(model);

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

1108
1109
1110
1111
1112
1113
1114
void GLSLShader::updateAllFromGLMatrices()
{
	GLdouble modelview[16];
	GLdouble projection[16];
	glGetDoublev( GL_MODELVIEW_MATRIX, modelview );
	glGetDoublev( GL_PROJECTION_MATRIX, projection );

1115
1116
	glm::mat4& model = currentModelView();
	glm::mat4& proj = currentProjection();
1117
1118

	for (unsigned int i=0; i< 4; ++i)
Sylvain Thery's avatar
Sylvain Thery committed
1119
	{
1120
1121
1122
1123
1124
		for (unsigned int j=0; j<4; ++j)
		{
			proj[i][j] = float(projection[4*i+j]);
			model[i][j] = float(modelview[4*i+j]);
		}
Sylvain Thery's avatar
Sylvain Thery committed
1125
1126
1127
1128
1129
	}
	model *= currentTransfo();

	currentPMV() = proj * model;
	currentNormalMatrix() = glm::gtx::inverse_transpose::inverseTranspose(model);
1130
1131

	for(std::set< std::pair<void*, GLSLShader*> >::iterator it = m_registeredShaders.begin(); it != m_registeredShaders.end(); ++it)
Sylvain Thery's avatar
Sylvain Thery committed
1132
		it->second->updateMatrices(proj, model, currentPMV(), currentNormalMatrix());
1133
1134
1135
}


Pierre Kraemer's avatar
Pierre Kraemer committed
1136
} // namespace Utils
Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
1137

Pierre Kraemer's avatar
Pierre Kraemer committed
1138
} // namespace CGoGN