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

Pierre Kraemer's avatar
Pierre Kraemer committed
25
26
27
28
29
#define EXPORTING 1

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

Sylvain Thery's avatar
Sylvain Thery committed
33
34
#include "glm/gtx/inverse_transpose.hpp"

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

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

unsigned int GLSLShader::CURRENT_OGL_VERSION = 2;
Sylvain Thery's avatar
Sylvain Thery committed
42
43
44

std::string GLSLShader::DEFINES_GL2=\
"#version 110\n"
45
"#define PRECISON float pipo_PRECISION\n"
Sylvain Thery's avatar
Sylvain Thery committed
46
47
48
"#define ATTRIBUTE attribute\n"
"#define VARYING_VERT varying\n"
"#define VARYING_FRAG varying\n"
49
50
"#define FRAG_OUT_DEF float pipo_FRAGDEF\n"
"#define INVARIANT_POS float pipo_INVARIANT\n";
Sylvain Thery's avatar
Sylvain Thery committed
51

Pierre Kraemer's avatar
Pierre Kraemer committed
52

Sylvain Thery's avatar
Sylvain Thery committed
53
std::string GLSLShader::DEFINES_GL3=\
54
"#version 150\n"
55
"#define PRECISON precision highp float\n"
Sylvain Thery's avatar
Sylvain Thery committed
56
57
58
59
"#define ATTRIBUTE in\n"
"#define VARYING_VERT smooth out\n"
"#define VARYING_FRAG smooth in\n"
"#define FRAG_OUT_DEF out vec4 gl_FragColor\n"
60
"#define INVARIANT_POS invariant gl_Position\n";
Sylvain Thery's avatar
Sylvain Thery committed
61

Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
62
63

std::string* GLSLShader::DEFINES_GL = NULL;
64
65
66

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

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


70
71
72
//glm::mat4* GLSLShader::s_current_matrices=NULL;
Utils::GL_Matrices* GLSLShader::s_current_matrices=NULL;

Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
73
74
75
76
77
78
79
80
81
82
83
84
GLSLShader::GLSLShader() :
	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),
	m_vertex_shader_source(NULL),
	m_fragment_shader_source(NULL),
	m_geom_shader_source(NULL)
Pierre Kraemer's avatar
Pierre Kraemer committed
85
{
Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
86
	if (DEFINES_GL == NULL)
87
		DEFINES_GL = &DEFINES_GL2;
Pierre Kraemer's avatar
Pierre Kraemer committed
88
89
}

Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
90
void GLSLShader::registerShader(void* ptr, GLSLShader* shader)
91
{
Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
92
	m_registeredShaders.insert(std::pair<void*,GLSLShader*>(ptr, shader));
93
94
}

Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
95
void GLSLShader::unregisterShader(void* ptr, GLSLShader* shader)
96
{
Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
97
	m_registeredShaders.erase(std::pair<void*,GLSLShader*>(ptr, shader));
98
99
100
101
}

std::string GLSLShader::defines_Geom(const std::string& primitivesIn, const std::string& primitivesOut, int maxVert)
{
Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
102
	if (CURRENT_OGL_VERSION == 3)
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
	{
		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");
		str.append("#define VARYING_IN in\n");
		str.append("#define VARYING_OUT smooth out\n");
		str.append("#define POSITION_IN(X) gl_in[X].gl_Position\n");
120
		str.append("#define NBVERTS_IN gl_in.length()\n");
121
122
123
124
		return str;
	}
	else
	{
Sylvain Thery's avatar
Sylvain Thery committed
125
126
127
		std::string str("#version 110\n");
		str.append("#extension GL_EXT_geometry_shader4 : enable\n");
		str.append("#define PRECISON float pipo_PRECISION\n");
128
129
130
131
		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");
132
		str.append("#define NBVERTS_IN gl_VerticesIn\n");
133
134
135
136
		return str;
	}
}

Pierre Kraemer's avatar
Pierre Kraemer committed
137
138
bool GLSLShader::areGeometryShadersSupported()
{
Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
139
140
	if (!glewGetExtension("GL_EXT_geometry_shader4"))
		return false;
Pierre Kraemer's avatar
Pierre Kraemer committed
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
	return true;
}

bool GLSLShader::areShadersSupported()
{
	if ( ! glewGetExtension("GL_ARB_vertex_shader")) return false;
	if ( ! glewGetExtension("GL_ARB_fragment_shader")) return false;
	if ( ! glewGetExtension("GL_ARB_shader_objects")) return false;
	if ( ! glewGetExtension("GL_ARB_shading_language_100")) return false;

	return true;
}

bool GLSLShader::areVBOSupported()
{
	if (!glewGetExtension("GL_ARB_vertex_buffer_object"))
		return false;
	return true;
}

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

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

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

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

208
209
	if (m_vertex_shader_source)
		delete [] m_vertex_shader_source;
Pierre Kraemer's avatar
Pierre Kraemer committed
210

211
	m_vertex_shader_source = loadSourceFile( filename );
Pierre Kraemer's avatar
Pierre Kraemer committed
212

213
	if( !m_vertex_shader_source )
Pierre Kraemer's avatar
Pierre Kraemer committed
214
	{
215
		CGoGNerr << "ERROR - GLSLShader::loadVertexShader() - error occured while loading source file." << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
216
217
218
219
		return false;
	}


220
221
	flag = loadVertexShaderSourceString( m_vertex_shader_source );
//	delete [] vertex_shader_source;
Pierre Kraemer's avatar
Pierre Kraemer committed
222
223
224
225

	return flag;
}

226
bool GLSLShader::loadFragmentShader(const std::string& filename )
Pierre Kraemer's avatar
Pierre Kraemer committed
227
228
{
	bool	flag;
229
//	char	*fragment_shader_source;
Pierre Kraemer's avatar
Pierre Kraemer committed
230

231
232
	if (m_fragment_shader_source)
		delete [] m_fragment_shader_source;
Pierre Kraemer's avatar
Pierre Kraemer committed
233

234
	m_fragment_shader_source = loadSourceFile( filename );
Pierre Kraemer's avatar
Pierre Kraemer committed
235

236
	if( !m_fragment_shader_source )
Pierre Kraemer's avatar
Pierre Kraemer committed
237
	{
238
		CGoGNerr << "ERROR - GLSLShader::loadFragmentShader() - error occured while loading source file." << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
239
240
241
		return false;
	}

242
243
	flag = loadFragmentShaderSourceString( m_fragment_shader_source );
//	delete [] fragment_shader_source;
Pierre Kraemer's avatar
Pierre Kraemer committed
244
245
246
247
248
249
250
251


	return flag;
}

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

254
255
	if (m_geom_shader_source)
		delete [] m_geom_shader_source;
Pierre Kraemer's avatar
Pierre Kraemer committed
256

257
	m_geom_shader_source = loadSourceFile( filename );
Pierre Kraemer's avatar
Pierre Kraemer committed
258

259
	if( !m_geom_shader_source )
Pierre Kraemer's avatar
Pierre Kraemer committed
260
	{
261
		CGoGNerr << "ERROR - GLSLShader::loadGeometryShader() - error occured while loading source file." << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
262
263
264
		return false;
	}

265
266
	flag = loadGeometryShaderSourceString( m_geom_shader_source );
//	delete [] geom_shader_source;
Pierre Kraemer's avatar
Pierre Kraemer committed
267
268
269
270
271
272
273
274
275

	return flag;
}

bool GLSLShader::loadVertexShaderSourceString( const char *vertex_shader_source )
{
	int		status;
	char	*info_log;

Sylvain Thery's avatar
Sylvain Thery committed
276
277
278
279
280
	if (m_vertex_shader_object==0)
	{
		glDeleteShader(m_vertex_shader_object);
		m_vertex_shader_object=0;
	}
Pierre Kraemer's avatar
Pierre Kraemer committed
281
282

	/*** create shader object ***/
Sylvain Thery's avatar
Sylvain Thery committed
283
	m_vertex_shader_object = glCreateShader( GL_VERTEX_SHADER );
Pierre Kraemer's avatar
Pierre Kraemer committed
284

285
	if( !m_vertex_shader_object )
Pierre Kraemer's avatar
Pierre Kraemer committed
286
	{
287
		CGoGNerr << "ERROR - GLSLShader::loadVertexShader() - unable to create shader object." << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
288
289
290
291
292
293
		return false;
	}

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

296
297
		glDeleteObjectARB( m_vertex_shader_object );
		m_vertex_shader_object = 0;
Pierre Kraemer's avatar
Pierre Kraemer committed
298
299
300
301

		return false;
	}

302
	glShaderSourceARB( m_vertex_shader_object, 1, (const char**)&vertex_shader_source, NULL );
Pierre Kraemer's avatar
Pierre Kraemer committed
303
304

	/*** compile shader object ***/
305
	glCompileShaderARB( m_vertex_shader_object );
Pierre Kraemer's avatar
Pierre Kraemer committed
306

307
	glGetObjectParameterivARB( m_vertex_shader_object, GL_OBJECT_COMPILE_STATUS_ARB, &status );
Pierre Kraemer's avatar
Pierre Kraemer committed
308
309
	if( !status )
	{
310
		CGoGNerr << "ERROR - GLshader::loadVertexShader() - error occured while compiling shader " << m_nameVS<< CGoGNendl;
311
		info_log = getInfoLog( m_vertex_shader_object );
312
				CGoGNerr << info_log << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
313
314
		delete [] info_log;

315
316
		glDeleteObjectARB( m_vertex_shader_object );
		m_vertex_shader_object = 0;
Pierre Kraemer's avatar
Pierre Kraemer committed
317
318
319
320
321
322
323
324

		return false;
	}

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

325
bool GLSLShader::loadFragmentShaderSourceString( const char *fragment_shader_source )
Pierre Kraemer's avatar
Pierre Kraemer committed
326
327
328
329
{
	int		status;
	char	*info_log;

Sylvain Thery's avatar
Sylvain Thery committed
330
331
332
333
334
	if (m_fragment_shader_object==0)
	{
		glDeleteShader(m_fragment_shader_object);
		m_fragment_shader_object=0;
	}
Pierre Kraemer's avatar
Pierre Kraemer committed
335
336

	/*** create shader object ***/
Sylvain Thery's avatar
Sylvain Thery committed
337
	m_fragment_shader_object = glCreateShader( GL_FRAGMENT_SHADER );
Pierre Kraemer's avatar
Pierre Kraemer committed
338

339
	if( !m_fragment_shader_object )
Pierre Kraemer's avatar
Pierre Kraemer committed
340
	{
341
		CGoGNerr << "ERROR - GLSLShader::loadFragmentShader() - unable to create shader object." << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
342
343
344
345
		return false;
	}

	/*** load source file ***/
346
	if( !fragment_shader_source )
Pierre Kraemer's avatar
Pierre Kraemer committed
347
	{
348
		CGoGNerr << "ERROR - GLSLShader::loadFragmentShader() - source string is empty." << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
349

350
351
		glDeleteObjectARB( m_fragment_shader_object );
		m_fragment_shader_object = 0;
Pierre Kraemer's avatar
Pierre Kraemer committed
352
353
354
355

		return false;
	}

356
	glShaderSourceARB( m_fragment_shader_object, 1, (const char**)&fragment_shader_source, NULL );
Pierre Kraemer's avatar
Pierre Kraemer committed
357
358

	/*** compile shader object ***/
359
	glCompileShaderARB( m_fragment_shader_object );
Pierre Kraemer's avatar
Pierre Kraemer committed
360

361
	glGetObjectParameterivARB( m_fragment_shader_object, GL_OBJECT_COMPILE_STATUS_ARB, &status );
Pierre Kraemer's avatar
Pierre Kraemer committed
362
363
	if( !status )
	{
364
		CGoGNerr << "ERROR - GLshader::loadFragmentShader() - error occured while compiling shader " <<  m_nameFS << CGoGNendl;
365
		info_log = getInfoLog( m_fragment_shader_object );
366
		CGoGNerr << info_log << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
367
368
		delete [] info_log;

369
370
		glDeleteObjectARB( m_fragment_shader_object );
		m_fragment_shader_object = 0;
Pierre Kraemer's avatar
Pierre Kraemer committed
371
372
373
374
375
376
377
378
379
380
381
382
383

		return false;
	}

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

bool GLSLShader::loadGeometryShaderSourceString( const char *geom_shader_source )
{
	int		status;
	char	*info_log;

Sylvain Thery's avatar
Sylvain Thery committed
384
385
386
387
388
	if (m_geom_shader_object==0)
	{
		glDeleteShader(m_geom_shader_object);
		m_geom_shader_object=0;
	}
Pierre Kraemer's avatar
Pierre Kraemer committed
389
	/*** create shader object ***/
390
	m_geom_shader_object = glCreateShader(GL_GEOMETRY_SHADER_EXT);
Pierre Kraemer's avatar
Pierre Kraemer committed
391

392
	if( !m_geom_shader_object )
Pierre Kraemer's avatar
Pierre Kraemer committed
393
	{
394
		CGoGNerr << "ERROR - GLSLShader::loadGeometryShader() - unable to create shader object." << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
395
396
397
398
399
400
		return false;
	}

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

403
404
		glDeleteObjectARB( m_geom_shader_object );
		m_geom_shader_object = 0;
Pierre Kraemer's avatar
Pierre Kraemer committed
405
406
407
408

		return false;
	}

409
	glShaderSourceARB( m_geom_shader_object, 1, (const char**)&geom_shader_source, NULL );
Pierre Kraemer's avatar
Pierre Kraemer committed
410
411

	/*** compile shader object ***/
412
	glCompileShaderARB( m_geom_shader_object );
Pierre Kraemer's avatar
Pierre Kraemer committed
413

414
	glGetObjectParameterivARB( m_geom_shader_object, GL_OBJECT_COMPILE_STATUS_ARB, &status );
Pierre Kraemer's avatar
Pierre Kraemer committed
415
416
	if( !status )
	{
417
		CGoGNerr << "ERROR - GLshader::loadGeometryShader() - error occured while compiling shader "<< m_nameGS << CGoGNendl;
418
		info_log = getInfoLog( m_geom_shader_object );
419
		CGoGNerr << info_log << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
420
421
		delete [] info_log;

422
423
		glDeleteObjectARB( m_geom_shader_object );
		m_geom_shader_object = 0;
Pierre Kraemer's avatar
Pierre Kraemer committed
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445

		return false;
	}

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

char* GLSLShader::getInfoLog( GLhandleARB obj )
{
	char	*info_log;
	int		info_log_length;
	int		length;

	glGetObjectParameterivARB( obj, GL_OBJECT_INFO_LOG_LENGTH_ARB, &info_log_length );

	info_log = new char [info_log_length];
	glGetInfoLogARB( obj, info_log_length, &length, info_log );

	return info_log;
}

Sylvain Thery's avatar
Sylvain Thery committed
446
bool GLSLShader::create(GLint inputGeometryPrimitive,GLint outputGeometryPrimitive, int nb_max_vertices)
Pierre Kraemer's avatar
Pierre Kraemer committed
447
448
449
450
{
	int		status;
	char	*info_log;

451
452
	m_geom_inputPrimitives = inputGeometryPrimitive;
	m_geom_outputPrimitives = outputGeometryPrimitive;
Pierre Kraemer's avatar
Pierre Kraemer committed
453
454

	/*** check if shaders are loaded ***/
455
	if( !m_vertex_shader_object || !m_fragment_shader_object )
Pierre Kraemer's avatar
Pierre Kraemer committed
456
	{
457
		CGoGNerr << "ERROR - GLSLShader::create() - shaders are not defined." << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
458
459
460
461
		return false;
	}

	/*** create program object ***/
462
	m_program_object = glCreateProgramObjectARB();
Pierre Kraemer's avatar
Pierre Kraemer committed
463

464
	if( !m_program_object )
Pierre Kraemer's avatar
Pierre Kraemer committed
465
	{
466
		CGoGNerr << "ERROR - GLSLShader::create() - unable to create program object." << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
467
468
469
470
		return false;
	}

	/*** attach shaders to program object ***/
471
472
473
	glAttachObjectARB( m_program_object, m_vertex_shader_object );
	glAttachObjectARB( m_program_object, m_fragment_shader_object );
	if (m_geom_shader_object)
Pierre Kraemer's avatar
Pierre Kraemer committed
474
	{
475
		glAttachObjectARB( m_program_object, m_geom_shader_object );
Pierre Kraemer's avatar
Pierre Kraemer committed
476

477
478
		glProgramParameteriEXT(m_program_object,GL_GEOMETRY_INPUT_TYPE_EXT,inputGeometryPrimitive);
		glProgramParameteriEXT(m_program_object,GL_GEOMETRY_OUTPUT_TYPE_EXT,outputGeometryPrimitive);
Sylvain Thery's avatar
Sylvain Thery committed
479
		glProgramParameteriEXT(m_program_object,GL_GEOMETRY_VERTICES_OUT_EXT,nb_max_vertices);
Pierre Kraemer's avatar
Pierre Kraemer committed
480
481
482
	}

	/*** link program object ***/
483
	glLinkProgramARB( m_program_object );
Pierre Kraemer's avatar
Pierre Kraemer committed
484

485
	glGetObjectParameterivARB( m_program_object, GL_OBJECT_LINK_STATUS_ARB, &status );
Pierre Kraemer's avatar
Pierre Kraemer committed
486
487
	if( !status )
	{
488
		CGoGNerr << "ERROR - GLSLShader::create() - error occured while linking shader program." << CGoGNendl;
489
		info_log = getInfoLog( m_program_object );
490
		CGoGNerr << "  LINK " << info_log << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
491
492
		delete [] info_log;

493
494
495
496
497
498
		glDetachObjectARB( m_program_object, m_vertex_shader_object );
		glDetachObjectARB( m_program_object, m_fragment_shader_object );
		if (m_geom_shader_object)
			glDetachObjectARB( m_program_object, m_geom_shader_object );
		glDeleteObjectARB( m_program_object );
		m_program_object = 0;
Pierre Kraemer's avatar
Pierre Kraemer committed
499
500
501
502

		return false;
	}

Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
503
504
505
506
	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");
507

Pierre Kraemer's avatar
Pierre Kraemer committed
508
509
510
	return true;
}

511
512
513
514
515
516
517
518
519
520
521
bool GLSLShader::link()
{
	int		status;
	char	*info_log;

	/*** link program object ***/
	glLinkProgramARB( m_program_object );

	glGetObjectParameterivARB( m_program_object, GL_OBJECT_LINK_STATUS_ARB, &status );
	if( !status )
	{
522
		CGoGNerr << "ERROR - GLSLShader::create() - error occured while linking shader program." << CGoGNendl;
523
		info_log = getInfoLog( m_program_object );
524
		CGoGNerr << "  LINK " << info_log << CGoGNendl;
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
		delete [] info_log;

		glDetachObjectARB( m_program_object, m_vertex_shader_object );
		glDetachObjectARB( m_program_object, m_fragment_shader_object );
		if (m_geom_shader_object)
			glDetachObjectARB( m_program_object, m_geom_shader_object );
		glDeleteObjectARB( m_program_object );
		m_program_object = 0;

		return false;
	}

	return true;
}

540
bool GLSLShader::bind() const
Pierre Kraemer's avatar
Pierre Kraemer committed
541
{
542
	if( m_program_object )
Pierre Kraemer's avatar
Pierre Kraemer committed
543
	{
544
		glUseProgramObjectARB( m_program_object );
Pierre Kraemer's avatar
Pierre Kraemer committed
545
546
		return true;
	}
547
548
	else
		return false;
Pierre Kraemer's avatar
Pierre Kraemer committed
549
550
}

551
void GLSLShader::unbind() const
Pierre Kraemer's avatar
Pierre Kraemer committed
552
{
553
	if( m_program_object )
Pierre Kraemer's avatar
Pierre Kraemer committed
554
555
556
557
558
559
560
	{
		glUseProgramObjectARB( 0 );
	}
}

bool GLSLShader::isBinded()
{
561
	return ( m_program_object && m_program_object == glGetHandleARB(GL_PROGRAM_OBJECT_ARB) );
Pierre Kraemer's avatar
Pierre Kraemer committed
562
563
564
565
}

GLSLShader::~GLSLShader()
{
566
	if( m_program_object )
Pierre Kraemer's avatar
Pierre Kraemer committed
567
568
569
	{
		unbind();

570
		if( m_vertex_shader_object )
Pierre Kraemer's avatar
Pierre Kraemer committed
571
		{
572
573
			glDetachObjectARB( m_program_object, m_vertex_shader_object );
			glDeleteObjectARB( m_vertex_shader_object );
Pierre Kraemer's avatar
Pierre Kraemer committed
574
		}
575
		if( m_fragment_shader_object )
Pierre Kraemer's avatar
Pierre Kraemer committed
576
		{
577
578
			glDetachObjectARB( m_program_object, m_fragment_shader_object );
			glDeleteObjectARB( m_fragment_shader_object );
Pierre Kraemer's avatar
Pierre Kraemer committed
579
		}
580
		if (m_geom_shader_object)
Pierre Kraemer's avatar
Pierre Kraemer committed
581
		{
582
583
			glDetachObjectARB( m_program_object, m_geom_shader_object );
			glDeleteObjectARB( m_geom_shader_object );
Pierre Kraemer's avatar
Pierre Kraemer committed
584
585
		}

586
		glDeleteObjectARB( m_program_object );
Pierre Kraemer's avatar
Pierre Kraemer committed
587
	}
588

Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
589
//	m_registeredShaders.erase(this);
Pierre Kraemer's avatar
Pierre Kraemer committed
590
591
592
593
}

std::string GLSLShader::findFile(const std::string filename)
{
Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
594
	// cherche d'abord dans le repertoire courant
Pierre Kraemer's avatar
Pierre Kraemer committed
595
596
597
598
599
600
601
602
603
	std::ifstream file;
	file.open(filename.c_str(),std::ios::in );
	if (!file.fail())
	{
		file.close();
		return filename;
	}
	file.close();

604
605
606
607
608
609
610
611
612
613
614
615
616
617
	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
618
	// LA MACRO SHADERPATH contient le chemin du repertoire qui contient les fichiers textes
Pierre Kraemer's avatar
Pierre Kraemer committed
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
	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()
{
	GLenum error = glewInit();

	if (error != GLEW_OK)
638
		CGoGNerr << "Error: " << glewGetErrorString(error) << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
639
	else
640
		CGoGNout << "Status: Using GLEW " << glewGetString(GLEW_VERSION) << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
641
642

	if (!areVBOSupported())
643
		CGoGNout << "VBO not supported !" << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
644
645

	if(!areShadersSupported()) {
646
		CGoGNout << "Shaders not supported !" << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
647
648
649
650
651
652
653
		return false;
	}
	return true; 
}

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

Pierre Kraemer's avatar
Pierre Kraemer committed
657
658
659
660
	std::string vss = findFile(vs);
	if(!loadVertexShader(vss)) return false;
	
	std::string pss = findFile(ps);
661
	if(!loadFragmentShader(pss)) return false;
Pierre Kraemer's avatar
Pierre Kraemer committed
662
663

	if(!create()) {
664
		CGoGNout << "Unable to create the shaders !" << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
665
666
		return false;
	}
667
	CGoGNout << "Shaders loaded (" << vs << "," << ps << ")" << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
668
669
670
	return true; 
}

Sylvain Thery's avatar
Sylvain Thery committed
671
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
672
{
Sylvain Thery's avatar
Sylvain Thery committed
673
674
675
676
	m_nameVS = vs;
	m_nameFS = ps;
	m_nameGS = gs;

Pierre Kraemer's avatar
Pierre Kraemer committed
677
678
679
680
	std::string vss = findFile(vs);
	if(!loadVertexShader(vss)) return false;

	std::string pss = findFile(ps);
681
	if(!loadFragmentShader(pss)) return false;
Pierre Kraemer's avatar
Pierre Kraemer committed
682
683
684
685
686
687

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

	if (!geomShaderLoaded)
	{
688
		CGoGNerr << "Error while loading geometry shader" << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
689
690
	}

Sylvain Thery's avatar
Sylvain Thery committed
691
	if(!create(inputGeometryPrimitive,outputGeometryPrimitive,nb_max_vertices))
Pierre Kraemer's avatar
Pierre Kraemer committed
692
	{
693
		CGoGNout << "Unable to create the shaders !" << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
694
695
696
		return false;
	}

697
	CGoGNout << "Shaders loaded (" << vs << "," << ps << "," << gs <<")" << CGoGNendl;
Pierre Kraemer's avatar
Pierre Kraemer committed
698
699
700
	return true;
}

Sylvain Thery's avatar
Sylvain Thery committed
701
702
bool GLSLShader::loadShadersFromMemory(const char* vs, const char* fs)
{
703
704
705
706
707
	if (m_vertex_shader_source)
		delete [] m_vertex_shader_source;

	unsigned int sz = strlen(vs);
	m_vertex_shader_source = new char[sz+1];
Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
708
	strcpy(m_vertex_shader_source, vs);
709
710
711
712
713
714

	if (m_fragment_shader_source)
		delete [] m_fragment_shader_source;

	sz = strlen(fs);
	m_fragment_shader_source = new char[sz+1];
Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
715
	strcpy(m_fragment_shader_source, fs);
716

Sylvain Thery's avatar
Sylvain Thery committed
717
718
719
720
721
722
	if(!loadVertexShaderSourceString(vs)) return false;

	if(!loadFragmentShaderSourceString(fs)) return false;

	if(!create())
	{
723
		CGoGNout << "Unable to create the shaders !" << CGoGNendl;
Sylvain Thery's avatar
Sylvain Thery committed
724
725
726
727
728
		return false;
	}
	return true;
}

Sylvain Thery's avatar
Sylvain Thery committed
729
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
730
{
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
	if (m_vertex_shader_source)
		delete [] m_vertex_shader_source;

	unsigned int sz = strlen(vs);
	m_vertex_shader_source = new char[sz+1];
	strcpy(m_vertex_shader_source,vs);

	if (m_fragment_shader_source)
		delete [] m_fragment_shader_source;

	sz = strlen(fs);
	m_fragment_shader_source = new char[sz+1];
	strcpy(m_fragment_shader_source,fs);

	if (m_geom_shader_source)
		delete [] m_geom_shader_source;

	sz = strlen(gs);
	m_geom_shader_source = new char[sz+1];
	strcpy(m_geom_shader_source,gs);

Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
752
753
	if(!loadVertexShaderSourceString(vs))
		return false;
Sylvain Thery's avatar
Sylvain Thery committed
754

Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
755
756
	if(!loadFragmentShaderSourceString(fs))
		return false;
Sylvain Thery's avatar
Sylvain Thery committed
757

Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
758
759
	if(!loadGeometryShaderSourceString(gs))
		return false;
Sylvain Thery's avatar
Sylvain Thery committed
760

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

	return true;
}

770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
bool GLSLShader::reloadVertexShaderFromMemory(const char* vs)
{
	if (m_vertex_shader_source)
		delete [] m_vertex_shader_source;

	unsigned int sz = strlen(vs);
	m_vertex_shader_source = new char[sz+1];
	strcpy(m_vertex_shader_source,vs);

	return true;
}

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

	unsigned int sz = strlen(fs);
	m_fragment_shader_source = new char[sz+1];
	strcpy(m_fragment_shader_source,fs);

	return true;
}

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

	unsigned int sz = strlen(gs);
	m_geom_shader_source = new char[sz+1];
	strcpy(m_geom_shader_source,gs);

	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))
	{
817
		CGoGNerr << "Unable to create the shaders !" << CGoGNendl;
818
819
820
821
822
823
824
825
826
827
		return false;
	}

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

	restoreUniformsAttribs();

828
829
	updateClippingUniforms();

830
831
832
	return true;
}

833
834
835
836
837
838
839
840
841
842
843
bool GLSLShader::validateProgram()
{
	if(!m_program_object)
		return false;

	glValidateProgram(m_program_object);
	GLint Result = GL_FALSE;
	glGetProgramiv(m_program_object, GL_VALIDATE_STATUS, &Result);

	if(Result == GL_FALSE)
	{
844
		CGoGNout << "Validate program:" << CGoGNendl;
845
846
847
848
		int InfoLogLength;
		glGetProgramiv(m_program_object, GL_INFO_LOG_LENGTH, &InfoLogLength);
		std::vector<char> Buffer(InfoLogLength);
		glGetProgramInfoLog(m_program_object, InfoLogLength, NULL, &Buffer[0]);
849
		CGoGNout <<  &(Buffer[0]) << CGoGNendl;
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
		return false;
	}

	return true;
}

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

	int InfoLogLength;
	glGetProgramiv(m_program_object, GL_INFO_LOG_LENGTH, &InfoLogLength);
	std::vector<char> Buffer(std::max(InfoLogLength, int(1)));
	glGetProgramInfoLog(m_program_object, InfoLogLength, NULL, &Buffer[0]);
865
	CGoGNout << &Buffer[0] << CGoGNendl;
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887

	return Result == GL_TRUE;
}

bool GLSLShader::checkShader(int shaderType)
{
	GLint Result = GL_FALSE;
	int InfoLogLength;
	GLhandleARB id;

	switch(shaderType)
	{
	case VERTEX_SHADER:
		id = m_vertex_shader_object;
		break;
	case FRAGMENT_SHADER:
		id = m_fragment_shader_object;
		break;
	case GEOMETRY_SHADER:
		id = m_geom_shader_object;
		break;
	default:
888
		CGoGNerr << "Error unkown shader type"<< CGoGNendl;
889
890
891
892
893
894
895
896
		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]);
897
	CGoGNout << &Buffer[0] << CGoGNendl;
898
899
900
901

	return Result == GL_TRUE;
}

Sylvain Thery's avatar
Sylvain Thery committed
902
void GLSLShader::bindAttrib(unsigned int att, const char* name) const
903
{
Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
904
	glBindAttribLocation(m_program_object, att, name);
905
906
}

907
908
909
910
911
void GLSLShader::addPathFileSeach(const std::string& path)
{
	m_pathes.push_back(path);
}

912
unsigned int GLSLShader::bindVA_VBO(const std::string& name, VBO* vbo)
Sylvain Thery's avatar
Sylvain Thery committed
913
914
915
916
917
{
	GLint idVA = glGetAttribLocation(this->m_program_object, name.c_str());
	//valid ?
	if (idVA < 0)
	{
Pierre Kraemer's avatar
Pierre Kraemer committed
918
		CGoGNerr << "GLSLShader: Attribute " << name << " does not exist in shader" << CGoGNendl;
919
		return idVA;
Sylvain Thery's avatar
Sylvain Thery committed
920
921
922
923
924
925
	}
	// 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)
		{
926
927
			it->vbo_ptr = vbo;
			return (it - m_va_vbo_binding.begin());
Sylvain Thery's avatar
Sylvain Thery committed
928
929
930
931
932
		}
	}
	// new one:
	VAStr temp;
	temp.va_id = idVA;
933
	temp.vbo_ptr = vbo;
Sylvain Thery's avatar
Sylvain Thery committed
934
	m_va_vbo_binding.push_back(temp);
935
936
937
938
939
940
	return (m_va_vbo_binding.size() -1);
}

void GLSLShader::changeVA_VBO(unsigned int id, VBO* vbo)
{
	m_va_vbo_binding[id].vbo_ptr = vbo;
Sylvain Thery's avatar
Sylvain Thery committed
941
942
943
944
945
946
947
948
}

void GLSLShader::unbindVA(const std::string& name)
{
	GLint idVA = glGetAttribLocation(this->m_program_object, name.c_str());
	//valid ?
	if (idVA < 0)
	{
949
		CGoGNerr << "GLSLShader: Attribute "<<name<< " does not exist in shader, not unbinded"<< CGoGNendl;
Sylvain Thery's avatar
Sylvain Thery committed
950
951
952
953
954
955
956
957
958
959
960
961
962
963
		return;
	}
	// search if name already exist
	unsigned int nb = m_va_vbo_binding.size();
	for (unsigned int i =0; i<nb; ++i)
	{
		if (m_va_vbo_binding[i].va_id == idVA)
		{
			if (i != (nb-1))
				m_va_vbo_binding[i] = m_va_vbo_binding[nb-1];
			m_va_vbo_binding.pop_back();
			return;
		}
	}
964
	CGoGNerr << "GLSLShader: Attribute "<<name<< " not binded"<< CGoGNendl;
Sylvain Thery's avatar
Sylvain Thery committed
965
966
967
968
}

void GLSLShader::setCurrentOGLVersion(unsigned int version)
{
Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
969
	CURRENT_OGL_VERSION = version;
Sylvain Thery's avatar
Sylvain Thery committed
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
	switch(version)
	{
	case 2:
		DEFINES_GL = &DEFINES_GL2;
		break;
	case 3:
		DEFINES_GL = &DEFINES_GL3;
		break;
	}
}

/**
 * update projection, modelview, ... matrices
 */
void GLSLShader::updateMatrices(const glm::mat4& projection, const glm::mat4& modelview)
{
	this->bind();
Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
987
	glm::mat4 PMV = projection * modelview;
988
	glm::mat4 normalMatrix = glm::gtx::inverse_transpose::inverseTranspose(modelview);
Sylvain Thery's avatar
Sylvain Thery committed
989

Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
990
	if (m_uniMat_Proj >= 0)
991
		glUniformMatrix4fv(m_uniMat_Proj,		1 , false, &projection[0][0]);
Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
992
	if (m_uniMat_Model >= 0)
993
		glUniformMatrix4fv(m_uniMat_Model,		1 , false, &modelview[0][0]);
Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
994
	if (m_uniMat_ModelProj >= 0)
995
		glUniformMatrix4fv(m_uniMat_ModelProj,	1 , false, &PMV[0][0]);
Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
996
	if (m_uniMat_Normal >= 0)
997
998
999
		glUniformMatrix4fv(m_uniMat_Normal, 	1 , false, &normalMatrix[0][0]);
}

1000
void GLSLShader::enableVertexAttribs(unsigned int stride, unsigned int begin) const
1001
1002
1003
1004
1005
1006
{
	this->bind();
	for (std::vector<Utils::GLSLShader::VAStr>::const_iterator it= m_va_vbo_binding.begin(); it != m_va_vbo_binding.end(); ++it)
	{
		glBindBuffer(GL_ARRAY_BUFFER, it->vbo_ptr->id());
		glEnableVertexAttribArray(it->va_id);
1007
		glVertexAttribPointer(it->va_id, it->vbo_ptr->dataSize(), GL_FLOAT, false, stride, (const GLvoid*)begin);
1008
1009
	}
}
Sylvain Thery's avatar
Sylvain Thery committed
1010

1011
1012
void GLSLShader::disableVertexAttribs() const
{
1013
	this->bind();
1014
	for (std::vector<Utils::GLSLShader::VAStr>::const_iterator it= m_va_vbo_binding.begin(); it != m_va_vbo_binding.end(); ++it)
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
		glDisableVertexAttribArray(it->va_id);
	this->unbind();
}

void GLSLShader::updateCurrentMatrices()
{
	glm::mat4 model(currentModelView());
	model *= currentTransfo();

	for(std::set< std::pair<void*, GLSLShader*> >::iterator it = m_registeredShaders.begin();it != m_registeredShaders.end();++it)
			it->second->updateMatrices(currentProjection(), model);
Sylvain Thery's avatar
Sylvain Thery committed
1026
}
Pierre Kraemer's avatar
Pierre Kraemer committed
1027
1028

} // namespace Utils
Pierre Kraemer's avatar
merge..    
Pierre Kraemer committed
1029

Pierre Kraemer's avatar
Pierre Kraemer committed
1030
} // namespace CGoGN