~thumper/nux/next-changes

« back to all changes in this revision

Viewing changes to NuxGraphics/IOpenGLGLSLShader.cpp

  • Committer: Neil Jagdish Patel
  • Date: 2010-09-01 21:15:42 UTC
  • Revision ID: neil.patel@canonical.com-20100901211542-cw2ce3ak28unouwb
Add NuxGraphics with licensing

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright 2010 Inalogic Inc.
 
3
 *
 
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.
 
7
 *
 
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.
 
13
 * 
 
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/>
 
17
 *
 
18
 * Authored by: Jay Taoko <jay.taoko_AT_gmail_DOT_com>
 
19
 *
 
20
 */
 
21
 
 
22
 
 
23
#include "GLDeviceFactory.h"
 
24
#include "GLDeviceObjects.h"
 
25
#include "IOpenGLGLSLShader.h"
 
26
 
 
27
NAMESPACE_BEGIN_OGL
 
28
 
 
29
IMPLEMENT_OBJECT_TYPE(IOpenGLShader);
 
30
IMPLEMENT_OBJECT_TYPE(IOpenGLVertexShader);
 
31
IMPLEMENT_OBJECT_TYPE(IOpenGLPixelShader);
 
32
IMPLEMENT_OBJECT_TYPE(IOpenGLShaderProgram);
 
33
 
 
34
struct ShaderDefinition
 
35
{
 
36
    NString         Name;
 
37
    NString     Value;
 
38
};
 
39
 
 
40
//----------------------------------------------------------------------------- 
 
41
static void AddShaderDefinition(std::vector<ShaderDefinition>& Definitions,const TCHAR* Name,const TCHAR* Format,...)
 
42
{
 
43
    TCHAR       DefinitionText[1024];
 
44
    GET_VARARGS(DefinitionText, INL_ARRAY_COUNT(DefinitionText), INL_ARRAY_COUNT(DefinitionText)-1,Format);
 
45
 
 
46
    ShaderDefinition    Definition;
 
47
    Definition.Name = Name;
 
48
    Definition.Value = DefinitionText;
 
49
    Definitions.push_back(Definition);
 
50
}
 
51
 
 
52
//----------------------------------------------------------------------------- 
 
53
bool ExtractShaderString3(const NString &ShaderToken, const NString &ShaderSource, NString &RetSource, NString ShaderPreprocessorDefines)
 
54
{
 
55
    t_size lineStart = 0;
 
56
    t_size lineCount = 1;
 
57
    bool startTokenFound = false;
 
58
    t_size shaderStringStart =0;
 
59
    t_size shaderStartLine   =1;
 
60
 
 
61
 
 
62
    //Loop for all characters in the string
 
63
    if(ShaderToken != TEXT(""))
 
64
    {
 
65
        t_size i;
 
66
        for(i = 0; i< ShaderSource.Length(); i++)
 
67
        {
 
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))
 
71
            {
 
72
                if(!startTokenFound)
 
73
                {
 
74
                    //Test for the start token
 
75
                    if(ShaderSource.FindFirstOccurence(ShaderToken) == i)
 
76
                    {   
 
77
                        // Found the shader token
 
78
                        shaderStringStart = i + ShaderToken.Length();
 
79
                        startTokenFound = true;
 
80
 
 
81
                        //Set what line the shader was found on
 
82
                        shaderStartLine = lineCount;
 
83
                    }
 
84
                }
 
85
                else
 
86
                {
 
87
                    //Break where the end token was found
 
88
                    break;
 
89
                }
 
90
            }
 
91
 
 
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))
 
95
            {
 
96
                lineStart = i + 1;
 
97
            }
 
98
 
 
99
            //Count the new lines
 
100
            if(TCharStringNCompare(&ShaderSource[i], TEXT("\n"), 1) == 0)
 
101
            {
 
102
                lineCount++;
 
103
            }
 
104
        }
 
105
 
 
106
        //If the string was not found, return false
 
107
        if(!startTokenFound || shaderStringStart >= i)
 
108
        {
 
109
            return false;
 
110
        }
 
111
 
 
112
        //Assign the return string
 
113
        RetSource = ShaderSource.GetSubString(shaderStringStart, i - shaderStringStart);
 
114
 
 
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'))
 
119
        {
 
120
            if(RetSource[Pos] == 0)
 
121
                break;
 
122
            ++Pos;
 
123
        }
 
124
        if(RetSource[Pos] != 0)
 
125
            ++Pos;
 
126
 
 
127
        t_size EndOfLinePosition = 0;
 
128
        t_size LinePosition = 0;
 
129
        while((EndOfLinePosition = RetSource.FindNextOccurence(TEXT('\n'), EndOfLinePosition)) < Pos-1)
 
130
        {
 
131
            ++EndOfLinePosition;
 
132
            ++LinePosition;
 
133
        }
 
134
 
 
135
        RetSource.Insert(Pos, NString::Printf(TEXT("#line %u\n"), LinePosition + shaderStartLine));
 
136
 
 
137
        // Insert the preprocessor definitions before the #line directive
 
138
        if(ShaderPreprocessorDefines.Length())
 
139
            RetSource.Insert(Pos, ShaderPreprocessorDefines + NString(TEXT('\n')));
 
140
 
 
141
        return true;
 
142
    }
 
143
    else
 
144
    {
 
145
        // We are not searching for a start token. Return the whole source.
 
146
        RetSource = ShaderSource;
 
147
        return true;
 
148
    }
 
149
}
 
150
 
 
151
static void InsertPreProcessorDefinitions(const NString &ShaderSource, NString &RetSource, NString& ShaderPreprocessorDefines)
 
152
{
 
153
    RetSource = ShaderSource;
 
154
 
 
155
    if(ShaderPreprocessorDefines.Length() == 0)
 
156
        return;
 
157
 
 
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"));
 
160
    if(Pos != -1)
 
161
    {
 
162
        Pos = RetSource.FindNextOccurence(TEXT('\n'), Pos);
 
163
        if(Pos == -1)
 
164
        {
 
165
            // this is most likely an incorrect shader
 
166
            Pos = RetSource.Size();
 
167
            RetSource.Insert(Pos, NString(TEXT('\n')));
 
168
            Pos = RetSource.Size();
 
169
        }
 
170
        else
 
171
        {
 
172
            // Skip character \n
 
173
            Pos++;
 
174
        }
 
175
    }
 
176
    else
 
177
    {
 
178
        Pos = 0;
 
179
    }
 
180
 
 
181
    if(ShaderPreprocessorDefines.Length())
 
182
        RetSource.Insert(Pos, ShaderPreprocessorDefines + NString(TEXT('\n')));
 
183
}
 
184
 
 
185
IOpenGLShader::IOpenGLShader(NString ShaderName, OpenGLResourceType ResourceType)
 
186
:   IOpenGLResource(ResourceType)
 
187
,   _ShaderName(ShaderName)
 
188
{
 
189
 
 
190
}
 
191
 
 
192
IOpenGLShader::~IOpenGLShader()
 
193
{
 
194
 
 
195
}
 
196
 
 
197
IOpenGLVertexShader::IOpenGLVertexShader(NString ShaderName)
 
198
:   m_CompiledAndReady(false)
 
199
,   IOpenGLShader(ShaderName, RT_GLSL_VERTEXSHADER)
 
200
{
 
201
    _OpenGLID = glCreateShader(GL_VERTEX_SHADER_ARB);
 
202
    CHECKGL_MSG( glCreateShader(GL_VERTEX_SHADER_ARB) );
 
203
}
 
204
 
 
205
IOpenGLVertexShader::~IOpenGLVertexShader()
 
206
{
 
207
    CHECKGL( glDeleteShader(_OpenGLID) );
 
208
    _OpenGLID = 0;
 
209
    m_CompiledAndReady = false;
 
210
}
 
211
 
 
212
void IOpenGLVertexShader::SetShaderCode(const TCHAR* ShaderCode, const TCHAR* VtxShaderPreprocessorDefines)
 
213
{
 
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);
 
219
 
 
220
    m_CompiledAndReady = false;
 
221
    _ShaderCode = ProcessedShaderSource;
 
222
}
 
223
 
 
224
bool IOpenGLVertexShader::Compile()
 
225
{
 
226
    t_size CodeSize = _ShaderCode.Size();
 
227
    if(CodeSize == 0)
 
228
    {
 
229
        nuxDebugMsg(TEXT("[IOpenGLVertexShader::Compile] Vertex shader source code is empty."));
 
230
    }
 
231
 
 
232
    char* ShaderSource = new char[CodeSize+1];
 
233
    Memset(ShaderSource, 0, CodeSize+1);
 
234
    Memcpy(ShaderSource, _ShaderCode.GetTCharPtr(), CodeSize);
 
235
 
 
236
    CHECKGL( glShaderSource(_OpenGLID, 1, (const GLcharARB **)&ShaderSource, NULL) );
 
237
    delete ShaderSource;
 
238
 
 
239
    // compile vertex shader object
 
240
    CHECKGL( glCompileShader(_OpenGLID) );
 
241
 
 
242
    // check if shader compiled
 
243
    m_CompiledAndReady = false;
 
244
    CHECKGL( glGetShaderiv(_OpenGLID, GL_COMPILE_STATUS, &m_CompiledAndReady) );
 
245
 
 
246
    if(!m_CompiledAndReady)
 
247
    {
 
248
        ANSICHAR* InfoLogBuffer = 0;
 
249
        GLint InfoLogBufferSize = 0;
 
250
        GLint InfoLogReturnSize = 0;
 
251
        GLint iLog = 0;
 
252
 
 
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)
 
258
        {
 
259
            nuxError(TEXT("[IOpenGLVertexShader::Compile] glCompileShader: %s"), InfoLogBuffer);
 
260
        }
 
261
        delete InfoLogBuffer;
 
262
    }
 
263
 
 
264
    return (m_CompiledAndReady ? true : false);
 
265
}
 
266
 
 
267
bool IOpenGLVertexShader::IsValid()
 
268
{
 
269
    return (m_CompiledAndReady ? true : false);
 
270
}
 
271
 
 
272
IOpenGLPixelShader::IOpenGLPixelShader(NString ShaderName)
 
273
:   m_CompiledAndReady(false)
 
274
,   IOpenGLShader(ShaderName, RT_GLSL_PIXELSHADER)
 
275
{
 
276
    _OpenGLID = glCreateShader(GL_FRAGMENT_SHADER_ARB);
 
277
    CHECKGL_MSG( glCreateShader(GL_FRAGMENT_SHADER_ARB) );
 
278
}
 
279
 
 
280
IOpenGLPixelShader::~IOpenGLPixelShader()
 
281
{
 
282
    CHECKGL( glDeleteShader(_OpenGLID) );
 
283
    _OpenGLID = 0;
 
284
    m_CompiledAndReady = false;
 
285
}
 
286
 
 
287
void IOpenGLPixelShader::SetShaderCode(const TCHAR* ShaderCode, const TCHAR* FrgShaderPreprocessorDefines)
 
288
{
 
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);
 
294
 
 
295
    m_CompiledAndReady = false;
 
296
    _ShaderCode = ProcessedShaderSource;
 
297
}
 
298
 
 
299
bool IOpenGLPixelShader::Compile()
 
300
{
 
301
 
 
302
    GLint CodeSize = (GLint)_ShaderCode.Size();
 
303
    if(CodeSize == 0)
 
304
    {
 
305
        nuxDebugMsg(TEXT("[IOpenGLPixelShader::Compile] Pixel shader source code is empty."));
 
306
    }
 
307
 
 
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) );
 
312
    delete ShaderSource;
 
313
 
 
314
    // compile pixel shader object
 
315
    CHECKGL( glCompileShader(_OpenGLID) );
 
316
 
 
317
    // check if shader compiled
 
318
    m_CompiledAndReady = false;
 
319
    CHECKGL( glGetShaderiv(_OpenGLID, GL_COMPILE_STATUS, &m_CompiledAndReady) );
 
320
 
 
321
    if(!m_CompiledAndReady)
 
322
    {
 
323
        ANSICHAR* InfoLogBuffer = 0;
 
324
        GLint InfoLogBufferSize = 0;
 
325
        GLint InfoLogReturnSize = 0;
 
326
        GLint iLog = 0;
 
327
 
 
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)
 
333
        {
 
334
            nuxError(TEXT("[IOpenGLPixelShader::Compile] glCompileShader: %s"), InfoLogBuffer);
 
335
        }
 
336
        delete InfoLogBuffer;
 
337
    }
 
338
    return (m_CompiledAndReady ? true : false);
 
339
}
 
340
 
 
341
bool IOpenGLPixelShader::IsValid()
 
342
{
 
343
    return (m_CompiledAndReady ? true : false);
 
344
}
 
345
 
 
346
IOpenGLShaderProgram::IOpenGLShaderProgram(NString ShaderProgramName)
 
347
:   m_CompiledAndReady(false)
 
348
,   IOpenGLResource(RT_GLSL_SHADERPROGRAM)
 
349
,   _ShaderProgramName(ShaderProgramName)
 
350
,   _FirstParameter(0)
 
351
{
 
352
    _OpenGLID = glCreateProgram();
 
353
    CHECKGL_MSG( glCreateProgram() );
 
354
}
 
355
 
 
356
IOpenGLShaderProgram::~IOpenGLShaderProgram()
 
357
{
 
358
    CHECKGL( glDeleteProgram(_OpenGLID) );
 
359
    _OpenGLID = 0;
 
360
    m_CompiledAndReady = false;
 
361
}
 
362
 
 
363
void IOpenGLShaderProgram::LoadIShaderFile(const TCHAR* ShaderFileName, const TCHAR* VtxShaderPreprocessorDefines, const TCHAR* FrgShaderPreprocessorDefines)
 
364
{
 
365
    nuxAssertMsg(ShaderFileName, TEXT("[IOpenGLShaderProgram::LoadIShaderFile] Invalid shader file name."));
 
366
    INL_RETURN_IF_NULL(ShaderFileName);
 
367
    NString SourceCode;
 
368
    LoadFileToString(SourceCode, ShaderFileName);
 
369
    LoadIShader(&SourceCode[0], VtxShaderPreprocessorDefines, FrgShaderPreprocessorDefines);
 
370
}
 
371
 
 
372
void IOpenGLShaderProgram::LoadIShader(const TCHAR* ShaderCode, const TCHAR* VtxShaderPreprocessorDefines, const TCHAR* FrgShaderPreprocessorDefines)
 
373
{
 
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));
 
380
 
 
381
    TRefGL<IOpenGLVertexShader> vs = GetThreadGLDeviceFactory()->CreateVertexShader(); //new IOpenGLVertexShader;
 
382
    TRefGL<IOpenGLPixelShader> ps = GetThreadGLDeviceFactory()->CreatePixelShader(); //new IOpenGLPixelShader;
 
383
 
 
384
    vs->SetShaderCode(&VertexShaderSource[0]);
 
385
    ps->SetShaderCode(&PixelShaderSource[0]);
 
386
    vs->Compile();
 
387
    ps->Compile();
 
388
 
 
389
    ShaderObjectList.clear();
 
390
 
 
391
    AddShaderObject(vs);
 
392
    AddShaderObject(ps);
 
393
}
 
394
 
 
395
void IOpenGLShaderProgram::LoadVertexShader(const TCHAR* glslshader, const TCHAR* VtxShaderPreprocessorDefines)
 
396
{
 
397
    nuxAssertMsg(glslshader, TEXT("[IOpenGLShaderProgram::LoadVertexShader] Invalid shader code."));
 
398
    INL_RETURN_IF_NULL(glslshader);
 
399
    TRefGL<IOpenGLVertexShader> vs = GetThreadGLDeviceFactory()->CreateVertexShader(); //new IOpenGLVertexShader;
 
400
 
 
401
    NString ProcessedShaderSource;
 
402
    NString Defines(VtxShaderPreprocessorDefines);
 
403
    InsertPreProcessorDefinitions(glslshader, ProcessedShaderSource, Defines);
 
404
 
 
405
    vs->SetShaderCode(glslshader);
 
406
    vs->Compile();
 
407
    AddShaderObject(vs);
 
408
}
 
409
 
 
410
void IOpenGLShaderProgram::LoadPixelShader(const TCHAR* glslshader, const TCHAR* FrgShaderPreprocessorDefines)
 
411
{
 
412
    nuxAssertMsg(glslshader, TEXT("[IOpenGLShaderProgram::LoadPixelShader] Invalid shader code."));
 
413
    INL_RETURN_IF_NULL(glslshader);
 
414
    TRefGL<IOpenGLPixelShader> ps = GetThreadGLDeviceFactory()->CreatePixelShader(); //new IOpenGLPixelShader;
 
415
 
 
416
    NString ProcessedShaderSource;
 
417
    NString Defines(FrgShaderPreprocessorDefines);
 
418
    InsertPreProcessorDefinitions(glslshader, ProcessedShaderSource, Defines);
 
419
 
 
420
    ps->SetShaderCode(glslshader);
 
421
    ps->Compile();
 
422
    AddShaderObject(ps);
 
423
}
 
424
 
 
425
void IOpenGLShaderProgram::AddShaderObject(TRefGL<IOpenGLShader> ShaderObject)
 
426
{
 
427
    ShaderObjectList.push_back(ShaderObject);
 
428
}
 
429
 
 
430
void IOpenGLShaderProgram::AddShaderParameter(GLShaderParameter* Parameter)
 
431
{
 
432
    Parameter->m_NextParameter = _FirstParameter;
 
433
    _FirstParameter = Parameter;
 
434
 
 
435
    // If we add shader parameters after the program is linked, we need to call CheckUniformLocation().
 
436
    CheckUniformLocation();
 
437
}
 
438
 
 
439
void IOpenGLShaderProgram::RemoveShaderObject(TRefGL<IOpenGLShader> ShaderObject)
 
440
{
 
441
    std::vector< TRefGL<IOpenGLShader> >::iterator it = find(ShaderObjectList.begin(), ShaderObjectList.end(), ShaderObject);
 
442
    if(it != ShaderObjectList.end())
 
443
    {
 
444
        ShaderObjectList.erase(it);
 
445
    }
 
446
}
 
447
 
 
448
void IOpenGLShaderProgram::ClearShaderObjects()
 
449
{
 
450
    ShaderObjectList.clear();
 
451
}
 
452
 
 
453
bool IOpenGLShaderProgram::Link()
 
454
{
 
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)
 
460
    {
 
461
        ShaderObjects = new GLuint[NumAttachedShaders];
 
462
    }
 
463
    CHECKGL( glGetAttachedShaders(_OpenGLID, NumAttachedShaders, NULL, ShaderObjects) );
 
464
 
 
465
    // Detach everything first
 
466
    for (int i=0; i < (int)NumAttachedShaders; i++)
 
467
    {
 
468
        unsigned int obj = ShaderObjects[i];
 
469
        CHECKGL( glDetachShader(_OpenGLID, obj) );
 
470
    }
 
471
    if(NumAttachedShaders)
 
472
    {
 
473
        delete ShaderObjects;
 
474
    }
 
475
 
 
476
    for (int i=0; i < (int)ShaderObjectList.size(); i++)
 
477
    {
 
478
        if(!ShaderObjectList[i]->IsValid())
 
479
        {
 
480
            if(ShaderObjectList[i]->Compile() == false)
 
481
            {
 
482
                nuxDebugMsg(TEXT("[IOpenGLShaderProgram::Link] Attached shader %s does not compile with program: %s."), ShaderObjectList[i]->_ShaderName.GetTCharPtr(), _ShaderProgramName.GetTCharPtr());
 
483
            }
 
484
        }
 
485
        unsigned int obj = ShaderObjectList[i]->GetOpenGLID();
 
486
        CHECKGL( glAttachShader(_OpenGLID, obj) );
 
487
    }
 
488
 
 
489
    GLint linked;
 
490
    CHECKGL( glLinkProgram(_OpenGLID) );
 
491
    CHECKGL( glGetProgramiv(_OpenGLID, GL_LINK_STATUS, &linked) );
 
492
    if(linked == GL_FALSE)
 
493
    {
 
494
        ANSICHAR* InfoLogBuffer = 0;
 
495
        GLint InfoLogBufferSize = 0;
 
496
        GLint InfoLogReturnSize = 0;
 
497
        GLint iLog = 0;
 
498
        glGetProgramiv(_OpenGLID, GL_INFO_LOG_LENGTH, &iLog);
 
499
        InfoLogBuffer = new ANSICHAR[iLog+1];
 
500
        InfoLogBufferSize = iLog+1;
 
501
 
 
502
        glGetProgramInfoLog(_OpenGLID, InfoLogBufferSize, &InfoLogReturnSize, InfoLogBuffer);
 
503
        if(InfoLogReturnSize != 0)
 
504
        {
 
505
            nuxError(TEXT("[IOpenGLShaderProgram::Link] glLinkProgram: %s"), InfoLogBuffer);
 
506
        }
 
507
        delete InfoLogBuffer;
 
508
        m_CompiledAndReady = false;
 
509
        return m_CompiledAndReady;
 
510
    }
 
511
 
 
512
    GLint validated;
 
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)
 
517
    {
 
518
        ANSICHAR* InfoLogBuffer = 0;
 
519
        GLint InfoLogBufferSize = 0;
 
520
        GLint InfoLogReturnSize = 0;
 
521
        GLint iLog = 0;
 
522
        glGetProgramiv(_OpenGLID, GL_INFO_LOG_LENGTH, &iLog);
 
523
        InfoLogBuffer = new ANSICHAR[iLog+1];
 
524
        InfoLogBufferSize = iLog+1;
 
525
 
 
526
        glGetProgramInfoLog(_OpenGLID, InfoLogBufferSize, &InfoLogReturnSize, InfoLogBuffer);
 
527
        if(InfoLogReturnSize != 0)
 
528
        {
 
529
            nuxError(TEXT("[IOpenGLShaderProgram::Link] glValidateProgram: %s"), InfoLogBuffer);
 
530
        }
 
531
        delete InfoLogBuffer;
 
532
    }
 
533
 
 
534
    m_CompiledAndReady = true;
 
535
 
 
536
    Begin();
 
537
    CheckAttributeLocation();
 
538
    CheckUniformLocation();
 
539
    End();
 
540
 
 
541
    return m_CompiledAndReady;
 
542
}
 
543
 
 
544
void IOpenGLShaderProgram::Begin(void)
 
545
{
 
546
    CHECKGL( glUseProgramObjectARB(_OpenGLID) );
 
547
}
 
548
 
 
549
void IOpenGLShaderProgram::End(void)
 
550
{
 
551
    CHECKGL( glUseProgramObjectARB(0) );
 
552
}
 
553
 
 
554
void IOpenGLShaderProgram::CheckAttributeLocation()
 
555
{
 
556
    //ResetAttributeVariable(m_ProgramAttributeDefinition);
 
557
    for(int i = 0; i < NUM_VERTEX_SHADER_INPUT_ATTRIBUTE; i++)
 
558
    {
 
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;
 
563
    }
 
564
 
 
565
    char active_attribute_name[256];
 
566
    GLsizei length;
 
567
    GLint size;
 
568
    GLenum type;
 
569
 
 
570
    GLint num_active_attributes;
 
571
    CHECKGL( glGetObjectParameterivARB(_OpenGLID, GL_OBJECT_ACTIVE_ATTRIBUTES_ARB, &num_active_attributes) );
 
572
 
 
573
 
 
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.
 
581
    // 
 
582
    //         Built-in vertex attribute name      Incompatible aliased vertex attribute index
 
583
    //         gl_Vertex                           0
 
584
    //         gl_Normal                           2
 
585
    //         gl_Color                            3
 
586
    //         gl_SecondaryColor                   4
 
587
    //         gl_FogCoord                         5
 
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.
 
601
 
 
602
    for(int index = 0; index < num_active_attributes; index++)
 
603
    {
 
604
        glGetActiveAttribARB(_OpenGLID,
 
605
            index,
 
606
            256,
 
607
            &length,
 
608
            &size,
 
609
            &type,
 
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;
 
615
 
 
616
        switch(type)
 
617
        {
 
618
        case GL_FLOAT:
 
619
            m_ProgramAttributeDefinition[index].type = VAT_FLOAT;
 
620
            break;
 
621
        case GL_FLOAT_VEC2:
 
622
            m_ProgramAttributeDefinition[index].type = VAT_FLOAT2;
 
623
            break;
 
624
        case GL_FLOAT_VEC3:
 
625
            m_ProgramAttributeDefinition[index].type = VAT_FLOAT3;
 
626
            break;
 
627
        case GL_FLOAT_VEC4:
 
628
            m_ProgramAttributeDefinition[index].type = VAT_FLOAT4;
 
629
            break;
 
630
 
 
631
        case GL_FLOAT_MAT2:
 
632
        case GL_FLOAT_MAT3:
 
633
        case GL_FLOAT_MAT4:
 
634
        default:
 
635
            //todo 
 
636
            nuxAssert(0);
 
637
        }
 
638
    }
 
639
 
 
640
 
 
641
    //    if(sad == 0)
 
642
    //        return;
 
643
    //    int n = sizeof(sad) / sizeof(IOpenGLShaderAttributeDefinition);
 
644
    //    for(int i = 0; i < num_active_attributes; i++)
 
645
    //    {
 
646
    //        bool found = false;
 
647
    //        for(int j = 0; j < n; j++)
 
648
    //        {
 
649
    //            if(m_ProgramAttributeDefinition[i].attribute_name == sad[j].attribute_name)
 
650
    //            {
 
651
    //                found = true;
 
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");
 
656
    //                break;
 
657
    //            }
 
658
    //            if(found == false)
 
659
    //            {
 
660
    //                OutputDebugString("*** Active binded but not requested in meta shader info.\n");
 
661
    //                nuxAssert(0);
 
662
    //            }
 
663
    //        }
 
664
    //    }
 
665
    //
 
666
    //
 
667
    //    for(int i = 0; i < n; i++)
 
668
    //    {
 
669
    //        bool found = false;
 
670
    //        for(int j = 0; j < num_active_attributes; j++)
 
671
    //        {
 
672
    //            if(sad[i].attribute_name == m_ProgramAttributeDefinition[j].attribute_name)
 
673
    //            {
 
674
    //                found = true;
 
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");
 
679
    //                break;
 
680
    //            }
 
681
    //            if(found == false)
 
682
    //            {
 
683
    //                OutputDebugString("*** Active requested in meta shader info but not binded.\n");
 
684
    //                nuxAssert(0);
 
685
    //            }
 
686
    //        }
 
687
    //    }
 
688
}
 
689
 
 
690
void IOpenGLShaderProgram::CheckUniformLocation()
 
691
{
 
692
    GLShaderParameter* parameter = _FirstParameter;
 
693
    while(m_CompiledAndReady && parameter)
 
694
    {
 
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))
 
699
        {
 
700
            nuxDebugMsg(TEXT("[IOpenGLShaderProgram::CheckUniformLocation] Couldn't find shader program parameter %s \n"), parameter->m_Name.GetTCharPtr());
 
701
            nuxAssert(0);
 
702
        }
 
703
 
 
704
        //GLsizei length;
 
705
        GLint size = 0;
 
706
        GLenum type = 0;
 
707
        if(location >= 0)
 
708
        {
 
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) );
 
712
        }
 
713
        parameter->m_Index = location;
 
714
        parameter->m_Size = size;
 
715
        parameter->m_Type = type;
 
716
 
 
717
        parameter = parameter->m_NextParameter;
 
718
    }
 
719
}
 
720
 
 
721
int IOpenGLShaderProgram::GetAttributeLocation(const TCHAR* AttributeName)
 
722
{
 
723
    for(int i = 0; i < 16 /*NUM_VERTEX_SHADER_INPUT_ATTRIBUTE*/; i++)
 
724
    {
 
725
        if(m_ProgramAttributeDefinition[i].attribute_name == AttributeName)
 
726
            return m_ProgramAttributeDefinition[i].attribute_index;
 
727
    }
 
728
    return -1;
 
729
}
 
730
 
 
731
//----------------------------------------------------------------------------- 
 
732
bool IOpenGLShaderProgram::SetUniform1f(char* varname, GLfloat v0)
 
733
{
 
734
    //if (!useGLSL) return false; // GLSL not available
 
735
    //if (!_noshader) return true;
 
736
 
 
737
    GLint loc = GetUniformLocationARB(varname);
 
738
    if (loc==-1) return false;  // can't find variable
 
739
 
 
740
    glUniform1fARB(loc, v0);
 
741
 
 
742
    return true;
 
743
}
 
744
bool IOpenGLShaderProgram::SetUniform1f(GLint loc, GLfloat v0)
 
745
{
 
746
    //if (!useGLSL) return false; // GLSL not available
 
747
    //if (!_noshader) return true;
 
748
 
 
749
    if (loc==-1) return false;  // can't find variable
 
750
    glUniform1fARB(loc, v0);
 
751
    return true;
 
752
}
 
753
 
 
754
//----------------------------------------------------------------------------- 
 
755
 
 
756
bool IOpenGLShaderProgram::SetUniform2f(char* varname, GLfloat v0, GLfloat v1)
 
757
{
 
758
    //if (!useGLSL) return false; // GLSL not available
 
759
    //if (!_noshader) return true;
 
760
 
 
761
    GLint loc = GetUniformLocationARB(varname);
 
762
    if (loc==-1) return false;  // can't find variable
 
763
 
 
764
    glUniform2fARB(loc, v0, v1);
 
765
 
 
766
    return true;
 
767
}
 
768
bool IOpenGLShaderProgram::SetUniform2f(GLint loc, GLfloat v0, GLfloat v1)
 
769
{
 
770
    //if (!useGLSL) return false; // GLSL not available
 
771
    //if (!_noshader) return true;
 
772
 
 
773
    if (loc==-1) return false;  // can't find variable
 
774
    glUniform2fARB(loc, v0, v1);
 
775
    return true;
 
776
}
 
777
//----------------------------------------------------------------------------- 
 
778
 
 
779
bool IOpenGLShaderProgram::SetUniform3f(char* varname, GLfloat v0, GLfloat v1, GLfloat v2)
 
780
{
 
781
    //if (!useGLSL) return false; // GLSL not available
 
782
    //if (!_noshader) return true;
 
783
 
 
784
    GLint loc = GetUniformLocationARB(varname);
 
785
    if (loc==-1) return false;  // can't find variable
 
786
 
 
787
    glUniform3fARB(loc, v0, v1, v2);
 
788
 
 
789
    return true;
 
790
}
 
791
bool IOpenGLShaderProgram::SetUniform3f(GLint loc, GLfloat v0, GLfloat v1, GLfloat v2)
 
792
{
 
793
    //if (!useGLSL) return false; // GLSL not available
 
794
    //if (!_noshader) return true;
 
795
 
 
796
    if (loc==-1) return false;  // can't find variable
 
797
 
 
798
    glUniform3fARB(loc, v0, v1, v2);
 
799
 
 
800
    return true;
 
801
}
 
802
//----------------------------------------------------------------------------- 
 
803
 
 
804
bool IOpenGLShaderProgram::SetUniform4f(char* varname, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3)
 
805
{
 
806
    //if (!useGLSL) return false; // GLSL not available
 
807
    //if (!_noshader) return true;
 
808
 
 
809
    GLint loc = GetUniformLocationARB(varname);
 
810
    if (loc==-1) return false;  // can't find variable
 
811
 
 
812
    glUniform4fARB(loc, v0, v1, v2, v3);
 
813
 
 
814
    return true;
 
815
}
 
816
bool IOpenGLShaderProgram::SetUniform4f(GLint loc, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3)
 
817
{
 
818
    //if (!useGLSL) return false; // GLSL not available
 
819
    //if (!_noshader) return true;
 
820
 
 
821
    if (loc==-1) return false;  // can't find variable
 
822
 
 
823
    glUniform4fARB(loc, v0, v1, v2, v3);
 
824
 
 
825
    return true;
 
826
}
 
827
//----------------------------------------------------------------------------- 
 
828
 
 
829
bool IOpenGLShaderProgram::SetUniform1i(char* varname, GLint v0)
 
830
 
831
    //if (!useGLSL) return false; // GLSL not available
 
832
    //if (!_noshader) return true;
 
833
 
 
834
    GLint loc = GetUniformLocationARB(varname);
 
835
    if (loc==-1) return false;  // can't find variable
 
836
 
 
837
    glUniform1iARB(loc, v0);
 
838
 
 
839
    return true;
 
840
}
 
841
bool IOpenGLShaderProgram::SetUniform1i(GLint loc, GLint v0)
 
842
 
843
    //if (!useGLSL) return false; // GLSL not available
 
844
    //if (!_noshader) return true;
 
845
 
 
846
    if (loc==-1) return false;  // can't find variable
 
847
 
 
848
    glUniform1iARB(loc, v0);
 
849
 
 
850
    return true;
 
851
}
 
852
 
 
853
bool IOpenGLShaderProgram::SetUniform2i(char* varname, GLint v0, GLint v1)
 
854
{
 
855
    //    if (!useGLSL) return false; // GLSL not available
 
856
    //    if (!_noshader) return true;
 
857
 
 
858
    GLint loc = GetUniformLocationARB(varname);
 
859
    if (loc==-1) return false;  // can't find variable
 
860
 
 
861
    glUniform2iARB(loc, v0, v1);
 
862
 
 
863
 
 
864
    return true;
 
865
}
 
866
bool IOpenGLShaderProgram::SetUniform2i(GLint loc, GLint v0, GLint v1)
 
867
{
 
868
    //    if (!useGLSL) return false; // GLSL not available
 
869
    //    if (!_noshader) return true;
 
870
 
 
871
    if (loc==-1) return false;  // can't find variable
 
872
 
 
873
    glUniform2iARB(loc, v0, v1);
 
874
 
 
875
 
 
876
    return true;
 
877
}
 
878
//----------------------------------------------------------------------------- 
 
879
 
 
880
bool IOpenGLShaderProgram::SetUniform3i(char* varname, GLint v0, GLint v1, GLint v2)
 
881
{
 
882
    //    if (!useGLSL) return false; // GLSL not available
 
883
    //    if (!_noshader) return true;
 
884
 
 
885
    GLint loc = GetUniformLocationARB(varname);
 
886
    if (loc==-1) return false;  // can't find variable
 
887
 
 
888
    glUniform3iARB(loc, v0, v1, v2);
 
889
 
 
890
    return true;
 
891
}
 
892
bool IOpenGLShaderProgram::SetUniform3i(GLint loc, GLint v0, GLint v1, GLint v2)
 
893
{
 
894
    //    if (!useGLSL) return false; // GLSL not available
 
895
    //    if (!_noshader) return true;
 
896
 
 
897
    if (loc==-1) return false;  // can't find variable
 
898
 
 
899
    glUniform3iARB(loc, v0, v1, v2);
 
900
 
 
901
    return true;
 
902
}
 
903
 
 
904
bool IOpenGLShaderProgram::SetUniform4i(char* varname, GLint v0, GLint v1, GLint v2, GLint v3)
 
905
{
 
906
    //    if (!useGLSL) return false; // GLSL not available
 
907
    //    if (!_noshader) return true;
 
908
 
 
909
    GLint loc = GetUniformLocationARB(varname);
 
910
    if (loc==-1) return false;  // can't find variable
 
911
 
 
912
    glUniform4iARB(loc, v0, v1, v2, v3);
 
913
 
 
914
    return true;
 
915
}
 
916
bool IOpenGLShaderProgram::SetUniform4i(GLint loc, GLint v0, GLint v1, GLint v2, GLint v3)
 
917
{
 
918
    //    if (!useGLSL) return false; // GLSL not available
 
919
    //    if (!_noshader) return true;
 
920
 
 
921
    if (loc==-1) return false;  // can't find variable
 
922
 
 
923
    glUniform4iARB(loc, v0, v1, v2, v3);
 
924
 
 
925
    return true;
 
926
}
 
927
//----------------------------------------------------------------------------- 
 
928
 
 
929
bool IOpenGLShaderProgram::SetUniform1fv(char* varname, GLsizei count, GLfloat *value)
 
930
{
 
931
    //    if (!useGLSL) return false; // GLSL not available
 
932
    //    if (!_noshader) return true;
 
933
 
 
934
    GLint loc = GetUniformLocationARB(varname);
 
935
    if (loc==-1) return false;  // can't find variable
 
936
 
 
937
    glUniform1fvARB(loc, count, value);
 
938
 
 
939
    return true;
 
940
}
 
941
bool IOpenGLShaderProgram::SetUniform1fv(GLint loc, GLsizei count, GLfloat *value)
 
942
{
 
943
    //    if (!useGLSL) return false; // GLSL not available
 
944
    //    if (!_noshader) return true;
 
945
 
 
946
    if (loc==-1) return false;  // can't find variable
 
947
 
 
948
    glUniform1fvARB(loc, count, value);
 
949
 
 
950
    return true;
 
951
}
 
952
 
 
953
bool IOpenGLShaderProgram::SetUniform2fv(char* varname, GLsizei count, GLfloat *value)
 
954
{
 
955
    //    if (!useGLSL) return false; // GLSL not available
 
956
    //    if (!_noshader) return true;
 
957
 
 
958
    GLint loc = GetUniformLocationARB(varname);
 
959
    if (loc==-1) return false;  // can't find variable
 
960
 
 
961
    glUniform2fvARB(loc, count, value);
 
962
 
 
963
    return true;
 
964
}
 
965
bool IOpenGLShaderProgram::SetUniform2fv(GLint loc, GLsizei count, GLfloat *value)
 
966
{
 
967
    //    if (!useGLSL) return false; // GLSL not available
 
968
    //    if (!_noshader) return true;
 
969
 
 
970
    if (loc==-1) return false;  // can't find variable
 
971
 
 
972
    glUniform2fvARB(loc, count, value);
 
973
 
 
974
    return true;
 
975
}
 
976
//----------------------------------------------------------------------------- 
 
977
 
 
978
bool IOpenGLShaderProgram::SetUniform3fv(char* varname, GLsizei count, GLfloat *value)
 
979
{
 
980
    //    if (!useGLSL) return false; // GLSL not available
 
981
    //    if (!_noshader) return true;
 
982
 
 
983
    GLint loc = GetUniformLocationARB(varname);
 
984
    if (loc==-1) return false;  // can't find variable
 
985
 
 
986
    glUniform3fvARB(loc, count, value);
 
987
 
 
988
    return true;
 
989
}
 
990
bool IOpenGLShaderProgram::SetUniform3fv(GLint loc, GLsizei count, GLfloat *value)
 
991
{
 
992
    //    if (!useGLSL) return false; // GLSL not available
 
993
    //    if (!_noshader) return true;
 
994
 
 
995
    if (loc==-1) return false;  // can't find variable
 
996
 
 
997
    glUniform3fvARB(loc, count, value);
 
998
 
 
999
    return true;
 
1000
}
 
1001
//----------------------------------------------------------------------------- 
 
1002
 
 
1003
bool IOpenGLShaderProgram::SetUniform4fv(char* varname, GLsizei count, GLfloat *value)
 
1004
{
 
1005
    //    if (!useGLSL) return false; // GLSL not available
 
1006
    //    if (!_noshader) return true;
 
1007
 
 
1008
    GLint loc = GetUniformLocationARB(varname);
 
1009
    if (loc==-1) return false;  // can't find variable
 
1010
 
 
1011
    glUniform4fvARB(loc, count, value);
 
1012
 
 
1013
    return true;
 
1014
}
 
1015
bool IOpenGLShaderProgram::SetUniform4fv(GLint loc, GLsizei count, GLfloat *value)
 
1016
{
 
1017
    //    if (!useGLSL) return false; // GLSL not available
 
1018
    //    if (!_noshader) return true;
 
1019
 
 
1020
    if (loc==-1) return false;  // can't find variable
 
1021
 
 
1022
    glUniform4fvARB(loc, count, value);
 
1023
 
 
1024
    return true;
 
1025
}
 
1026
//----------------------------------------------------------------------------- 
 
1027
 
 
1028
bool IOpenGLShaderProgram::SetUniform1iv(char* varname, GLsizei count, GLint *value)
 
1029
{
 
1030
    //    if (!useGLSL) return false; // GLSL not available
 
1031
    //    if (!_noshader) return true;
 
1032
 
 
1033
    GLint loc = GetUniformLocationARB(varname);
 
1034
    if (loc==-1) return false;  // can't find variable
 
1035
 
 
1036
    glUniform1ivARB(loc, count, value);
 
1037
 
 
1038
    return true;
 
1039
}
 
1040
bool IOpenGLShaderProgram::SetUniform1iv(GLint loc, GLsizei count, GLint *value)
 
1041
{
 
1042
    //    if (!useGLSL) return false; // GLSL not available
 
1043
    //    if (!_noshader) return true;
 
1044
 
 
1045
    if (loc==-1) return false;  // can't find variable
 
1046
 
 
1047
    glUniform1ivARB(loc, count, value);
 
1048
 
 
1049
    return true;
 
1050
}
 
1051
//----------------------------------------------------------------------------- 
 
1052
 
 
1053
bool IOpenGLShaderProgram::SetUniform2iv(char* varname, GLsizei count, GLint *value)
 
1054
{
 
1055
    //    if (!useGLSL) return false; // GLSL not available
 
1056
    //    if (!_noshader) return true;
 
1057
 
 
1058
    GLint loc = GetUniformLocationARB(varname);
 
1059
    if (loc==-1) return false;  // can't find variable
 
1060
 
 
1061
    glUniform2ivARB(loc, count, value);
 
1062
 
 
1063
    return true;
 
1064
}
 
1065
bool IOpenGLShaderProgram::SetUniform2iv(GLint loc, GLsizei count, GLint *value)
 
1066
{
 
1067
    //    if (!useGLSL) return false; // GLSL not available
 
1068
    //    if (!_noshader) return true;
 
1069
 
 
1070
    if (loc==-1) return false;  // can't find variable
 
1071
 
 
1072
    glUniform2ivARB(loc, count, value);
 
1073
 
 
1074
    return true;
 
1075
}
 
1076
//----------------------------------------------------------------------------- 
 
1077
 
 
1078
bool IOpenGLShaderProgram::SetUniform3iv(char* varname, GLsizei count, GLint *value)
 
1079
{
 
1080
    //    if (!useGLSL) return false; // GLSL not available
 
1081
    //    if (!_noshader) return true;
 
1082
 
 
1083
    GLint loc = GetUniformLocationARB(varname);
 
1084
    if (loc==-1) return false;  // can't find variable
 
1085
 
 
1086
    glUniform3ivARB(loc, count, value);
 
1087
 
 
1088
    return true;
 
1089
}
 
1090
bool IOpenGLShaderProgram::SetUniform3iv(GLint loc, GLsizei count, GLint *value)
 
1091
{
 
1092
    //    if (!useGLSL) return false; // GLSL not available
 
1093
    //    if (!_noshader) return true;
 
1094
 
 
1095
    if (loc==-1) return false;  // can't find variable
 
1096
 
 
1097
    glUniform3ivARB(loc, count, value);
 
1098
 
 
1099
    return true;
 
1100
}
 
1101
//----------------------------------------------------------------------------- 
 
1102
 
 
1103
bool IOpenGLShaderProgram::SetUniform4iv(char* varname, GLsizei count, GLint *value)
 
1104
{
 
1105
    //    if (!useGLSL) return false; // GLSL not available
 
1106
    //    if (!_noshader) return true;
 
1107
 
 
1108
    GLint loc = GetUniformLocationARB(varname);
 
1109
    if (loc==-1) return false;  // can't find variable
 
1110
 
 
1111
    glUniform4ivARB(loc, count, value);
 
1112
 
 
1113
    return true;
 
1114
}
 
1115
bool IOpenGLShaderProgram::SetUniform4iv(GLint loc, GLsizei count, GLint *value)
 
1116
{
 
1117
    //    if (!useGLSL) return false; // GLSL not available
 
1118
    //    if (!_noshader) return true;
 
1119
 
 
1120
    if (loc==-1) return false;  // can't find variable
 
1121
 
 
1122
    glUniform4ivARB(loc, count, value);
 
1123
 
 
1124
    return true;
 
1125
}
 
1126
//----------------------------------------------------------------------------- 
 
1127
 
 
1128
bool IOpenGLShaderProgram::SetUniformMatrix2fv(char* varname, GLsizei count, GLboolean transpose, GLfloat *value)
 
1129
{
 
1130
    //    if (!useGLSL) return false; // GLSL not available
 
1131
    //    if (!_noshader) return true;
 
1132
 
 
1133
    GLint loc = GetUniformLocationARB(varname);
 
1134
    if (loc==-1) return false;  // can't find variable
 
1135
 
 
1136
    glUniformMatrix2fvARB(loc, count, transpose, value);
 
1137
 
 
1138
    return true;
 
1139
}
 
1140
bool IOpenGLShaderProgram::SetUniformLocMatrix2fv(GLint loc, GLsizei count, GLboolean transpose, GLfloat *value)
 
1141
{
 
1142
    //    if (!useGLSL) return false; // GLSL not available
 
1143
    //    if (!_noshader) return true;
 
1144
 
 
1145
    if (loc==-1) return false;  // can't find variable
 
1146
 
 
1147
    glUniformMatrix2fvARB(loc, count, transpose, value);
 
1148
 
 
1149
    return true;
 
1150
}
 
1151
//----------------------------------------------------------------------------- 
 
1152
 
 
1153
bool IOpenGLShaderProgram::SetUniformMatrix3fv(char* varname, GLsizei count, GLboolean transpose, GLfloat *value)
 
1154
{
 
1155
    //    if (!useGLSL) return false; // GLSL not available
 
1156
    //    if (!_noshader) return true;
 
1157
 
 
1158
    GLint loc = GetUniformLocationARB(varname);
 
1159
    if (loc==-1) return false;  // can't find variable
 
1160
 
 
1161
    glUniformMatrix3fvARB(loc, count, transpose, value);
 
1162
 
 
1163
    return true;
 
1164
}
 
1165
bool IOpenGLShaderProgram::SetUniformLocMatrix3fv(GLint loc, GLsizei count, GLboolean transpose, GLfloat *value)
 
1166
{
 
1167
    //    if (!useGLSL) return false; // GLSL not available
 
1168
    //    if (!_noshader) return true;
 
1169
 
 
1170
    if (loc==-1) return false;  // can't find variable
 
1171
 
 
1172
    glUniformMatrix3fvARB(loc, count, transpose, value);
 
1173
 
 
1174
    return true;
 
1175
}
 
1176
//----------------------------------------------------------------------------- 
 
1177
 
 
1178
bool IOpenGLShaderProgram::SetUniformMatrix4fv(char* varname, GLsizei count, GLboolean transpose, GLfloat *value)
 
1179
{
 
1180
    //    if (!useGLSL) return false; // GLSL not available
 
1181
    //    if (!_noshader) return true;
 
1182
 
 
1183
    GLint loc = GetUniformLocationARB(varname);
 
1184
    if (loc==-1) return false;  // can't find variable
 
1185
 
 
1186
    glUniformMatrix4fvARB(loc, count, transpose, value);
 
1187
 
 
1188
    return true;
 
1189
}
 
1190
bool IOpenGLShaderProgram::SetUniformLocMatrix4fv(GLint loc, GLsizei count, GLboolean transpose, GLfloat *value)
 
1191
{
 
1192
    //    if (!useGLSL) return false; // GLSL not available
 
1193
    //    if (!_noshader) return true;
 
1194
 
 
1195
    if (loc==-1) return false;  // can't find variable
 
1196
 
 
1197
    glUniformMatrix4fvARB(loc, count, transpose, value);
 
1198
 
 
1199
    return true;
 
1200
}
 
1201
 
 
1202
//----------------------------------------------------------------------------- 
 
1203
 
 
1204
void IOpenGLShaderProgram::GetUniformfv(char* name, GLfloat* values)
 
1205
{
 
1206
    //     if (!useGLSL) return;
 
1207
    GLint loc;
 
1208
 
 
1209
    loc = glGetUniformLocationARB(_OpenGLID, name);
 
1210
    CHECKGL_MSG( glGetUniformLocationARB );
 
1211
    if (loc == -1) 
 
1212
    {
 
1213
        std::cout << "Error: can't find uniform variable \"" << name << "\"\n";
 
1214
    }
 
1215
    CHECKGL( glGetUniformfvARB(_OpenGLID, loc, values) );
 
1216
}
 
1217
 
 
1218
//----------------------------------------------------------------------------- 
 
1219
 
 
1220
void IOpenGLShaderProgram::GetUniformiv(char* name, GLint* values)
 
1221
{
 
1222
    //if (!useGLSL) return;
 
1223
    GLint loc;
 
1224
    loc = glGetUniformLocationARB(_OpenGLID, name);
 
1225
    CHECKGL_MSG( glGetUniformLocationARB );
 
1226
    if (loc == -1) 
 
1227
    {
 
1228
        std::cout << "Error: can't find uniform variable \"" << name << "\"\n";
 
1229
    }
 
1230
    CHECKGL( glGetUniformivARB(_OpenGLID, loc, values) );
 
1231
}
 
1232
//----------------------------------------------------------------------------- 
 
1233
 
 
1234
int IOpenGLShaderProgram::GetUniformLocationARB(const GLcharARB* name)
 
1235
{
 
1236
    GLint loc;
 
1237
    loc = glGetUniformLocationARB(_OpenGLID, name);
 
1238
    CHECKGL_MSG( glGetUniformLocationARB );
 
1239
    return loc;
 
1240
}
 
1241
 
 
1242
//----------------------------------------------------------------------------- 
 
1243
void IOpenGLShaderProgram::GetActiveUniformARB(
 
1244
    GLuint index,
 
1245
    GLsizei maxLength,
 
1246
    GLsizei *length,
 
1247
    GLint *size,
 
1248
    GLenum *type,
 
1249
    GLcharARB *name)
 
1250
{
 
1251
 
 
1252
    glGetActiveUniformARB(_OpenGLID,
 
1253
        index,
 
1254
        maxLength,
 
1255
        length,
 
1256
        size,
 
1257
        type,
 
1258
        name);
 
1259
    CHECKGL_MSG(glGetActiveUniformARB);
 
1260
}
 
1261
 
 
1262
//----------------------------------------------------------------------------- 
 
1263
 
 
1264
void IOpenGLShaderProgram::GetObjectParameterfvARB(GLenum pname,
 
1265
                                                   GLfloat *params)
 
1266
{
 
1267
    glGetObjectParameterfvARB(_OpenGLID,
 
1268
        pname,
 
1269
        params);
 
1270
    CHECKGL_MSG(glGetObjectParameterfvARB);
 
1271
}
 
1272
 
 
1273
//----------------------------------------------------------------------------- 
 
1274
 
 
1275
BOOL IOpenGLShaderProgram::SetSampler(char* name, int texture_unit)
 
1276
{
 
1277
    GLint loc = GetUniformLocationARB(name);
 
1278
    if (loc==-1) return false;  // can't find variable
 
1279
 
 
1280
    glUniform1iARB(loc, texture_unit);
 
1281
    return true;
 
1282
}
 
1283
 
 
1284
NAMESPACE_END_OGL