nux-1.16.0
IOpenGLGLSLShader.cpp
00001 /*
00002  * Copyright 2010 Inalogic® Inc.
00003  *
00004  * This program is free software: you can redistribute it and/or modify it
00005  * under the terms of the GNU Lesser General Public License, as
00006  * published by the  Free Software Foundation; either version 2.1 or 3.0
00007  * of the License.
00008  *
00009  * This program is distributed in the hope that it will be useful, but
00010  * WITHOUT ANY WARRANTY; without even the implied warranties of
00011  * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
00012  * PURPOSE.  See the applicable version of the GNU Lesser General Public
00013  * License for more details.
00014  *
00015  * You should have received a copy of both the GNU Lesser General Public
00016  * License along with this program. If not, see <http://www.gnu.org/licenses/>
00017  *
00018  * Authored by: Jay Taoko <jaytaoko@inalogic.com>
00019  *
00020  */
00021 
00022 #include "GLResource.h"
00023 #include "GraphicsDisplay.h"
00024 #include "GpuDevice.h"
00025 #include "GLDeviceObjects.h"
00026 #include "IOpenGLGLSLShader.h"
00027 
00028 namespace nux
00029 {
00030   namespace local
00031   {
00032   namespace
00033   {
00034     GLuint last_loaded_shader = 0;
00035     bool enable_tracking = false;
00036   }
00037   }
00038 
00039   NUX_IMPLEMENT_OBJECT_TYPE (IOpenGLShader);
00040   NUX_IMPLEMENT_OBJECT_TYPE (IOpenGLVertexShader);
00041   NUX_IMPLEMENT_OBJECT_TYPE (IOpenGLPixelShader);
00042   //NUX_IMPLEMENT_OBJECT_TYPE (IOpenGLGeometryShader);
00043   NUX_IMPLEMENT_OBJECT_TYPE (IOpenGLShaderProgram);
00044 
00045 
00046   bool ExtractShaderString3 (const NString &ShaderToken, const NString &ShaderSource, NString &RetSource, NString ShaderPreprocessorDefines)
00047   {
00048     t_size lineStart = 0;
00049     t_size lineCount = 1;
00050     bool startTokenFound = false;
00051     t_size shaderStringStart = 0;
00052     t_size shaderStartLine   = 1;
00053 
00054 
00055     //Loop for all characters in the string
00056     if (ShaderToken != TEXT ("") )
00057     {
00058       t_size i;
00059 
00060       for (i = 0; i < ShaderSource.Length(); i++)
00061       {
00062         //Check if the starting character '[' (open bracket) is found at the beginning of the line
00063         // i counts the characters in the file. lineStart is equal to i at the beginning of the line.
00064         if ( (TCharStringNCompare (&ShaderSource[i], TEXT ("["), 1) == 0) && (lineStart == i) )
00065         {
00066           if (!startTokenFound)
00067           {
00068             //Test for the start token
00069             if (ShaderSource.FindFirstOccurence (ShaderToken) == i)
00070             {
00071               // Found the shader token
00072               shaderStringStart = i + ShaderToken.Length();
00073               startTokenFound = true;
00074 
00075               //Set what line the shader was found on
00076               shaderStartLine = lineCount;
00077             }
00078           }
00079           else
00080           {
00081             //Break where the end token was found
00082             break;
00083           }
00084         }
00085 
00086         //If the character is equal to the new line character,
00087         // The next character must be on the new line
00088         if ( (TCharStringNCompare (&ShaderSource[i], TEXT ("\r"), 1) == 0) || (TCharStringNCompare (&ShaderSource[i], TEXT ("\n"), 1) == 0) )
00089         {
00090           lineStart = i + 1;
00091         }
00092 
00093         //Count the new lines
00094         if (TCharStringNCompare (&ShaderSource[i], TEXT ("\n"), 1) == 0)
00095         {
00096           lineCount++;
00097         }
00098       }
00099 
00100       //If the string was not found, return false
00101       if (!startTokenFound || shaderStringStart >= i)
00102       {
00103         return false;
00104       }
00105 
00106       //Assign the return string
00107       RetSource = ShaderSource.GetSubString (shaderStringStart, i - shaderStringStart);
00108 
00109       //Add the line directive to the shader source. See the documentation for GLSL #line directive.
00110       // GLSL spec: The #version directive must occur in a shader before anything else, except for comments and white space.
00111       t_size Pos = RetSource.FindFirstOccurence (TEXT ("#version") );
00112 
00113       while (RetSource[Pos] != TEXT ('\n') )
00114       {
00115         if (RetSource[Pos] == 0)
00116           break;
00117 
00118         ++Pos;
00119       }
00120 
00121       if (RetSource[Pos] != 0)
00122         ++Pos;
00123 
00124       t_size EndOfLinePosition = 0;
00125       t_size LinePosition = 0;
00126 
00127       while ( (EndOfLinePosition = RetSource.FindNextOccurence (TEXT ('\n'), EndOfLinePosition) ) < Pos - 1)
00128       {
00129         ++EndOfLinePosition;
00130         ++LinePosition;
00131       }
00132 
00133       RetSource.Insert (Pos, NString::Printf (TEXT ("#line %u\n"), LinePosition + shaderStartLine) );
00134 
00135       // Insert the preprocessor definitions before the #line directive
00136       if (ShaderPreprocessorDefines.Length() )
00137         RetSource.Insert (Pos, ShaderPreprocessorDefines + NString (TEXT ('\n') ) );
00138 
00139       return true;
00140     }
00141     else
00142     {
00143       // We are not searching for a start token. Return the whole source.
00144       RetSource = ShaderSource;
00145       return true;
00146     }
00147   }
00148 
00149   static void InsertPreProcessorDefinitions (const NString &ShaderSource, NString &RetSource, NString &ShaderPreprocessorDefines)
00150   {
00151     RetSource = ShaderSource;
00152 
00153     if (ShaderPreprocessorDefines.Length() == 0)
00154       return;
00155 
00156     // GLSL spec: The #version directive must occur in a shader before anything else, except for comments and white space.
00157     t_size Pos = RetSource.FindFirstOccurence (TEXT ("#version") );
00158 
00159     if (Pos != tstring::npos)
00160     {
00161       Pos = RetSource.FindNextOccurence (TEXT ('\n'), Pos);
00162 
00163       if (Pos == tstring::npos)
00164       {
00165         // this is most likely an incorrect shader
00166         Pos = RetSource.Size();
00167         RetSource.Insert (Pos, NString (TEXT ('\n') ) );
00168         Pos = RetSource.Size();
00169       }
00170       else
00171       {
00172         // Skip character \n
00173         Pos++;
00174       }
00175     }
00176     else
00177     {
00178       Pos = 0;
00179     }
00180 
00181     if (ShaderPreprocessorDefines.Length() )
00182       RetSource.Insert (Pos, ShaderPreprocessorDefines + NString (TEXT ('\n') ) );
00183   }
00184 
00185   IOpenGLShader::IOpenGLShader (NString ShaderName, OpenGLResourceType ResourceType)
00186     :   IOpenGLResource (ResourceType)
00187     ,   _ShaderName (ShaderName)
00188   {
00189 
00190   }
00191 
00192   IOpenGLShader::~IOpenGLShader()
00193   {
00194 
00195   }
00196 
00197   IOpenGLVertexShader::IOpenGLVertexShader (NString ShaderName)
00198     :   IOpenGLShader (ShaderName, RT_GLSL_VERTEXSHADER)
00199     ,   m_CompiledAndReady (false)
00200   {
00201     _OpenGLID = glCreateShader (GL_VERTEX_SHADER_ARB);
00202     CHECKGL_MSG ( glCreateShader (GL_VERTEX_SHADER_ARB) );
00203   }
00204 
00205   IOpenGLVertexShader::~IOpenGLVertexShader()
00206   {
00207     CHECKGL ( glDeleteShader (_OpenGLID) );
00208     _OpenGLID = 0;
00209     m_CompiledAndReady = false;
00210   }
00211 
00212   void IOpenGLVertexShader::SetShaderCode (const TCHAR *ShaderCode, const TCHAR *VtxShaderPreprocessorDefines)
00213   {
00214     nuxAssertMsg (ShaderCode, TEXT ("[IOpenGLVertexShader::SetShaderCode] Invalid shader code.") );
00215     NUX_RETURN_IF_NULL (ShaderCode);
00216     NString ProcessedShaderSource;
00217     NString Defines (VtxShaderPreprocessorDefines);
00218     InsertPreProcessorDefinitions (ShaderCode, ProcessedShaderSource, Defines);
00219 
00220     m_CompiledAndReady = false;
00221     _ShaderCode = ProcessedShaderSource;
00222   }
00223 
00224   bool IOpenGLVertexShader::Compile()
00225   {
00226     t_size CodeSize = _ShaderCode.Size();
00227 
00228     if (CodeSize == 0)
00229     {
00230       nuxDebugMsg (TEXT ("[IOpenGLVertexShader::Compile] Vertex shader source code is empty.") );
00231     }
00232 
00233     char *ShaderSource = new char[CodeSize+1];
00234     Memset (ShaderSource, 0, CodeSize + 1);
00235     Memcpy (ShaderSource, _ShaderCode.GetTCharPtr(), CodeSize);
00236 
00237     CHECKGL ( glShaderSource (_OpenGLID, 1, (const GLcharARB **) &ShaderSource, NULL) );
00238     delete [] ShaderSource;
00239 
00240     // compile vertex shader object
00241     CHECKGL ( glCompileShader (_OpenGLID) );
00242 
00243     // check if shader compiled
00244     m_CompiledAndReady = false;
00245     CHECKGL ( glGetShaderiv (_OpenGLID, GL_COMPILE_STATUS, &m_CompiledAndReady) );
00246 
00247     if (!m_CompiledAndReady)
00248     {
00249       ANSICHAR *InfoLogBuffer = 0;
00250       GLint InfoLogBufferSize = 0;
00251       GLint InfoLogReturnSize = 0;
00252       GLint iLog = 0;
00253 
00254       glGetShaderiv (_OpenGLID, GL_INFO_LOG_LENGTH, &iLog);
00255       InfoLogBuffer = new ANSICHAR[iLog+1];
00256       InfoLogBufferSize = iLog + 1;
00257       glGetShaderInfoLog (_OpenGLID, InfoLogBufferSize, &InfoLogReturnSize, InfoLogBuffer);
00258 
00259       if (InfoLogReturnSize != 0)
00260       {
00261         nuxError (TEXT ("[IOpenGLVertexShader::Compile] glCompileShader: %s"), InfoLogBuffer);
00262       }
00263 
00264       delete[] InfoLogBuffer;
00265     }
00266 
00267     return (m_CompiledAndReady ? true : false);
00268   }
00269 
00270   bool IOpenGLVertexShader::IsValid()
00271   {
00272     return (m_CompiledAndReady ? true : false);
00273   }
00274 
00275   IOpenGLPixelShader::IOpenGLPixelShader (NString ShaderName)
00276     :   IOpenGLShader (ShaderName, RT_GLSL_PIXELSHADER)
00277     ,   m_CompiledAndReady (false)
00278 
00279   {
00280     _OpenGLID = glCreateShader (GL_FRAGMENT_SHADER_ARB);
00281     CHECKGL_MSG ( glCreateShader (GL_FRAGMENT_SHADER_ARB) );
00282   }
00283 
00284   IOpenGLPixelShader::~IOpenGLPixelShader()
00285   {
00286     CHECKGL ( glDeleteShader (_OpenGLID) );
00287     _OpenGLID = 0;
00288     m_CompiledAndReady = false;
00289   }
00290 
00291   void IOpenGLPixelShader::SetShaderCode (const TCHAR *ShaderCode, const TCHAR *FrgShaderPreprocessorDefines)
00292   {
00293     nuxAssertMsg (ShaderCode, TEXT ("[IOpenGLPixelShader::SetShaderCode] Invalid shader code.") );
00294     NUX_RETURN_IF_NULL (ShaderCode);
00295     NString ProcessedShaderSource;
00296     NString Defines (FrgShaderPreprocessorDefines);
00297     InsertPreProcessorDefinitions (ShaderCode, ProcessedShaderSource, Defines);
00298 
00299     m_CompiledAndReady = false;
00300     _ShaderCode = ProcessedShaderSource;
00301   }
00302 
00303   bool IOpenGLPixelShader::Compile()
00304   {
00305 
00306     GLint CodeSize = (GLint) _ShaderCode.Size();
00307 
00308     if (CodeSize == 0)
00309     {
00310       nuxDebugMsg (TEXT ("[IOpenGLPixelShader::Compile] Pixel shader source code is empty.") );
00311     }
00312 
00313     char *ShaderSource = new char[CodeSize+1];
00314     Memset (ShaderSource, 0, CodeSize + 1);
00315     Memcpy (ShaderSource, _ShaderCode.m_string.c_str(), CodeSize);
00316     CHECKGL ( glShaderSource (_OpenGLID, 1, (const GLcharARB **) &ShaderSource, &CodeSize) );
00317     delete [] ShaderSource;
00318 
00319     // compile pixel shader object
00320     CHECKGL ( glCompileShader (_OpenGLID) );
00321 
00322     // check if shader compiled
00323     m_CompiledAndReady = false;
00324     CHECKGL ( glGetShaderiv (_OpenGLID, GL_COMPILE_STATUS, &m_CompiledAndReady) );
00325 
00326     if (!m_CompiledAndReady)
00327     {
00328       ANSICHAR *InfoLogBuffer = 0;
00329       GLint InfoLogBufferSize = 0;
00330       GLint InfoLogReturnSize = 0;
00331       GLint iLog = 0;
00332 
00333       glGetShaderiv (_OpenGLID, GL_INFO_LOG_LENGTH, &iLog);
00334       InfoLogBuffer = new ANSICHAR[iLog+1];
00335       InfoLogBufferSize = iLog + 1;
00336       glGetShaderInfoLog (_OpenGLID, InfoLogBufferSize, &InfoLogReturnSize, InfoLogBuffer);
00337 
00338       if (InfoLogReturnSize != 0)
00339       {
00340         nuxError (TEXT ("[IOpenGLPixelShader::Compile] glCompileShader: %s"), InfoLogBuffer);
00341       }
00342 
00343       delete[] InfoLogBuffer;
00344     }
00345 
00346     return (m_CompiledAndReady ? true : false);
00347   }
00348 
00349   bool IOpenGLPixelShader::IsValid()
00350   {
00351     return (m_CompiledAndReady ? true : false);
00352   }
00353 
00354 #if 0
00355   IOpenGLGeometryShader::IOpenGLGeometryShader (NString ShaderName)
00356     :   IOpenGLShader (ShaderName, RT_GLSL_GEOMETRYSHADER)
00357     ,   m_CompiledAndReady (false)
00358 
00359   {
00360     _OpenGLID = glCreateShader(GL_GEOMETRY_SHADER);
00361     CHECKGL_MSG(glCreateShader(GL_GEOMETRY_SHADER));
00362   }
00363 
00364   IOpenGLGeometryShader::~IOpenGLGeometryShader()
00365   {
00366     CHECKGL(glDeleteShader(_OpenGLID));
00367     _OpenGLID = 0;
00368     m_CompiledAndReady = false;
00369   }
00370 
00371   void IOpenGLGeometryShader::SetShaderCode (const TCHAR *ShaderCode, const TCHAR *GeometryShaderPreprocessorDefines)
00372   {
00373     nuxAssertMsg (ShaderCode, TEXT("[IOpenGLGeometryShader::SetShaderCode] Invalid shader code.") );
00374     NUX_RETURN_IF_NULL(ShaderCode);
00375     NString ProcessedShaderSource;
00376     NString Defines(GeometryShaderPreprocessorDefines);
00377     InsertPreProcessorDefinitions(ShaderCode, ProcessedShaderSource, Defines);
00378 
00379     m_CompiledAndReady = false;
00380     _ShaderCode = ProcessedShaderSource;
00381   }
00382 
00383   bool IOpenGLGeometryShader::Compile()
00384   {
00385 
00386     GLint CodeSize = (GLint) _ShaderCode.Size();
00387 
00388     if (CodeSize == 0)
00389     {
00390       nuxDebugMsg(TEXT("[IOpenGLGeometryShader::Compile] Pixel shader source code is empty.") );
00391     }
00392 
00393     char *ShaderSource = new char[CodeSize+1];
00394     Memset(ShaderSource, 0, CodeSize + 1);
00395     Memcpy(ShaderSource, _ShaderCode.m_string.c_str(), CodeSize);
00396     CHECKGL( glShaderSource(_OpenGLID, 1, (const GLcharARB **) &ShaderSource, &CodeSize) );
00397     delete [] ShaderSource;
00398 
00399     // compile pixel shader object
00400     CHECKGL(glCompileShader(_OpenGLID) );
00401 
00402     // check if shader compiled
00403     m_CompiledAndReady = false;
00404     CHECKGL( glGetShaderiv(_OpenGLID, GL_COMPILE_STATUS, &m_CompiledAndReady) );
00405 
00406     if (!m_CompiledAndReady)
00407     {
00408       ANSICHAR *InfoLogBuffer = 0;
00409       GLint InfoLogBufferSize = 0;
00410       GLint InfoLogReturnSize = 0;
00411       GLint iLog = 0;
00412 
00413       glGetShaderiv(_OpenGLID, GL_INFO_LOG_LENGTH, &iLog);
00414       InfoLogBuffer = new ANSICHAR[iLog+1];
00415       InfoLogBufferSize = iLog + 1;
00416       glGetShaderInfoLog(_OpenGLID, InfoLogBufferSize, &InfoLogReturnSize, InfoLogBuffer);
00417 
00418       if (InfoLogReturnSize != 0)
00419       {
00420         nuxError(TEXT("[IOpenGLGeometryShader::Compile] glCompileShader: %s"), InfoLogBuffer);
00421       }
00422 
00423       delete InfoLogBuffer;
00424     }
00425 
00426     return (m_CompiledAndReady ? true : false);
00427   }
00428 
00429   bool IOpenGLGeometryShader::IsValid()
00430   {
00431     return (m_CompiledAndReady ? true : false);
00432   }
00433 
00434   void IOpenGLGeometryShader::SetInputPrimitiveType(GLenum type)
00435   {
00436     CHECKGL(glProgramParameteri(_OpenGLID, GL_GEOMETRY_INPUT_TYPE_EXT, type));
00437   }
00438 
00439   void IOpenGLGeometryShader::SetOutputPrimitiveType(GLenum type)
00440   {
00441     CHECKGL(glProgramParameteri(_OpenGLID, GL_GEOMETRY_OUTPUT_TYPE_EXT, type));
00442   }
00443 
00444   void IOpenGLGeometryShader::SetMaxVertexOutput(int max_vertex_output)
00445   {
00446     CHECKGL(glProgramParameteri(_OpenGLID, GL_GEOMETRY_VERTICES_OUT_EXT, max_vertex_output));
00447   }
00448 #endif
00449 
00450   IOpenGLShaderProgram::IOpenGLShaderProgram(NString ShaderProgramName)
00451     :   IOpenGLResource(RT_GLSL_SHADERPROGRAM)
00452     ,   _FirstParameter(0)
00453     ,   m_CompiledAndReady(false)
00454     ,   _ShaderProgramName(ShaderProgramName)
00455   {
00456     _OpenGLID = glCreateProgram();
00457     CHECKGL_MSG( glCreateProgram() );
00458   }
00459 
00460   IOpenGLShaderProgram::~IOpenGLShaderProgram()
00461   {
00462     if (local::last_loaded_shader == _OpenGLID)
00463     {
00464       CHECKGL( glUseProgramObjectARB(0) );
00465       local::last_loaded_shader = 0;
00466     }
00467       
00468     CHECKGL( glDeleteProgram(_OpenGLID) );
00469     _OpenGLID = 0;
00470     m_CompiledAndReady = false;
00471   }
00472 
00473   void IOpenGLShaderProgram::LoadIShaderFile(const TCHAR *ShaderFileName, const TCHAR *VtxShaderPreprocessorDefines, const TCHAR *FrgShaderPreprocessorDefines)
00474   {
00475     nuxAssertMsg(ShaderFileName, TEXT("[IOpenGLShaderProgram::LoadIShaderFile] Invalid shader file name.") );
00476     NUX_RETURN_IF_NULL(ShaderFileName);
00477     NString SourceCode;
00478     LoadFileToString(SourceCode, ShaderFileName);
00479     LoadIShader(&SourceCode[0], VtxShaderPreprocessorDefines, FrgShaderPreprocessorDefines);
00480   }
00481 
00482   void IOpenGLShaderProgram::LoadIShader(const TCHAR *ShaderCode, const TCHAR *VtxShaderPreprocessorDefines, const TCHAR *FrgShaderPreprocessorDefines)
00483   {
00484     nuxAssertMsg(ShaderCode, TEXT("[IOpenGLShaderProgram::LoadIShader] Invalid shader code.") );
00485     NUX_RETURN_IF_NULL(ShaderCode);
00486     NString VertexShaderSource;
00487     ExtractShaderString3(TEXT("[Vertex Shader]"), ShaderCode, VertexShaderSource, NString(VtxShaderPreprocessorDefines) );
00488     NString PixelShaderSource;
00489     ExtractShaderString3(TEXT("[Fragment Shader]"), ShaderCode, PixelShaderSource, NString(FrgShaderPreprocessorDefines) );
00490 
00491     ObjectPtr<IOpenGLVertexShader> vs = GetGraphicsDisplay()->GetGpuDevice()->CreateVertexShader(); //new IOpenGLVertexShader;
00492     ObjectPtr<IOpenGLPixelShader> ps = GetGraphicsDisplay()->GetGpuDevice()->CreatePixelShader(); //new IOpenGLPixelShader;
00493 
00494     vs->SetShaderCode(&VertexShaderSource[0]);
00495     ps->SetShaderCode(&PixelShaderSource[0]);
00496     vs->Compile();
00497     ps->Compile();
00498 
00499     ShaderObjectList.clear();
00500 
00501     AddShaderObject(vs);
00502     AddShaderObject(ps);
00503   }
00504 
00505   void IOpenGLShaderProgram::LoadVertexShader(const TCHAR *glslshader, const TCHAR *VtxShaderPreprocessorDefines)
00506   {
00507     nuxAssertMsg(glslshader, TEXT("[IOpenGLShaderProgram::LoadVertexShader] Invalid shader code.") );
00508     NUX_RETURN_IF_NULL(glslshader);
00509     ObjectPtr<IOpenGLVertexShader> vs = GetGraphicsDisplay()->GetGpuDevice()->CreateVertexShader(); //new IOpenGLVertexShader;
00510 
00511     NString ProcessedShaderSource;
00512     NString Defines(VtxShaderPreprocessorDefines);
00513     InsertPreProcessorDefinitions(glslshader, ProcessedShaderSource, Defines);
00514 
00515     vs->SetShaderCode(glslshader);
00516     vs->Compile();
00517     AddShaderObject(vs);
00518   }
00519 
00520   void IOpenGLShaderProgram::LoadPixelShader(const TCHAR *glslshader, const TCHAR *FrgShaderPreprocessorDefines)
00521   {
00522     nuxAssertMsg(glslshader, TEXT("[IOpenGLShaderProgram::LoadPixelShader] Invalid shader code.") );
00523     NUX_RETURN_IF_NULL(glslshader);
00524     ObjectPtr<IOpenGLPixelShader> ps = GetGraphicsDisplay()->GetGpuDevice()->CreatePixelShader(); //new IOpenGLPixelShader;
00525 
00526     NString ProcessedShaderSource;
00527     NString Defines(FrgShaderPreprocessorDefines);
00528     InsertPreProcessorDefinitions(glslshader, ProcessedShaderSource, Defines);
00529 
00530     ps->SetShaderCode(glslshader);
00531     ps->Compile();
00532     AddShaderObject(ps);
00533   }
00534 
00535   void IOpenGLShaderProgram::AddShaderObject(ObjectPtr<IOpenGLShader> ShaderObject)
00536   {
00537     ShaderObjectList.push_back(ShaderObject);
00538   }
00539 
00540   void IOpenGLShaderProgram::AddShaderParameter(GLShaderParameter* parameter)
00541   {
00542     GLShaderParameter* temp = _FirstParameter;
00543 
00544     while(temp)
00545     {
00546       if(temp == parameter)
00547       {
00548         // Parameter already added
00549         return;
00550       }
00551       temp = temp->m_NextParameter;
00552     }
00553 
00554     parameter->m_NextParameter = _FirstParameter;
00555     _FirstParameter = parameter;
00556 
00557     // If we add shader parameters after the program is linked, we need to call CheckUniformLocation().
00558     CheckUniformLocation();
00559   }
00560 
00561   void IOpenGLShaderProgram::RemoveShaderObject(ObjectPtr<IOpenGLShader> ShaderObject)
00562   {
00563     std::vector< ObjectPtr<IOpenGLShader> >::iterator it = find(ShaderObjectList.begin(), ShaderObjectList.end(), ShaderObject);
00564 
00565     if (it != ShaderObjectList.end() )
00566     {
00567       ShaderObjectList.erase(it);
00568     }
00569   }
00570 
00571   void IOpenGLShaderProgram::ClearShaderObjects()
00572   {
00573     ShaderObjectList.clear();
00574   }
00575 
00576   bool IOpenGLShaderProgram::Link()
00577   {
00578     // Get the number of attached shaders.
00579     GLint NumAttachedShaders;
00580     CHECKGL( glGetProgramiv(_OpenGLID, GL_ATTACHED_SHADERS, &NumAttachedShaders) );
00581     GLuint *ShaderObjects = 0;
00582 
00583     if (NumAttachedShaders)
00584     {
00585       ShaderObjects = new GLuint[NumAttachedShaders];
00586     }
00587 
00588     CHECKGL( glGetAttachedShaders(_OpenGLID, NumAttachedShaders, NULL, ShaderObjects) );
00589 
00590     // Detach everything first
00591     for (int i = 0; i < (int) NumAttachedShaders; i++)
00592     {
00593       unsigned int obj = ShaderObjects[i];
00594       CHECKGL( glDetachShader(_OpenGLID, obj) );
00595     }
00596 
00597     if (NumAttachedShaders)
00598     {
00599       delete[] ShaderObjects;
00600     }
00601 
00602     for (int i = 0; i < (int) ShaderObjectList.size(); i++)
00603     {
00604       if (!ShaderObjectList[i]->IsValid() )
00605       {
00606         if (ShaderObjectList[i]->Compile() == false)
00607         {
00608           nuxDebugMsg(TEXT("[IOpenGLShaderProgram::Link] Attached shader %s does not compile with program: %s."), ShaderObjectList[i]->_ShaderName.GetTCharPtr(), _ShaderProgramName.GetTCharPtr() );
00609         }
00610       }
00611 
00612       unsigned int obj = ShaderObjectList[i]->GetOpenGLID();
00613       CHECKGL( glAttachShader(_OpenGLID, obj) );
00614     }
00615 
00616     GLint linked;
00617     CHECKGL( glLinkProgram(_OpenGLID) );
00618     CHECKGL( glGetProgramiv(_OpenGLID, GL_LINK_STATUS, &linked) );
00619 
00620     if (linked == GL_FALSE)
00621     {
00622       ANSICHAR *InfoLogBuffer = 0;
00623       GLint InfoLogBufferSize = 0;
00624       GLint InfoLogReturnSize = 0;
00625       GLint iLog = 0;
00626       glGetProgramiv(_OpenGLID, GL_INFO_LOG_LENGTH, &iLog);
00627       InfoLogBuffer = new ANSICHAR[iLog+1];
00628       InfoLogBufferSize = iLog + 1;
00629 
00630       glGetProgramInfoLog(_OpenGLID, InfoLogBufferSize, &InfoLogReturnSize, InfoLogBuffer);
00631 
00632       if (InfoLogReturnSize != 0)
00633       {
00634         nuxError(TEXT("[IOpenGLShaderProgram::Link] glLinkProgram: %s"), InfoLogBuffer);
00635       }
00636 
00637       delete[] InfoLogBuffer;
00638       m_CompiledAndReady = false;
00639       return m_CompiledAndReady;
00640     }
00641 
00642     GLint validated;
00643     // glValidateProgram checks to see whether the executables contained in program can execute given the current OpenGL state.
00644     CHECKGL( glValidateProgram(_OpenGLID) );
00645     CHECKGL( glGetProgramiv(_OpenGLID, GL_VALIDATE_STATUS, &validated) );
00646 
00647     if (validated == GL_FALSE)
00648     {
00649       ANSICHAR *InfoLogBuffer = 0;
00650       GLint InfoLogBufferSize = 0;
00651       GLint InfoLogReturnSize = 0;
00652       GLint iLog = 0;
00653       glGetProgramiv(_OpenGLID, GL_INFO_LOG_LENGTH, &iLog);
00654       InfoLogBuffer = new ANSICHAR[iLog+1];
00655       InfoLogBufferSize = iLog + 1;
00656 
00657       glGetProgramInfoLog(_OpenGLID, InfoLogBufferSize, &InfoLogReturnSize, InfoLogBuffer);
00658 
00659       if (InfoLogReturnSize != 0)
00660       {
00661         nuxError(TEXT("[IOpenGLShaderProgram::Link] glValidateProgram: %s"), InfoLogBuffer);
00662       }
00663 
00664       delete [] InfoLogBuffer;
00665     }
00666 
00667     m_CompiledAndReady = true;
00668 
00669     Begin();
00670     CheckUniformLocation();
00671     CheckAttributeLocation();
00672     
00673     End();
00674 
00675     return m_CompiledAndReady;
00676   }
00677 
00678   void IOpenGLShaderProgram::SetShaderTracking (bool enabled)
00679   {
00680     local::enable_tracking = enabled;
00681     local::last_loaded_shader = 0;
00682     CHECKGL( glUseProgramObjectARB(0) );
00683   }
00684 
00685   void IOpenGLShaderProgram::Begin(void)
00686   {
00687     if (local::last_loaded_shader == _OpenGLID && local::enable_tracking)
00688       return;
00689     
00690     local::last_loaded_shader = _OpenGLID;
00691     CHECKGL( glUseProgramObjectARB(_OpenGLID) );
00692   }
00693 
00694   void IOpenGLShaderProgram::End(void)
00695   {
00696     if (!local::enable_tracking)
00697       CHECKGL( glUseProgramObjectARB(0) );
00698   }
00699 
00700   void IOpenGLShaderProgram::CheckAttributeLocation()
00701   {
00702     //ResetAttributeVariable(m_ProgramAttributeDefinition);
00703     for (int i = 0; i < NUM_VERTEX_SHADER_INPUT_ATTRIBUTE; i++)
00704     {
00705       m_ProgramAttributeDefinition[i].attribute_index = -1;
00706       m_ProgramAttributeDefinition[i].attribute_name = "";
00707       m_ProgramAttributeDefinition[i].type = VAT_UNDEFINED;
00708       m_ProgramAttributeDefinition[i].valid = false;
00709     }
00710 
00711     char active_attribute_name[256];
00712     GLsizei length;
00713     GLint size;
00714     GLenum type;
00715 
00716     GLint num_active_attributes;
00717     CHECKGL( glGetObjectParameterivARB(_OpenGLID, GL_OBJECT_ACTIVE_ATTRIBUTES_ARB, &num_active_attributes) );
00718 
00719 
00720     //         Vertex Attribute Aliasing
00721     //         GLSL attempts to eliminate aliasing of vertex attributes but this is integral to NVIDIA’s hardware
00722     //         approach and necessary for maintaining compatibility with existing OpenGL applications that NVIDIA customers rely on.
00723     //         NVIDIA’s GLSL implementation therefore does not allow built-in vertex attributes to collide with a
00724     //         generic vertex attributes that is assigned to a particular vertex attribute index with glBindAttribLocation.
00725     //         For example, you should not use gl_Normal (a built-in vertex attribute) and also use glBindAttribLocation to
00726     //         bind a generic vertex attribute named “whatever” to vertex attribute index 2 because gl_Normal aliases to index 2.
00727     //
00728     //         Built-in vertex attribute name      Incompatible aliased vertex attribute index
00729     //         gl_Vertex                           0
00730     //         gl_Normal                           2
00731     //         gl_Color                            3
00732     //         gl_SecondaryColor                   4
00733     //         gl_FogCoord                         5
00734     //         gl_MultiTexCoord0                   8
00735     //         gl_MultiTexCoord1                   9
00736     //         gl_MultiTexCoord2                   10
00737     //         gl_MultiTexCoord3                   11
00738     //         gl_MultiTexCoord4                   12
00739     //         gl_MultiTexCoord5                   13
00740     //         gl_MultiTexCoord6                   14
00741     //         gl_MultiTexCoord7                   15
00742     //         The compiler will automatically assign vertex shader attribute variables not pre-assigned
00743     //         by glBindAttribLocation to locations that do not collide with any built-in attribute variables
00744     //         used by the vertex shader. The assigned locations can be queries with glGetAttribLocation.
00745     //         This means that a developer only needs to worry about collisions when they are explicitly requesting
00746     //         an attribute to be bound to a specific location.
00747 
00748     for (int index = 0; index < num_active_attributes; index++)
00749     {
00750       glGetActiveAttribARB (_OpenGLID,
00751                             index,
00752                             256,
00753                             &length,
00754                             &size,
00755                             &type,
00756                             active_attribute_name);
00757       CHECKGL_MSG ( glGetActiveAttribARB );
00758       m_ProgramAttributeDefinition[index].attribute_index = glGetAttribLocationARB(_OpenGLID, active_attribute_name);
00759       CHECKGL_MSG ( glGetAttribLocationARB );
00760       m_ProgramAttributeDefinition[index].attribute_name = active_attribute_name;
00761       m_ProgramAttributeDefinition[index].valid = true;
00762 
00763       switch (type)
00764       {
00765         case GL_FLOAT:
00766           m_ProgramAttributeDefinition[index].type = VAT_FLOAT;
00767           break;
00768         case GL_FLOAT_VEC2:
00769           m_ProgramAttributeDefinition[index].type = VAT_FLOAT2;
00770           break;
00771         case GL_FLOAT_VEC3:
00772           m_ProgramAttributeDefinition[index].type = VAT_FLOAT3;
00773           break;
00774         case GL_FLOAT_VEC4:
00775           m_ProgramAttributeDefinition[index].type = VAT_FLOAT4;
00776           break;
00777 
00778         case GL_FLOAT_MAT2:
00779         case GL_FLOAT_MAT3:
00780         case GL_FLOAT_MAT4:
00781         default:
00782           //todo
00783           nuxAssert(0);
00784       }
00785     }
00786   }
00787 
00788   void IOpenGLShaderProgram::CheckUniformLocation()
00789   {
00790     GLShaderParameter *parameter = _FirstParameter;
00791 
00792     while (m_CompiledAndReady && parameter)
00793     {
00794       int location = glGetUniformLocationARB (_OpenGLID, TCHAR_TO_ANSI (parameter->m_Name.GetTCharPtr() ) );
00795       CHECKGL_MSG ( glGetUniformLocationARB (_OpenGLID, TCHAR_TO_ANSI (parameter->m_Name.GetTCharPtr() ) ) );
00796 
00797       //nuxDebugMsg(TEXT("[IOpenGLShaderProgram::CheckUniformLocation] Location index: %d"), location);
00798       if (location == -1 && (!parameter->m_bIsOptional) )
00799       {
00800         nuxDebugMsg (TEXT ("[IOpenGLShaderProgram::CheckUniformLocation] Couldn't find shader program parameter %s \n"), parameter->m_Name.GetTCharPtr() );
00801         nuxAssert (0);
00802       }
00803 
00804       GLint size = 0;
00805       GLenum type = 0;
00806 
00807       if (location >= 0)
00808       {
00809         CHECKGL ( glGetActiveUniformARB (_OpenGLID, location, 0, NULL /*&length*/, &size, &type, NULL) );
00810       }
00811 
00812       parameter->m_Index = location;
00813       parameter->m_Size = size;
00814       parameter->m_Type = type;
00815 
00816       parameter = parameter->m_NextParameter;
00817     }
00818   }
00819 
00820   int IOpenGLShaderProgram::GetAttributeLocation (const TCHAR *AttributeName)
00821   {
00822     for (int i = 0; i < 16 /*NUM_VERTEX_SHADER_INPUT_ATTRIBUTE*/; i++)
00823     {
00824       if (m_ProgramAttributeDefinition[i].attribute_name == AttributeName)
00825         return m_ProgramAttributeDefinition[i].attribute_index;
00826     }
00827 
00828     return -1;
00829   }
00830 
00831   bool IOpenGLShaderProgram::SetUniform1f (char *varname, GLfloat v0)
00832   {
00833     GLint loc = GetUniformLocationARB (varname);
00834 
00835     if (loc == -1) return false; // can't find variable
00836 
00837     glUniform1fARB (loc, v0);
00838 
00839     return true;
00840   }
00841   bool IOpenGLShaderProgram::SetUniform1f (GLint loc, GLfloat v0)
00842   {
00843     if (loc == -1) return false; // can't find variable
00844 
00845     glUniform1fARB (loc, v0);
00846     return true;
00847   }
00848 
00849 
00850   bool IOpenGLShaderProgram::SetUniform2f (char *varname, GLfloat v0, GLfloat v1)
00851   {
00852     GLint loc = GetUniformLocationARB (varname);
00853 
00854     if (loc == -1) return false; // can't find variable
00855 
00856     glUniform2fARB (loc, v0, v1);
00857 
00858     return true;
00859   }
00860   bool IOpenGLShaderProgram::SetUniform2f (GLint loc, GLfloat v0, GLfloat v1)
00861   {
00862     if (loc == -1) return false; // can't find variable
00863 
00864     glUniform2fARB (loc, v0, v1);
00865     return true;
00866   }
00867 
00868   bool IOpenGLShaderProgram::SetUniform3f (char *varname, GLfloat v0, GLfloat v1, GLfloat v2)
00869   {
00870     GLint loc = GetUniformLocationARB (varname);
00871 
00872     if (loc == -1) return false; // can't find variable
00873 
00874     glUniform3fARB (loc, v0, v1, v2);
00875 
00876     return true;
00877   }
00878   bool IOpenGLShaderProgram::SetUniform3f (GLint loc, GLfloat v0, GLfloat v1, GLfloat v2)
00879   {
00880     if (loc == -1) return false; // can't find variable
00881 
00882     glUniform3fARB (loc, v0, v1, v2);
00883 
00884     return true;
00885   }
00886 
00887   bool IOpenGLShaderProgram::SetUniform4f (char *varname, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3)
00888   {
00889     GLint loc = GetUniformLocationARB (varname);
00890 
00891     if (loc == -1) return false; // can't find variable
00892 
00893     glUniform4fARB (loc, v0, v1, v2, v3);
00894 
00895     return true;
00896   }
00897   bool IOpenGLShaderProgram::SetUniform4f (GLint loc, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3)
00898   {
00899     if (loc == -1) return false; // can't find variable
00900 
00901     glUniform4fARB (loc, v0, v1, v2, v3);
00902 
00903     return true;
00904   }
00905 
00906   bool IOpenGLShaderProgram::SetUniform1i (char *varname, GLint v0)
00907   {
00908     GLint loc = GetUniformLocationARB (varname);
00909 
00910     if (loc == -1) return false; // can't find variable
00911 
00912     glUniform1iARB (loc, v0);
00913 
00914     return true;
00915   }
00916   bool IOpenGLShaderProgram::SetUniform1i (GLint loc, GLint v0)
00917   {
00918     if (loc == -1) return false; // can't find variable
00919 
00920     glUniform1iARB (loc, v0);
00921 
00922     return true;
00923   }
00924 
00925   bool IOpenGLShaderProgram::SetUniform2i (char *varname, GLint v0, GLint v1)
00926   {
00927     GLint loc = GetUniformLocationARB (varname);
00928 
00929     if (loc == -1) return false; // can't find variable
00930 
00931     glUniform2iARB (loc, v0, v1);
00932 
00933 
00934     return true;
00935   }
00936   bool IOpenGLShaderProgram::SetUniform2i (GLint loc, GLint v0, GLint v1)
00937   {
00938     if (loc == -1) return false; // can't find variable
00939 
00940     glUniform2iARB (loc, v0, v1);
00941 
00942 
00943     return true;
00944   }
00945 
00946   bool IOpenGLShaderProgram::SetUniform3i (char *varname, GLint v0, GLint v1, GLint v2)
00947   {
00948     GLint loc = GetUniformLocationARB (varname);
00949 
00950     if (loc == -1) return false; // can't find variable
00951 
00952     glUniform3iARB (loc, v0, v1, v2);
00953 
00954     return true;
00955   }
00956   bool IOpenGLShaderProgram::SetUniform3i (GLint loc, GLint v0, GLint v1, GLint v2)
00957   {
00958     if (loc == -1) return false; // can't find variable
00959 
00960     glUniform3iARB (loc, v0, v1, v2);
00961 
00962     return true;
00963   }
00964 
00965   bool IOpenGLShaderProgram::SetUniform4i (char *varname, GLint v0, GLint v1, GLint v2, GLint v3)
00966   {
00967     GLint loc = GetUniformLocationARB (varname);
00968 
00969     if (loc == -1) return false; // can't find variable
00970 
00971     glUniform4iARB (loc, v0, v1, v2, v3);
00972 
00973     return true;
00974   }
00975   bool IOpenGLShaderProgram::SetUniform4i (GLint loc, GLint v0, GLint v1, GLint v2, GLint v3)
00976   {
00977     if (loc == -1) return false; // can't find variable
00978 
00979     glUniform4iARB (loc, v0, v1, v2, v3);
00980 
00981     return true;
00982   }
00983 
00984   bool IOpenGLShaderProgram::SetUniform1fv (char *varname, GLsizei count, GLfloat *value)
00985   {
00986     GLint loc = GetUniformLocationARB (varname);
00987 
00988     if (loc == -1) return false; // can't find variable
00989 
00990     glUniform1fvARB (loc, count, value);
00991 
00992     return true;
00993   }
00994   bool IOpenGLShaderProgram::SetUniform1fv (GLint loc, GLsizei count, GLfloat *value)
00995   {
00996     if (loc == -1) return false; // can't find variable
00997 
00998     glUniform1fvARB (loc, count, value);
00999 
01000     return true;
01001   }
01002 
01003   bool IOpenGLShaderProgram::SetUniform2fv (char *varname, GLsizei count, GLfloat *value)
01004   {
01005     GLint loc = GetUniformLocationARB (varname);
01006 
01007     if (loc == -1) return false; // can't find variable
01008 
01009     glUniform2fvARB (loc, count, value);
01010 
01011     return true;
01012   }
01013   bool IOpenGLShaderProgram::SetUniform2fv (GLint loc, GLsizei count, GLfloat *value)
01014   {
01015     if (loc == -1) return false; // can't find variable
01016 
01017     glUniform2fvARB (loc, count, value);
01018 
01019     return true;
01020   }
01021 
01022   bool IOpenGLShaderProgram::SetUniform3fv (char *varname, GLsizei count, GLfloat *value)
01023   {
01024     GLint loc = GetUniformLocationARB (varname);
01025 
01026     if (loc == -1) return false; // can't find variable
01027 
01028     glUniform3fvARB (loc, count, value);
01029 
01030     return true;
01031   }
01032   bool IOpenGLShaderProgram::SetUniform3fv (GLint loc, GLsizei count, GLfloat *value)
01033   {
01034     if (loc == -1) return false; // can't find variable
01035 
01036     glUniform3fvARB (loc, count, value);
01037 
01038     return true;
01039   }
01040 
01041   bool IOpenGLShaderProgram::SetUniform4fv (char *varname, GLsizei count, GLfloat *value)
01042   {
01043     GLint loc = GetUniformLocationARB (varname);
01044 
01045     if (loc == -1) return false; // can't find variable
01046 
01047     glUniform4fvARB (loc, count, value);
01048 
01049     return true;
01050   }
01051   bool IOpenGLShaderProgram::SetUniform4fv (GLint loc, GLsizei count, GLfloat *value)
01052   {
01053     if (loc == -1) return false; // can't find variable
01054 
01055     glUniform4fvARB (loc, count, value);
01056 
01057     return true;
01058   }
01059 
01060   bool IOpenGLShaderProgram::SetUniform1iv (char *varname, GLsizei count, GLint *value)
01061   {
01062     GLint loc = GetUniformLocationARB (varname);
01063 
01064     if (loc == -1) return false; // can't find variable
01065 
01066     glUniform1ivARB (loc, count, value);
01067 
01068     return true;
01069   }
01070   bool IOpenGLShaderProgram::SetUniform1iv (GLint loc, GLsizei count, GLint *value)
01071   {
01072     if (loc == -1) return false; // can't find variable
01073 
01074     glUniform1ivARB (loc, count, value);
01075 
01076     return true;
01077   }
01078 
01079   bool IOpenGLShaderProgram::SetUniform2iv (char *varname, GLsizei count, GLint *value)
01080   {
01081     GLint loc = GetUniformLocationARB (varname);
01082 
01083     if (loc == -1) return false; // can't find variable
01084 
01085     glUniform2ivARB (loc, count, value);
01086 
01087     return true;
01088   }
01089   bool IOpenGLShaderProgram::SetUniform2iv (GLint loc, GLsizei count, GLint *value)
01090   {
01091     if (loc == -1) return false; // can't find variable
01092 
01093     glUniform2ivARB (loc, count, value);
01094 
01095     return true;
01096   }
01097 
01098   bool IOpenGLShaderProgram::SetUniform3iv (char *varname, GLsizei count, GLint *value)
01099   {
01100     GLint loc = GetUniformLocationARB (varname);
01101 
01102     if (loc == -1) return false; // can't find variable
01103 
01104     glUniform3ivARB (loc, count, value);
01105 
01106     return true;
01107   }
01108   bool IOpenGLShaderProgram::SetUniform3iv (GLint loc, GLsizei count, GLint *value)
01109   {
01110     if (loc == -1) return false; // can't find variable
01111 
01112     glUniform3ivARB (loc, count, value);
01113 
01114     return true;
01115   }
01116 
01117   bool IOpenGLShaderProgram::SetUniform4iv (char *varname, GLsizei count, GLint *value)
01118   {
01119     GLint loc = GetUniformLocationARB (varname);
01120 
01121     if (loc == -1) return false; // can't find variable
01122 
01123     glUniform4ivARB (loc, count, value);
01124 
01125     return true;
01126   }
01127   bool IOpenGLShaderProgram::SetUniform4iv (GLint loc, GLsizei count, GLint *value)
01128   {
01129     if (loc == -1) return false; // can't find variable
01130 
01131     glUniform4ivARB (loc, count, value);
01132 
01133     return true;
01134   }
01135 
01136   bool IOpenGLShaderProgram::SetUniformMatrix2fv (char *varname, GLsizei count, GLboolean transpose, GLfloat *value)
01137   {
01138     GLint loc = GetUniformLocationARB (varname);
01139 
01140     if (loc == -1) return false; // can't find variable
01141 
01142     glUniformMatrix2fvARB (loc, count, transpose, value);
01143 
01144     return true;
01145   }
01146   bool IOpenGLShaderProgram::SetUniformLocMatrix2fv (GLint loc, GLsizei count, GLboolean transpose, GLfloat *value)
01147   {
01148     if (loc == -1) return false; // can't find variable
01149 
01150     glUniformMatrix2fvARB (loc, count, transpose, value);
01151 
01152     return true;
01153   }
01154 
01155   bool IOpenGLShaderProgram::SetUniformMatrix3fv (char *varname, GLsizei count, GLboolean transpose, GLfloat *value)
01156   {
01157     GLint loc = GetUniformLocationARB (varname);
01158 
01159     if (loc == -1) return false; // can't find variable
01160 
01161     glUniformMatrix3fvARB (loc, count, transpose, value);
01162 
01163     return true;
01164   }
01165   bool IOpenGLShaderProgram::SetUniformLocMatrix3fv (GLint loc, GLsizei count, GLboolean transpose, GLfloat *value)
01166   {
01167     if (loc == -1) return false; // can't find variable
01168 
01169     glUniformMatrix3fvARB (loc, count, transpose, value);
01170 
01171     return true;
01172   }
01173 
01174   bool IOpenGLShaderProgram::SetUniformMatrix4fv (char *varname, GLsizei count, GLboolean transpose, GLfloat *value)
01175   {
01176     GLint loc = GetUniformLocationARB (varname);
01177 
01178     if (loc == -1) return false; // can't find variable
01179 
01180     glUniformMatrix4fvARB (loc, count, transpose, value);
01181 
01182     return true;
01183   }
01184   bool IOpenGLShaderProgram::SetUniformLocMatrix4fv (GLint loc, GLsizei count, GLboolean transpose, GLfloat *value)
01185   {
01186     if (loc == -1) return false; // can't find variable
01187 
01188     glUniformMatrix4fvARB (loc, count, transpose, value);
01189 
01190     return true;
01191   }
01192 
01193 
01194   void IOpenGLShaderProgram::GetUniformfv (char *name, GLfloat *values)
01195   {
01196     GLint loc;
01197 
01198     loc = glGetUniformLocationARB (_OpenGLID, name);
01199     CHECKGL_MSG ( glGetUniformLocationARB );
01200 
01201     if (loc == -1)
01202     {
01203       std::cout << "Error: can't find uniform variable \"" << name << "\"\n";
01204     }
01205 
01206     CHECKGL ( glGetUniformfvARB (_OpenGLID, loc, values) );
01207   }
01208 
01209 
01210   void IOpenGLShaderProgram::GetUniformiv (char *name, GLint *values)
01211   {
01212     GLint loc;
01213     loc = glGetUniformLocationARB (_OpenGLID, name);
01214     CHECKGL_MSG ( glGetUniformLocationARB );
01215 
01216     if (loc == -1)
01217     {
01218       std::cout << "Error: can't find uniform variable \"" << name << "\"\n";
01219     }
01220 
01221     CHECKGL ( glGetUniformivARB (_OpenGLID, loc, values) );
01222   }
01223 
01224   int IOpenGLShaderProgram::GetUniformLocationARB (const GLcharARB *name)
01225   {
01226     GLint loc;
01227     loc = glGetUniformLocationARB (_OpenGLID, name);
01228     CHECKGL_MSG ( glGetUniformLocationARB );
01229     return loc;
01230   }
01231 
01232   void IOpenGLShaderProgram::GetActiveUniformARB (
01233     GLuint index,
01234     GLsizei maxLength,
01235     GLsizei *length,
01236     GLint *size,
01237     GLenum *type,
01238     GLcharARB *name)
01239   {
01240 
01241     glGetActiveUniformARB (_OpenGLID,
01242                            index,
01243                            maxLength,
01244                            length,
01245                            size,
01246                            type,
01247                            name);
01248     CHECKGL_MSG (glGetActiveUniformARB);
01249   }
01250 
01251 
01252   void IOpenGLShaderProgram::GetObjectParameterfvARB (GLenum pname,
01253       GLfloat *params)
01254   {
01255     glGetObjectParameterfvARB (_OpenGLID,
01256                                pname,
01257                                params);
01258     CHECKGL_MSG (glGetObjectParameterfvARB);
01259   }
01260 
01261   bool IOpenGLShaderProgram::SetSampler (char *name, int texture_unit)
01262   {
01263     GLint loc = GetUniformLocationARB (name);
01264 
01265     if (loc == -1) return false; // can't find variable
01266 
01267     glUniform1iARB (loc, texture_unit);
01268     return true;
01269   }
01270 
01271 }
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends