GLSLShader.h 9.4 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>
Pierre Kraemer's avatar
Pierre Kraemer committed
41 42 43 44 45 46 47

namespace CGoGN
{
namespace Utils
{


48
class GLSLShader
Pierre Kraemer's avatar
Pierre Kraemer committed
49 50
{

Sylvain Thery's avatar
Sylvain Thery committed
51

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

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


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

Sylvain Thery's avatar
Sylvain Thery committed
68 69
	static unsigned int CURRENT_OGL_VERSION;

Pierre Kraemer's avatar
Pierre Kraemer committed
70 71

protected:
Sylvain Thery's avatar
Sylvain Thery committed
72 73 74 75 76 77 78

	static std::string DEFINES_GL2;

	static std::string DEFINES_GL3;

	static std::string* DEFINES_GL;

79 80 81 82 83 84 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;

	/**
	 * handle of program
	 */
	GLhandleARB m_program_object;


Sylvain Thery's avatar
Sylvain Thery committed
100 101 102 103 104 105 106 107 108
	/**
	 * 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;

109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
	/**
	 * 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
126

127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155
	/**
	 * 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);

156

157 158 159 160 161 162
	/**
	 * 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
163 164

public:
165 166 167
	/**
	 * constructor
	 */
Pierre Kraemer's avatar
Pierre Kraemer committed
168 169 170
	GLSLShader();


171 172 173 174
	/**
	 * destructor
	 */
	virtual ~GLSLShader();
Pierre Kraemer's avatar
Pierre Kraemer committed
175

Sylvain Thery's avatar
Sylvain Thery committed
176 177 178 179

	static void setCurrentOGLVersion(unsigned int version);


180 181 182 183 184
	/*
	 * search file in different path
	 */
	static std::string findFile(const std::string filename);

185 186 187 188
	/**
	 * test support of shader
	 */
	static bool	areShadersSupported();
Pierre Kraemer's avatar
Pierre Kraemer committed
189

190 191 192 193 194 195 196 197 198
	/**
	 * test support of Vertex Buffer Object
	 */
	static bool	areVBOSupported();

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

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


206
	static bool init();
Pierre Kraemer's avatar
Pierre Kraemer committed
207 208


209 210 211 212 213 214 215 216 217
	/**
	 * 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
218 219 220
	 * @param vs vertex shader source file name
	 * @param fs fragment shader source file name
	 * @param gs geometry shader source file name
221 222 223 224
	 * @param inputGeometryPrimitive primitives used in geometry shader as input
	 * @param outputGeometryPrimitive primitives generated in geometry shader as output
	 */
	bool loadShaders(const std::string& vs, const std::string& fs, const std::string& gs, GLint inputGeometryPrimitive=GL_TRIANGLES,GLint outputGeometryPrimitive=GL_TRIANGLES);
Pierre Kraemer's avatar
Pierre Kraemer committed
225 226


Sylvain Thery's avatar
Sylvain Thery committed
227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246
	/**
	 * 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);


247 248 249 250 251
	/**
	 * Link the shader do it just after binding the attributes
	 */
	bool link();

Sylvain Thery's avatar
Sylvain Thery committed
252 253


Pierre Kraemer's avatar
Pierre Kraemer committed
254
	inline bool		isCreated();
255

Pierre Kraemer's avatar
Pierre Kraemer committed
256 257 258
	bool			isBinded();

	virtual bool	bind();
259

Pierre Kraemer's avatar
Pierre Kraemer committed
260 261 262
	virtual void	unbind();


263 264 265
	/**
	 *
	 */
Sylvain Thery's avatar
Sylvain Thery committed
266
//	GLuint 	getAttribIndex( char* attribName );
Pierre Kraemer's avatar
Pierre Kraemer committed
267 268

	
269 270 271 272
	/**
	 * get handler of program for external use og gl functions
	 */
	GLuint program_handler() { return m_program_object;}
Pierre Kraemer's avatar
Pierre Kraemer committed
273 274 275
	


276

277 278 279
	/**
	 * check shader validity width official GLSL syntax
	 */
280 281
	bool validateProgram();

282 283 284
	/**
	 * check program link status
	 */
285 286
	bool checkProgram();

287 288 289
	/**
	 * check shader compile status
	 */
290 291
	bool checkShader(int shaderType);

Pierre Kraemer's avatar
Pierre Kraemer committed
292
public:
293

294 295 296 297 298 299 300
	/**
	 * 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
	 */
301
	template<unsigned int NB>
Sylvain Thery's avatar
Sylvain Thery committed
302
	void setuniformf( const char* name, const float* val);
303

304 305 306 307 308 309 310
	/**
	 * 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
	 */
311
	template<unsigned int NB>
Sylvain Thery's avatar
Sylvain Thery committed
312
	void setuniformi( const char* name, const int* val);
313 314 315 316 317 318 319

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

Sylvain Thery's avatar
Sylvain Thery committed
320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346
	/**
	 * 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
	 */
	void bindVA_VBO(const std::string& name, VBO& vbo);

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


	void bindAttrib(unsigned int att, const char* name) const;

	/**
	 * update projection, modelview, ... matrices
	 */
	void updateMatrices(const glm::mat4& projection, const glm::mat4& modelview);
347 348 349 350 351 352 353 354 355 356 357 358
};


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


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

template<unsigned int NB>
Sylvain Thery's avatar
Sylvain Thery committed
359
void GLSLShader::setuniformf( const char* name, const float* val)
360 361 362
{
	GLint uni = glGetUniformLocationARB(m_program_object,name);
	if (uni>=0)
363 364 365 366 367 368 369
	{
		switch(NB)
		{
		case 1:
			glUniform1fvARB( uni, 1, val) ;
			break;
		case 2:
370
			glUniform2fvARB( uni, 1, val) ;
371 372
			break;
		case 3:
373
			glUniform3fvARB( uni, 1, val) ;
374 375
			break;
		case 4:
376 377 378 379
			glUniform4fvARB( uni, 1, val) ;
			break;
		case 16:
			glUniformMatrix4fv(uni, 1 , false, val);
380 381 382
			break;
		}
	}
383
}
384

385
template<unsigned int NB>
Sylvain Thery's avatar
Sylvain Thery committed
386
void GLSLShader::setuniformi( const char* name, const int* val)
387 388 389
{
	GLint uni = glGetUniformLocationARB(m_program_object,name);
	if (uni>=0)
390 391 392 393 394 395 396
	{
		switch(NB)
		{
		case 1:
			glUniform1ivARB( uni, 1, val) ;
			break;
		case 2:
397
			glUniform2ivARB( uni, 1, val) ;
398 399
			break;
		case 3:
400
			glUniform3ivARB( uni, 1, val) ;
401 402
			break;
		case 4:
403
			glUniform4ivARB( uni, 1, val) ;
404 405 406
			break;
		}
	}
Pierre Kraemer's avatar
Pierre Kraemer committed
407 408 409 410
}



411 412


413

414
} //namespace Utils
Pierre Kraemer's avatar
Pierre Kraemer committed
415 416 417 418 419
} //namespace CGoGN




Sylvain Thery's avatar
Sylvain Thery committed
420
#endif