| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137 |
- #include "Config.h"
- #include "ErrorHandlerLocator.h"
- #include "ShaderLoader.h"
- #include "ShaderUniformUpdater.h"
- #include "Utilities.h"
- unsigned int ShaderLoader::ShaderProgram::m_defaultProgramHandle = 0;
- ShaderLoader::ShaderLoader()
- {
- // Assign shader types, so they could be resolved from array type
- //m_shaderTypes[ArrayFragment] = ShaderFragment;
- //m_shaderTypes[ArrayGeometry] = ShaderGeometry;
- //m_shaderTypes[ArrayVertex] = ShaderVertex;
- //m_shaderTypes[ArrayTessControl] = ShaderTessControl;
- //m_shaderTypes[ArrayTessEvaluation] = ShaderTessEvaluation;
- }
- ShaderLoader::~ShaderLoader()
- {
- }
- ErrorCode ShaderLoader::init()
- {
- // Initialize default shader program
- m_defaultProgram.loadToMemory();
- m_defaultProgram.m_uniformUpdater = new ShaderUniformUpdater(m_defaultProgram);
- m_defaultProgram.m_loadedToVideoMemory = true;
- // Reserve space in the program pool, to speed up push_backs
- m_shaderPrograms.reserve(Config::rendererVar().shader_pool_size);
- ShaderProgram::m_defaultProgramHandle = m_defaultProgram.m_programHandle;
- return ErrorCode::Success;
- }
- ShaderLoader::ShaderProgram *ShaderLoader::load(const PropertySet &p_properties)
- {
- if(p_properties)
- {
- // Create shader filename array
- std::string shaderFilename[ShaderType_NumOfTypes];
- std::string programName;
- int numberOfShaders = 0;
- // Iterate over all passed properties
- for(decltype(p_properties.getNumProperties()) i = 0, size = p_properties.getNumProperties(); i < size; i++)
- {
- switch(p_properties[i].getPropertyID())
- {
- case Properties::Name:
- programName = p_properties[i].getString();
- break;
- case Properties::FragmentShader:
- shaderFilename[ShaderType_Fragment] = p_properties[i].getString();
- numberOfShaders++;
- break;
- case Properties::VertexShader:
- shaderFilename[ShaderType_Vertex] = p_properties[i].getString();
- numberOfShaders++;
- break;
- case Properties::GeometryShader:
- shaderFilename[ShaderType_Geometry] = p_properties[i].getString();
- numberOfShaders++;
- break;
- case Properties::TessControlShader:
- shaderFilename[ShaderType_TessControl] = p_properties[i].getString();
- numberOfShaders++;
- break;
- case Properties::TessEvaluationShader:
- shaderFilename[ShaderType_TessEvaluation] = p_properties[i].getString();
- numberOfShaders++;
- break;
- }
- }
- if(numberOfShaders > 0)
- {
- // If program name was not specified, combine all shader names into one program name
- if(programName.empty())
- {
- // For every shader filename, if it's not empty, add it to the program name
- for(unsigned int shaderType = 0; shaderType < ShaderType_NumOfTypes; shaderType++)
- if(!shaderFilename[shaderType].empty())
- programName += shaderFilename[shaderType] + ", ";
- // Remove the last 2 characters from the filename (comma and space)
- if(!programName.empty())
- {
- programName.pop_back();
- programName.pop_back();
- }
- }
- // Generate hash key from program's name
- unsigned int programHashkey = Utilities::getHashKey(programName);
- // Make sure calls from other threads are locked, while current call is in progress
- // This is needed to as the object that is being requested might be currently loading /
- // being added to the pool. Mutex prevents duplicates being loaded, and same data being changed.
- SpinWait::Lock lock(m_mutex);
- // Iterate over all shader programs and match hash key and name; if match is found, return it
- for(decltype(m_shaderPrograms.size()) i = 0, size = m_shaderPrograms.size(); i < size; i++)
- if(m_shaderPrograms[i]->m_filenameHash == programHashkey)
- if(m_shaderPrograms[i]->m_combinedFilename == programName)
- return m_shaderPrograms[i];
- // Add the new program to the array
- ShaderProgram *newProgram = new ShaderProgram(programName, programHashkey);
- m_shaderPrograms.push_back(newProgram);
- // Iterate over shader types
- for(unsigned int shaderType = 0; shaderType < ShaderType_NumOfTypes; shaderType++)
- // If shader filename is valid
- if(!shaderFilename[shaderType].empty())
- newProgram->addShader(static_cast<ShaderType>(shaderType), shaderFilename[shaderType]);
- // Create a uniform updater for the new shader
- newProgram->m_uniformUpdater = new ShaderUniformUpdater(*newProgram);
- return newProgram;
- }
- }
- return &m_defaultProgram;
- }
|