diff options
author | Kae <80987908+Novaenia@users.noreply.github.com> | 2023-06-30 05:55:41 +1000 |
---|---|---|
committer | Kae <80987908+Novaenia@users.noreply.github.com> | 2023-06-30 05:55:41 +1000 |
commit | fd5247321f36e7cb50dd90cb9bd1b5d60a3a289f (patch) | |
tree | 8603fa144341728da19da8df5d6790be792ceef1 /source/application | |
parent | d5fbd2001b0ad3591a7f969dfd75c809ab55b40e (diff) |
Split world & interface shaders
Diffstat (limited to 'source/application')
-rw-r--r-- | source/application/StarRenderer.hpp | 4 | ||||
-rw-r--r-- | source/application/StarRenderer_opengl20.cpp | 92 | ||||
-rw-r--r-- | source/application/StarRenderer_opengl20.hpp | 19 |
3 files changed, 75 insertions, 40 deletions
diff --git a/source/application/StarRenderer.hpp b/source/application/StarRenderer.hpp index 908f121..58c1c27 100644 --- a/source/application/StarRenderer.hpp +++ b/source/application/StarRenderer.hpp @@ -135,13 +135,15 @@ public: // specific to each type of renderer, so it will be necessary to key the // configuration off of the renderId string. This should not be called every // frame, because it will result in a recompile of the underlying shader set. - virtual void setEffectConfig(Json const& effectConfig, StringMap<String> const& shaders) = 0; + virtual void loadEffectConfig(String const& name, Json const& effectConfig, StringMap<String> const& shaders) = 0; // The effect config will specify named parameters and textures which can be // set here. virtual void setEffectParameter(String const& parameterName, RenderEffectParameter const& parameter) = 0; virtual void setEffectTexture(String const& textureName, Image const& image) = 0; + virtual bool switchEffectConfig(String const& name) = 0; + // Any further rendering will be scissored based on this rect, specified in // pixels virtual void setScissorRect(Maybe<RectI> const& scissorRect) = 0; diff --git a/source/application/StarRenderer_opengl20.cpp b/source/application/StarRenderer_opengl20.cpp index 375149e..70185cc 100644 --- a/source/application/StarRenderer_opengl20.cpp +++ b/source/application/StarRenderer_opengl20.cpp @@ -93,7 +93,7 @@ OpenGl20Renderer::OpenGl20Renderer() { TextureFiltering::Nearest); m_immediateRenderBuffer = createGlRenderBuffer(); - setEffectConfig(JsonObject(), {{"vertex", DefaultVertexShader}, {"fragment", DefaultFragmentShader}}); + loadEffectConfig("internal", JsonObject(), {{"vertex", DefaultVertexShader}, {"fragment", DefaultFragmentShader}}); m_limitTextureGroupSize = false; m_useMultiTexturing = true; @@ -102,7 +102,8 @@ OpenGl20Renderer::OpenGl20Renderer() { } OpenGl20Renderer::~OpenGl20Renderer() { - glDeleteProgram(m_program); + for (auto& effect : m_effects) + glDeleteProgram(effect.second.program); logGlErrorSummary("OpenGL errors during shutdown"); } @@ -115,8 +116,13 @@ Vec2U OpenGl20Renderer::screenSize() const { return m_screenSize; } -void OpenGl20Renderer::setEffectConfig(Json const& effectConfig, StringMap<String> const& shaders) { - flushImmediatePrimitives(); +void OpenGl20Renderer::loadEffectConfig(String const& name, Json const& effectConfig, StringMap<String> const& shaders) { + if (m_effects.contains(name)) { + Logger::warn("OpenGL effect {} already exists", name); + switchEffectConfig(name); + return; + } + GLint status = 0; char logBuffer[1024]; @@ -161,32 +167,11 @@ void OpenGl20Renderer::setEffectConfig(Json const& effectConfig, StringMap<Strin throw RendererException(strf("Failed to link program: {}\n", logBuffer)); } - if (m_program != 0) - glDeleteProgram(m_program); - m_program = program; - glUseProgram(m_program); - - m_positionAttribute = glGetAttribLocation(m_program, "vertexPosition"); - m_texCoordAttribute = glGetAttribLocation(m_program, "vertexTextureCoordinate"); - m_texIndexAttribute = glGetAttribLocation(m_program, "vertexTextureIndex"); - m_colorAttribute = glGetAttribLocation(m_program, "vertexColor"); - m_param1Attribute = glGetAttribLocation(m_program, "vertexParam1"); + glUseProgram(m_program = program); + setupGlUniforms(m_program); - m_textureUniforms.clear(); - m_textureSizeUniforms.clear(); - for (size_t i = 0; i < MultiTextureCount; ++i) { - m_textureUniforms.append(glGetUniformLocation(m_program, strf("texture{}", i).c_str())); - m_textureSizeUniforms.append(glGetUniformLocation(m_program, strf("textureSize{}", i).c_str())); - } - m_screenSizeUniform = glGetUniformLocation(m_program, "screenSize"); - m_vertexTransformUniform = glGetUniformLocation(m_program, "vertexTransform"); - - for (size_t i = 0; i < MultiTextureCount; ++i) { - glUniform1i(m_textureUniforms[i], i); - } - glUniform2f(m_screenSizeUniform, m_screenSize[0], m_screenSize[1]); - - m_effectParameters.clear(); + auto& effect = m_effects.emplace(name, Effect{ program, effectConfig, {}, {} }).first->second; + m_currentEffect = &effect; for (auto const& p : effectConfig.getObject("effectParameters", {})) { EffectParameter effectParameter; @@ -212,7 +197,7 @@ void OpenGl20Renderer::setEffectConfig(Json const& effectConfig, StringMap<Strin throw RendererException::format("Unrecognized effect parameter type '{}'", type); } - m_effectParameters[p.first] = effectParameter; + effect.parameters[p.first] = effectParameter; if (Json def = p.second.get("default", {})) { if (type == "bool") { @@ -232,8 +217,6 @@ void OpenGl20Renderer::setEffectConfig(Json const& effectConfig, StringMap<Strin } } - m_effectTextures.clear(); - // Assign each texture parameter a texture unit starting with MultiTextureCount, the first // few texture units are used by the primary textures being drawn. Currently, // maximum texture units are not checked. @@ -256,7 +239,7 @@ void OpenGl20Renderer::setEffectConfig(Json const& effectConfig, StringMap<Strin Logger::warn("OpenGL20 effect parameter '{}' has textureSizeUniform '{}' with no associated uniform", p.first, *tsu); } - m_effectTextures[p.first] = effectTexture; + effect.textures[p.first] = effectTexture; } } @@ -265,7 +248,7 @@ void OpenGl20Renderer::setEffectConfig(Json const& effectConfig, StringMap<Strin } void OpenGl20Renderer::setEffectParameter(String const& parameterName, RenderEffectParameter const& value) { - auto ptr = m_effectParameters.ptr(parameterName); + auto ptr = m_currentEffect->parameters.ptr(parameterName); if (!ptr || (ptr->parameterValue && *ptr->parameterValue == value)) return; @@ -291,7 +274,7 @@ void OpenGl20Renderer::setEffectParameter(String const& parameterName, RenderEff } void OpenGl20Renderer::setEffectTexture(String const& textureName, Image const& image) { - auto ptr = m_effectTextures.ptr(textureName); + auto ptr = m_currentEffect->textures.ptr(textureName); if (!ptr) return; @@ -311,6 +294,21 @@ void OpenGl20Renderer::setEffectTexture(String const& textureName, Image const& } } +bool OpenGl20Renderer::switchEffectConfig(String const& name) { + flushImmediatePrimitives(); + auto find = m_effects.find(name); + if (find == m_effects.end()) + return false; + + Effect& effect = find->second; + + glUseProgram(m_program = effect.program); + setupGlUniforms(m_program); + m_currentEffect = &effect; + + return true; +} + void OpenGl20Renderer::setScissorRect(Maybe<RectI> const& scissorRect) { if (scissorRect == m_scissorRect) return; @@ -798,7 +796,7 @@ void OpenGl20Renderer::renderGlBuffer(GlRenderBuffer const& renderBuffer, Mat3F glBindTexture(GL_TEXTURE_2D, vb.textures[i].texture); } - for (auto const& p : m_effectTextures) { + for (auto const& p : m_currentEffect->textures) { if (p.second.textureValue) { glActiveTexture(GL_TEXTURE0 + p.second.textureUnit); glBindTexture(GL_TEXTURE_2D, p.second.textureValue->textureId); @@ -823,4 +821,26 @@ void OpenGl20Renderer::renderGlBuffer(GlRenderBuffer const& renderBuffer, Mat3F } } +void OpenGl20Renderer::setupGlUniforms(GLuint program) { + m_positionAttribute = glGetAttribLocation(program, "vertexPosition"); + m_texCoordAttribute = glGetAttribLocation(program, "vertexTextureCoordinate"); + m_texIndexAttribute = glGetAttribLocation(program, "vertexTextureIndex"); + m_colorAttribute = glGetAttribLocation(program, "vertexColor"); + m_param1Attribute = glGetAttribLocation(program, "vertexParam1"); + + m_textureUniforms.clear(); + m_textureSizeUniforms.clear(); + for (size_t i = 0; i < MultiTextureCount; ++i) { + m_textureUniforms.append(glGetUniformLocation(program, strf("texture{}", i).c_str())); + m_textureSizeUniforms.append(glGetUniformLocation(program, strf("textureSize{}", i).c_str())); + } + m_screenSizeUniform = glGetUniformLocation(program, "screenSize"); + m_vertexTransformUniform = glGetUniformLocation(program, "vertexTransform"); + + for (size_t i = 0; i < MultiTextureCount; ++i) + glUniform1i(m_textureUniforms[i], i); + + glUniform2f(m_screenSizeUniform, m_screenSize[0], m_screenSize[1]); +} + } diff --git a/source/application/StarRenderer_opengl20.hpp b/source/application/StarRenderer_opengl20.hpp index ff82d3a..5add227 100644 --- a/source/application/StarRenderer_opengl20.hpp +++ b/source/application/StarRenderer_opengl20.hpp @@ -20,12 +20,15 @@ public: String rendererId() const override; Vec2U screenSize() const override; - void setEffectConfig(Json const& effectConfig, StringMap<String> const& shaders) override; + void loadEffectConfig(String const& name, Json const& effectConfig, StringMap<String> const& shaders) override; + void setEffectParameter(String const& parameterName, RenderEffectParameter const& parameter) override; void setEffectTexture(String const& textureName, Image const& image) override; void setScissorRect(Maybe<RectI> const& scissorRect) override; + bool switchEffectConfig(String const& name) override; + TexturePtr createTexture(Image const& texture, TextureAddressing addressing, TextureFiltering filtering) override; void setSizeLimitEnabled(bool enabled) override; void setMultiTexturingEnabled(bool enabled) override; @@ -155,6 +158,13 @@ private: RefPtr<GlLoneTexture> textureValue; }; + struct Effect { + GLuint program; + Json config; + StringMap<EffectParameter> parameters; + StringMap<EffectTexture> textures; + }; + static void logGlErrorSummary(String prefix); static void uploadTextureImage(PixelFormat pixelFormat, Vec2U size, uint8_t const* data); @@ -166,6 +176,8 @@ private: void renderGlBuffer(GlRenderBuffer const& renderBuffer, Mat3F const& transformation); + void setupGlUniforms(GLuint program); + Vec2U m_screenSize; GLuint m_program = 0; @@ -181,10 +193,11 @@ private: GLint m_screenSizeUniform = -1; GLint m_vertexTransformUniform = -1; + StringMap<Effect> m_effects; + Effect* m_currentEffect; + RefPtr<GlTexture> m_whiteTexture; - StringMap<EffectParameter> m_effectParameters; - StringMap<EffectTexture> m_effectTextures; Maybe<RectI> m_scissorRect; bool m_limitTextureGroupSize; |