Advertisement
Guest User

Untitled

a guest
Nov 30th, 2014
250
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 19.91 KB | None | 0 0
  1. #include "stdafx.h"
  2. #include "ShaderManager.h"
  3. #include "TextFileReader.h"
  4.  
  5. namespace key{
  6.     // Opengl Shader API
  7. static PFNGLACTIVETEXTUREPROC       glActiveTexture     = nullptr;
  8. static PFNGLATTACHSHADERPROC        glAttachShader      = nullptr;
  9. static PFNGLCOMPILESHADERPROC       glCompileShader     = nullptr;
  10. static PFNGLCREATESHADERPROC        glCreateShader      = nullptr;
  11. static PFNGLCREATEPROGRAMPROC       glCreateProgram     = nullptr;
  12. static PFNGLDELETEPROGRAMPROC       glDeleteProgram     = nullptr;
  13. static PFNGLDELETESHADERPROC        glDeleteShader      = nullptr;
  14. static PFNGLDETACHSHADERPROC        glDetachShader      = nullptr;
  15. static PFNGLGETACTIVEATTRIBPROC     glGetActiveAttrib   = nullptr;
  16. static PFNGLGETACTIVEUNIFORMPROC    glGetActiveUniform  = nullptr;
  17. static PFNGLGETATTRIBLOCATIONPROC   glGetAttribLocation = nullptr;
  18. static PFNGLGETPROGRAMINFOLOGPROC   glGetProgramInfoLog = nullptr;
  19. static PFNGLGETPROGRAMIVPROC        glGetProgramiv      = nullptr;
  20. static PFNGLGETSHADERIVPROC         glGetShaderiv       = nullptr;
  21. static PFNGLGETSHADERINFOLOGPROC    glGetShaderInfoLog  = nullptr;
  22. static PFNGLGETUNIFORMLOCATIONPROC  glGetUniformLocation= nullptr;
  23. static PFNGLLINKPROGRAMPROC         glLinkProgram       = nullptr;
  24. static PFNGLSHADERSOURCEPROC        glShaderSource      = nullptr;
  25. static PFNGLUNIFORM1FPROC           glUniform1f         = nullptr;
  26. static PFNGLUNIFORM1IPROC           glUniform1i         = nullptr;
  27. static PFNGLUNIFORM3FVPROC          glUniform3fv        = nullptr;
  28. static PFNGLUNIFORMMATRIX4FVPROC    glUniformMatrix4fv  = nullptr;
  29. static PFNGLUSEPROGRAMPROC          glUseProgram        = nullptr;
  30.  
  31.  
  32.  
  33. static const Program NO_SHADER_PROGRAM = static_cast<Program>(-1);
  34. template<typename T>
  35. static int getSize(T t){
  36.     switch(t){
  37.     case AT_FLOAT_VEC2:
  38.         return 2;
  39.     case AT_FLOAT_VEC3:
  40.         return 3;
  41.     case AT_FLOAT_VEC4:
  42.         return 4;
  43.     default:
  44.         {
  45.             std::ostringstream str;
  46.             str << __FUNCTION__ << " invalid type("<<t<<")\n";
  47.             throw ExceptionHandler(str);
  48.             return 0;
  49.         }
  50.  
  51.     }
  52. }
  53.  
  54. ShaderManager::AttributeVariable::AttributeVariable(AttributeType eTypeIn, unsigned uLocIn):
  55.     uLocation(uLocIn),
  56.     eType(eTypeIn),
  57.     iSize(getSize(eTypeIn))
  58. {}
  59.  
  60. ShaderManager::UniformVariable::UniformVariable(UniformType eTypeIn, unsigned uLocIn):
  61.     uLocation(uLocIn),
  62.     eType(eTypeIn)
  63. {}
  64.  
  65. ShaderManager::InfoProgram::InfoProgram():
  66.     uId(glCreateProgram())
  67. {
  68.     aShaderIndex.assign(INVALID_UNSIGNED);
  69. }
  70.  
  71. ShaderManager::InfoShader::InfoShader(int iglId, std::string filename):
  72.     uId(glCreateShader(iglId)),
  73.     strFilename(filename)
  74. {}
  75.  
  76. static void DefineOpenGLAPI(){
  77.     std::ostringstream strStream;
  78.     strStream << __FUNCTION__ << " can not initialize function pointer named: ";
  79.    
  80.     // OpenGL 2.1
  81.     if((glActiveTexture     = (PFNGLACTIVETEXTUREPROC)      wglGetProcAddress("glActiveTexture"     ))==nullptr)throw ExceptionHandler(std::string(strStream.str() +"glActiveTexture"   ));
  82.     if((glAttachShader      = (PFNGLATTACHSHADERPROC)       wglGetProcAddress("glAttachShader"      ))==nullptr)throw ExceptionHandler(std::string(strStream.str() +"glAttachShader"    ));
  83.     if((glCompileShader     = (PFNGLCOMPILESHADERPROC)      wglGetProcAddress("glCompileShader"     ))==nullptr)throw ExceptionHandler(std::string(strStream.str() +"glCompileShader"   ));
  84.     if((glCreateProgram     = (PFNGLCREATEPROGRAMPROC)      wglGetProcAddress("glCreateProgram"     ))==nullptr)throw ExceptionHandler(std::string(strStream.str() +"glCreateProgram"   ));
  85.     if((glCreateShader      = (PFNGLCREATESHADERPROC)       wglGetProcAddress("glCreateShader"      ))==nullptr)throw ExceptionHandler(std::string(strStream.str() +"glCreateShader"    ));
  86.     if((glDeleteProgram     = (PFNGLDELETEPROGRAMPROC)      wglGetProcAddress("glDeleteProgram"     ))==nullptr)throw ExceptionHandler(std::string(strStream.str() +"glDeleteProgram"   ));
  87.     if((glDeleteShader      = (PFNGLDELETESHADERPROC)       wglGetProcAddress("glDeleteShader"      ))==nullptr)throw ExceptionHandler(std::string(strStream.str() +"glDeleteShader"    ));
  88.     if((glDetachShader      = (PFNGLDETACHSHADERPROC)       wglGetProcAddress("glDetachShader"      ))==nullptr)throw ExceptionHandler(std::string(strStream.str() +"glDetachShader"    ));
  89.     if((glGetActiveAttrib   = (PFNGLGETACTIVEATTRIBPROC)    wglGetProcAddress("glGetActiveAttrib"   ))==nullptr)throw ExceptionHandler(std::string(strStream.str() +"glGetActiveAttrib" ));
  90.     if((glGetActiveUniform  = (PFNGLGETACTIVEUNIFORMPROC)   wglGetProcAddress("glGetActiveUniform"  ))==nullptr)throw ExceptionHandler(std::string(strStream.str() +"glGetActiveUniform"    ));
  91.     if((glGetAttribLocation = (PFNGLGETATTRIBLOCATIONPROC)  wglGetProcAddress("glGetAttribLocation" ))==nullptr)throw ExceptionHandler(std::string(strStream.str() +"glGetAttribLocation"   ));
  92.     if((glGetShaderInfoLog  = (PFNGLGETSHADERINFOLOGPROC)   wglGetProcAddress("glGetShaderInfoLog"  ))==nullptr)throw ExceptionHandler(std::string(strStream.str() +"glGetShaderInfoLog"));
  93.     if((glGetShaderiv       = (PFNGLGETSHADERIVPROC)        wglGetProcAddress("glGetShaderiv"       ))==nullptr)throw ExceptionHandler(std::string(strStream.str() +"glGetShaderiv"     ));
  94.     if((glGetProgramiv      = (PFNGLGETPROGRAMIVPROC)       wglGetProcAddress("glGetProgramiv"      ))==nullptr)throw ExceptionHandler(std::string(strStream.str() +"glGetProgramiv"    ));
  95.     if((glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC)  wglGetProcAddress("glGetProgramInfoLog" ))==nullptr)throw ExceptionHandler(std::string(strStream.str() +"glGetProgramInfoLog"   ));
  96.     if((glGetUniformLocation= (PFNGLGETUNIFORMLOCATIONPROC) wglGetProcAddress("glGetUniformLocation"))==nullptr)throw ExceptionHandler(std::string(strStream.str() +"glGetUniformLocation"  ));
  97.     if((glLinkProgram       = (PFNGLLINKPROGRAMPROC)        wglGetProcAddress("glLinkProgram"       ))==nullptr)throw ExceptionHandler(std::string(strStream.str() +"glLinkProgram"     ));
  98.     if((glShaderSource      = (PFNGLSHADERSOURCEPROC)       wglGetProcAddress("glShaderSource"      ))==nullptr)throw ExceptionHandler(std::string(strStream.str() +"glShaderSource"    ));
  99.     if((glUseProgram        = (PFNGLUSEPROGRAMPROC)         wglGetProcAddress("glUseProgram"        ))==nullptr)throw ExceptionHandler(std::string(strStream.str() +"glUseProgram"  ));
  100.     if((glUniform1f         = (PFNGLUNIFORM1FPROC)          wglGetProcAddress("glUniform1f"         ))==nullptr)throw ExceptionHandler(std::string(strStream.str() +"glUniform1f"));
  101.     if((glUniform1i         = (PFNGLUNIFORM1IPROC)          wglGetProcAddress("glUniform1i"         ))==nullptr)throw ExceptionHandler(std::string(strStream.str() +"glUniform1i"));
  102.     if((glUniform3fv        = (PFNGLUNIFORM3FVPROC)         wglGetProcAddress("glUniform3fv"        ))==nullptr)throw ExceptionHandler(std::string(strStream.str() +"glUniform3fv"));
  103.     if((glUniformMatrix4fv  = (PFNGLUNIFORMMATRIX4FVPROC)   wglGetProcAddress("glUniformMatrix4fv"  ))==nullptr)throw ExceptionHandler(std::string(strStream.str() +"glUniformMatrix4fv"));
  104.     if((glUseProgram        = (PFNGLUSEPROGRAMPROC)         wglGetProcAddress("glUseProgram"        ))==nullptr)throw ExceptionHandler(std::string(strStream.str() +"glUseProgram"      ));
  105. }
  106. ShaderManager::ShaderManager():
  107.     Singleton(TYPE_SHADER_MANAGER),
  108.     _vPrograms(NUMBER_OF_PROGRAM_IDS),
  109.     _eEnableShaderProgram(NO_SHADER_PROGRAM)
  110. {
  111.     DefineOpenGLAPI();
  112. }
  113. ShaderManager::~ShaderManager(){
  114.     _eEnableShaderProgram = NO_SHADER_PROGRAM;
  115.     if(glUseProgram){
  116.         glUseProgram(0);
  117.     }
  118.    
  119.     // Detach/Delete programs/shaders
  120.     unsigned uShaderIndex = 0;
  121.     for(unsigned uProgramIndex = 0; uProgramIndex < _vPrograms.size(); ++uProgramIndex){
  122.         SharedInfoProgram pInfoProgram = _vPrograms[uProgramIndex];
  123.         if(pInfoProgram){
  124.             for(unsigned uShaderType = 0; uShaderType < pInfoProgram->aShaderIndex.size(); ++uShaderType){
  125.                 uShaderIndex = pInfoProgram->aShaderIndex[uShaderType];
  126.                 if(uShaderIndex != INVALID_UNSIGNED){
  127.                     try{
  128.                         glDetachShader(pInfoProgram->uId, _avShaders[uShaderType].at(uShaderIndex)->uId);
  129.                     } catch(std::exception&){
  130.                         std::ostringstream str;
  131.                         str << __FUNCTION__ << "Shader Index{" << uShaderIndex << "} is out of range for ShaderManager::_avShaders["
  132.                             << uShaderType << "] there are onle " << _avShaders[uShaderType].size()
  133.                             << " InfoShader* stored in vector for ShaderProgramId[" << uProgramIndex << "]";
  134.                         Logger::log(str, Logger::TYPE_ERROR);
  135.                     }
  136.                 }
  137.             }
  138.             glDeleteProgram(pInfoProgram->uId);
  139.         }
  140.     }
  141.     _vPrograms.clear();
  142.  
  143.     // Free memory used by shaders
  144.     for(unsigned uShaderType = 0; uShaderType < _avShaders.size(); ++uShaderType){
  145.         for each(const SharedInfoShader& pInfoShader in _avShaders[uShaderType]){
  146.             glDeleteShader(pInfoShader->uId);
  147.         }
  148.         _avShaders[uShaderType].clear();
  149.     }
  150. }
  151. void ShaderManager::Create(ShaderProgramSettings& shaderProgramSettings){
  152.     SharedInfoProgram pInfoProgram;
  153.     try {
  154.         pInfoProgram = _vPrograms.at(shaderProgramSettings._eShaderProgram);
  155.         if(pInfoProgram){
  156.             std::ostringstream str;
  157.             str << __FUNCTION__ << " failed. ShaderProgram [" << shaderProgramSettings._eShaderProgram << "] has already been created.";
  158.             throw ExceptionHandler(str);
  159.         }
  160.     } catch(...){
  161.         std::ostringstream str;
  162.         str << __FUNCTION__ << " failed. ShaderProgram [" << shaderProgramSettings._eShaderProgram << "] is not valid.";
  163.         throw ExceptionHandler(str);
  164.     }
  165.  
  166.     // Create a new program if a previous was not found
  167.     pInfoProgram.reset(new InfoProgram());
  168.     if(pInfoProgram->uId == 0){
  169.         std::ostringstream str;
  170.         str << __FUNCTION__ << " failed. glCreateProgram returned 0 for ShaderProg["<< shaderProgramSettings._eShaderProgram << "]";
  171.         throw ExceptionHandler(str);
  172.     }
  173.  
  174.     pInfoProgram->aShaderIndex[TYPE_VERTEX]     = _InitializeShader(TYPE_VERTEX, shaderProgramSettings._strVertexShaderFilename);
  175.     pInfoProgram->aShaderIndex[TYPE_FRAGMENT]   = _InitializeShader(TYPE_FRAGMENT, shaderProgramSettings._strFragmentShaderFilename);
  176.  
  177.     glAttachShader(pInfoProgram->uId, _avShaders[TYPE_VERTEX].at(   pInfoProgram->aShaderIndex[TYPE_VERTEX])->uId);
  178.     glAttachShader(pInfoProgram->uId, _avShaders[TYPE_FRAGMENT].at( pInfoProgram->aShaderIndex[TYPE_FRAGMENT])->uId);
  179.    
  180.     glLinkProgram(pInfoProgram->uId);
  181.  
  182.     int iStatus;
  183.     glGetProgramiv(pInfoProgram->uId, GL_LINK_STATUS, &iStatus);
  184.     if(!iStatus){
  185.         std::ostringstream str;
  186.         str << __FUNCTION__ << " failed. \nLink program failed for ShaderProgram[" << shaderProgramSettings._eShaderProgram << "]";
  187.         str << "\n";
  188.  
  189.         int iLength = 0;
  190.         glGetProgramiv(pInfoProgram->uId, GL_INFO_LOG_LENGTH, &iLength);
  191.         if(iLength > 0){
  192.             str << "Log Message:\n - ";
  193.             std::unique_ptr<char[]> pLogInfo(new char[iLength]);
  194.             int iWritten = 0;
  195.             glGetProgramInfoLog(pInfoProgram->uId, iLength, &iWritten, pLogInfo.get());
  196.             str << pLogInfo.get();
  197.         }
  198.         throw ExceptionHandler(str);
  199.     }
  200.  
  201.     // Verify and process attribute and uniform variables
  202.     _ProcessAttributes(pInfoProgram->uId, shaderProgramSettings._eShaderProgram, shaderProgramSettings._vAttributes, pInfoProgram->mAttributes);
  203.     _ProcessUniforms(pInfoProgram->uId, shaderProgramSettings._eShaderProgram, shaderProgramSettings._vUniforms, pInfoProgram->mUniforms);
  204.  
  205.     _vPrograms[shaderProgramSettings._eShaderProgram] = pInfoProgram;
  206. }
  207. unsigned ShaderManager::_InitializeShader(ShaderType eType, const std::string& filename){
  208.     int iOpenglShaderId = 0;
  209.  
  210.     switch(eType){
  211.         case TYPE_VERTEX:
  212.             iOpenglShaderId = GL_VERTEX_SHADER;
  213.             break;
  214.         case TYPE_FRAGMENT:
  215.             iOpenglShaderId = GL_FRAGMENT_SHADER;
  216.             break;
  217.         default:
  218.             throw ExceptionHandler(__FUNCTION__ + std::string(" Invalid type passed in."));
  219.     } // switch
  220.  
  221.     VectorInfoShaders& vectorInfoShaders = _avShaders[eType];
  222.  
  223.     for(unsigned u = 0; u < vectorInfoShaders.size(); ++u){
  224.         if(vectorInfoShaders[u]->strFilename == filename){
  225.             // Already loaded shader file
  226.             return u;
  227.         }
  228.     }
  229.  
  230.     // Create new shader
  231.     SharedInfoShader pInfoShader(new InfoShader(iOpenglShaderId, filename));
  232.     if(pInfoShader->uId==0)
  233.         throw ExceptionHandler(__FUNCTION__ + std::string(" glCreateShader failed for ") + filename);
  234.  
  235.     // Get source code
  236.     TextFileReader file(filename.c_str());
  237.     std::string contents = file.readAll();
  238.     const char* szContents = contents.c_str();
  239.     glShaderSource(pInfoShader->uId, 1, &szContents, nullptr);
  240.  
  241.     // Compile shader
  242.     glCompileShader(pInfoShader->uId);
  243.  
  244.     int iStatus;
  245.     glGetShaderiv(pInfoShader->uId, GL_COMPILE_STATUS, &iStatus);
  246.     if(!iStatus){
  247.         std::ostringstream str;
  248.         str << __FUNCTION__ << " failed. Compile shader failed for Shader[" << filename << "]";
  249.         str << "\n";
  250.  
  251.         int iLength = 0;
  252.         glGetShaderiv(pInfoShader->uId, GL_INFO_LOG_LENGTH, &iLength);
  253.         if(iLength > 0){
  254.             str << "Log Message:\n";
  255.             std::unique_ptr<char[]> pLogInfo(new char[iLength]);
  256.             int iWritten = 0;
  257.             glGetShaderInfoLog(pInfoShader->uId, iLength, &iWritten, pLogInfo.get());
  258.             str << pLogInfo.get();
  259.         }
  260.         throw ExceptionHandler(str);
  261.     }
  262.  
  263.     vectorInfoShaders.push_back(pInfoShader);
  264.     return (vectorInfoShaders.size()-1);
  265. }
  266. void ShaderManager::_ProcessAttributes(unsigned uInfo, Program prog, std::vector<ShaderProgramSettings::AttributeInfo>& vAttribs, MapAttributes& mAttribs) const {
  267.     bool bError = false;
  268.  
  269.     std::ostringstream str;
  270.     str << __FUNCTION__ << "\nErrors were found with ATTRIBUTE variables in ShaderProg " << prog << "\n";
  271.  
  272.     int iNumVariables = 0;
  273.     glGetProgramiv(uInfo, GL_ACTIVE_ATTRIBUTES, &iNumVariables);
  274.     std::cout << "GL_ACTIVE_ATTRIBUTES returns " << iNumVariables << std::endl;
  275.  
  276.     if(iNumVariables == 0 && !vAttribs.empty()){
  277.         for each(const ShaderProgramSettings::AttributeInfo& attrib in vAttribs){
  278.             str << attrib.strName << " " << attrib.shaderVariable << " is not used in shader.\n";
  279.         }
  280.         throw ExceptionHandler(str);
  281.     }
  282.  
  283.     int iMaxLen = 0;
  284.     glGetProgramiv(uInfo, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &iMaxLen);
  285.     std::unique_ptr<char[]> pAttributeName(new char[iMaxLen]);
  286.     for(int i=0; i<iNumVariables; i++){
  287.         int iSize;
  288.         GLenum eType;
  289.         glGetActiveAttrib(uInfo, i, iMaxLen, NULL, &iSize, &eType, pAttributeName.get());
  290.         unsigned uiLoc = glGetAttribLocation(uInfo, pAttributeName.get());
  291.         std::cout << "Attrib List["<<i<<"]: " << pAttributeName.get() << " Position: " << uiLoc << "\n";
  292.     }
  293.     for(int i=0; i<iNumVariables; ++i){
  294.         int iSize;
  295.         GLenum eType;
  296.         glGetActiveAttrib(uInfo, i, iMaxLen, NULL, &iSize, &eType, pAttributeName.get());
  297.  
  298.         AttributeType eAttributeType = static_cast<AttributeType>(eType);
  299.         bool bFound = false;
  300.         for(auto it = vAttribs.begin(); it!=vAttribs.end(); it++){
  301.             std::cout << "Current attrib " << it->strName << " vs " << pAttributeName.get() << "\n";
  302.             if(it->strName == pAttributeName.get()){
  303.                 bFound = true;
  304.                 std::cout << "Found attrib " << pAttributeName.get() << "\n";
  305.                 if(it->shaderVariable._eType != eAttributeType){
  306.                     str << "Type missmatch in " << pAttributeName.get() << ". "
  307.                         << it->shaderVariable << " was defined, but shader used type{" << GetShaderTypeName(eAttributeType) << "}.\n";
  308.                 } else {
  309.                     std::cout << "Verified attrib " << pAttributeName.get() << "\n";
  310.                     it->isVerified = true;
  311.                 }
  312.             }
  313.         }
  314.         if(!bFound){
  315.             str << pAttributeName.get() << " of type{" << GetShaderTypeName(eAttributeType) << "} is used in the shader but was not added to the ShaderProgramSettings.\n";
  316.             bError = true;
  317.         }
  318.  
  319.         // Check to ensure all variables were verified
  320.         for each(const ShaderProgramSettings::AttributeInfo& attrib in vAttribs){
  321.             if(!attrib.isVerified){
  322.                 str<< attrib.strName << " " << attrib.shaderVariable << " is not verified.\n";
  323.                 bError = true;
  324.             } else {
  325.                 unsigned uiLoc = glGetAttribLocation(uInfo, attrib.strName.c_str());
  326.                 if(uiLoc == INVALID_UNSIGNED){
  327.                     str << " Can not find attribute locaton for {" << attrib.strName << "}\n";
  328.                     throw ExceptionHandler(str);
  329.                 }
  330.  
  331.                 mAttribs.insert(MapAttributes::value_type(attrib.shaderVariable._eVariable,
  332.                     AttributeVariable(attrib.shaderVariable._eType, uiLoc)));
  333.             }
  334.         }
  335.         if(bError)
  336.             throw ExceptionHandler(str);
  337.     }
  338. }
  339. void ShaderManager::_ProcessUniforms(unsigned uInfo, Program prog, std::vector<ShaderProgramSettings::UniformInfo>& vUniforms, MapUniforms& mUniforms) const {
  340.     bool bError = false;
  341.  
  342.     std::ostringstream str;
  343.     str << __FUNCTION__ << " Errors were found with UNIFORM variables in ShaderProg " << prog << "\n";
  344.  
  345.     int iNumVariables = 0;
  346.     glGetProgramiv(uInfo, GL_ACTIVE_UNIFORMS, &iNumVariables);
  347.     if(iNumVariables == 0 && !vUniforms.empty()){
  348.         for each(const ShaderProgramSettings::UniformInfo& uni in vUniforms){
  349.             str << uni.strName << " " << uni.shaderVariable << " is not used in shader.\n";
  350.         }
  351.         throw ExceptionHandler(str);
  352.     }
  353.  
  354.     int iMaxLen = 0;
  355.     glGetProgramiv(uInfo, GL_ACTIVE_UNIFORM_MAX_LENGTH, &iMaxLen);
  356.     std::unique_ptr<char[]> pUniformName(new char[iMaxLen]);
  357.  
  358.     for(int i=0; i<iNumVariables; ++i){
  359.         int iSize;
  360.         GLenum eType;
  361.         glGetActiveUniform(uInfo, i, iMaxLen, NULL, &iSize, &eType, pUniformName.get());
  362.  
  363.         UniformType eUniformType = static_cast<UniformType>(eType);
  364.         bool bFound = false;
  365.         for(auto it = vUniforms.begin(); it!=vUniforms.end(); it++){
  366.             if(it->strName == pUniformName.get()){
  367.                 bFound = true;
  368.                 if(it->shaderVariable._eType != eUniformType){
  369.                     str << "Type missmatch in " << pUniformName.get() << ". "
  370.                         << it->shaderVariable << " was defined, but shader used type{" << GetShaderTypeName(eUniformType) << "}.\n";
  371.                 } else {
  372.                     it->isVerified = true;
  373.                 }
  374.             }
  375.         }
  376.         if(!bFound){
  377.             str << pUniformName.get() << " of type{" << GetShaderTypeName(eUniformType) << "} is used in the shader but was not added to the ShaderProgramSettings.\n";
  378.             bError = true;
  379.         }
  380.  
  381.         // Check to ensure all variables were verified
  382.         for each(const ShaderProgramSettings::UniformInfo& uni in vUniforms){
  383.             if(!uni.isVerified){
  384.                 str<< uni.strName << " " << uni.shaderVariable << " is not verified.\n";
  385.                 bError = true;
  386.             } else {
  387.                 unsigned uiLoc = glGetUniformLocation(uInfo, uni.strName.c_str());
  388.                 if(uiLoc == INVALID_UNSIGNED){
  389.                     str << " Can not find uniform locaton for {" << uni.strName << "}\n";
  390.                     throw ExceptionHandler(str);
  391.                 }
  392.  
  393.                 mUniforms.insert(MapUniforms::value_type(uni.shaderVariable._eVariable,
  394.                     UniformVariable(uni.shaderVariable._eType, uiLoc)));
  395.             }
  396.         }
  397.         if(bError)
  398.             throw ExceptionHandler(str);
  399.     }
  400. }
  401. void ShaderManager::Enable(Program eProg){
  402.     try{
  403.         glUseProgram(_vPrograms.at(eProg)->uId);
  404.         _eEnableShaderProgram = eProg;
  405.     } catch (std::exception&){
  406.         std::ostringstream str;
  407.         str << __FUNCTION__ << " ShaderProgram[" << eProg << "] is out of range in _avProgram\n";
  408.         throw ExceptionHandler(str);
  409.     }
  410. }
  411. void ShaderManager::EnableAttribute(Attribute eAttrib, unsigned stride, unsigned offset, bool normalize) const{
  412.     _SetVertexAttribute(eAttrib, reinterpret_cast<const void* const>(0), true, stride, offset, normalize);
  413. }
  414. void ShaderManager::DisableAttribute(Attribute eAttrib) const{
  415.     _SetVertexAttribute(eAttrib, reinterpret_cast<const void* const>(0), false, 0, 0, false);
  416. }
  417.  
  418. void ShaderManager::_SetVertexAttribute(AttributeVariable a,const void* const p, bool b, unsigned s, unsigned o, bool n)const{
  419.     if(b){
  420.         glVertexAttribPointer(a.uLocation, a.iSize, GL_FLOAT, (n?GL_TRUE:GL_FALSE),s, reinterpret_cast<const void*>(o));
  421.         glEnableVertexAttribArray(a.uLocation);
  422.     } else {
  423.         glDisableVertexAttribArray(a.uLocation);
  424.     }
  425. }
  426. void ShaderManager::_SetVertexAttribute(AttributeVariable a, const float* const p, bool _x1_, unsigned _x2_, unsigned _x3_, bool _x4_) const{
  427.     //glVertexAttrib4fv(a.uLocation, p);
  428. }
  429. void ShaderManager::SetUniform(Uniform eShaderUniform, const glm::mat4& m4Matrix) const{
  430.     try{
  431.         SharedInfoProgram pInfo = _vPrograms.at(_eEnableShaderProgram);
  432.         MapUniforms::const_iterator it = pInfo->mUniforms.find(eShaderUniform);
  433.         if(it==pInfo->mUniforms.cend()){
  434.             std::ostringstream str;
  435.             str << __FUNCTION__ << " Can not find Uniform location for Uniform{" << eShaderUniform<<"} in the active program {" << _eEnableShaderProgram <<"}\n";
  436.             throw ExceptionHandler(str);
  437.         }
  438.         if( !(it->second.eType == UT_FLOAT_MAT4))
  439.         {
  440.             std::ostringstream str;
  441.             str << __FUNCTION__ << " Invalid type passed into function.\n";
  442.             throw ExceptionHandler(str);
  443.         }
  444.         glUniformMatrix4fv(it->second.uLocation, 1, false, &m4Matrix[0][0]);
  445.  
  446.     } catch(std::exception&){
  447.         std::ostringstream str;
  448.         str << __FUNCTION__ << " failed.\n";
  449.         if(_eEnableShaderProgram == NO_SHADER_PROGRAM){
  450.             str << "ShaderManager::Enable has not been called.\n";
  451.         } else {
  452.             str << "ShaderProgram is out of ranged. (" << _eEnableShaderProgram << std::endl;
  453.         }
  454.         throw ExceptionHandler(str);
  455.     }
  456. }
  457. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement