2
* Copyright 2010 Inalogic Inc.
4
* This program is free software: you can redistribute it and/or modify it
5
* under the terms of the GNU Lesser General Public License version 3, as
6
* published by the Free Software Foundation.
8
* This program is distributed in the hope that it will be useful, but
9
* WITHOUT ANY WARRANTY; without even the implied warranties of
10
* MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
11
* PURPOSE. See the applicable version of the GNU Lesser General Public
12
* License for more details.
14
* You should have received a copy of both the GNU Lesser General Public
15
* License version 3 along with this program. If not, see
16
* <http://www.gnu.org/licenses/>
18
* Authored by: Jay Taoko <jay.taoko_AT_gmail_DOT_com>
23
#include "GLDeviceFactory.h"
24
#include "GLDeviceObjects.h"
25
#include "IOpenGLGLSLShader.h"
29
IMPLEMENT_OBJECT_TYPE(IOpenGLShader);
30
IMPLEMENT_OBJECT_TYPE(IOpenGLVertexShader);
31
IMPLEMENT_OBJECT_TYPE(IOpenGLPixelShader);
32
IMPLEMENT_OBJECT_TYPE(IOpenGLShaderProgram);
34
struct ShaderDefinition
40
//-----------------------------------------------------------------------------
41
static void AddShaderDefinition(std::vector<ShaderDefinition>& Definitions,const TCHAR* Name,const TCHAR* Format,...)
43
TCHAR DefinitionText[1024];
44
GET_VARARGS(DefinitionText, INL_ARRAY_COUNT(DefinitionText), INL_ARRAY_COUNT(DefinitionText)-1,Format);
46
ShaderDefinition Definition;
47
Definition.Name = Name;
48
Definition.Value = DefinitionText;
49
Definitions.push_back(Definition);
52
//-----------------------------------------------------------------------------
53
bool ExtractShaderString3(const NString &ShaderToken, const NString &ShaderSource, NString &RetSource, NString ShaderPreprocessorDefines)
57
bool startTokenFound = false;
58
t_size shaderStringStart =0;
59
t_size shaderStartLine =1;
62
//Loop for all characters in the string
63
if(ShaderToken != TEXT(""))
66
for(i = 0; i< ShaderSource.Length(); i++)
68
//Check if the starting character '[' (open bracket) is found at the beginning of the line
69
// i counts the characters in the file. lineStart is equal to i at the beginning of the line.
70
if((TCharStringNCompare(&ShaderSource[i],TEXT("["), 1) == 0) && (lineStart == i))
74
//Test for the start token
75
if(ShaderSource.FindFirstOccurence(ShaderToken) == i)
77
// Found the shader token
78
shaderStringStart = i + ShaderToken.Length();
79
startTokenFound = true;
81
//Set what line the shader was found on
82
shaderStartLine = lineCount;
87
//Break where the end token was found
92
//If the character is equal to the new line character,
93
// The next character must be on the new line
94
if((TCharStringNCompare(&ShaderSource[i], TEXT("\r"), 1) == 0) || (TCharStringNCompare(&ShaderSource[i], TEXT("\n"), 1) == 0))
100
if(TCharStringNCompare(&ShaderSource[i], TEXT("\n"), 1) == 0)
106
//If the string was not found, return false
107
if(!startTokenFound || shaderStringStart >= i)
112
//Assign the return string
113
RetSource = ShaderSource.GetSubString(shaderStringStart, i - shaderStringStart);
115
//Add the line directive to the shader source. See the documentation for GLSL #line directive.
116
// GLSL spec: The #version directive must occur in a shader before anything else, except for comments and white space.
117
t_size Pos = RetSource.FindFirstOccurence(TEXT("#version"));
118
while(RetSource[Pos] != TEXT('\n'))
120
if(RetSource[Pos] == 0)
124
if(RetSource[Pos] != 0)
127
t_size EndOfLinePosition = 0;
128
t_size LinePosition = 0;
129
while((EndOfLinePosition = RetSource.FindNextOccurence(TEXT('\n'), EndOfLinePosition)) < Pos-1)
135
RetSource.Insert(Pos, NString::Printf(TEXT("#line %u\n"), LinePosition + shaderStartLine));
137
// Insert the preprocessor definitions before the #line directive
138
if(ShaderPreprocessorDefines.Length())
139
RetSource.Insert(Pos, ShaderPreprocessorDefines + NString(TEXT('\n')));
145
// We are not searching for a start token. Return the whole source.
146
RetSource = ShaderSource;
151
static void InsertPreProcessorDefinitions(const NString &ShaderSource, NString &RetSource, NString& ShaderPreprocessorDefines)
153
RetSource = ShaderSource;
155
if(ShaderPreprocessorDefines.Length() == 0)
158
// GLSL spec: The #version directive must occur in a shader before anything else, except for comments and white space.
159
t_size Pos = RetSource.FindFirstOccurence(TEXT("#version"));
162
Pos = RetSource.FindNextOccurence(TEXT('\n'), Pos);
165
// this is most likely an incorrect shader
166
Pos = RetSource.Size();
167
RetSource.Insert(Pos, NString(TEXT('\n')));
168
Pos = RetSource.Size();
181
if(ShaderPreprocessorDefines.Length())
182
RetSource.Insert(Pos, ShaderPreprocessorDefines + NString(TEXT('\n')));
185
IOpenGLShader::IOpenGLShader(NString ShaderName, OpenGLResourceType ResourceType)
186
: IOpenGLResource(ResourceType)
187
, _ShaderName(ShaderName)
192
IOpenGLShader::~IOpenGLShader()
197
IOpenGLVertexShader::IOpenGLVertexShader(NString ShaderName)
198
: m_CompiledAndReady(false)
199
, IOpenGLShader(ShaderName, RT_GLSL_VERTEXSHADER)
201
_OpenGLID = glCreateShader(GL_VERTEX_SHADER_ARB);
202
CHECKGL_MSG( glCreateShader(GL_VERTEX_SHADER_ARB) );
205
IOpenGLVertexShader::~IOpenGLVertexShader()
207
CHECKGL( glDeleteShader(_OpenGLID) );
209
m_CompiledAndReady = false;
212
void IOpenGLVertexShader::SetShaderCode(const TCHAR* ShaderCode, const TCHAR* VtxShaderPreprocessorDefines)
214
nuxAssertMsg(ShaderCode, TEXT("[IOpenGLVertexShader::SetShaderCode] Invalid shader code."));
215
INL_RETURN_IF_NULL(ShaderCode);
216
NString ProcessedShaderSource;
217
NString Defines(VtxShaderPreprocessorDefines);
218
InsertPreProcessorDefinitions(ShaderCode, ProcessedShaderSource, Defines);
220
m_CompiledAndReady = false;
221
_ShaderCode = ProcessedShaderSource;
224
bool IOpenGLVertexShader::Compile()
226
t_size CodeSize = _ShaderCode.Size();
229
nuxDebugMsg(TEXT("[IOpenGLVertexShader::Compile] Vertex shader source code is empty."));
232
char* ShaderSource = new char[CodeSize+1];
233
Memset(ShaderSource, 0, CodeSize+1);
234
Memcpy(ShaderSource, _ShaderCode.GetTCharPtr(), CodeSize);
236
CHECKGL( glShaderSource(_OpenGLID, 1, (const GLcharARB **)&ShaderSource, NULL) );
239
// compile vertex shader object
240
CHECKGL( glCompileShader(_OpenGLID) );
242
// check if shader compiled
243
m_CompiledAndReady = false;
244
CHECKGL( glGetShaderiv(_OpenGLID, GL_COMPILE_STATUS, &m_CompiledAndReady) );
246
if(!m_CompiledAndReady)
248
ANSICHAR* InfoLogBuffer = 0;
249
GLint InfoLogBufferSize = 0;
250
GLint InfoLogReturnSize = 0;
253
glGetShaderiv(_OpenGLID, GL_INFO_LOG_LENGTH, &iLog);
254
InfoLogBuffer = new ANSICHAR[iLog+1];
255
InfoLogBufferSize = iLog+1;
256
glGetShaderInfoLog(_OpenGLID, InfoLogBufferSize, &InfoLogReturnSize, InfoLogBuffer);
257
if(InfoLogReturnSize != 0)
259
nuxError(TEXT("[IOpenGLVertexShader::Compile] glCompileShader: %s"), InfoLogBuffer);
261
delete InfoLogBuffer;
264
return (m_CompiledAndReady ? true : false);
267
bool IOpenGLVertexShader::IsValid()
269
return (m_CompiledAndReady ? true : false);
272
IOpenGLPixelShader::IOpenGLPixelShader(NString ShaderName)
273
: m_CompiledAndReady(false)
274
, IOpenGLShader(ShaderName, RT_GLSL_PIXELSHADER)
276
_OpenGLID = glCreateShader(GL_FRAGMENT_SHADER_ARB);
277
CHECKGL_MSG( glCreateShader(GL_FRAGMENT_SHADER_ARB) );
280
IOpenGLPixelShader::~IOpenGLPixelShader()
282
CHECKGL( glDeleteShader(_OpenGLID) );
284
m_CompiledAndReady = false;
287
void IOpenGLPixelShader::SetShaderCode(const TCHAR* ShaderCode, const TCHAR* FrgShaderPreprocessorDefines)
289
nuxAssertMsg(ShaderCode, TEXT("[IOpenGLPixelShader::SetShaderCode] Invalid shader code."));
290
INL_RETURN_IF_NULL(ShaderCode);
291
NString ProcessedShaderSource;
292
NString Defines(FrgShaderPreprocessorDefines);
293
InsertPreProcessorDefinitions(ShaderCode, ProcessedShaderSource, Defines);
295
m_CompiledAndReady = false;
296
_ShaderCode = ProcessedShaderSource;
299
bool IOpenGLPixelShader::Compile()
302
GLint CodeSize = (GLint)_ShaderCode.Size();
305
nuxDebugMsg(TEXT("[IOpenGLPixelShader::Compile] Pixel shader source code is empty."));
308
char* ShaderSource = new char[CodeSize+1];
309
Memset(ShaderSource, 0, CodeSize+1);
310
Memcpy(ShaderSource, _ShaderCode.m_string.c_str(), CodeSize);
311
CHECKGL( glShaderSource(_OpenGLID, 1, (const GLcharARB **)&ShaderSource, &CodeSize) );
314
// compile pixel shader object
315
CHECKGL( glCompileShader(_OpenGLID) );
317
// check if shader compiled
318
m_CompiledAndReady = false;
319
CHECKGL( glGetShaderiv(_OpenGLID, GL_COMPILE_STATUS, &m_CompiledAndReady) );
321
if(!m_CompiledAndReady)
323
ANSICHAR* InfoLogBuffer = 0;
324
GLint InfoLogBufferSize = 0;
325
GLint InfoLogReturnSize = 0;
328
glGetShaderiv(_OpenGLID, GL_INFO_LOG_LENGTH, &iLog);
329
InfoLogBuffer = new ANSICHAR[iLog+1];
330
InfoLogBufferSize = iLog+1;
331
glGetShaderInfoLog(_OpenGLID, InfoLogBufferSize, &InfoLogReturnSize, InfoLogBuffer);
332
if(InfoLogReturnSize != 0)
334
nuxError(TEXT("[IOpenGLPixelShader::Compile] glCompileShader: %s"), InfoLogBuffer);
336
delete InfoLogBuffer;
338
return (m_CompiledAndReady ? true : false);
341
bool IOpenGLPixelShader::IsValid()
343
return (m_CompiledAndReady ? true : false);
346
IOpenGLShaderProgram::IOpenGLShaderProgram(NString ShaderProgramName)
347
: m_CompiledAndReady(false)
348
, IOpenGLResource(RT_GLSL_SHADERPROGRAM)
349
, _ShaderProgramName(ShaderProgramName)
352
_OpenGLID = glCreateProgram();
353
CHECKGL_MSG( glCreateProgram() );
356
IOpenGLShaderProgram::~IOpenGLShaderProgram()
358
CHECKGL( glDeleteProgram(_OpenGLID) );
360
m_CompiledAndReady = false;
363
void IOpenGLShaderProgram::LoadIShaderFile(const TCHAR* ShaderFileName, const TCHAR* VtxShaderPreprocessorDefines, const TCHAR* FrgShaderPreprocessorDefines)
365
nuxAssertMsg(ShaderFileName, TEXT("[IOpenGLShaderProgram::LoadIShaderFile] Invalid shader file name."));
366
INL_RETURN_IF_NULL(ShaderFileName);
368
LoadFileToString(SourceCode, ShaderFileName);
369
LoadIShader(&SourceCode[0], VtxShaderPreprocessorDefines, FrgShaderPreprocessorDefines);
372
void IOpenGLShaderProgram::LoadIShader(const TCHAR* ShaderCode, const TCHAR* VtxShaderPreprocessorDefines, const TCHAR* FrgShaderPreprocessorDefines)
374
nuxAssertMsg(ShaderCode, TEXT("[IOpenGLShaderProgram::LoadIShader] Invalid shader code."));
375
INL_RETURN_IF_NULL(ShaderCode);
376
NString VertexShaderSource;
377
ExtractShaderString3(TEXT("[Vertex Shader]"), ShaderCode, VertexShaderSource, NString(VtxShaderPreprocessorDefines));
378
NString PixelShaderSource;
379
ExtractShaderString3(TEXT("[Fragment Shader]"), ShaderCode, PixelShaderSource, NString(FrgShaderPreprocessorDefines));
381
TRefGL<IOpenGLVertexShader> vs = GetThreadGLDeviceFactory()->CreateVertexShader(); //new IOpenGLVertexShader;
382
TRefGL<IOpenGLPixelShader> ps = GetThreadGLDeviceFactory()->CreatePixelShader(); //new IOpenGLPixelShader;
384
vs->SetShaderCode(&VertexShaderSource[0]);
385
ps->SetShaderCode(&PixelShaderSource[0]);
389
ShaderObjectList.clear();
395
void IOpenGLShaderProgram::LoadVertexShader(const TCHAR* glslshader, const TCHAR* VtxShaderPreprocessorDefines)
397
nuxAssertMsg(glslshader, TEXT("[IOpenGLShaderProgram::LoadVertexShader] Invalid shader code."));
398
INL_RETURN_IF_NULL(glslshader);
399
TRefGL<IOpenGLVertexShader> vs = GetThreadGLDeviceFactory()->CreateVertexShader(); //new IOpenGLVertexShader;
401
NString ProcessedShaderSource;
402
NString Defines(VtxShaderPreprocessorDefines);
403
InsertPreProcessorDefinitions(glslshader, ProcessedShaderSource, Defines);
405
vs->SetShaderCode(glslshader);
410
void IOpenGLShaderProgram::LoadPixelShader(const TCHAR* glslshader, const TCHAR* FrgShaderPreprocessorDefines)
412
nuxAssertMsg(glslshader, TEXT("[IOpenGLShaderProgram::LoadPixelShader] Invalid shader code."));
413
INL_RETURN_IF_NULL(glslshader);
414
TRefGL<IOpenGLPixelShader> ps = GetThreadGLDeviceFactory()->CreatePixelShader(); //new IOpenGLPixelShader;
416
NString ProcessedShaderSource;
417
NString Defines(FrgShaderPreprocessorDefines);
418
InsertPreProcessorDefinitions(glslshader, ProcessedShaderSource, Defines);
420
ps->SetShaderCode(glslshader);
425
void IOpenGLShaderProgram::AddShaderObject(TRefGL<IOpenGLShader> ShaderObject)
427
ShaderObjectList.push_back(ShaderObject);
430
void IOpenGLShaderProgram::AddShaderParameter(GLShaderParameter* Parameter)
432
Parameter->m_NextParameter = _FirstParameter;
433
_FirstParameter = Parameter;
435
// If we add shader parameters after the program is linked, we need to call CheckUniformLocation().
436
CheckUniformLocation();
439
void IOpenGLShaderProgram::RemoveShaderObject(TRefGL<IOpenGLShader> ShaderObject)
441
std::vector< TRefGL<IOpenGLShader> >::iterator it = find(ShaderObjectList.begin(), ShaderObjectList.end(), ShaderObject);
442
if(it != ShaderObjectList.end())
444
ShaderObjectList.erase(it);
448
void IOpenGLShaderProgram::ClearShaderObjects()
450
ShaderObjectList.clear();
453
bool IOpenGLShaderProgram::Link()
455
// Get the number of attached shaders.
456
GLint NumAttachedShaders;
457
CHECKGL( glGetProgramiv(_OpenGLID, GL_ATTACHED_SHADERS, &NumAttachedShaders) );
458
GLuint* ShaderObjects = 0;
459
if(NumAttachedShaders)
461
ShaderObjects = new GLuint[NumAttachedShaders];
463
CHECKGL( glGetAttachedShaders(_OpenGLID, NumAttachedShaders, NULL, ShaderObjects) );
465
// Detach everything first
466
for (int i=0; i < (int)NumAttachedShaders; i++)
468
unsigned int obj = ShaderObjects[i];
469
CHECKGL( glDetachShader(_OpenGLID, obj) );
471
if(NumAttachedShaders)
473
delete ShaderObjects;
476
for (int i=0; i < (int)ShaderObjectList.size(); i++)
478
if(!ShaderObjectList[i]->IsValid())
480
if(ShaderObjectList[i]->Compile() == false)
482
nuxDebugMsg(TEXT("[IOpenGLShaderProgram::Link] Attached shader %s does not compile with program: %s."), ShaderObjectList[i]->_ShaderName.GetTCharPtr(), _ShaderProgramName.GetTCharPtr());
485
unsigned int obj = ShaderObjectList[i]->GetOpenGLID();
486
CHECKGL( glAttachShader(_OpenGLID, obj) );
490
CHECKGL( glLinkProgram(_OpenGLID) );
491
CHECKGL( glGetProgramiv(_OpenGLID, GL_LINK_STATUS, &linked) );
492
if(linked == GL_FALSE)
494
ANSICHAR* InfoLogBuffer = 0;
495
GLint InfoLogBufferSize = 0;
496
GLint InfoLogReturnSize = 0;
498
glGetProgramiv(_OpenGLID, GL_INFO_LOG_LENGTH, &iLog);
499
InfoLogBuffer = new ANSICHAR[iLog+1];
500
InfoLogBufferSize = iLog+1;
502
glGetProgramInfoLog(_OpenGLID, InfoLogBufferSize, &InfoLogReturnSize, InfoLogBuffer);
503
if(InfoLogReturnSize != 0)
505
nuxError(TEXT("[IOpenGLShaderProgram::Link] glLinkProgram: %s"), InfoLogBuffer);
507
delete InfoLogBuffer;
508
m_CompiledAndReady = false;
509
return m_CompiledAndReady;
513
// glValidateProgram checks to see whether the executables contained in program can execute given the current OpenGL state.
514
CHECKGL( glValidateProgram(_OpenGLID) );
515
CHECKGL( glGetProgramiv(_OpenGLID, GL_VALIDATE_STATUS, &validated) );
516
if(validated == GL_FALSE)
518
ANSICHAR* InfoLogBuffer = 0;
519
GLint InfoLogBufferSize = 0;
520
GLint InfoLogReturnSize = 0;
522
glGetProgramiv(_OpenGLID, GL_INFO_LOG_LENGTH, &iLog);
523
InfoLogBuffer = new ANSICHAR[iLog+1];
524
InfoLogBufferSize = iLog+1;
526
glGetProgramInfoLog(_OpenGLID, InfoLogBufferSize, &InfoLogReturnSize, InfoLogBuffer);
527
if(InfoLogReturnSize != 0)
529
nuxError(TEXT("[IOpenGLShaderProgram::Link] glValidateProgram: %s"), InfoLogBuffer);
531
delete InfoLogBuffer;
534
m_CompiledAndReady = true;
537
CheckAttributeLocation();
538
CheckUniformLocation();
541
return m_CompiledAndReady;
544
void IOpenGLShaderProgram::Begin(void)
546
CHECKGL( glUseProgramObjectARB(_OpenGLID) );
549
void IOpenGLShaderProgram::End(void)
551
CHECKGL( glUseProgramObjectARB(0) );
554
void IOpenGLShaderProgram::CheckAttributeLocation()
556
//ResetAttributeVariable(m_ProgramAttributeDefinition);
557
for(int i = 0; i < NUM_VERTEX_SHADER_INPUT_ATTRIBUTE; i++)
559
m_ProgramAttributeDefinition[i].attribute_index = -1;
560
m_ProgramAttributeDefinition[i].attribute_name = "";
561
m_ProgramAttributeDefinition[i].type = VAT_UNDEFINED;
562
m_ProgramAttributeDefinition[i].valid = false;
565
char active_attribute_name[256];
570
GLint num_active_attributes;
571
CHECKGL( glGetObjectParameterivARB(_OpenGLID, GL_OBJECT_ACTIVE_ATTRIBUTES_ARB, &num_active_attributes) );
574
// Vertex Attribute Aliasing
575
// GLSL attempts to eliminate aliasing of vertex attributes but this is integral to NVIDIA�s hardware
576
// approach and necessary for maintaining compatibility with existing OpenGL applications that NVIDIA customers rely on.
577
// NVIDIA�s GLSL implementation therefore does not allow built-in vertex attributes to collide with a
578
// generic vertex attributes that is assigned to a particular vertex attribute index with glBindAttribLocation.
579
// For example, you should not use gl_Normal (a built-in vertex attribute) and also use glBindAttribLocation to
580
// bind a generic vertex attribute named �whatever� to vertex attribute index 2 because gl_Normal aliases to index 2.
582
// Built-in vertex attribute name Incompatible aliased vertex attribute index
586
// gl_SecondaryColor 4
588
// gl_MultiTexCoord0 8
589
// gl_MultiTexCoord1 9
590
// gl_MultiTexCoord2 10
591
// gl_MultiTexCoord3 11
592
// gl_MultiTexCoord4 12
593
// gl_MultiTexCoord5 13
594
// gl_MultiTexCoord6 14
595
// gl_MultiTexCoord7 15
596
// The compiler will automatically assign vertex shader attribute variables not pre-assigned
597
// by glBindAttribLocation to locations that do not collide with any built-in attribute variables
598
// used by the vertex shader. The assigned locations can be queries with glGetAttribLocation.
599
// This means that a developer only needs to worry about collisions when they are explicitly requesting
600
// an attribute to be bound to a specific location.
602
for(int index = 0; index < num_active_attributes; index++)
604
glGetActiveAttribARB(_OpenGLID,
610
active_attribute_name);
611
CHECKGL( glGetActiveAttribARB );
612
m_ProgramAttributeDefinition[index].attribute_index = index;
613
m_ProgramAttributeDefinition[index].attribute_name = active_attribute_name;
614
m_ProgramAttributeDefinition[index].valid = true;
619
m_ProgramAttributeDefinition[index].type = VAT_FLOAT;
622
m_ProgramAttributeDefinition[index].type = VAT_FLOAT2;
625
m_ProgramAttributeDefinition[index].type = VAT_FLOAT3;
628
m_ProgramAttributeDefinition[index].type = VAT_FLOAT4;
643
// int n = sizeof(sad) / sizeof(IOpenGLShaderAttributeDefinition);
644
// for(int i = 0; i < num_active_attributes; i++)
646
// bool found = false;
647
// for(int j = 0; j < n; j++)
649
// if(m_ProgramAttributeDefinition[i].attribute_name == sad[j].attribute_name)
652
// if(m_ProgramAttributeDefinition[i].attribute_index != sad[j].attribute_index)
653
// OutputDebugString("*** Active attribute has incorrect index.\n");
654
// if(m_ProgramAttributeDefinition[i].type != sad[j].type)
655
// OutputDebugString("*** Active attribute has incorrect type.\n");
658
// if(found == false)
660
// OutputDebugString("*** Active binded but not requested in meta shader info.\n");
667
// for(int i = 0; i < n; i++)
669
// bool found = false;
670
// for(int j = 0; j < num_active_attributes; j++)
672
// if(sad[i].attribute_name == m_ProgramAttributeDefinition[j].attribute_name)
675
// if(sad[i].attribute_index != m_ProgramAttributeDefinition[j].attribute_index)
676
// OutputDebugString("*** Active attribute has incorrect index.\n");
677
// if(sad[i].type != m_ProgramAttributeDefinition[j].type)
678
// OutputDebugString("*** Active attribute has incorrect type.\n");
681
// if(found == false)
683
// OutputDebugString("*** Active requested in meta shader info but not binded.\n");
690
void IOpenGLShaderProgram::CheckUniformLocation()
692
GLShaderParameter* parameter = _FirstParameter;
693
while(m_CompiledAndReady && parameter)
695
int location = glGetUniformLocationARB(_OpenGLID, TCHAR_TO_ANSI(parameter->m_Name.GetTCharPtr()));
696
CHECKGL_MSG( glGetUniformLocationARB(_OpenGLID, TCHAR_TO_ANSI(parameter->m_Name.GetTCharPtr())) );
697
//nuxDebugMsg(TEXT("[IOpenGLShaderProgram::CheckUniformLocation] Location index: %d"), location);
698
if(location == -1 && (!parameter->m_bIsOptional))
700
nuxDebugMsg(TEXT("[IOpenGLShaderProgram::CheckUniformLocation] Couldn't find shader program parameter %s \n"), parameter->m_Name.GetTCharPtr());
709
//nuxDebugMsg(TEXT("[IOpenGLShaderProgram::CheckUniformLocation] Program OpenGL ID: %d"), _OpenGLID);
710
//nuxDebugMsg(TEXT("[IOpenGLShaderProgram::CheckUniformLocation] Location index:%s %d"), TCHAR_TO_ANSI(parameter->m_Name.GetTCharPtr()), location);
711
CHECKGL( glGetActiveUniformARB(_OpenGLID, location, 0, NULL /*&length*/, &size, &type, NULL) );
713
parameter->m_Index = location;
714
parameter->m_Size = size;
715
parameter->m_Type = type;
717
parameter = parameter->m_NextParameter;
721
int IOpenGLShaderProgram::GetAttributeLocation(const TCHAR* AttributeName)
723
for(int i = 0; i < 16 /*NUM_VERTEX_SHADER_INPUT_ATTRIBUTE*/; i++)
725
if(m_ProgramAttributeDefinition[i].attribute_name == AttributeName)
726
return m_ProgramAttributeDefinition[i].attribute_index;
731
//-----------------------------------------------------------------------------
732
bool IOpenGLShaderProgram::SetUniform1f(char* varname, GLfloat v0)
734
//if (!useGLSL) return false; // GLSL not available
735
//if (!_noshader) return true;
737
GLint loc = GetUniformLocationARB(varname);
738
if (loc==-1) return false; // can't find variable
740
glUniform1fARB(loc, v0);
744
bool IOpenGLShaderProgram::SetUniform1f(GLint loc, GLfloat v0)
746
//if (!useGLSL) return false; // GLSL not available
747
//if (!_noshader) return true;
749
if (loc==-1) return false; // can't find variable
750
glUniform1fARB(loc, v0);
754
//-----------------------------------------------------------------------------
756
bool IOpenGLShaderProgram::SetUniform2f(char* varname, GLfloat v0, GLfloat v1)
758
//if (!useGLSL) return false; // GLSL not available
759
//if (!_noshader) return true;
761
GLint loc = GetUniformLocationARB(varname);
762
if (loc==-1) return false; // can't find variable
764
glUniform2fARB(loc, v0, v1);
768
bool IOpenGLShaderProgram::SetUniform2f(GLint loc, GLfloat v0, GLfloat v1)
770
//if (!useGLSL) return false; // GLSL not available
771
//if (!_noshader) return true;
773
if (loc==-1) return false; // can't find variable
774
glUniform2fARB(loc, v0, v1);
777
//-----------------------------------------------------------------------------
779
bool IOpenGLShaderProgram::SetUniform3f(char* varname, GLfloat v0, GLfloat v1, GLfloat v2)
781
//if (!useGLSL) return false; // GLSL not available
782
//if (!_noshader) return true;
784
GLint loc = GetUniformLocationARB(varname);
785
if (loc==-1) return false; // can't find variable
787
glUniform3fARB(loc, v0, v1, v2);
791
bool IOpenGLShaderProgram::SetUniform3f(GLint loc, GLfloat v0, GLfloat v1, GLfloat v2)
793
//if (!useGLSL) return false; // GLSL not available
794
//if (!_noshader) return true;
796
if (loc==-1) return false; // can't find variable
798
glUniform3fARB(loc, v0, v1, v2);
802
//-----------------------------------------------------------------------------
804
bool IOpenGLShaderProgram::SetUniform4f(char* varname, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3)
806
//if (!useGLSL) return false; // GLSL not available
807
//if (!_noshader) return true;
809
GLint loc = GetUniformLocationARB(varname);
810
if (loc==-1) return false; // can't find variable
812
glUniform4fARB(loc, v0, v1, v2, v3);
816
bool IOpenGLShaderProgram::SetUniform4f(GLint loc, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3)
818
//if (!useGLSL) return false; // GLSL not available
819
//if (!_noshader) return true;
821
if (loc==-1) return false; // can't find variable
823
glUniform4fARB(loc, v0, v1, v2, v3);
827
//-----------------------------------------------------------------------------
829
bool IOpenGLShaderProgram::SetUniform1i(char* varname, GLint v0)
831
//if (!useGLSL) return false; // GLSL not available
832
//if (!_noshader) return true;
834
GLint loc = GetUniformLocationARB(varname);
835
if (loc==-1) return false; // can't find variable
837
glUniform1iARB(loc, v0);
841
bool IOpenGLShaderProgram::SetUniform1i(GLint loc, GLint v0)
843
//if (!useGLSL) return false; // GLSL not available
844
//if (!_noshader) return true;
846
if (loc==-1) return false; // can't find variable
848
glUniform1iARB(loc, v0);
853
bool IOpenGLShaderProgram::SetUniform2i(char* varname, GLint v0, GLint v1)
855
// if (!useGLSL) return false; // GLSL not available
856
// if (!_noshader) return true;
858
GLint loc = GetUniformLocationARB(varname);
859
if (loc==-1) return false; // can't find variable
861
glUniform2iARB(loc, v0, v1);
866
bool IOpenGLShaderProgram::SetUniform2i(GLint loc, GLint v0, GLint v1)
868
// if (!useGLSL) return false; // GLSL not available
869
// if (!_noshader) return true;
871
if (loc==-1) return false; // can't find variable
873
glUniform2iARB(loc, v0, v1);
878
//-----------------------------------------------------------------------------
880
bool IOpenGLShaderProgram::SetUniform3i(char* varname, GLint v0, GLint v1, GLint v2)
882
// if (!useGLSL) return false; // GLSL not available
883
// if (!_noshader) return true;
885
GLint loc = GetUniformLocationARB(varname);
886
if (loc==-1) return false; // can't find variable
888
glUniform3iARB(loc, v0, v1, v2);
892
bool IOpenGLShaderProgram::SetUniform3i(GLint loc, GLint v0, GLint v1, GLint v2)
894
// if (!useGLSL) return false; // GLSL not available
895
// if (!_noshader) return true;
897
if (loc==-1) return false; // can't find variable
899
glUniform3iARB(loc, v0, v1, v2);
904
bool IOpenGLShaderProgram::SetUniform4i(char* varname, GLint v0, GLint v1, GLint v2, GLint v3)
906
// if (!useGLSL) return false; // GLSL not available
907
// if (!_noshader) return true;
909
GLint loc = GetUniformLocationARB(varname);
910
if (loc==-1) return false; // can't find variable
912
glUniform4iARB(loc, v0, v1, v2, v3);
916
bool IOpenGLShaderProgram::SetUniform4i(GLint loc, GLint v0, GLint v1, GLint v2, GLint v3)
918
// if (!useGLSL) return false; // GLSL not available
919
// if (!_noshader) return true;
921
if (loc==-1) return false; // can't find variable
923
glUniform4iARB(loc, v0, v1, v2, v3);
927
//-----------------------------------------------------------------------------
929
bool IOpenGLShaderProgram::SetUniform1fv(char* varname, GLsizei count, GLfloat *value)
931
// if (!useGLSL) return false; // GLSL not available
932
// if (!_noshader) return true;
934
GLint loc = GetUniformLocationARB(varname);
935
if (loc==-1) return false; // can't find variable
937
glUniform1fvARB(loc, count, value);
941
bool IOpenGLShaderProgram::SetUniform1fv(GLint loc, GLsizei count, GLfloat *value)
943
// if (!useGLSL) return false; // GLSL not available
944
// if (!_noshader) return true;
946
if (loc==-1) return false; // can't find variable
948
glUniform1fvARB(loc, count, value);
953
bool IOpenGLShaderProgram::SetUniform2fv(char* varname, GLsizei count, GLfloat *value)
955
// if (!useGLSL) return false; // GLSL not available
956
// if (!_noshader) return true;
958
GLint loc = GetUniformLocationARB(varname);
959
if (loc==-1) return false; // can't find variable
961
glUniform2fvARB(loc, count, value);
965
bool IOpenGLShaderProgram::SetUniform2fv(GLint loc, GLsizei count, GLfloat *value)
967
// if (!useGLSL) return false; // GLSL not available
968
// if (!_noshader) return true;
970
if (loc==-1) return false; // can't find variable
972
glUniform2fvARB(loc, count, value);
976
//-----------------------------------------------------------------------------
978
bool IOpenGLShaderProgram::SetUniform3fv(char* varname, GLsizei count, GLfloat *value)
980
// if (!useGLSL) return false; // GLSL not available
981
// if (!_noshader) return true;
983
GLint loc = GetUniformLocationARB(varname);
984
if (loc==-1) return false; // can't find variable
986
glUniform3fvARB(loc, count, value);
990
bool IOpenGLShaderProgram::SetUniform3fv(GLint loc, GLsizei count, GLfloat *value)
992
// if (!useGLSL) return false; // GLSL not available
993
// if (!_noshader) return true;
995
if (loc==-1) return false; // can't find variable
997
glUniform3fvARB(loc, count, value);
1001
//-----------------------------------------------------------------------------
1003
bool IOpenGLShaderProgram::SetUniform4fv(char* varname, GLsizei count, GLfloat *value)
1005
// if (!useGLSL) return false; // GLSL not available
1006
// if (!_noshader) return true;
1008
GLint loc = GetUniformLocationARB(varname);
1009
if (loc==-1) return false; // can't find variable
1011
glUniform4fvARB(loc, count, value);
1015
bool IOpenGLShaderProgram::SetUniform4fv(GLint loc, GLsizei count, GLfloat *value)
1017
// if (!useGLSL) return false; // GLSL not available
1018
// if (!_noshader) return true;
1020
if (loc==-1) return false; // can't find variable
1022
glUniform4fvARB(loc, count, value);
1026
//-----------------------------------------------------------------------------
1028
bool IOpenGLShaderProgram::SetUniform1iv(char* varname, GLsizei count, GLint *value)
1030
// if (!useGLSL) return false; // GLSL not available
1031
// if (!_noshader) return true;
1033
GLint loc = GetUniformLocationARB(varname);
1034
if (loc==-1) return false; // can't find variable
1036
glUniform1ivARB(loc, count, value);
1040
bool IOpenGLShaderProgram::SetUniform1iv(GLint loc, GLsizei count, GLint *value)
1042
// if (!useGLSL) return false; // GLSL not available
1043
// if (!_noshader) return true;
1045
if (loc==-1) return false; // can't find variable
1047
glUniform1ivARB(loc, count, value);
1051
//-----------------------------------------------------------------------------
1053
bool IOpenGLShaderProgram::SetUniform2iv(char* varname, GLsizei count, GLint *value)
1055
// if (!useGLSL) return false; // GLSL not available
1056
// if (!_noshader) return true;
1058
GLint loc = GetUniformLocationARB(varname);
1059
if (loc==-1) return false; // can't find variable
1061
glUniform2ivARB(loc, count, value);
1065
bool IOpenGLShaderProgram::SetUniform2iv(GLint loc, GLsizei count, GLint *value)
1067
// if (!useGLSL) return false; // GLSL not available
1068
// if (!_noshader) return true;
1070
if (loc==-1) return false; // can't find variable
1072
glUniform2ivARB(loc, count, value);
1076
//-----------------------------------------------------------------------------
1078
bool IOpenGLShaderProgram::SetUniform3iv(char* varname, GLsizei count, GLint *value)
1080
// if (!useGLSL) return false; // GLSL not available
1081
// if (!_noshader) return true;
1083
GLint loc = GetUniformLocationARB(varname);
1084
if (loc==-1) return false; // can't find variable
1086
glUniform3ivARB(loc, count, value);
1090
bool IOpenGLShaderProgram::SetUniform3iv(GLint loc, GLsizei count, GLint *value)
1092
// if (!useGLSL) return false; // GLSL not available
1093
// if (!_noshader) return true;
1095
if (loc==-1) return false; // can't find variable
1097
glUniform3ivARB(loc, count, value);
1101
//-----------------------------------------------------------------------------
1103
bool IOpenGLShaderProgram::SetUniform4iv(char* varname, GLsizei count, GLint *value)
1105
// if (!useGLSL) return false; // GLSL not available
1106
// if (!_noshader) return true;
1108
GLint loc = GetUniformLocationARB(varname);
1109
if (loc==-1) return false; // can't find variable
1111
glUniform4ivARB(loc, count, value);
1115
bool IOpenGLShaderProgram::SetUniform4iv(GLint loc, GLsizei count, GLint *value)
1117
// if (!useGLSL) return false; // GLSL not available
1118
// if (!_noshader) return true;
1120
if (loc==-1) return false; // can't find variable
1122
glUniform4ivARB(loc, count, value);
1126
//-----------------------------------------------------------------------------
1128
bool IOpenGLShaderProgram::SetUniformMatrix2fv(char* varname, GLsizei count, GLboolean transpose, GLfloat *value)
1130
// if (!useGLSL) return false; // GLSL not available
1131
// if (!_noshader) return true;
1133
GLint loc = GetUniformLocationARB(varname);
1134
if (loc==-1) return false; // can't find variable
1136
glUniformMatrix2fvARB(loc, count, transpose, value);
1140
bool IOpenGLShaderProgram::SetUniformLocMatrix2fv(GLint loc, GLsizei count, GLboolean transpose, GLfloat *value)
1142
// if (!useGLSL) return false; // GLSL not available
1143
// if (!_noshader) return true;
1145
if (loc==-1) return false; // can't find variable
1147
glUniformMatrix2fvARB(loc, count, transpose, value);
1151
//-----------------------------------------------------------------------------
1153
bool IOpenGLShaderProgram::SetUniformMatrix3fv(char* varname, GLsizei count, GLboolean transpose, GLfloat *value)
1155
// if (!useGLSL) return false; // GLSL not available
1156
// if (!_noshader) return true;
1158
GLint loc = GetUniformLocationARB(varname);
1159
if (loc==-1) return false; // can't find variable
1161
glUniformMatrix3fvARB(loc, count, transpose, value);
1165
bool IOpenGLShaderProgram::SetUniformLocMatrix3fv(GLint loc, GLsizei count, GLboolean transpose, GLfloat *value)
1167
// if (!useGLSL) return false; // GLSL not available
1168
// if (!_noshader) return true;
1170
if (loc==-1) return false; // can't find variable
1172
glUniformMatrix3fvARB(loc, count, transpose, value);
1176
//-----------------------------------------------------------------------------
1178
bool IOpenGLShaderProgram::SetUniformMatrix4fv(char* varname, GLsizei count, GLboolean transpose, GLfloat *value)
1180
// if (!useGLSL) return false; // GLSL not available
1181
// if (!_noshader) return true;
1183
GLint loc = GetUniformLocationARB(varname);
1184
if (loc==-1) return false; // can't find variable
1186
glUniformMatrix4fvARB(loc, count, transpose, value);
1190
bool IOpenGLShaderProgram::SetUniformLocMatrix4fv(GLint loc, GLsizei count, GLboolean transpose, GLfloat *value)
1192
// if (!useGLSL) return false; // GLSL not available
1193
// if (!_noshader) return true;
1195
if (loc==-1) return false; // can't find variable
1197
glUniformMatrix4fvARB(loc, count, transpose, value);
1202
//-----------------------------------------------------------------------------
1204
void IOpenGLShaderProgram::GetUniformfv(char* name, GLfloat* values)
1206
// if (!useGLSL) return;
1209
loc = glGetUniformLocationARB(_OpenGLID, name);
1210
CHECKGL_MSG( glGetUniformLocationARB );
1213
std::cout << "Error: can't find uniform variable \"" << name << "\"\n";
1215
CHECKGL( glGetUniformfvARB(_OpenGLID, loc, values) );
1218
//-----------------------------------------------------------------------------
1220
void IOpenGLShaderProgram::GetUniformiv(char* name, GLint* values)
1222
//if (!useGLSL) return;
1224
loc = glGetUniformLocationARB(_OpenGLID, name);
1225
CHECKGL_MSG( glGetUniformLocationARB );
1228
std::cout << "Error: can't find uniform variable \"" << name << "\"\n";
1230
CHECKGL( glGetUniformivARB(_OpenGLID, loc, values) );
1232
//-----------------------------------------------------------------------------
1234
int IOpenGLShaderProgram::GetUniformLocationARB(const GLcharARB* name)
1237
loc = glGetUniformLocationARB(_OpenGLID, name);
1238
CHECKGL_MSG( glGetUniformLocationARB );
1242
//-----------------------------------------------------------------------------
1243
void IOpenGLShaderProgram::GetActiveUniformARB(
1252
glGetActiveUniformARB(_OpenGLID,
1259
CHECKGL_MSG(glGetActiveUniformARB);
1262
//-----------------------------------------------------------------------------
1264
void IOpenGLShaderProgram::GetObjectParameterfvARB(GLenum pname,
1267
glGetObjectParameterfvARB(_OpenGLID,
1270
CHECKGL_MSG(glGetObjectParameterfvARB);
1273
//-----------------------------------------------------------------------------
1275
BOOL IOpenGLShaderProgram::SetSampler(char* name, int texture_unit)
1277
GLint loc = GetUniformLocationARB(name);
1278
if (loc==-1) return false; // can't find variable
1280
glUniform1iARB(loc, texture_unit);