Support for static shaders in ShaderManager
parent
b09b48b1ab
commit
9745b125f3
|
@ -125,6 +125,24 @@ Vec4ShaderParameter::operator=(const Eigen::Vector4f& v)
|
|||
}
|
||||
|
||||
|
||||
IntegerShaderParameter::IntegerShaderParameter() :
|
||||
slot(-1)
|
||||
{
|
||||
}
|
||||
|
||||
IntegerShaderParameter::IntegerShaderParameter(GLuint obj, const char* name)
|
||||
{
|
||||
slot = glGetUniformLocation(obj, name);
|
||||
}
|
||||
|
||||
IntegerShaderParameter&
|
||||
IntegerShaderParameter::operator=(int i)
|
||||
{
|
||||
if (slot != -1)
|
||||
glUniform1i(slot, i);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//************* GLProgram **************
|
||||
|
||||
GLProgram::GLProgram(GLuint _id) :
|
||||
|
|
|
@ -124,6 +124,18 @@ class Vec4ShaderParameter
|
|||
};
|
||||
|
||||
|
||||
class IntegerShaderParameter
|
||||
{
|
||||
public:
|
||||
IntegerShaderParameter();
|
||||
IntegerShaderParameter(GLuint obj, const char* name);
|
||||
|
||||
IntegerShaderParameter& operator=(int);
|
||||
|
||||
private:
|
||||
int slot;
|
||||
};
|
||||
|
||||
|
||||
class GLShaderLoader
|
||||
{
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include <fmt/printf.h>
|
||||
#include <cassert>
|
||||
#include <Eigen/Geometry>
|
||||
#include <sys/stat.h>
|
||||
|
||||
using namespace Eigen;
|
||||
using namespace std;
|
||||
|
@ -290,19 +291,22 @@ ShaderManager::ShaderManager()
|
|||
|
||||
ShaderManager::~ShaderManager()
|
||||
{
|
||||
for(const auto& shader : shaders)
|
||||
{
|
||||
for(const auto& shader : dynamicShaders)
|
||||
delete shader.second;
|
||||
}
|
||||
|
||||
shaders.clear();
|
||||
dynamicShaders.clear();
|
||||
|
||||
for(const auto& shader : staticShaders)
|
||||
delete shader.second;
|
||||
|
||||
staticShaders.clear();
|
||||
}
|
||||
|
||||
CelestiaGLProgram*
|
||||
ShaderManager::getShader(const ShaderProperties& props)
|
||||
{
|
||||
map<ShaderProperties, CelestiaGLProgram*>::iterator iter = shaders.find(props);
|
||||
if (iter != shaders.end())
|
||||
auto iter = dynamicShaders.find(props);
|
||||
if (iter != dynamicShaders.end())
|
||||
{
|
||||
// Shader already exists
|
||||
return iter->second;
|
||||
|
@ -311,12 +315,88 @@ ShaderManager::getShader(const ShaderProperties& props)
|
|||
{
|
||||
// Create a new shader and add it to the table of created shaders
|
||||
CelestiaGLProgram* prog = buildProgram(props);
|
||||
shaders[props] = prog;
|
||||
dynamicShaders[props] = prog;
|
||||
|
||||
return prog;
|
||||
}
|
||||
}
|
||||
|
||||
CelestiaGLProgram*
|
||||
ShaderManager::getShader(const string& name, const string& vs, const string& fs)
|
||||
{
|
||||
auto iter = staticShaders.find(name);
|
||||
if (iter != staticShaders.end())
|
||||
{
|
||||
// Shader already exists
|
||||
return iter->second;
|
||||
}
|
||||
|
||||
// Create a new shader and add it to the table of created shaders
|
||||
CelestiaGLProgram* prog = buildProgram(vs, fs);
|
||||
staticShaders[name] = prog;
|
||||
|
||||
return prog;
|
||||
}
|
||||
|
||||
#ifndef _WIN32
|
||||
constexpr const char fsDelimeter = '/';
|
||||
#else
|
||||
constexpr const char fsDelimeter = '\\';
|
||||
#endif
|
||||
|
||||
CelestiaGLProgram*
|
||||
ShaderManager::getShader(const string& name)
|
||||
{
|
||||
auto iter = staticShaders.find(name);
|
||||
if (iter != staticShaders.end())
|
||||
{
|
||||
// Shader already exists
|
||||
return iter->second;
|
||||
}
|
||||
|
||||
auto vsName = fmt::sprintf("shaders%c%s_vert.glsl", fsDelimeter, name);
|
||||
auto fsName = fmt::sprintf("shaders%c%s_frag.glsl", fsDelimeter, name);
|
||||
|
||||
struct stat s;
|
||||
if (stat(vsName.c_str(), &s) == -1)
|
||||
{
|
||||
fmt::fprintf(cerr, "Failed to stat %s\n", vsName);
|
||||
return getShader(name, errorVertexShaderSource, errorFragmentShaderSource);
|
||||
}
|
||||
auto vsSize = s.st_size;
|
||||
|
||||
if (stat(fsName.c_str(), &s) == -1)
|
||||
{
|
||||
fmt::fprintf(cerr, "Failed to stat %s\n", fsName);
|
||||
return getShader(name, errorVertexShaderSource, errorFragmentShaderSource);
|
||||
}
|
||||
auto fsSize = s.st_size;
|
||||
|
||||
ifstream vsf(vsName);
|
||||
if (!vsf.good())
|
||||
{
|
||||
fmt::fprintf(cerr, "Failed to open %s\n", vsName);
|
||||
return getShader(name, errorVertexShaderSource, errorFragmentShaderSource);
|
||||
}
|
||||
|
||||
ifstream fsf(fsName);
|
||||
if (!fsf.good())
|
||||
{
|
||||
fmt::fprintf(cerr, "Failed to open %s\n", fsName);
|
||||
return getShader(name, errorVertexShaderSource, errorFragmentShaderSource);
|
||||
}
|
||||
|
||||
string vs(vsSize, '\0'), fs(fsSize, '\0');
|
||||
|
||||
vsf.read(&vs[0], vsSize);
|
||||
fsf.read(&fs[0], fsSize);
|
||||
|
||||
// Create a new shader and add it to the table of created shaders
|
||||
CelestiaGLProgram* prog = buildProgram(vs, fs);
|
||||
staticShaders[name] = prog;
|
||||
|
||||
return prog;
|
||||
}
|
||||
|
||||
static string
|
||||
LightProperty(unsigned int i, const char* property)
|
||||
|
@ -3095,6 +3175,51 @@ ShaderManager::buildProgram(const ShaderProperties& props)
|
|||
return new CelestiaGLProgram(*prog, props);
|
||||
}
|
||||
|
||||
CelestiaGLProgram*
|
||||
ShaderManager::buildProgram(const std::string& vs, const std::string& fs)
|
||||
{
|
||||
GLProgram* prog = nullptr;
|
||||
GLShaderStatus status;
|
||||
|
||||
DumpVSSource(vs);
|
||||
DumpFSSource(fs);
|
||||
|
||||
status = GLShaderLoader::CreateProgram(vs, fs, &prog);
|
||||
if (status == ShaderStatus_OK)
|
||||
{
|
||||
// Tangents always in attribute 6 (should be a constant
|
||||
// someplace)
|
||||
glBindAttribLocation(prog->getID(), 6, "tangent");
|
||||
|
||||
// Point size is always in attribute 7
|
||||
glBindAttribLocation(prog->getID(), 7, "pointSize");
|
||||
|
||||
status = prog->link();
|
||||
}
|
||||
|
||||
if (status != ShaderStatus_OK)
|
||||
{
|
||||
// If the shader creation failed for some reason, substitute the
|
||||
// error shader.
|
||||
status = GLShaderLoader::CreateProgram(errorVertexShaderSource,
|
||||
errorFragmentShaderSource,
|
||||
&prog);
|
||||
if (status != ShaderStatus_OK)
|
||||
{
|
||||
if (g_shaderLogFile != nullptr)
|
||||
*g_shaderLogFile << "Failed to create error shader!\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
status = prog->link();
|
||||
}
|
||||
}
|
||||
|
||||
if (prog == nullptr)
|
||||
return nullptr;
|
||||
|
||||
return new CelestiaGLProgram(*prog);
|
||||
}
|
||||
|
||||
CelestiaGLProgram::CelestiaGLProgram(GLProgram& _program,
|
||||
const ShaderProperties& _props) :
|
||||
|
@ -3106,6 +3231,11 @@ CelestiaGLProgram::CelestiaGLProgram(GLProgram& _program,
|
|||
};
|
||||
|
||||
|
||||
CelestiaGLProgram::CelestiaGLProgram(GLProgram& _program) :
|
||||
program(&_program)
|
||||
{
|
||||
}
|
||||
|
||||
CelestiaGLProgram::~CelestiaGLProgram()
|
||||
{
|
||||
delete program;
|
||||
|
@ -3119,6 +3249,20 @@ CelestiaGLProgram::floatParam(const string& paramName)
|
|||
}
|
||||
|
||||
|
||||
IntegerShaderParameter
|
||||
CelestiaGLProgram::intParam(const string& paramName)
|
||||
{
|
||||
return IntegerShaderParameter(program->getID(), paramName.c_str());
|
||||
}
|
||||
|
||||
|
||||
IntegerShaderParameter
|
||||
CelestiaGLProgram::samplerParam(const string& paramName)
|
||||
{
|
||||
return IntegerShaderParameter(program->getID(), paramName.c_str());
|
||||
}
|
||||
|
||||
|
||||
Vec3ShaderParameter
|
||||
CelestiaGLProgram::vec3Param(const string& paramName)
|
||||
{
|
||||
|
|
|
@ -153,6 +153,7 @@ struct CelestiaGLProgramShadow
|
|||
class CelestiaGLProgram
|
||||
{
|
||||
public:
|
||||
CelestiaGLProgram(GLProgram& _program);
|
||||
CelestiaGLProgram(GLProgram& _program, const ShaderProperties&);
|
||||
~CelestiaGLProgram();
|
||||
|
||||
|
@ -173,12 +174,12 @@ class CelestiaGLProgram
|
|||
float atmPlanetRadius,
|
||||
float objRadius);
|
||||
|
||||
enum
|
||||
{
|
||||
VertexCoordAttributeIndex = 0,
|
||||
TangentAttributeIndex = 6,
|
||||
PointSizeAttributeIndex = 7,
|
||||
};
|
||||
enum
|
||||
{
|
||||
VertexCoordAttributeIndex = 0,
|
||||
TangentAttributeIndex = 6,
|
||||
PointSizeAttributeIndex = 7,
|
||||
};
|
||||
|
||||
public:
|
||||
CelestiaGLProgramLight lights[MaxShaderLights];
|
||||
|
@ -249,14 +250,16 @@ class CelestiaGLProgram
|
|||
|
||||
CelestiaGLProgramShadow shadows[MaxShaderLights][MaxShaderEclipseShadows];
|
||||
|
||||
FloatShaderParameter floatParam(const std::string&);
|
||||
IntegerShaderParameter intParam(const std::string&);
|
||||
IntegerShaderParameter samplerParam(const std::string&);
|
||||
Vec3ShaderParameter vec3Param(const std::string&);
|
||||
Vec4ShaderParameter vec4Param(const std::string&);
|
||||
|
||||
private:
|
||||
void initParameters();
|
||||
void initSamplers();
|
||||
|
||||
FloatShaderParameter floatParam(const std::string&);
|
||||
Vec3ShaderParameter vec3Param(const std::string&);
|
||||
Vec4ShaderParameter vec4Param(const std::string&);
|
||||
|
||||
GLProgram* program;
|
||||
const ShaderProperties props;
|
||||
};
|
||||
|
@ -269,9 +272,12 @@ class ShaderManager
|
|||
~ShaderManager();
|
||||
|
||||
CelestiaGLProgram* getShader(const ShaderProperties&);
|
||||
CelestiaGLProgram* getShader(const std::string&);
|
||||
CelestiaGLProgram* getShader(const std::string&, const std::string&, const std::string&);
|
||||
|
||||
private:
|
||||
CelestiaGLProgram* buildProgram(const ShaderProperties&);
|
||||
CelestiaGLProgram* buildProgram(const std::string&, const std::string&);
|
||||
|
||||
GLVertexShader* buildVertexShader(const ShaderProperties&);
|
||||
GLFragmentShader* buildFragmentShader(const ShaderProperties&);
|
||||
|
@ -291,7 +297,8 @@ class ShaderManager
|
|||
GLVertexShader* buildStaticVertexShader(const ShaderProperties&);
|
||||
GLFragmentShader* buildStaticFragmentShader(const ShaderProperties&);
|
||||
|
||||
std::map<ShaderProperties, CelestiaGLProgram*> shaders;
|
||||
std::map<ShaderProperties, CelestiaGLProgram*> dynamicShaders;
|
||||
std::map<std::string, CelestiaGLProgram*> staticShaders;
|
||||
};
|
||||
|
||||
#endif // _CELENGINE_SHADERMANAGER_H_
|
||||
|
|
Loading…
Reference in New Issue