diff --git a/src/celengine/asterism.cpp b/src/celengine/asterism.cpp index b055f792..5587a33f 100644 --- a/src/celengine/asterism.cpp +++ b/src/celengine/asterism.cpp @@ -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); diff --git a/src/celengine/asterism.h b/src/celengine/asterism.h index ef1311b5..99297320 100644 --- a/src/celengine/asterism.h +++ b/src/celengine/asterism.h @@ -73,7 +73,7 @@ class AsterismList : public std::vector 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&); diff --git a/src/celengine/axisarrow.cpp b/src/celengine/axisarrow.cpp index f4ec04e0..19e1c634 100644 --- a/src/celengine/axisarrow.cpp +++ b/src/celengine/axisarrow.cpp @@ -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; } diff --git a/src/celengine/axisarrow.h b/src/celengine/axisarrow.h index 73e4335c..9f918b7b 100644 --- a/src/celengine/axisarrow.h +++ b/src/celengine/axisarrow.h @@ -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 }; }; diff --git a/src/celengine/boundaries.cpp b/src/celengine/boundaries.cpp index a5c93f85..9bbcd5ca 100644 --- a/src/celengine/boundaries.cpp +++ b/src/celengine/boundaries.cpp @@ -24,9 +24,6 @@ ConstellationBoundaries::ConstellationBoundaries() { currentChain = new Chain(); currentChain->emplace_back(Vector3f::Zero()); - - shadprop.staticShader = true; - shadprop.staticProps = ShaderProperties::UniformColor; } ConstellationBoundaries::~ConstellationBoundaries() diff --git a/src/celengine/boundaries.h b/src/celengine/boundaries.h index 320ac8be..280d14ce 100644 --- a/src/celengine/boundaries.h +++ b/src/celengine/boundaries.h @@ -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&); diff --git a/src/celengine/shadermanager.cpp b/src/celengine/shadermanager.cpp index 5d79b8c5..51a93b3d 100644 --- a/src/celengine/shadermanager.cpp +++ b/src/celengine/shadermanager.cpp @@ -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"); } } diff --git a/src/celengine/shadermanager.h b/src/celengine/shadermanager.h index 197a095c..b376fa5d 100644 --- a/src/celengine/shadermanager.h +++ b/src/celengine/shadermanager.h @@ -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 dynamicShaders; + std::map dynamicShaders; std::map staticShaders; };