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.h 11.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-2011, 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.u-strasbg.fr/                                         *
Pierre Kraemer's avatar
Pierre Kraemer committed
21
22
23
24
25
26
27
28
* Contact information: cgogn@unistra.fr                                        *
*                                                                              *
*******************************************************************************/

/***********************************************
*  Thanks to Frederic Larue for this class
***********************************************/

Sylvain Thery's avatar
Sylvain Thery committed
29
30
#ifndef __CGoGN_GLSL_SHADER__
#define __CGoGN_GLSL_SHADER__
Pierre Kraemer's avatar
Pierre Kraemer committed
31
32

#include "Utils/os_spec.h"
Sylvain Thery's avatar
Sylvain Thery committed
33
#include "Utils/vbo.h"
34
#include "Utils/gl_matrices.h"
Pierre Kraemer's avatar
Pierre Kraemer committed
35

Sylvain Thery's avatar
Sylvain Thery committed
36
#include "glm/glm.hpp"
Pierre Kraemer's avatar
Pierre Kraemer committed
37
38
39
40
#include <GL/glew.h>

#include <stdlib.h>
#include <string>
41
#include <vector>
42
43
#include <set>

Pierre Kraemer's avatar
Pierre Kraemer committed
44
45
namespace CGoGN
{
Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
46

Pierre Kraemer's avatar
Pierre Kraemer committed
47
48
49
namespace Utils
{

50
class GLSLShader
Pierre Kraemer's avatar
Pierre Kraemer committed
51
{
52
public:
Sylvain Thery's avatar
Sylvain Thery committed
53
54
55
56
57
58
59
60
	struct VAStr
	{
		int va_id;
		VBO* vbo_ptr;
//		GLuint vbo_id;
//		unsigned int size;
	};

61
62
63
64
	/**
	 * enum of supported shader type
	 */
	enum shaderType {VERTEX_SHADER = 1, FRAGMENT_SHADER = 2, GEOMETRY_SHADER = 3 };
Pierre Kraemer's avatar
Pierre Kraemer committed
65

Sylvain Thery's avatar
Sylvain Thery committed
66
67
	static unsigned int CURRENT_OGL_VERSION;

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

70
71
72
//	static glm::mat4* s_current_matrices;
	static Utils::GL_Matrices* s_current_matrices;

Pierre Kraemer's avatar
Pierre Kraemer committed
73
protected:
Sylvain Thery's avatar
Sylvain Thery committed
74
75
76
77
78
79
	static std::string DEFINES_GL2;

	static std::string DEFINES_GL3;

	static std::string* DEFINES_GL;

80
81
	static std::string defines_Geom(const std::string& primitivesIn, const std::string& primitivesOut, int maxVert);

82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
	/**
	 * handle of vertex shader
	 */
	GLhandleARB	m_vertex_shader_object;

	/**
	 * handle of fragment shader
	 */
	GLhandleARB	m_fragment_shader_object;

	/**
	 * handle of geometry shader
	 */
	GLhandleARB	m_geom_shader_object;

Sylvain Thery's avatar
Sylvain Thery committed
97
98
99
100
	std::string m_nameVS;
	std::string m_nameFS;
	std::string m_nameGS;

101
102
103
104
105
	/**
	 * handle of program
	 */
	GLhandleARB m_program_object;

106
107
108
109
110
111
112
113
114
115
116
117
	GLint m_uniMat_Proj;
	GLint m_uniMat_Model;
	GLint m_uniMat_ModelProj;
	GLint m_uniMat_Normal;

	char* m_vertex_shader_source;
	char* m_fragment_shader_source;
	char* m_geom_shader_source;

	GLint m_geom_inputPrimitives;
	GLint m_geom_outputPrimitives;

Sylvain Thery's avatar
Sylvain Thery committed
118
119
120
121
122
123
124
125
	/**
	 * a set of pair VA_id / VBO_id
	 */
//	std::vector<pair<int,unsigned int> > m_va_vbo_binding;
	std::vector<VAStr> m_va_vbo_binding;

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

126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
	/**
	 * load vertex shader
	 * @param vertex_shader_source src text shader
	 */
	bool loadVertexShaderSourceString( const char* vertex_shader_source );

	/**
	 * load fragment shader
	 * @param fragment_shader_source src text shader
	 */
	bool loadFragmentShaderSourceString( const char* fragment_shader_source );

	/**
	 * load geometry shader
	 * @param geom_shader_source src text shader
	 */
	bool loadGeometryShaderSourceString( const char* geom_shader_source );
Pierre Kraemer's avatar
Pierre Kraemer committed
143

144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
	/**
	 * load vertex shader
	 * @param filename file name
	 */
	bool loadVertexShader( const std::string& filename );

	/**
	 * load fragment shader
	 * @param filename file name
	 */
	bool loadFragmentShader( const std::string& filename );

	/**
	 * load geometry shader
	 * @param filename file name
	 */
	bool  loadGeometryShader( const std::string& filename );

	/**
	 * Load of source file in a char buffer
	 * @param source_file file name
	 */
	char* loadSourceFile( const std::string& source_file );

	/**
	 * create the shader (attach and link shaders into program)
	 */
	bool create(GLint inputGeometryPrimitive=GL_TRIANGLES,GLint outputGeometryPrimitive=GL_TRIANGLES);

	/**
	 * get log after compiling
	 * @param obj what log do you want ?
	 * @return the log
	 */
	char* getInfoLog( GLhandleARB obj );
Pierre Kraemer's avatar
Pierre Kraemer committed
179
180

public:
181
182
183
	/**
	 * constructor
	 */
Pierre Kraemer's avatar
Pierre Kraemer committed
184
185
	GLSLShader();

186
187
188
189
	/**
	 * destructor
	 */
	virtual ~GLSLShader();
Pierre Kraemer's avatar
Pierre Kraemer committed
190

Sylvain Thery's avatar
Sylvain Thery committed
191
192
	static void setCurrentOGLVersion(unsigned int version);

193
194
195
196
197
	/*
	 * search file in different path
	 */
	static std::string findFile(const std::string filename);

198
199
200
201
	/**
	 * test support of shader
	 */
	static bool	areShadersSupported();
Pierre Kraemer's avatar
Pierre Kraemer committed
202

203
204
205
206
207
208
209
210
211
	/**
	 * test support of Vertex Buffer Object
	 */
	static bool	areVBOSupported();

	/**
	 * test support of geometry shader
	 */
	static bool	areGeometryShadersSupported();
Pierre Kraemer's avatar
Pierre Kraemer committed
212

213
214
215
216
	/**
	 * test support of gl3
	 */
	static bool	isGL3Supported();
Pierre Kraemer's avatar
Pierre Kraemer committed
217

218
	static bool init();
Pierre Kraemer's avatar
Pierre Kraemer committed
219

Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
220
	static void registerShader(void* ptr, GLSLShader* shader);
Pierre Kraemer's avatar
Pierre Kraemer committed
221

Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
222
	static void unregisterShader(void* ptr, GLSLShader* shader);
223
224
225

//	static void updateMatricesRunningShaders(const glm::mat4& projection, const glm::mat4& modelview);

226
227
228
229
230
231
232
233
234
	/**
	 * load shaders (compile and link)
	 * @param vs vertex shader source file
	 * @param fs fragment shader source file
	 */
	bool loadShaders(const std::string& vs, const std::string& fs);

	/**
	 * load shaders (compile and link)
Sylvain Thery's avatar
Sylvain Thery committed
235
236
237
	 * @param vs vertex shader source file name
	 * @param fs fragment shader source file name
	 * @param gs geometry shader source file name
238
239
240
	 * @param inputGeometryPrimitive primitives used in geometry shader as input
	 * @param outputGeometryPrimitive primitives generated in geometry shader as output
	 */
241
	bool loadShaders(const std::string& vs, const std::string& fs, const std::string& gs, GLint inputGeometryPrimitive=GL_TRIANGLES,GLint outputGeometryPrimitive=GL_TRIANGLE_STRIP);
Pierre Kraemer's avatar
Pierre Kraemer committed
242

Sylvain Thery's avatar
Sylvain Thery committed
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
	/**
	 * load shaders (compile and link)
	 * @param vs vertex shader source char* prt
	 * @param fs fragment shader source char* prt

	 * @param outputGeometryPrimitive primitives generated in geometry shader as output
	 */
	bool loadShadersFromMemory(const char* vs, const char* fs);

	/**
	 * load shaders (compile and link)
	 * @param vs vertex shader source char* prt
	 * @param fs fragment shader source char* prt
	 * @param fs geometry shader source char* prt
	 * @param inputGeometryPrimitive primitives used in geometry shader as input
	 * @param outputGeometryPrimitive primitives generated in geometry shader as output
	 */
	bool loadShadersFromMemory(const char* vs, const char* fs, const char* gs, GLint inputGeometryPrimitive,GLint outputGeometryPrimitive);

Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
262
263
264
	const char* getVertexShaderSrc() { return m_vertex_shader_source; }
	const char* getFragmentShaderSrc() { return m_fragment_shader_source; }
	const char* getGeometryShaderSrc() { return m_geom_shader_source; }
265
266
267
268
269
270
271
272
273

	bool reloadVertexShaderFromMemory(const char* vs);

	bool reloadFragmentShaderFromMemory(const char* fs);

	bool reloadGeometryShaderFromMemory(const char* gs);

	bool recompile();

274
275
276
277
278
	/**
	 * Link the shader do it just after binding the attributes
	 */
	bool link();

Pierre Kraemer's avatar
Pierre Kraemer committed
279
	inline bool		isCreated();
280

Pierre Kraemer's avatar
Pierre Kraemer committed
281
282
	bool			isBinded();

283
284
285
	virtual bool	bind() const;

	virtual void	unbind() const;
286

287
288
289
	/**
	 * restore all uniforms and vertex attributes after recompiling
	 */
290
	virtual void restoreUniformsAttribs() {CGoGNerr << "Warning restoreUniformsAttribs not implemented"<< CGoGNendl;}
Pierre Kraemer's avatar
Pierre Kraemer committed
291

292
293
294
	/**
	 *
	 */
Sylvain Thery's avatar
Sylvain Thery committed
295
//	GLuint 	getAttribIndex( char* attribName );
Pierre Kraemer's avatar
Pierre Kraemer committed
296
	
297
298
299
300
301
	/**
	 * get handler of program for external use og gl functions
	 */
	GLuint program_handler() { return m_program_object;}

302
303
304
	/**
	 * check shader validity width official GLSL syntax
	 */
305
306
	bool validateProgram();

307
308
309
	/**
	 * check program link status
	 */
310
311
	bool checkProgram();

312
313
314
	/**
	 * check shader compile status
	 */
315
316
	bool checkShader(int shaderType);

Pierre Kraemer's avatar
Pierre Kraemer committed
317
public:
318
319
320
321
322
323
324
	/**
	 * set uniform shader float variable
	 * @warning practical but less efficient that storing id (get with glGetUniformLocation) and use glUniform*fvARB
	 * @param NB template size of variable to set
	 * @param name name in shader
	 * @param pointer on data to copy
	 */
325
	template<unsigned int NB>
Sylvain Thery's avatar
Sylvain Thery committed
326
	void setuniformf( const char* name, const float* val);
327

328
329
330
331
332
333
334
	/**
	 * set uniform shader int variable
	 * @warning practical but less efficient that storing id (get with glGetUniformLocation) and use glUniform*ivARB
	 * @param NB template size of variable to set
	 * @param name name in shader
	 * @param pointer on data to copy
	 */
335
	template<unsigned int NB>
Sylvain Thery's avatar
Sylvain Thery committed
336
	void setuniformi( const char* name, const int* val);
337
338
339
340
341
342
343

	/**
	 * add search path for file
	 * @param path to add
	 */
	void addPathFileSeach(const std::string& path);

Sylvain Thery's avatar
Sylvain Thery committed
344
345
346
347
348
349
350
351
352
353
354
355
	/**
	 * remove VBO index from binding
	 */
	void unbindVBO(VBO* ptr);

	/**
	 * remove VBO index from binding
	 */
	void unbindVA(const std::string& name);

	/**
	 * associate an attribute name of shader with a vbo
356
	 * @return the index in vector of pair binding, negative if fail
Sylvain Thery's avatar
Sylvain Thery committed
357
	 */
358
359
360
361
362
363
	unsigned int bindVA_VBO(const std::string& name, VBO* vbo);

	/**
	 * change the vbo of id case of binding vector
	 */
	void changeVA_VBO(unsigned int id, VBO* vbo);
Sylvain Thery's avatar
Sylvain Thery committed
364
365
366
367

	/**
	 * get binding VA VBO
	 */
Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
368
	const std::vector<VAStr>& getVA_VBO_Bindings() { return m_va_vbo_binding; }
369

Sylvain Thery's avatar
Sylvain Thery committed
370
371
372
373
374
375
	void bindAttrib(unsigned int att, const char* name) const;

	/**
	 * update projection, modelview, ... matrices
	 */
	void updateMatrices(const glm::mat4& projection, const glm::mat4& modelview);
376
377
378
379
380

	/**
	 * bind, enable, and set all vertex attrib pointers
	 * @param stride: the stride parameter, number osf byte between two consecutive attributes
	 */
381
	void enableVertexAttribs(unsigned int stride=0, unsigned int begin=0) const;
382
383
384
385
386

	/**
	 * disenable all vertex attribs
	 */
	void disableVertexAttribs() const;
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402

	/// sent current matrices to all shaders
	static void updateCurrentMatrices();
	/// get current transformation matrix
	static glm::mat4& currentTransfo() { return s_current_matrices->m_matrices[2];}
	/// get current modelview matrix
	static glm::mat4& currentModelView() { return s_current_matrices->m_matrices[1];}
	/// get current projection matrix
	static glm::mat4& currentProjection() { return s_current_matrices->m_matrices[0];}

	/// push transformation matrix
	static void pushTransfo() {s_current_matrices->pushTransfo();}
	/// pop transformation matrix
	static void popTransfo() {s_current_matrices->popTransfo();}


403
404
405
406
407
408
409
410
411
412
413
414
};


////////// INLINE FUNCTIONS //////////


inline bool GLSLShader::isCreated()
{
	return ( m_program_object != 0 );
}

template<unsigned int NB>
Sylvain Thery's avatar
Sylvain Thery committed
415
void GLSLShader::setuniformf( const char* name, const float* val)
416
417
{
	GLint uni = glGetUniformLocationARB(m_program_object,name);
Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
418
	if (uni >= 0)
419
420
421
422
	{
		switch(NB)
		{
		case 1:
Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
423
			glUniform1fvARB(uni, 1, val) ;
424
425
			break;
		case 2:
Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
426
			glUniform2fvARB(uni, 1, val) ;
427
428
			break;
		case 3:
Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
429
			glUniform3fvARB(uni, 1, val) ;
430
431
			break;
		case 4:
Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
432
			glUniform4fvARB(uni, 1, val) ;
433
434
			break;
		case 16:
Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
435
			glUniformMatrix4fv(uni, 1, false, val);
436
437
438
			break;
		}
	}
439
}
440

441
template<unsigned int NB>
Sylvain Thery's avatar
Sylvain Thery committed
442
void GLSLShader::setuniformi( const char* name, const int* val)
443
444
445
{
	GLint uni = glGetUniformLocationARB(m_program_object,name);
	if (uni>=0)
446
447
448
449
	{
		switch(NB)
		{
		case 1:
Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
450
			glUniform1ivARB(uni, 1, val) ;
451
452
			break;
		case 2:
Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
453
			glUniform2ivARB(uni, 1, val) ;
454
455
			break;
		case 3:
Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
456
			glUniform3ivARB(uni, 1, val) ;
457
458
			break;
		case 4:
Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
459
			glUniform4ivARB(uni, 1, val) ;
460
461
462
			break;
		}
	}
Pierre Kraemer's avatar
Pierre Kraemer committed
463
464
}

465
} //namespace Utils
Pierre Kraemer's avatar
Pierre Kraemer committed
466

Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
467
} //namespace CGoGN
Pierre Kraemer's avatar
Pierre Kraemer committed
468

Sylvain Thery's avatar
Sylvain Thery committed
469
#endif