Création d'un compte pour un collaborateur extérieur au laboratoire depuis l'intranet ICube : https://intranet.icube.unistra.fr/fr/labs/member/profile

GLSLShader.cpp 28.9 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;
Pierre Kraemer's avatar
Pierre Kraemer committed
89
90
}

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

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

std::string GLSLShader::defines_Geom(const std::string& primitivesIn, const std::string& primitivesOut, int maxVert)
{
Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
103
	if (CURRENT_OGL_VERSION == 3)
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
	{
		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");
121
		str.append("#define NBVERTS_IN gl_in.length()\n");
122
123
124
125
		return str;
	}
	else
	{
Sylvain Thery's avatar
Sylvain Thery committed
126
127
128
		std::string str("#version 110\n");
		str.append("#extension GL_EXT_geometry_shader4 : enable\n");
		str.append("#define PRECISON float pipo_PRECISION\n");
129
130
131
132
		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");
133
		str.append("#define NBVERTS_IN gl_VerticesIn\n");
134
135
136
137
		return str;
	}
}

Pierre Kraemer's avatar
Pierre Kraemer committed
138
139
bool GLSLShader::areGeometryShadersSupported()
{
Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
140
141
	if (!glewGetExtension("GL_EXT_geometry_shader4"))
		return false;
Pierre Kraemer's avatar
Pierre Kraemer committed
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
	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
162
char* GLSLShader::loadSourceFile(const std::string& filename)
Pierre Kraemer's avatar
Pierre Kraemer committed
163
164
165
166
167
168
169
170
171
172
{
	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() )
	{
173
		CGoGNerr << "ERROR - GLSLShader::loadSourceFile() - unable to open the file " << filename << "." << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
		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 )
	{
194
		CGoGNerr << "ERROR - GLSLShader::loadSourceFile() - " << io_exception.what() << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
195
196
197
198
199
200
201
202
203
204
205
206
		file.close();
		return NULL;
	}

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

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

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

213
	m_vertex_shader_source = loadSourceFile( filename );
Pierre Kraemer's avatar
Pierre Kraemer committed
214

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


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

	return flag;
}

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

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

237
	m_fragment_shader_source = loadSourceFile( filename );
Pierre Kraemer's avatar
Pierre Kraemer committed
238

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

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


	return flag;
}

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

257
258
	if (m_geom_shader_source)
		delete [] m_geom_shader_source;
Pierre Kraemer's avatar
Pierre Kraemer committed
259

260
	m_geom_shader_source = loadSourceFile( filename );
Pierre Kraemer's avatar
Pierre Kraemer committed
261

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

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

	return flag;
}

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

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

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

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

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

299
300
		glDeleteObjectARB(*m_vertex_shader_object );
		*m_vertex_shader_object = 0;
Pierre Kraemer's avatar
Pierre Kraemer committed
301
302
303
304

		return false;
	}

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

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

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

318
319
		glDeleteObjectARB( *m_vertex_shader_object );
		*m_vertex_shader_object = 0;
Pierre Kraemer's avatar
Pierre Kraemer committed
320
321
322
323
324
325
326
327

		return false;
	}

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

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

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

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

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

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

353
354
		glDeleteObjectARB( *m_fragment_shader_object );
		*m_fragment_shader_object = 0;
Pierre Kraemer's avatar
Pierre Kraemer committed
355
356
357
358

		return false;
	}

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

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

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

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

		return false;
	}

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

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

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

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

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

406
407
		glDeleteObjectARB( *m_geom_shader_object );
		*m_geom_shader_object = 0;
Pierre Kraemer's avatar
Pierre Kraemer committed
408
409
410
411

		return false;
	}

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

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

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

425
426
		glDeleteObjectARB( *m_geom_shader_object );
		*m_geom_shader_object = 0;
Pierre Kraemer's avatar
Pierre Kraemer committed
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448

		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
449
bool GLSLShader::create(GLint inputGeometryPrimitive,GLint outputGeometryPrimitive, int nb_max_vertices)
Pierre Kraemer's avatar
Pierre Kraemer committed
450
451
452
453
{
	int		status;
	char	*info_log;

454
455
	m_geom_inputPrimitives = inputGeometryPrimitive;
	m_geom_outputPrimitives = outputGeometryPrimitive;
Pierre Kraemer's avatar
Pierre Kraemer committed
456
457

	/*** check if shaders are loaded ***/
458
	if( !*m_vertex_shader_object || !*m_fragment_shader_object )
Pierre Kraemer's avatar
Pierre Kraemer committed
459
	{
460
		CGoGNerr << "ERROR - GLSLShader::create() - shaders are not defined." << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
461
462
463
464
		return false;
	}

	/*** create program object ***/
465
	m_program_object = glCreateProgramObjectARB();
Pierre Kraemer's avatar
Pierre Kraemer committed
466

467
	if( !*m_program_object )
Pierre Kraemer's avatar
Pierre Kraemer committed
468
	{
469
		CGoGNerr << "ERROR - GLSLShader::create() - unable to create program object." << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
470
471
472
473
		return false;
	}

	/*** attach shaders to program object ***/
474
475
476
	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
477
	{
478
		glAttachObjectARB( *m_program_object, *m_geom_shader_object );
Pierre Kraemer's avatar
Pierre Kraemer committed
479

480
481
482
		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,nb_max_vertices);
Pierre Kraemer's avatar
Pierre Kraemer committed
483
484
485
	}

	/*** link program object ***/
486
	glLinkProgramARB( *m_program_object );
Pierre Kraemer's avatar
Pierre Kraemer committed
487

488
	glGetObjectParameterivARB( *m_program_object, GL_OBJECT_LINK_STATUS_ARB, &status );
Pierre Kraemer's avatar
Pierre Kraemer committed
489
490
	if( !status )
	{
491
		CGoGNerr << "ERROR - GLSLShader::create() - error occured while linking shader program." << CGoGNendl;
492
		info_log = getInfoLog( *m_program_object );
493
		CGoGNerr << "  LINK " << info_log << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
494
495
		delete [] info_log;

496
497
498
499
500
501
		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
502
503
504
505

		return false;
	}

506
507
508
509
	*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");
510

Pierre Kraemer's avatar
Pierre Kraemer committed
511
512
513
	return true;
}

514
515
516
517
518
519
bool GLSLShader::link()
{
	int		status;
	char	*info_log;

	/*** link program object ***/
520
	glLinkProgramARB( *m_program_object );
521

522
	glGetObjectParameterivARB( *m_program_object, GL_OBJECT_LINK_STATUS_ARB, &status );
523
524
	if( !status )
	{
525
		CGoGNerr << "ERROR - GLSLShader::create() - error occured while linking shader program." << CGoGNendl;
526
		info_log = getInfoLog( *m_program_object );
527
		CGoGNerr << "  LINK " << info_log << CGoGNendl;
528
529
		delete [] info_log;

530
531
532
533
534
535
		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;
536
537
538
539
540
541
542

		return false;
	}

	return true;
}

543
bool GLSLShader::bind() const
Pierre Kraemer's avatar
Pierre Kraemer committed
544
{
545
	if( *m_program_object )
Pierre Kraemer's avatar
Pierre Kraemer committed
546
	{
547
		glUseProgramObjectARB( *m_program_object );
Pierre Kraemer's avatar
Pierre Kraemer committed
548
549
		return true;
	}
550
551
	else
		return false;
Pierre Kraemer's avatar
Pierre Kraemer committed
552
553
}

554
void GLSLShader::unbind() const
Pierre Kraemer's avatar
Pierre Kraemer committed
555
{
556
	if( *m_program_object )
Pierre Kraemer's avatar
Pierre Kraemer committed
557
558
559
560
561
562
563
	{
		glUseProgramObjectARB( 0 );
	}
}

bool GLSLShader::isBinded()
{
564
	return ( *m_program_object && *m_program_object == glGetHandleARB(GL_PROGRAM_OBJECT_ARB) );
Pierre Kraemer's avatar
Pierre Kraemer committed
565
566
567
568
}

GLSLShader::~GLSLShader()
{
569
	if( *m_program_object )
Pierre Kraemer's avatar
Pierre Kraemer committed
570
571
572
	{
		unbind();

573
		if( *m_vertex_shader_object )
Pierre Kraemer's avatar
Pierre Kraemer committed
574
		{
575
576
			glDetachObjectARB( *m_program_object, *m_vertex_shader_object );
			glDeleteObjectARB( *m_vertex_shader_object );
Pierre Kraemer's avatar
Pierre Kraemer committed
577
		}
578
		if( *m_fragment_shader_object )
Pierre Kraemer's avatar
Pierre Kraemer committed
579
		{
580
581
			glDetachObjectARB( *m_program_object, *m_fragment_shader_object );
			glDeleteObjectARB( *m_fragment_shader_object );
Pierre Kraemer's avatar
Pierre Kraemer committed
582
		}
583
		if (*m_geom_shader_object)
Pierre Kraemer's avatar
Pierre Kraemer committed
584
		{
585
586
			glDetachObjectARB( *m_program_object, *m_geom_shader_object );
			glDeleteObjectARB( *m_geom_shader_object );
Pierre Kraemer's avatar
Pierre Kraemer committed
587
588
		}

589
		glDeleteObjectARB( *m_program_object );
Pierre Kraemer's avatar
Pierre Kraemer committed
590
	}
591

592
593
594
595
596
597
598
	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
599
//	m_registeredShaders.erase(this);
Pierre Kraemer's avatar
Pierre Kraemer committed
600
601
602
603
}

std::string GLSLShader::findFile(const std::string filename)
{
Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
604
	// cherche d'abord dans le repertoire courant
Pierre Kraemer's avatar
Pierre Kraemer committed
605
606
607
608
609
610
611
612
613
	std::ifstream file;
	file.open(filename.c_str(),std::ios::in );
	if (!file.fail())
	{
		file.close();
		return filename;
	}
	file.close();

614
615
616
617
618
619
620
621
622
623
624
625
626
627
	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
628
	// LA MACRO SHADERPATH contient le chemin du repertoire qui contient les fichiers textes
Pierre Kraemer's avatar
Pierre Kraemer committed
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
	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()
{
645
#ifndef GLEW_MX
Pierre Kraemer's avatar
Pierre Kraemer committed
646
647
648
	GLenum error = glewInit();

	if (error != GLEW_OK)
649
		CGoGNerr << "Error: " << glewGetErrorString(error) << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
650
	else
651
		CGoGNout << "Status: Using GLEW " << glewGetString(GLEW_VERSION) << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
652
653

	if (!areVBOSupported())
654
		CGoGNout << "VBO not supported !" << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
655
656

	if(!areShadersSupported()) {
657
		CGoGNout << "Shaders not supported !" << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
658
659
		return false;
	}
660
661
662
#endif
	return true;

Pierre Kraemer's avatar
Pierre Kraemer committed
663
664
665
666
}

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

Pierre Kraemer's avatar
Pierre Kraemer committed
670
671
672
673
	std::string vss = findFile(vs);
	if(!loadVertexShader(vss)) return false;
	
	std::string pss = findFile(ps);
674
	if(!loadFragmentShader(pss)) return false;
Pierre Kraemer's avatar
Pierre Kraemer committed
675
676

	if(!create()) {
677
		CGoGNout << "Unable to create the shaders !" << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
678
679
		return false;
	}
680
	CGoGNout << "Shaders loaded (" << vs << "," << ps << ")" << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
681
682
683
	return true; 
}

Sylvain Thery's avatar
Sylvain Thery committed
684
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
685
{
Sylvain Thery's avatar
Sylvain Thery committed
686
687
688
689
	m_nameVS = vs;
	m_nameFS = ps;
	m_nameGS = gs;

Pierre Kraemer's avatar
Pierre Kraemer committed
690
691
692
693
	std::string vss = findFile(vs);
	if(!loadVertexShader(vss)) return false;

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

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

	if (!geomShaderLoaded)
	{
701
		CGoGNerr << "Error while loading geometry shader" << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
702
703
	}

Sylvain Thery's avatar
Sylvain Thery committed
704
	if(!create(inputGeometryPrimitive,outputGeometryPrimitive,nb_max_vertices))
Pierre Kraemer's avatar
Pierre Kraemer committed
705
	{
706
		CGoGNout << "Unable to create the shaders !" << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
707
708
709
		return false;
	}

710
	CGoGNout << "Shaders loaded (" << vs << "," << ps << "," << gs <<")" << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
711
712
713
	return true;
}

Sylvain Thery's avatar
Sylvain Thery committed
714
715
bool GLSLShader::loadShadersFromMemory(const char* vs, const char* fs)
{
716
717
	if (m_vertex_shader_source)
		delete [] m_vertex_shader_source;
718
	m_vertex_shader_source = NULL;
719
720
721

	unsigned int sz = strlen(vs);
	m_vertex_shader_source = new char[sz+1];
Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
722
	strcpy(m_vertex_shader_source, vs);
723
724
725
726
727
728

	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
729
	strcpy(m_fragment_shader_source, fs);
730

Sylvain Thery's avatar
Sylvain Thery committed
731
732
733
734
735
736
	if(!loadVertexShaderSourceString(vs)) return false;

	if(!loadFragmentShaderSourceString(fs)) return false;

	if(!create())
	{
737
		CGoGNout << "Unable to create the shaders !" << CGoGNendl;
Sylvain Thery's avatar
Sylvain Thery committed
738
739
740
741
742
		return false;
	}
	return true;
}

Sylvain Thery's avatar
Sylvain Thery committed
743
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
744
{
745
746
	if (m_vertex_shader_source)
		delete [] m_vertex_shader_source;
747
	m_vertex_shader_source = NULL;
748
749
750

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

752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
	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
768
769
	if(!loadVertexShaderSourceString(vs))
		return false;
Sylvain Thery's avatar
Sylvain Thery committed
770

Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
771
772
	if(!loadFragmentShaderSourceString(fs))
		return false;
Sylvain Thery's avatar
Sylvain Thery committed
773

Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
774
775
	if(!loadGeometryShaderSourceString(gs))
		return false;
Sylvain Thery's avatar
Sylvain Thery committed
776

Sylvain Thery's avatar
Sylvain Thery committed
777
	if(!create(inputGeometryPrimitive,outputGeometryPrimitive,nb_max_vertices))
Sylvain Thery's avatar
Sylvain Thery committed
778
	{
779
		CGoGNout << "Unable to create the shaders !" << CGoGNendl;
Sylvain Thery's avatar
Sylvain Thery committed
780
781
782
783
784
785
		return false;
	}

	return true;
}

786
787
788
789
bool GLSLShader::reloadVertexShaderFromMemory(const char* vs)
{
	if (m_vertex_shader_source)
		delete [] m_vertex_shader_source;
790
	m_vertex_shader_source = NULL;
791
792
793

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

795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
	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))
	{
835
		CGoGNerr << "Unable to create the shaders !" << CGoGNendl;
836
837
838
		return false;
	}

839
840
841
842
	*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");
843
844
845

	restoreUniformsAttribs();

846
847
	updateClippingUniforms();

848
849
850
	return true;
}

851
852
bool GLSLShader::validateProgram()
{
853
	if(!*m_program_object)
854
855
		return false;

856
	glValidateProgram(*m_program_object);
857
	GLint Result = GL_FALSE;
858
	glGetProgramiv(*m_program_object, GL_VALIDATE_STATUS, &Result);
859
860
861

	if(Result == GL_FALSE)
	{
862
		CGoGNout << "Validate program:" << CGoGNendl;
863
		int InfoLogLength;
864
		glGetProgramiv(*m_program_object, GL_INFO_LOG_LENGTH, &InfoLogLength);
865
		std::vector<char> Buffer(InfoLogLength);
866
		glGetProgramInfoLog(*m_program_object, InfoLogLength, NULL, &Buffer[0]);
867
		CGoGNout <<  &(Buffer[0]) << CGoGNendl;
868
869
870
871
872
873
874
875
876
		return false;
	}

	return true;
}

bool GLSLShader::checkProgram()
{
	GLint Result = GL_FALSE;
877
	glGetProgramiv(*m_program_object, GL_LINK_STATUS, &Result);
878
879

	int InfoLogLength;
880
	glGetProgramiv(*m_program_object, GL_INFO_LOG_LENGTH, &InfoLogLength);
881
	std::vector<char> Buffer(std::max(InfoLogLength, int(1)));
882
	glGetProgramInfoLog(*m_program_object, InfoLogLength, NULL, &Buffer[0]);
883
	CGoGNout << &Buffer[0] << CGoGNendl;
884
885
886
887
888
889
890
891
892
893
894
895
896

	return Result == GL_TRUE;
}

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

	switch(shaderType)
	{
	case VERTEX_SHADER:
897
		id = *m_vertex_shader_object;
898
899
		break;
	case FRAGMENT_SHADER:
900
		id = *m_fragment_shader_object;
901
902
		break;
	case GEOMETRY_SHADER:
903
		id = *m_geom_shader_object;
904
905
		break;
	default:
906
		CGoGNerr << "Error unkown shader type" << CGoGNendl;
907
908
909
910
911
912
913
914
		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]);
915
	CGoGNout << &Buffer[0] << CGoGNendl;
916
917
918
919

	return Result == GL_TRUE;
}

Sylvain Thery's avatar
Sylvain Thery committed
920
void GLSLShader::bindAttrib(unsigned int att, const char* name) const
921
{
922
	glBindAttribLocation(*m_program_object, att, name);
923
924
}

925
926
927
928
929
void GLSLShader::addPathFileSeach(const std::string& path)
{
	m_pathes.push_back(path);
}

930
unsigned int GLSLShader::bindVA_VBO(const std::string& name, VBO* vbo)
Sylvain Thery's avatar
Sylvain Thery committed
931
{
932
	GLint idVA = glGetAttribLocation(*(this->m_program_object), name.c_str());
Sylvain Thery's avatar
Sylvain Thery committed
933
934
935
	//valid ?
	if (idVA < 0)
	{
Pierre Kraemer's avatar
Pierre Kraemer committed
936
		CGoGNerr << "GLSLShader: Attribute " << name << " does not exist in shader" << CGoGNendl;
937
		return idVA;
Sylvain Thery's avatar
Sylvain Thery committed
938
939
940
941
942
943
	}
	// 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)
		{
944
945
			it->vbo_ptr = vbo;
			return (it - m_va_vbo_binding.begin());
Sylvain Thery's avatar
Sylvain Thery committed
946
947
948
949
950
		}
	}
	// new one:
	VAStr temp;
	temp.va_id = idVA;
951
	temp.vbo_ptr = vbo;
Sylvain Thery's avatar
Sylvain Thery committed
952
	m_va_vbo_binding.push_back(temp);
953
954
955
956
957
958
	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
959
960
961
962
}

void GLSLShader::unbindVA(const std::string& name)
{
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)
	{
967
		CGoGNerr << "GLSLShader: Attribute " << name << " does not exist in shader, not unbinded" << CGoGNendl;
Sylvain Thery's avatar
Sylvain Thery committed
968
969
970
971
		return;
	}
	// search if name already exist
	unsigned int nb = m_va_vbo_binding.size();
972
	for (unsigned int i = 0; i < nb; ++i)
Sylvain Thery's avatar
Sylvain Thery committed
973
974
975
976
977
978
979
980
981
	{
		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;
		}
	}
982
	CGoGNerr << "GLSLShader: Attribute "<<name<< " not binded"<< CGoGNendl;
Sylvain Thery's avatar
Sylvain Thery committed
983
984
985
986
}

void GLSLShader::setCurrentOGLVersion(unsigned int version)
{
Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
987
	CURRENT_OGL_VERSION = version;
Sylvain Thery's avatar
Sylvain Thery committed
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
	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();
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022

	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]);
	}
Sylvain Thery's avatar
Sylvain Thery committed
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
}

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

Sylvain Thery's avatar
Sylvain Thery committed
1040
1041
1042
1043
	if (*m_uniMat_Normal >= 0)
	{
		glUniformMatrix4fv(*m_uniMat_Normal, 	1 , false, &normalMatrix[0][0]);
	}
1044
1045
}

Sylvain Thery's avatar
Sylvain Thery committed
1046
1047
1048



1049
void GLSLShader::enableVertexAttribs(unsigned int stride, unsigned int begin) const
1050
1051
{
	this->bind();
1052
	for (std::vector<Utils::GLSLShader::VAStr>::const_iterator it = m_va_vbo_binding.begin(); it != m_va_vbo_binding.end(); ++it)
1053
1054
1055
	{
		glBindBuffer(GL_ARRAY_BUFFER, it->vbo_ptr->id());
		glEnableVertexAttribArray(it->va_id);
1056
		glVertexAttribPointer(it->va_id, it->vbo_ptr->dataSize(), GL_FLOAT, false, stride, (const GLvoid*)begin);
1057
1058
	}
}
Sylvain Thery's avatar
Sylvain Thery committed
1059

1060
1061
void GLSLShader::disableVertexAttribs() const
{
1062
	this->bind();
1063
	for (std::vector<Utils::GLSLShader::VAStr>::const_iterator it = m_va_vbo_binding.begin(); it != m_va_vbo_binding.end(); ++it)
1064
1065
1066
1067
		glDisableVertexAttribArray(it->va_id);
	this->unbind();
}

Sylvain Thery's avatar
Sylvain Thery committed
1068

1069
1070
1071
1072
1073
void GLSLShader::updateCurrentMatrices()
{
	glm::mat4 model(currentModelView());
	model *= currentTransfo();

Sylvain Thery's avatar
Sylvain Thery committed
1074
1075
1076
	currentPMV() = currentProjection() * model;
	currentNormalMatrix() = glm::gtx::inverse_transpose::inverseTranspose(model);

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

1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
void GLSLShader::updateAllFromGLMatrices()
{
	GLdouble modelview[16];
	GLdouble projection[16];
	glGetDoublev( GL_MODELVIEW_MATRIX, modelview );
	glGetDoublev( GL_PROJECTION_MATRIX, projection );

	glm::mat4 model;
	glm::mat4 proj;

	for (unsigned int i=0; i< 4; ++i)
Sylvain Thery's avatar
Sylvain Thery committed
1092
	{
1093
1094
1095
1096
1097
		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
1098
1099
1100
1101
1102
	}
	model *= currentTransfo();

	currentPMV() = proj * model;
	currentNormalMatrix() = glm::gtx::inverse_transpose::inverseTranspose(model);
1103
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(proj, model, currentPMV(), currentNormalMatrix());
1106
1107
1108
}


Pierre Kraemer's avatar
Pierre Kraemer committed
1109
} // namespace Utils
Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
1110

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