Refactor simple shader generation

pull/3/head
Hleb Valoshka 2019-07-07 12:34:53 +03:00
parent ba0b39fdff
commit 35b53b22d5
8 changed files with 68 additions and 77 deletions

View File

@ -114,9 +114,6 @@ void AsterismList::render(const Color& defaultColor, const Renderer& renderer)
m_vo.allocate(vtx_num * 3 * sizeof(GLfloat), vtx_buf);
cleanup();
m_vo.setVertices(3, GL_FLOAT, false, 0, 0);
shadprop.staticShader = true;
shadprop.staticProps = ShaderProperties::UniformColor;
}
CelestiaGLProgram* prog = renderer.getShaderManager().getShader(shadprop);

View File

@ -73,7 +73,7 @@ class AsterismList : public std::vector<Asterism*>
bool prepared{ false };
celgl::VertexObject m_vo{GL_ARRAY_BUFFER, 0, GL_STATIC_DRAW};
ShaderProperties shadprop;
ShaderProperties shadprop{ ShaderProperties::UniformColor };
};
AsterismList* ReadAsterismList(std::istream&, const StarDatabase&);

View File

@ -219,8 +219,6 @@ ArrowReferenceMark::ArrowReferenceMark(const Body& _body) :
opacity(1.0f)
#endif
{
shadprop.staticShader = true;
shadprop.staticProps = ShaderProperties::UniformColor;
}
@ -309,8 +307,6 @@ AxesReferenceMark::AxesReferenceMark(const Body& _body) :
opacity(1.0f)
#endif
{
shadprop.staticShader = true;
shadprop.staticProps = ShaderProperties::UniformColor;
}

View File

@ -49,7 +49,7 @@ class ArrowReferenceMark : public ReferenceMark
float size;
Color color;
float opacity;
ShaderProperties shadprop;
ShaderProperties shadprop{ ShaderProperties::UniformColor };
};
@ -80,7 +80,7 @@ class AxesReferenceMark : public ReferenceMark
private:
float size;
float opacity;
ShaderProperties shadprop;
ShaderProperties shadprop{ ShaderProperties::UniformColor };
};

View File

@ -24,9 +24,6 @@ ConstellationBoundaries::ConstellationBoundaries()
{
currentChain = new Chain();
currentChain->emplace_back(Vector3f::Zero());
shadprop.staticShader = true;
shadprop.staticProps = ShaderProperties::UniformColor;
}
ConstellationBoundaries::~ConstellationBoundaries()

View File

@ -48,7 +48,7 @@ class ConstellationBoundaries
GLsizei vtx_num{ 0 };
celgl::VertexObject m_vo{GL_ARRAY_BUFFER, 0, GL_STATIC_DRAW};
ShaderProperties shadprop;
ShaderProperties shadprop{ ShaderProperties::UniformColor };
};
ConstellationBoundaries* ReadBoundaries(std::istream&);

View File

@ -55,16 +55,6 @@ static const char* errorFragmentShaderSource =
static const char* CommonHeader = "#version 120\n";
ShaderProperties::ShaderProperties() :
nLights(0),
texUsage(0),
lightModel(DiffuseModel),
shadowCounts(0),
effects(0)
{
}
bool
ShaderProperties::usesShadows() const
{
@ -2996,37 +2986,26 @@ ShaderManager::buildParticleFragmentShader(const ShaderProperties& props)
}
GLVertexShader*
ShaderManager::buildStaticVertexShader(const ShaderProperties& props)
ShaderManager::buildSimpleVertexShader(uint32_t props)
{
ostringstream source;
source << CommonHeader << "// static shader\n";
source << CommonHeader;
if (props.texUsage & ShaderProperties::NormalTexture)
{
source << "uniform sampler2D normTex;\n";
}
if (props.texUsage & ShaderProperties::PointSprite)
{
source << DeclareUniform("pointScale", Shader_Float);
source << DeclareAttribute("pointSize", Shader_Float);
}
if (props.staticProps & ShaderProperties::UniformColor)
source << DeclareUniform("color", Shader_Vector4);
else
if (props & ShaderProperties::PerVertexColor)
source << DeclareVarying("color", Shader_Vector4);
if (props & ShaderProperties::HasTexture)
source << DeclareVarying("texCoord", Shader_Vector2);
// Begin main()
source << "\nvoid main(void)\n";
source << "{\n";
// Optional point size
if (props.texUsage & ShaderProperties::PointSprite)
source << " gl_PointSize = pointSize;\n";
if (!(props.staticProps & ShaderProperties::UniformColor))
if (props & ShaderProperties::PerVertexColor)
source << " color = gl_Color;\n";
if (props & ShaderProperties::HasTexture)
source << " texCoord = gl_MultiTexCoord0.st;\n";
source << " gl_Position = ftransform();\n";
source << "}\n";
@ -3041,34 +3020,32 @@ ShaderManager::buildStaticVertexShader(const ShaderProperties& props)
GLFragmentShader*
ShaderManager::buildStaticFragmentShader(const ShaderProperties& props)
ShaderManager::buildSimpleFragmentShader(uint32_t props)
{
ostringstream source;
source << CommonHeader;
if (props.texUsage & ShaderProperties::NormalTexture)
if (props & ShaderProperties::UniformColor)
source << DeclareUniform("color", Shader_Vector4);
if (props & ShaderProperties::HasTexture)
{
source << "uniform sampler2D normTex;\n";
source << DeclareUniform("tex", Shader_Sampler2D);
source << DeclareVarying("texCoord", Shader_Vector2);
}
if (props.staticProps & ShaderProperties::UniformColor)
source << DeclareUniform("color", Shader_Vector4);
else
if (props & ShaderProperties::PerVertexColor)
source << DeclareVarying("color", Shader_Vector4);
// Begin main()
source << "\nvoid main(void)\n";
source << "{\n";
if (props.texUsage & ShaderProperties::NormalTexture)
{
source << " gl_FragColor = texture2D(normTex, gl_PointCoord) * color;\n";
}
if (props & ShaderProperties::HasTexture)
source << " gl_FragColor = texture2D(tex, texCoord) * color;\n";
else
{
source << " gl_FragColor = color;\n";
}
source << "}\n";
// End of main()
@ -3091,10 +3068,10 @@ ShaderManager::buildProgram(const ShaderProperties& props)
GLVertexShader* vs = nullptr;
GLFragmentShader* fs = nullptr;
if (props.staticShader)
if (props.simpleProps != 0)
{
vs = buildStaticVertexShader(props);
fs = buildStaticFragmentShader(props);
vs = buildSimpleVertexShader(props.simpleProps);
fs = buildSimpleFragmentShader(props.simpleProps);
}
else if (props.lightModel == ShaderProperties::RingIllumModel)
{
@ -3384,10 +3361,9 @@ CelestiaGLProgram::initParameters()
pointScale = floatParam("pointScale");
}
if (props.staticShader)
if (props.simpleProps & ShaderProperties::UniformColor)
{
if (props.staticProps & ShaderProperties::UniformColor)
color = vec4Param("color");
color = vec4Param("color");
}
}

View File

@ -23,7 +23,8 @@
class ShaderProperties
{
public:
ShaderProperties();
ShaderProperties() = default;
ShaderProperties(uint32_t p) : simpleProps(p) {};
bool usesShadows() const;
bool usesFragmentLighting() const;
bool usesTangentSpaceLighting() const;
@ -87,15 +88,20 @@ class ShaderProperties
VolumetricEmissionEffect = 0x0004,
};
enum
enum : uint32_t
{
UniformColor = 0x0001,
UniformColor = 0x0001,
PerVertexColor = 0x0002,
HasTexture = 0x0004
};
public:
unsigned short nLights;
unsigned short texUsage;
unsigned short lightModel;
unsigned short nLights{ 0 };
unsigned short texUsage{ 0 };
unsigned short lightModel{ DiffuseModel };
// Effects that may be applied with any light model
unsigned short effects{ 0 };
// Eight bits per light, up to four lights
// For each light:
@ -103,15 +109,32 @@ class ShaderProperties
// Bit 2, on if there are ring shadows
// Bit 3, on for self shadowing
// Bit 4, on for cloud shadows
uint32_t shadowCounts;
uint32_t shadowCounts{ 0 };
// Effects that may be applied with any light model
unsigned short effects;
bool staticShader{ false };
uint32_t staticProps{ 0 };
// Properties of "simple" shaders. Other properties are ignored.
uint32_t simpleProps{ 0 };
private:
// This struct is required to compare keys in ShaderManager
// Default one doesn't work properly in some cases.
struct Cmp
{
bool operator()(const ShaderProperties& lhs, const ShaderProperties& rhs) const
{
if (lhs.simpleProps != 0 && rhs.simpleProps != 0)
return lhs.simpleProps < rhs.simpleProps;
if (lhs.nLights != rhs.nLights)
return lhs.nLights < rhs.nLights;
if (lhs.texUsage != rhs.texUsage)
return lhs.texUsage < rhs.texUsage;
if (lhs.lightModel != rhs.lightModel)
return lhs.lightModel < rhs.lightModel;
if (lhs.shadowCounts != rhs.shadowCounts)
return lhs.shadowCounts < rhs.shadowCounts;
return lhs.effects < rhs.effects;
}
};
enum
{
ShadowBitsPerLight = 4,
@ -128,6 +151,8 @@ class ShaderProperties
AnySelfShadowMask = 0x08080808,
AnyCloudShadowMask = 0x10101010,
};
friend class ShaderManager;
};
@ -298,10 +323,10 @@ class ShaderManager
GLVertexShader* buildParticleVertexShader(const ShaderProperties&);
GLFragmentShader* buildParticleFragmentShader(const ShaderProperties&);
GLVertexShader* buildStaticVertexShader(const ShaderProperties&);
GLFragmentShader* buildStaticFragmentShader(const ShaderProperties&);
GLVertexShader* buildSimpleVertexShader(uint32_t);
GLFragmentShader* buildSimpleFragmentShader(uint32_t);
std::map<ShaderProperties, CelestiaGLProgram*> dynamicShaders;
std::map<ShaderProperties, CelestiaGLProgram*, ShaderProperties::Cmp> dynamicShaders;
std::map<std::string, CelestiaGLProgram*> staticShaders;
};