GLSLShader.cpp 32 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

Sylvain Thery's avatar
Sylvain Thery committed
25
#define CGoGN_UTILS_DLL_EXPORT 1
Pierre Kraemer's avatar
Pierre Kraemer committed
26
27
28
29

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

Sylvain Thery's avatar
Sylvain Thery committed
34
#include "glm/gtc/matrix_inverse.hpp"
Sylvain Thery's avatar
Sylvain Thery committed
35

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

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

42
#ifdef CGOGN_USE_OGL_CORE_PROFILE
43
unsigned int GLSLShader::CURRENT_OGL_VERSION = 3;
Sylvain Thery's avatar
Sylvain Thery committed
44
45
unsigned int GLSLShader::MAJOR_OGL_CORE = 3;
unsigned int GLSLShader::MINOR_OGL_CORE = 3;
46
#else
Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
47
unsigned int GLSLShader::CURRENT_OGL_VERSION = 2;
Sylvain Thery's avatar
Sylvain Thery committed
48
49
unsigned int GLSLShader::MAJOR_OGL_CORE = 2;
unsigned int GLSLShader::MINOR_OGL_CORE = 1;
50
51
52
#endif


Sylvain Thery's avatar
Sylvain Thery committed
53
54
55

std::string GLSLShader::DEFINES_GL2=\
"#version 110\n"
56
"#define PRECISION float pipo_PRECISION\n"
Sylvain Thery's avatar
Sylvain Thery committed
57
58
59
"#define ATTRIBUTE attribute\n"
"#define VARYING_VERT varying\n"
"#define VARYING_FRAG varying\n"
60
"#define FRAG_OUT_DEF float pipo_FRAGDEF\n"
61
"#define FRAG_OUT gl_FragColor\n"
Sylvain Thery's avatar
Sylvain Thery committed
62
63
64
"#define INVARIANT_POS float pipo_INVARIANT\n"
"#define TEXTURE2D texture2D\n"
;
Sylvain Thery's avatar
Sylvain Thery committed
65

Pierre Kraemer's avatar
Pierre Kraemer committed
66

Sylvain Thery's avatar
Sylvain Thery committed
67
std::string GLSLShader::DEFINES_GL3=\
68
"#version 150\n"
69
"#define PRECISION precision highp float\n"
Sylvain Thery's avatar
Sylvain Thery committed
70
"#define ATTRIBUTE in\n"
sylvain thery's avatar
sylvain thery committed
71
72
"#define VARYING_VERT out\n"
"#define VARYING_FRAG in\n"
73
74
"#define FRAG_OUT_DEF out vec4 outFragColor\n"
"#define FRAG_OUT outFragColor\n"
Sylvain Thery's avatar
Sylvain Thery committed
75
76
"#define INVARIANT_POS invariant gl_Position\n"
"#define TEXTURE2D texture\n";
Sylvain Thery's avatar
Sylvain Thery committed
77

Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
78
79

std::string* GLSLShader::DEFINES_GL = NULL;
80
81
82

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

83
std::set< std::pair<void*, GLSLShader*> >* GLSLShader::m_registeredShaders = NULL;
Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
84

85
86
87
//glm::mat4* GLSLShader::s_current_matrices=NULL;
Utils::GL_Matrices* GLSLShader::s_current_matrices=NULL;

Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
88
GLSLShader::GLSLShader() :
89
	m_vao(0),
Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
90
91
92
	m_vertex_shader_source(NULL),
	m_fragment_shader_source(NULL),
	m_geom_shader_source(NULL)
Pierre Kraemer's avatar
Pierre Kraemer committed
93
{
94
95
96
97
98
99
100
101
102
	*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
103
	if (DEFINES_GL == NULL)
Sylvain Thery's avatar
Sylvain Thery committed
104
		setCurrentOGLVersion(MAJOR_OGL_CORE,MINOR_OGL_CORE);
Sylvain Thery's avatar
Sylvain Thery committed
105
106

	m_nbMaxVertices = 16;
107
108
109

	if (m_registeredShaders==NULL)
		m_registeredShaders = new std::set< std::pair<void*, GLSLShader*> >;
Pierre Kraemer's avatar
Pierre Kraemer committed
110
111
}

Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
112
void GLSLShader::registerShader(void* ptr, GLSLShader* shader)
113
{
114
	m_registeredShaders->insert(std::pair<void*,GLSLShader*>(ptr, shader));
115
116
}

Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
117
void GLSLShader::unregisterShader(void* ptr, GLSLShader* shader)
118
{
119
	m_registeredShaders->erase(std::pair<void*,GLSLShader*>(ptr, shader));
120
121
122
123
}

std::string GLSLShader::defines_Geom(const std::string& primitivesIn, const std::string& primitivesOut, int maxVert)
{
124
	if (CURRENT_OGL_VERSION >= 3)
125
126
127
128
129
130
131
132
133
134
135
136
137
138
	{
		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");
sylvain thery's avatar
sylvain thery committed
139
140
		str.append("#define VARYING_IN in\n");
		str.append("#define VARYING_OUT out\n");
141
		str.append("#define POSITION_IN(X) gl_in[X].gl_Position\n");
142
		str.append("#define NBVERTS_IN gl_in.length()\n");
143
144
145
146
		return str;
	}
	else
	{
Sylvain Thery's avatar
Sylvain Thery committed
147
148
		std::string str("#version 110\n");
		str.append("#extension GL_EXT_geometry_shader4 : enable\n");
kvanhoey's avatar
kvanhoey committed
149
		str.append("#define PRECISION float pipo_PRECISION\n");
150
151
152
153
		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");
154
		str.append("#define NBVERTS_IN gl_VerticesIn\n");
155
156
157
158
		return str;
	}
}

Pierre Kraemer's avatar
Pierre Kraemer committed
159
160
bool GLSLShader::areGeometryShadersSupported()
{
161
	if (!glewGetExtension("GL_ARB_geometry_shader4"))
Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
162
		return false;
Pierre Kraemer's avatar
Pierre Kraemer committed
163
164
165
166
167
168
	return true;
}


bool GLSLShader::areVBOSupported()
{
169
	if (!glewGetExtension("GL_vertex_buffer_object"))
Pierre Kraemer's avatar
Pierre Kraemer committed
170
171
172
173
		return false;
	return true;
}

Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
174
char* GLSLShader::loadSourceFile(const std::string& filename)
Pierre Kraemer's avatar
Pierre Kraemer committed
175
176
177
178
179
180
181
182
183
184
{
	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() )
	{
185
		CGoGNerr << "ERROR - GLSLShader::loadSourceFile() - unable to open the file " << filename << "." << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
186
187
188
189
190
191
192
193
		return NULL;
	}

	/*** reading file ***/
	try
	{
		/* get file size */
		file.seekg( 0, std::ios::end );
194
		file_size = int(file.tellg());
Pierre Kraemer's avatar
Pierre Kraemer committed
195
196
197
198
199
200
201
202
203
204
205
		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 )
	{
206
		CGoGNerr << "ERROR - GLSLShader::loadSourceFile() - " << io_exception.what() << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
207
208
209
210
211
212
213
214
215
216
217
218
		file.close();
		return NULL;
	}

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

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

221
222
	if (m_vertex_shader_source)
		delete [] m_vertex_shader_source;
223
	m_vertex_shader_source = NULL;
Pierre Kraemer's avatar
Pierre Kraemer committed
224

225
	m_vertex_shader_source = loadSourceFile( filename );
Pierre Kraemer's avatar
Pierre Kraemer committed
226

227
	if( !m_vertex_shader_source )
Pierre Kraemer's avatar
Pierre Kraemer committed
228
	{
229
		CGoGNerr << "ERROR - GLSLShader::loadVertexShader() - error occured while loading source file." << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
230
231
232
		return false;
	}

233
234
	flag = loadVertexShaderSourceString( m_vertex_shader_source );
//	delete [] vertex_shader_source;
Pierre Kraemer's avatar
Pierre Kraemer committed
235
236
237
238

	return flag;
}

239
bool GLSLShader::loadFragmentShader(const std::string& filename )
Pierre Kraemer's avatar
Pierre Kraemer committed
240
241
{
	bool	flag;
242
//	char	*fragment_shader_source;
Pierre Kraemer's avatar
Pierre Kraemer committed
243

244
245
	if (m_fragment_shader_source)
		delete [] m_fragment_shader_source;
246
	m_fragment_shader_source = NULL;
Pierre Kraemer's avatar
Pierre Kraemer committed
247

248
	m_fragment_shader_source = loadSourceFile( filename );
Pierre Kraemer's avatar
Pierre Kraemer committed
249

250
	if( !m_fragment_shader_source )
Pierre Kraemer's avatar
Pierre Kraemer committed
251
	{
252
		CGoGNerr << "ERROR - GLSLShader::loadFragmentShader() - error occured while loading source file." << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
253
254
255
		return false;
	}

256
257
	flag = loadFragmentShaderSourceString( m_fragment_shader_source );
//	delete [] fragment_shader_source;
Pierre Kraemer's avatar
Pierre Kraemer committed
258
259
260
261
262
263
264

	return flag;
}

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

267
268
	if (m_geom_shader_source)
		delete [] m_geom_shader_source;
Pierre Kraemer's avatar
Pierre Kraemer committed
269

270
	m_geom_shader_source = loadSourceFile( filename );
Pierre Kraemer's avatar
Pierre Kraemer committed
271

272
	if( !m_geom_shader_source )
Pierre Kraemer's avatar
Pierre Kraemer committed
273
	{
274
		CGoGNerr << "ERROR - GLSLShader::loadGeometryShader() - error occured while loading source file." << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
275
276
277
		return false;
	}

278
279
	flag = loadGeometryShaderSourceString( m_geom_shader_source );
//	delete [] geom_shader_source;
Pierre Kraemer's avatar
Pierre Kraemer committed
280
281
282
283

	return flag;
}

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

Sylvain Thery's avatar
Sylvain Thery committed
310
311
bool GLSLShader::loadVertexShaderSourceString( const char *vertex_shader_source )
{
312
	if (*m_vertex_shader_object!=0)
Sylvain Thery's avatar
Sylvain Thery committed
313
	{
314
315
		glDeleteShader(*m_vertex_shader_object);
		*m_vertex_shader_object=0;
Sylvain Thery's avatar
Sylvain Thery committed
316
	}
Pierre Kraemer's avatar
Pierre Kraemer committed
317
318

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

321
	if( !*m_vertex_shader_object )
Pierre Kraemer's avatar
Pierre Kraemer committed
322
	{
323
		CGoGNerr << "ERROR - GLSLShader::loadVertexShader() - unable to create shader object." << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
324
325
326
327
328
329
		return false;
	}

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

332
		glDeleteShader(*m_vertex_shader_object );
333
		*m_vertex_shader_object = 0;
Pierre Kraemer's avatar
Pierre Kraemer committed
334
335
336
337

		return false;
	}

338
	glShaderSource( *m_vertex_shader_object, 1, (const char**)&vertex_shader_source, NULL );
Pierre Kraemer's avatar
Pierre Kraemer committed
339
340

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

Sylvain Thery's avatar
Sylvain Thery committed
343
	if (!logError(*m_vertex_shader_object, m_nameVS, vertex_shader_source))
Pierre Kraemer's avatar
Pierre Kraemer committed
344
	{
345
		glDeleteShader( *m_vertex_shader_object );
346
		*m_vertex_shader_object = 0;
Pierre Kraemer's avatar
Pierre Kraemer committed
347
348
349
350
351
352
353
		return false;
	}

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

354
bool GLSLShader::loadFragmentShaderSourceString( const char *fragment_shader_source )
Pierre Kraemer's avatar
Pierre Kraemer committed
355
{
356
	if (*m_fragment_shader_object!=0)
Sylvain Thery's avatar
Sylvain Thery committed
357
	{
358
359
		glDeleteShader(*m_fragment_shader_object);
		*m_fragment_shader_object=0;
Sylvain Thery's avatar
Sylvain Thery committed
360
	}
Pierre Kraemer's avatar
Pierre Kraemer committed
361
362

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

365
	if( !*m_fragment_shader_object )
Pierre Kraemer's avatar
Pierre Kraemer committed
366
	{
367
		CGoGNerr << "ERROR - GLSLShader::loadFragmentShader() - unable to create shader object." << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
368
369
370
371
		return false;
	}

	/*** load source file ***/
372
	if( !fragment_shader_source )
Pierre Kraemer's avatar
Pierre Kraemer committed
373
	{
374
		CGoGNerr << "ERROR - GLSLShader::loadFragmentShader() - source string is empty." << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
375

376
		glDeleteShader( *m_fragment_shader_object );
377
		*m_fragment_shader_object = 0;
Pierre Kraemer's avatar
Pierre Kraemer committed
378
379
380
381

		return false;
	}

382
	glShaderSource( *m_fragment_shader_object, 1, (const char**)&fragment_shader_source, NULL );
Pierre Kraemer's avatar
Pierre Kraemer committed
383
384

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

Sylvain Thery's avatar
Sylvain Thery committed
387
	if (!logError(*m_fragment_shader_object, m_nameFS, fragment_shader_source))
Pierre Kraemer's avatar
Pierre Kraemer committed
388
	{
389
		glDeleteShader( *m_fragment_shader_object );
390
		*m_fragment_shader_object = 0;
Pierre Kraemer's avatar
Pierre Kraemer committed
391
392
393
394
395
396
397
398
399
		return false;
	}

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

bool GLSLShader::loadGeometryShaderSourceString( const char *geom_shader_source )
{
400
	if (*m_geom_shader_object!=0)
Sylvain Thery's avatar
Sylvain Thery committed
401
	{
402
403
		glDeleteShader(*m_geom_shader_object);
		*m_geom_shader_object=0;
Sylvain Thery's avatar
Sylvain Thery committed
404
	}
Pierre Kraemer's avatar
Pierre Kraemer committed
405
	/*** create shader object ***/
Sylvain Thery's avatar
Sylvain Thery committed
406
	*m_geom_shader_object = glCreateShader(GL_GEOMETRY_SHADER);
Pierre Kraemer's avatar
Pierre Kraemer committed
407

408
	if( !*m_geom_shader_object )
Pierre Kraemer's avatar
Pierre Kraemer committed
409
	{
410
		CGoGNerr << "ERROR - GLSLShader::loadGeometryShader() - unable to create shader object." << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
411
412
413
414
415
416
		return false;
	}

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

419
		glDeleteShader( *m_geom_shader_object );
420
		*m_geom_shader_object = 0;
Pierre Kraemer's avatar
Pierre Kraemer committed
421
422
423
424

		return false;
	}

425
	glShaderSource( *m_geom_shader_object, 1, (const char**)&geom_shader_source, NULL );
Pierre Kraemer's avatar
Pierre Kraemer committed
426
427

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

Sylvain Thery's avatar
Sylvain Thery committed
430
	if (!logError(*m_geom_shader_object, m_nameGS, geom_shader_source))
Pierre Kraemer's avatar
Pierre Kraemer committed
431
	{
432
		glDeleteShader( *m_geom_shader_object );
433
		*m_geom_shader_object = 0;
Pierre Kraemer's avatar
Pierre Kraemer committed
434
435
436
437
438
439
440
		return false;
	}

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

441
char* GLSLShader::getInfoLog( GLuint obj )
Pierre Kraemer's avatar
Pierre Kraemer committed
442
{
443
444
445
	char* info_log;
	int info_log_length;
	int length;
Pierre Kraemer's avatar
Pierre Kraemer committed
446

447
	glGetProgramiv(obj, GL_INFO_LOG_LENGTH, &info_log_length);
Sylvain Thery's avatar
Sylvain Thery committed
448
449
450

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

	info_log = new char [info_log_length];
453
	glGetProgramInfoLog( obj, info_log_length, &length, info_log );
Pierre Kraemer's avatar
Pierre Kraemer committed
454
455
456
457

	return info_log;
}

458
459
char* GLSLShader::getInfoLogShader( GLuint obj )
{
460
461
462
	char* info_log;
	int	info_log_length;
	int	length;
463
464
465
466
467
468
469
470
471
472
473
474

    glGetShaderiv(obj, GL_INFO_LOG_LENGTH, &info_log_length);

    if (info_log_length <= 1)
        return NULL;

    info_log = new char [info_log_length+1];
    glGetShaderInfoLog( obj, info_log_length, &length, info_log );
    info_log[info_log_length]=0;
    return info_log;
}

Sylvain Thery's avatar
Sylvain Thery committed
475
bool GLSLShader::create(GLint inputGeometryPrimitive,GLint outputGeometryPrimitive, int nb_max_vertices)
Pierre Kraemer's avatar
Pierre Kraemer committed
476
{
477
478
	int	status;
	char* info_log;
Pierre Kraemer's avatar
Pierre Kraemer committed
479

480
	if (nb_max_vertices != -1)
Sylvain Thery's avatar
Sylvain Thery committed
481
482
		m_nbMaxVertices = nb_max_vertices;

483
484
	m_geom_inputPrimitives = inputGeometryPrimitive;
	m_geom_outputPrimitives = outputGeometryPrimitive;
Pierre Kraemer's avatar
Pierre Kraemer committed
485
486

	/*** check if shaders are loaded ***/
487
	if( !*m_vertex_shader_object || !*m_fragment_shader_object )
Pierre Kraemer's avatar
Pierre Kraemer committed
488
	{
489
		CGoGNerr << "ERROR - GLSLShader::create() - shaders are not defined." << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
490
491
492
493
		return false;
	}

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

496
	if( !*m_program_object )
Pierre Kraemer's avatar
Pierre Kraemer committed
497
	{
498
		CGoGNerr << "ERROR - GLSLShader::create() - unable to create program object." << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
499
500
501
502
		return false;
	}

	/*** attach shaders to program object ***/
503
504
	glAttachShader( *m_program_object, *m_vertex_shader_object );
	glAttachShader( *m_program_object, *m_fragment_shader_object );
505
	if (*m_geom_shader_object)
Pierre Kraemer's avatar
Pierre Kraemer committed
506
	{
507
		glAttachShader( *m_program_object, *m_geom_shader_object );
Pierre Kraemer's avatar
Pierre Kraemer committed
508

509
510
511
512
513
514
		if (CURRENT_OGL_VERSION == 2)
		{
			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
515
516
517
	}

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

520
	glGetProgramiv( *m_program_object, GL_LINK_STATUS, &status );
Pierre Kraemer's avatar
Pierre Kraemer committed
521
522
	if( !status )
	{
523
		CGoGNerr << "ERROR - GLSLShader::create() - error occured while linking shader program." << CGoGNendl;
524
		info_log = getInfoLog( *m_program_object );
525
		CGoGNerr << "  LINK " << info_log << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
526
527
		delete [] info_log;

528
529
		glDetachShader( *m_program_object, *m_vertex_shader_object );
		glDetachShader( *m_program_object, *m_fragment_shader_object );
530
		if (*m_geom_shader_object)
531
532
			glDetachShader( *m_program_object, *m_geom_shader_object );
		glDeleteShader( *m_program_object );
533
		*m_program_object = 0;
Pierre Kraemer's avatar
Pierre Kraemer committed
534
535
536
537

		return false;
	}

538
539
540
541
	*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");
542

Pierre Kraemer's avatar
Pierre Kraemer committed
543
544
545
	return true;
}

Sylvain Thery's avatar
Sylvain Thery committed
546
547
548
bool GLSLShader::changeNbMaxVertices(int nb_max_vertices)
{
	m_nbMaxVertices = nb_max_vertices;
549
	if ((*m_geom_shader_object) && (CURRENT_OGL_VERSION == 2))
Sylvain Thery's avatar
Sylvain Thery committed
550
	{
551
		glProgramParameteriEXT(*m_program_object, GL_GEOMETRY_VERTICES_OUT_EXT, m_nbMaxVertices);
Sylvain Thery's avatar
Sylvain Thery committed
552
553
554
555
556
557
		// need to relink
		return true;
	}
	return false;
}

558
559
560
561
562
563
bool GLSLShader::link()
{
	int		status;
	char	*info_log;

	/*** link program object ***/
564
	glLinkProgram( *m_program_object );
565

566
	glGetProgramiv( *m_program_object, GL_OBJECT_LINK_STATUS_ARB, &status );
567
568
	if( !status )
	{
569
		CGoGNerr << "ERROR - GLSLShader::create() - error occured while linking shader program." << CGoGNendl;
570
		info_log = getInfoLog( *m_program_object );
571
		CGoGNerr << "  LINK " << info_log << CGoGNendl;
572
573
		delete [] info_log;

574
575
		glDetachShader( *m_program_object, *m_vertex_shader_object );
		glDetachShader( *m_program_object, *m_fragment_shader_object );
576
		if (*m_geom_shader_object)
577
578
			glDetachShader( *m_program_object, *m_geom_shader_object );
		glDeleteShader( *m_program_object );
579
		*m_program_object = 0;
580
581
582
583
584
585

		return false;
	}
	return true;
}

586
bool GLSLShader::bind() const
Pierre Kraemer's avatar
Pierre Kraemer committed
587
{
588
	if( *m_program_object )
Pierre Kraemer's avatar
Pierre Kraemer committed
589
	{
590
		glUseProgram( *m_program_object );
Pierre Kraemer's avatar
Pierre Kraemer committed
591
592
		return true;
	}
593
594
	else
		return false;
Pierre Kraemer's avatar
Pierre Kraemer committed
595
596
}

597
void GLSLShader::unbind() const
Pierre Kraemer's avatar
Pierre Kraemer committed
598
{
599
	if( *m_program_object )
Pierre Kraemer's avatar
Pierre Kraemer committed
600
	{
601
		glUseProgram( 0 );
Pierre Kraemer's avatar
Pierre Kraemer committed
602
603
604
605
606
	}
}

bool GLSLShader::isBinded()
{
607
608
609
610
611
612
	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
613
614
615
616
}

GLSLShader::~GLSLShader()
{
617
	if( *m_program_object )
Pierre Kraemer's avatar
Pierre Kraemer committed
618
619
620
	{
		unbind();

621
		if( *m_vertex_shader_object )
Pierre Kraemer's avatar
Pierre Kraemer committed
622
		{
623
624
			glDetachShader( *m_program_object, *m_vertex_shader_object );
			glDeleteShader( *m_vertex_shader_object );
Pierre Kraemer's avatar
Pierre Kraemer committed
625
		}
626
		if( *m_fragment_shader_object )
Pierre Kraemer's avatar
Pierre Kraemer committed
627
		{
628
629
			glDetachShader( *m_program_object, *m_fragment_shader_object );
			glDeleteShader( *m_fragment_shader_object );
Pierre Kraemer's avatar
Pierre Kraemer committed
630
		}
631
		if (*m_geom_shader_object)
Pierre Kraemer's avatar
Pierre Kraemer committed
632
		{
633
634
			glDetachShader( *m_program_object, *m_geom_shader_object );
			glDeleteShader( *m_geom_shader_object );
Pierre Kraemer's avatar
Pierre Kraemer committed
635
636
		}

637
		glDeleteShader( *m_program_object );
Pierre Kraemer's avatar
Pierre Kraemer committed
638
	}
639

640
641
642
643
644
645
646
	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;

647
//	m_registeredShaders->erase(this);
Pierre Kraemer's avatar
Pierre Kraemer committed
648
649
650
651
}

std::string GLSLShader::findFile(const std::string filename)
{
Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
652
	// cherche d'abord dans le repertoire courant
Pierre Kraemer's avatar
Pierre Kraemer committed
653
654
655
656
657
658
659
660
661
	std::ifstream file;
	file.open(filename.c_str(),std::ios::in );
	if (!file.fail())
	{
		file.close();
		return filename;
	}
	file.close();

662
663
664
665
666
667
668
669
670
671
672
673
674
675
	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
676
	// LA MACRO SHADERPATH contient le chemin du repertoire qui contient les fichiers textes
Pierre Kraemer's avatar
Pierre Kraemer committed
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
	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()
{
693
#ifndef CGOGN_GLEW_MX
Pierre Kraemer's avatar
Pierre Kraemer committed
694
695
696
	GLenum error = glewInit();

	if (error != GLEW_OK)
697
		CGoGNerr << "Error: " << glewGetErrorString(error) << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
698
	else
699
		CGoGNout << "Status: Using GLEW " << glewGetString(GLEW_VERSION) << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
700
701

	if (!areVBOSupported())
702
		CGoGNerr << "VBO not supported !" << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
703

704
705
706
	if  ((CURRENT_OGL_VERSION == 2) && (!glewIsSupported("GL_VERSION_2_0")))
	{
		CGoGNerr << " GL 2.0 not supported" << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
707
708
		return false;
	}
709
710
711
712
713
714
715

	if ((CURRENT_OGL_VERSION == 3) && (!glewIsSupported("GL_VERSION_3_3")))
	{
		CGoGNerr << " GL 3.3 not supported" << CGoGNendl;
		return false;
	}

716
717
718
#endif
	return true;

Pierre Kraemer's avatar
Pierre Kraemer committed
719
720
721
722
}

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

Pierre Kraemer's avatar
Pierre Kraemer committed
726
727
728
729
	std::string vss = findFile(vs);
	if(!loadVertexShader(vss)) return false;
	
	std::string pss = findFile(ps);
730
	if(!loadFragmentShader(pss)) return false;
Pierre Kraemer's avatar
Pierre Kraemer committed
731
732

	if(!create()) {
733
		CGoGNout << "Unable to create the shaders !" << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
734
735
		return false;
	}
736
	CGoGNout << "Shaders loaded (" << vs << "," << ps << ")" << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
737
738
739
	return true; 
}

Sylvain Thery's avatar
Sylvain Thery committed
740
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
741
{
Sylvain Thery's avatar
Sylvain Thery committed
742
743
744
745
	m_nameVS = vs;
	m_nameFS = ps;
	m_nameGS = gs;

Pierre Kraemer's avatar
Pierre Kraemer committed
746
747
748
749
	std::string vss = findFile(vs);
	if(!loadVertexShader(vss)) return false;

	std::string pss = findFile(ps);
750
	if(!loadFragmentShader(pss)) return false;
Pierre Kraemer's avatar
Pierre Kraemer committed
751
752
753
754
755
756

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

	if (!geomShaderLoaded)
	{
757
		CGoGNerr << "Error while loading geometry shader" << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
758
759
	}

Sylvain Thery's avatar
Sylvain Thery committed
760
	if(!create(inputGeometryPrimitive,outputGeometryPrimitive,nb_max_vertices))
Pierre Kraemer's avatar
Pierre Kraemer committed
761
	{
762
		CGoGNout << "Unable to create the shaders !" << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
763
764
765
		return false;
	}

766
	CGoGNout << "Shaders loaded (" << vs << "," << ps << "," << gs <<")" << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
767
768
769
	return true;
}

Sylvain Thery's avatar
Sylvain Thery committed
770
771
bool GLSLShader::loadShadersFromMemory(const char* vs, const char* fs)
{
772
773
	if (m_vertex_shader_source)
		delete [] m_vertex_shader_source;
774
	m_vertex_shader_source = NULL;
775

776
	size_t sz = strlen(vs);
777
	m_vertex_shader_source = new char[sz+1];
778
779
780
	memcpy(m_vertex_shader_source, vs,sz+1);
	

781
782
783
784
785
786

	if (m_fragment_shader_source)
		delete [] m_fragment_shader_source;

	sz = strlen(fs);
	m_fragment_shader_source = new char[sz+1];
787
	memcpy(m_fragment_shader_source, fs,sz+1);
788

789
790
	if(!loadVertexShaderSourceString(vs))
		return false;
Sylvain Thery's avatar
Sylvain Thery committed
791

792
793
	if(!loadFragmentShaderSourceString(fs))
		return false;
Sylvain Thery's avatar
Sylvain Thery committed
794
795
796

	if(!create())
	{
797
		CGoGNout << "Unable to create the shaders !" << CGoGNendl;
Sylvain Thery's avatar
Sylvain Thery committed
798
799
800
801
802
		return false;
	}
	return true;
}

Sylvain Thery's avatar
Sylvain Thery committed
803
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
804
{
805
806
	if (m_vertex_shader_source)
		delete [] m_vertex_shader_source;
807
	m_vertex_shader_source = NULL;
808

809
	size_t sz = strlen(vs);
810
	m_vertex_shader_source = new char[sz+1];
811
	memcpy(m_vertex_shader_source,vs,sz+1);
812
813
814
815
816
817

	if (m_fragment_shader_source)
		delete [] m_fragment_shader_source;

	sz = strlen(fs);
	m_fragment_shader_source = new char[sz+1];
818
	memcpy(m_fragment_shader_source,fs,sz+1);
819
820
821
822
823
824

	if (m_geom_shader_source)
		delete [] m_geom_shader_source;

	sz = strlen(gs);
	m_geom_shader_source = new char[sz+1];
825
	memcpy(m_geom_shader_source,gs,sz+1);
826

Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
827
828
	if(!loadVertexShaderSourceString(vs))
		return false;
Sylvain Thery's avatar
Sylvain Thery committed
829

Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
830
831
	if(!loadFragmentShaderSourceString(fs))
		return false;
Sylvain Thery's avatar
Sylvain Thery committed
832

Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
833
834
	if(!loadGeometryShaderSourceString(gs))
		return false;
Sylvain Thery's avatar
Sylvain Thery committed
835

836
	if(!create(inputGeometryPrimitive, outputGeometryPrimitive, nb_max_vertices))
Sylvain Thery's avatar
Sylvain Thery committed
837
	{
838
		CGoGNout << "Unable to create the shaders !" << CGoGNendl;
Sylvain Thery's avatar
Sylvain Thery committed
839
840
841
842
843
844
		return false;
	}

	return true;
}

845
846
847
848
bool GLSLShader::reloadVertexShaderFromMemory(const char* vs)
{
	if (m_vertex_shader_source)
		delete [] m_vertex_shader_source;
849
	m_vertex_shader_source = NULL;
850

851
	size_t sz = strlen(vs);
852
	m_vertex_shader_source = new char[sz+1];
853
	memcpy(m_vertex_shader_source,vs,sz+1);
854
855
856
857
858
859
860
861
862

	return true;
}

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

863
	unsigned int sz = uint32(strlen(fs));
864
	m_fragment_shader_source = new char[sz+1];
865
	memcpy(m_fragment_shader_source,fs,sz+1);
866
867
868
869
870
871
872
873
874

	return true;
}

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

875
	unsigned int sz = uint32(strlen(gs));
876
	m_geom_shader_source = new char[sz+1];
877
	memcpy(m_geom_shader_source,gs,sz+1);
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892

	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))
	{
893
		CGoGNerr << "Unable to create the shaders !" << CGoGNendl;
894
895
896
		return false;
	}

897
898
899
	*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
900
	*m_uniMat_Normal	= glGetUniformLocation(*m_program_object,"NormalMatrix");
901
902
903

	restoreUniformsAttribs();

904
905
	updateClippingUniforms();

906
907
908
	return true;
}

909
910
bool GLSLShader::validateProgram()
{
911
	if(!*m_program_object)
912
913
		return false;

914
	glValidateProgram(*m_program_object);
915
	GLint Result = GL_FALSE;
916
	glGetProgramiv(*m_program_object, GL_VALIDATE_STATUS, &Result);
917
918
919

	if(Result == GL_FALSE)
	{
920
		CGoGNout << "Validate program:" << CGoGNendl;
921
		int InfoLogLength;
922
		glGetProgramiv(*m_program_object, GL_INFO_LOG_LENGTH, &InfoLogLength);
923
		std::vector<char> Buffer(InfoLogLength);
924
		glGetProgramInfoLog(*m_program_object, InfoLogLength, NULL, &Buffer[0]);
925
		CGoGNout <<  &(Buffer[0]) << CGoGNendl;
926
927
928
929
930
931
932
933
934
		return false;
	}

	return true;
}

bool GLSLShader::checkProgram()
{
	GLint Result = GL_FALSE;
935
	glGetProgramiv(*m_program_object, GL_LINK_STATUS, &Result);
936
937

	int InfoLogLength;
938
	glGetProgramiv(*m_program_object, GL_INFO_LOG_LENGTH, &InfoLogLength);
939
	std::vector<char> Buffer(std::max(InfoLogLength, int(1)));
940
	glGetProgramInfoLog(*m_program_object, InfoLogLength, NULL, &Buffer[0]);
941
	CGoGNout << &Buffer[0] << CGoGNendl;
942
943
944
945
946
947
948
949

	return Result == GL_TRUE;
}

bool GLSLShader::checkShader(int shaderType)
{
	GLint Result = GL_FALSE;
	int InfoLogLength;
950
	GLuint id;
951
952
953
954

	switch(shaderType)
	{
	case VERTEX_SHADER:
955
		id = *m_vertex_shader_object;
956
957
		break;
	case FRAGMENT_SHADER:
958
		id = *m_fragment_shader_object;
959
960
		break;
	case GEOMETRY_SHADER:
961
		id = *m_geom_shader_object;
962
963
		break;
	default:
964
		CGoGNerr << "Error unkown shader type" << CGoGNendl;
965
966
967
968
969
970
971
972
		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]);
973
	CGoGNout << &Buffer[0] << CGoGNendl;
974
975
976
977

	return Result == GL_TRUE;
}

Sylvain Thery's avatar
Sylvain Thery committed
978
void GLSLShader::bindAttrib(unsigned int att, const char* name) const
979
{
980
	glBindAttribLocation(*m_program_object, att, name);
981
982
}

983
984
985
986
987
void GLSLShader::addPathFileSeach(const std::string& path)
{
	m_pathes.push_back(path);
}

988
unsigned int GLSLShader::bindVA_VBO(const std::string& name, VBO* vbo)
Sylvain Thery's avatar
Sylvain Thery committed
989
{
990
	GLint idVA = glGetAttribLocation(*(this->m_program_object), name.c_str());
Sylvain Thery's avatar
Sylvain Thery committed
991
992
993
	//valid ?
	if (idVA < 0)
	{
Pierre Kraemer's avatar
Pierre Kraemer committed
994
		CGoGNerr << "GLSLShader: Attribute " << name << " does not exist in shader" << CGoGNendl;
995
		return idVA;
Sylvain Thery's avatar
Sylvain Thery committed
996
	}
997

Sylvain Thery's avatar
Sylvain Thery committed
998
999
1000
1001
1002
	// 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)
		{
1003
			it->vbo_ptr = vbo;
1004
			return uint32(it - m_va_vbo_binding.begin());
Sylvain Thery's avatar
Sylvain Thery committed
1005
1006
1007
1008
1009
		}
	}
	// new one:
	VAStr temp;
	temp.va_id = idVA;
1010
	temp.vbo_ptr = vbo;
Sylvain Thery's avatar
Sylvain Thery committed
1011
	m_va_vbo_binding.push_back(temp);
1012

1013
	return uint32(m_va_vbo_binding.size() -1);
1014
1015
1016
1017
1018
}

void GLSLShader::changeVA_VBO(unsigned int id, VBO* vbo)
{
	m_va_vbo_binding[id].vbo_ptr = vbo;
Sylvain Thery's avatar
Sylvain Thery committed
1019
1020
1021
1022
}

void GLSLShader::unbindVA(const std::string& name)
{
1023
	GLint idVA = glGetAttribLocation(*(this->m_program_object), name.c_str());
Sylvain Thery's avatar
Sylvain Thery committed
1024
1025
1026
	//valid ?
	if (idVA < 0)
	{
1027
		CGoGNerr << "GLSLShader: Attribute " << name << " does not exist in shader, not unbinded" << CGoGNendl;
Sylvain Thery's avatar
Sylvain Thery committed
1028
1029
1030
		return;
	}
	// search if name already exist
1031
	unsigned int nb = uint32(m_va_vbo_binding.size());
Pierre Kraemer's avatar