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 12.6 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
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/gl_def.h"
Pierre Kraemer's avatar
Pierre Kraemer committed
33
#include "Utils/os_spec.h"
Sylvain Thery's avatar
Sylvain Thery committed
34
#include "Utils/vbo.h"
35
#include "Utils/gl_matrices.h"
Pierre Kraemer's avatar
Pierre Kraemer committed
36

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

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

45

Pierre Kraemer's avatar
Pierre Kraemer committed
46
47
namespace CGoGN
{
Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
48

Pierre Kraemer's avatar
Pierre Kraemer committed
49
50
51
namespace Utils
{

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

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

Sylvain Thery's avatar
Sylvain Thery committed
82
83
84
	int m_nbMaxVertices;


85
86
87
	/**
	 * handle of vertex shader
	 */
88
	CGoGNGLhandleARB	m_vertex_shader_object;
89
90
91
92

	/**
	 * handle of fragment shader
	 */
93
	CGoGNGLhandleARB	m_fragment_shader_object;
94
95
96
97

	/**
	 * handle of geometry shader
	 */
98
	CGoGNGLhandleARB	m_geom_shader_object;
99

Sylvain Thery's avatar
Sylvain Thery committed
100
101
102
103
	std::string m_nameVS;
	std::string m_nameFS;
	std::string m_nameGS;

104
105
106
	/**
	 * handle of program
	 */
107
	CGoGNGLhandleARB m_program_object;
108

109
110
111
112
	CGoGNGLint m_uniMat_Proj;
	CGoGNGLint m_uniMat_Model;
	CGoGNGLint m_uniMat_ModelProj;
	CGoGNGLint m_uniMat_Normal;
113
114
115
116
117
118
119
120

	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
121
122
123
124
125
126
127
	/**
	 * a set of pair VA_id / VBO_id
	 */
	std::vector<VAStr> m_va_vbo_binding;

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

128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
	/**
	 * 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
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
	/**
	 * 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)
	 */
Sylvain Thery's avatar
Sylvain Thery committed
173
	bool create(GLint inputGeometryPrimitive=GL_TRIANGLES,GLint outputGeometryPrimitive=GL_TRIANGLES, int nb_max_vertices=-1);
174
175
176
177
178
179
180

	/**
	 * 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
181
182

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

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

Sylvain Thery's avatar
Sylvain Thery committed
193
194
	static void setCurrentOGLVersion(unsigned int version);

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

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

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

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

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

220
	static bool init();
Pierre Kraemer's avatar
Pierre Kraemer committed
221

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

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

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

228
229
230
231
232
233
234
235
236
	/**
	 * 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
237
238
239
	 * @param vs vertex shader source file name
	 * @param fs fragment shader source file name
	 * @param gs geometry shader source file name
240
241
242
	 * @param inputGeometryPrimitive primitives used in geometry shader as input
	 * @param outputGeometryPrimitive primitives generated in geometry shader as output
	 */
Sylvain Thery's avatar
Sylvain Thery committed
243
	bool loadShaders(const std::string& vs, const std::string& fs, const std::string& gs, GLint inputGeometryPrimitive=GL_TRIANGLES,GLint outputGeometryPrimitive=GL_TRIANGLE_STRIP, int nb_max_vertices=16);
Pierre Kraemer's avatar
Pierre Kraemer committed
244

Sylvain Thery's avatar
Sylvain Thery committed
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
	 */
Sylvain Thery's avatar
Sylvain Thery committed
262
	bool loadShadersFromMemory(const char* vs, const char* fs, const char* gs, GLint inputGeometryPrimitive,GLint outputGeometryPrimitive, int nb_max_vertices=16);
Sylvain Thery's avatar
Sylvain Thery committed
263

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

	bool reloadVertexShaderFromMemory(const char* vs);

	bool reloadFragmentShaderFromMemory(const char* fs);

	bool reloadGeometryShaderFromMemory(const char* gs);

	bool recompile();

Sylvain Thery's avatar
Sylvain Thery committed
276
277
	bool changeNbMaxVertices(int nb_max_vertices);

278
279
280
281
282
	/**
	 * Link the shader do it just after binding the attributes
	 */
	bool link();

Pierre Kraemer's avatar
Pierre Kraemer committed
283
	inline bool		isCreated();
284

Pierre Kraemer's avatar
Pierre Kraemer committed
285
286
	bool			isBinded();

287
288
289
	virtual bool	bind() const;

	virtual void	unbind() const;
290

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

296
297
	virtual void updateClippingUniforms() {CGoGNerr << "Warning updateClippingUniforms not implemented"<< CGoGNendl;}

298
299
300
	/**
	 *
	 */
Sylvain Thery's avatar
Sylvain Thery committed
301
//	GLuint 	getAttribIndex( char* attribName );
Pierre Kraemer's avatar
Pierre Kraemer committed
302
	
303
304
305
	/**
	 * get handler of program for external use og gl functions
	 */
306
	GLhandleARB program_handler() { return *m_program_object;}
307

308
309
310
	/**
	 * check shader validity width official GLSL syntax
	 */
311
312
	bool validateProgram();

313
314
315
	/**
	 * check program link status
	 */
316
317
	bool checkProgram();

318
319
320
	/**
	 * check shader compile status
	 */
321
322
	bool checkShader(int shaderType);

Pierre Kraemer's avatar
Pierre Kraemer committed
323
public:
324
325
326
327
328
329
330
	/**
	 * 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
	 */
331
	template<unsigned int NB>
Sylvain Thery's avatar
Sylvain Thery committed
332
	void setuniformf( const char* name, const float* val);
333

334
335
336
337
338
339
340
	/**
	 * 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
	 */
341
	template<unsigned int NB>
Sylvain Thery's avatar
Sylvain Thery committed
342
	void setuniformi( const char* name, const int* val);
343
344
345
346
347
348
349

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

Sylvain Thery's avatar
Sylvain Thery committed
350
351
352
353
354
355
356
	/**
	 * remove VBO index from binding
	 */
	void unbindVA(const std::string& name);

	/**
	 * associate an attribute name of shader with a vbo
357
	 * @return the index in vector of pair binding, negative if fail
Sylvain Thery's avatar
Sylvain Thery committed
358
	 */
359
360
361
362
363
364
	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
365
366
367
368

	/**
	 * get binding VA VBO
	 */
369
//	const std::vector<VAStr>& getVA_VBO_Bindings() { return m_va_vbo_binding; }
370

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

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

Sylvain Thery's avatar
Sylvain Thery committed
378
379
380
381
382
383
	/**
	 * update projection, modelview, ... matrices
	 */
	void updateMatrices(const glm::mat4& projection, const glm::mat4& modelview, const glm::mat4& PMV, const glm::mat4& normalMatrix);


384
385
386
387
	/**
	 * bind, enable, and set all vertex attrib pointers
	 * @param stride: the stride parameter, number osf byte between two consecutive attributes
	 */
388
	void enableVertexAttribs(unsigned int stride = 0, unsigned int begin = 0) const;
389
390
391
392
393

	/**
	 * disenable all vertex attribs
	 */
	void disableVertexAttribs() const;
394

395
396
397
	/// get back OpenGL standard matrices & send to all shaders
	static void updateAllFromGLMatrices();

398
399
	/// sent current matrices to all shaders
	static void updateCurrentMatrices();
Sylvain Thery's avatar
Sylvain Thery committed
400
401
402
403
404


	static glm::mat4& currentNormalMatrix() { return s_current_matrices->m_matrices[4];}
	static glm::mat4& currentPMV() { return s_current_matrices->m_matrices[3];}

405
406
407
408
409
410
411
412
413
414
415
	/// 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();}
416
417
	// apply a transformation given by its matrix
	static void applyTransfo(const glm::mat4& m) { s_current_matrices->apply(m);}
418
419
420
421
422
423
424
425
};


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


inline bool GLSLShader::isCreated()
{
426
	return ( *m_program_object != 0 );
427
428
429
}

template<unsigned int NB>
Sylvain Thery's avatar
Sylvain Thery committed
430
void GLSLShader::setuniformf( const char* name, const float* val)
431
{
432
	GLint uni = glGetUniformLocationARB(*m_program_object,name);
Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
433
	if (uni >= 0)
434
435
436
437
	{
		switch(NB)
		{
		case 1:
Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
438
			glUniform1fvARB(uni, 1, val) ;
439
440
			break;
		case 2:
Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
441
			glUniform2fvARB(uni, 1, val) ;
442
443
			break;
		case 3:
Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
444
			glUniform3fvARB(uni, 1, val) ;
445
446
			break;
		case 4:
Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
447
			glUniform4fvARB(uni, 1, val) ;
448
449
			break;
		case 16:
Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
450
			glUniformMatrix4fv(uni, 1, false, val);
451
452
453
			break;
		}
	}
454
}
455

456
template<unsigned int NB>
Sylvain Thery's avatar
Sylvain Thery committed
457
void GLSLShader::setuniformi( const char* name, const int* val)
458
{
459
	GLint uni = glGetUniformLocationARB(*m_program_object,name);
460
	if (uni>=0)
461
462
463
464
	{
		switch(NB)
		{
		case 1:
Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
465
			glUniform1ivARB(uni, 1, val) ;
466
467
			break;
		case 2:
Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
468
			glUniform2ivARB(uni, 1, val) ;
469
470
			break;
		case 3:
Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
471
			glUniform3ivARB(uni, 1, val) ;
472
473
			break;
		case 4:
Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
474
			glUniform4ivARB(uni, 1, val) ;
475
476
477
			break;
		}
	}
Pierre Kraemer's avatar
Pierre Kraemer committed
478
479
}

480
} //namespace Utils
Pierre Kraemer's avatar
Pierre Kraemer committed
481

Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
482
} //namespace CGoGN
Pierre Kraemer's avatar
Pierre Kraemer committed
483

Sylvain Thery's avatar
Sylvain Thery committed
484
#endif