GLSLShader.h 11.2 KB
Newer Older
Pierre Kraemer's avatar
Pierre Kraemer committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
/*******************************************************************************
* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps  *
* version 0.1                                                                  *
* Copyright (C) 2009, IGG Team, LSIIT, University of Strasbourg                *
*                                                                              *
* 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.           *
*                                                                              *
* Web site: https://iggservis.u-strasbg.fr/CGoGN/                              *
* 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"
Pierre Kraemer's avatar
Pierre Kraemer committed
34

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

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

Pierre Kraemer's avatar
Pierre Kraemer committed
43 44 45 46 47 48 49

namespace CGoGN
{
namespace Utils
{


50
class GLSLShader
Pierre Kraemer's avatar
Pierre Kraemer committed
51 52
{

Sylvain Thery's avatar
Sylvain Thery committed
53

54
public:
Sylvain Thery's avatar
Sylvain Thery committed
55 56 57 58 59 60 61 62 63 64

	struct VAStr
	{
		int va_id;
		VBO* vbo_ptr;
//		GLuint vbo_id;
//		unsigned int size;
	};


65 66 67 68
	/**
	 * enum of supported shader type
	 */
	enum shaderType {VERTEX_SHADER = 1, FRAGMENT_SHADER = 2, GEOMETRY_SHADER = 3 };
Pierre Kraemer's avatar
Pierre Kraemer committed
69

Sylvain Thery's avatar
Sylvain Thery committed
70 71
	static unsigned int CURRENT_OGL_VERSION;

72
	static std::set< std::pair<void*, GLSLShader*> > m_registredRunning;
Pierre Kraemer's avatar
Pierre Kraemer committed
73 74

protected:
Sylvain Thery's avatar
Sylvain Thery committed
75 76 77 78 79 80 81

	static std::string DEFINES_GL2;

	static std::string DEFINES_GL3;

	static std::string* DEFINES_GL;

82 83 84
	static std::string defines_Geom(const std::string& primitivesIn, const std::string& primitivesOut, int maxVert);


85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
	/**
	 * 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
100 101 102 103
	std::string m_nameVS;
	std::string m_nameFS;
	std::string m_nameGS;

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


110 111 112 113 114 115 116 117 118 119 120 121 122 123
	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
124 125 126 127 128 129 130 131 132
	/**
	 * 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;

133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
	/**
	 * 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
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 179
	/**
	 * 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);

180

181 182 183 184 185 186
	/**
	 * 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
187 188

public:
189 190 191
	/**
	 * constructor
	 */
Pierre Kraemer's avatar
Pierre Kraemer committed
192 193 194
	GLSLShader();


195 196 197 198
	/**
	 * destructor
	 */
	virtual ~GLSLShader();
Pierre Kraemer's avatar
Pierre Kraemer committed
199

Sylvain Thery's avatar
Sylvain Thery committed
200 201 202 203

	static void setCurrentOGLVersion(unsigned int version);


204 205 206 207 208
	/*
	 * search file in different path
	 */
	static std::string findFile(const std::string filename);

209 210 211 212
	/**
	 * test support of shader
	 */
	static bool	areShadersSupported();
Pierre Kraemer's avatar
Pierre Kraemer committed
213

214 215 216 217 218 219 220 221 222
	/**
	 * test support of Vertex Buffer Object
	 */
	static bool	areVBOSupported();

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

224 225 226 227
	/**
	 * test support of gl3
	 */
	static bool	isGL3Supported();
Pierre Kraemer's avatar
Pierre Kraemer committed
228 229


230
	static bool init();
Pierre Kraemer's avatar
Pierre Kraemer committed
231 232


233 234 235 236 237 238
	static void registerRunning(GLSLShader* ptr);

	static void unregisterRunning(GLSLShader* ptr);
//
//	static void updateMatricesRunningShaders(const glm::mat4& projection, const glm::mat4& modelview);

239 240 241 242 243 244 245 246 247
	/**
	 * 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
248 249 250
	 * @param vs vertex shader source file name
	 * @param fs fragment shader source file name
	 * @param gs geometry shader source file name
251 252 253
	 * @param inputGeometryPrimitive primitives used in geometry shader as input
	 * @param outputGeometryPrimitive primitives generated in geometry shader as output
	 */
254
	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
255 256


Sylvain Thery's avatar
Sylvain Thery committed
257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276
	/**
	 * 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);


277 278 279 280 281 282 283 284 285 286 287 288 289
	const char* getVertexShaderSrc() {return m_vertex_shader_source;}
	const char* getFragmentShaderSrc() {return m_fragment_shader_source;}
	const char* getGeometryShaderSrc() {return m_geom_shader_source;}


	bool reloadVertexShaderFromMemory(const char* vs);

	bool reloadFragmentShaderFromMemory(const char* fs);

	bool reloadGeometryShaderFromMemory(const char* gs);

	bool recompile();

290 291 292 293 294
	/**
	 * Link the shader do it just after binding the attributes
	 */
	bool link();

Sylvain Thery's avatar
Sylvain Thery committed
295 296


Pierre Kraemer's avatar
Pierre Kraemer committed
297
	inline bool		isCreated();
298

Pierre Kraemer's avatar
Pierre Kraemer committed
299 300
	bool			isBinded();

301 302 303
	virtual bool	bind() const;

	virtual void	unbind() const;
304

305 306 307 308
	/**
	 * restore all uniforms and vertex attributes after recompiling
	 */
	virtual void restoreUniformsAttribs() {std::cerr << "Warning restoreUniformsAttribs not implemented"<< std::endl;}
Pierre Kraemer's avatar
Pierre Kraemer committed
309 310


311 312 313
	/**
	 *
	 */
Sylvain Thery's avatar
Sylvain Thery committed
314
//	GLuint 	getAttribIndex( char* attribName );
Pierre Kraemer's avatar
Pierre Kraemer committed
315 316

	
317 318 319 320
	/**
	 * get handler of program for external use og gl functions
	 */
	GLuint program_handler() { return m_program_object;}
Pierre Kraemer's avatar
Pierre Kraemer committed
321 322 323
	


324

325 326 327
	/**
	 * check shader validity width official GLSL syntax
	 */
328 329
	bool validateProgram();

330 331 332
	/**
	 * check program link status
	 */
333 334
	bool checkProgram();

335 336 337
	/**
	 * check shader compile status
	 */
338 339
	bool checkShader(int shaderType);

Pierre Kraemer's avatar
Pierre Kraemer committed
340
public:
341

342 343 344 345 346 347 348
	/**
	 * 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
	 */
349
	template<unsigned int NB>
Sylvain Thery's avatar
Sylvain Thery committed
350
	void setuniformf( const char* name, const float* val);
351

352 353 354 355 356 357 358
	/**
	 * 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
	 */
359
	template<unsigned int NB>
Sylvain Thery's avatar
Sylvain Thery committed
360
	void setuniformi( const char* name, const int* val);
361 362 363 364 365 366 367

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

Sylvain Thery's avatar
Sylvain Thery committed
368 369 370 371 372 373 374 375 376 377 378 379
	/**
	 * 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
380
	 * @return the index in vector of pair binding, negative if fail
Sylvain Thery's avatar
Sylvain Thery committed
381
	 */
382 383 384 385 386 387
	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
388 389 390 391 392 393 394

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


395 396


Sylvain Thery's avatar
Sylvain Thery committed
397 398 399 400 401 402
	void bindAttrib(unsigned int att, const char* name) const;

	/**
	 * update projection, modelview, ... matrices
	 */
	void updateMatrices(const glm::mat4& projection, const glm::mat4& modelview);
403 404 405 406 407 408 409 410 411 412 413

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

	/**
	 * disenable all vertex attribs
	 */
	void disableVertexAttribs() const;
414 415 416 417 418 419 420 421 422 423 424 425
};


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


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

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

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



478 479


480

481
} //namespace Utils
Pierre Kraemer's avatar
Pierre Kraemer committed
482 483 484 485 486
} //namespace CGoGN




Sylvain Thery's avatar
Sylvain Thery committed
487
#endif