From 8c9aa31059f7ac47768029df8741236527d7f49a Mon Sep 17 00:00:00 2001 From: Razakhel Date: Sat, 2 Dec 2023 18:22:09 +0100 Subject: [PATCH] [Render/Renderer] Added setBlendFunction() - Initializing the RenderSystem enables the blending capability - No blend function is set, as transparency isn't properly used yet - The cubemap is displayed before all entities - Being supposed to be behind everything else, it makes more sense and allows for a proper transparency workflow - Setting a transparency map, either loaded from an OBJ or set as a default map, sets a nearest filter - As a transparency map is supposed to be binary, the texels shouldn't be interpolated --- include/RaZ/Render/Renderer.hpp | 25 +++++++++++++++++++++++++ src/RaZ/Data/ObjLoad.cpp | 13 +++++++------ src/RaZ/Render/Material.cpp | 7 +++++-- src/RaZ/Render/RenderGraph.cpp | 6 +++--- src/RaZ/Render/RenderSystem.cpp | 1 + src/RaZ/Render/Renderer.cpp | 8 ++++++++ src/RaZ/Render/SsrRenderProcess.cpp | 1 - 7 files changed, 49 insertions(+), 12 deletions(-) diff --git a/include/RaZ/Render/Renderer.hpp b/include/RaZ/Render/Renderer.hpp index ec02f55f..ea30da67 100644 --- a/include/RaZ/Render/Renderer.hpp +++ b/include/RaZ/Render/Renderer.hpp @@ -151,6 +151,30 @@ enum class FaceOrientation : unsigned int { FRONT_BACK = 1032 /* GL_FRONT_AND_BACK */ ///< }; +enum class BlendFactor : unsigned int { + ZERO = 0 /* GL_ZERO */, ///< + ONE = 1 /* GL_ONE */, ///< + SRC_COLOR = 768 /* GL_SRC_COLOR */, ///< + ONE_MINUS_SRC_COLOR = 769 /* GL_ONE_MINUS_SRC_COLOR */, ///< + SRC_ALPHA = 770 /* GL_SRC_ALPHA */, ///< + ONE_MINUS_SRC_ALPHA = 771 /* GL_ONE_MINUS_SRC_ALPHA */, ///< + DST_ALPHA = 772 /* GL_DST_ALPHA */, ///< + ONE_MINUS_DST_ALPHA = 773 /* GL_ONE_MINUS_DST_ALPHA */, ///< + DST_COLOR = 774 /* GL_DST_COLOR */, ///< + ONE_MINUS_DST_COLOR = 775 /* GL_ONE_MINUS_DST_COLOR */, ///< + SRC_ALPHA_SATURATE = 776 /* GL_SRC_ALPHA_SATURATE */, ///< + CONSTANT_COLOR = 32769 /* GL_CONSTANT_COLOR */, ///< + ONE_MINUS_CONSTANT_COLOR = 32770 /* GL_ONE_MINUS_CONSTANT_COLOR */, ///< + CONSTANT_ALPHA = 32771 /* GL_CONSTANT_ALPHA */, ///< + ONE_MINUS_CONSTANT_ALPHA = 32772 /* GL_ONE_MINUS_CONSTANT_ALPHA */, ///< +#if !defined(USE_OPENGL_ES) + SRC1_COLOR = 35065 /* GL_SRC1_COLOR */, ///< + ONE_MINUS_SRC1_COLOR = 35066 /* GL_ONE_MINUS_SRC1_COLOR */, ///< + SRC1_ALPHA = 34185 /* GL_SRC1_ALPHA */, ///< + ONE_MINUS_SRC1_ALPHA = 35067 /* GL_ONE_MINUS_SRC1_ALPHA */ ///< +#endif +}; + enum class PolygonMode : unsigned int { POINT = 6912 /* GL_POINT */, ///< LINE = 6913 /* GL_LINE */, ///< @@ -909,6 +933,7 @@ class Renderer { /// \param mask Bitmask defining which stencil bits can be written. /// \param orientation Face orientation for which to set the mask. static void setStencilMask(unsigned int mask, FaceOrientation orientation = FaceOrientation::FRONT_BACK); + static void setBlendFunction(BlendFactor source, BlendFactor destination); static void setFaceCulling(FaceOrientation orientation); #if !defined(USE_OPENGL_ES) static void setPolygonMode(FaceOrientation orientation, PolygonMode mode); diff --git a/src/RaZ/Data/ObjLoad.cpp b/src/RaZ/Data/ObjLoad.cpp index 4787933c..545f21ca 100644 --- a/src/RaZ/Data/ObjLoad.cpp +++ b/src/RaZ/Data/ObjLoad.cpp @@ -49,7 +49,7 @@ inline void loadMtl(const FilePath& mtlFilePath, std::string nextValue; file >> tag >> nextValue; - if (tag[0] == 'K') { // Standard properties + if (tag[0] == 'K') { // Standard properties [K*] std::string secondValue; std::string thirdValue; file >> secondValue >> thirdValue; @@ -64,7 +64,7 @@ inline void loadMtl(const FilePath& mtlFilePath, material.getProgram().setAttribute(values, MaterialAttribute::Ambient); else if (tag[1] == 's') // Specular factor [Ks] material.getProgram().setAttribute(values, MaterialAttribute::Specular); - } else if (tag[0] == 'P') { // PBR properties + } else if (tag[0] == 'P') { // PBR properties [P*] const float factor = std::stof(nextValue); if (tag[1] == 'm') // Metallic factor [Pm] @@ -73,13 +73,13 @@ inline void loadMtl(const FilePath& mtlFilePath, material.getProgram().setAttribute(factor, MaterialAttribute::Roughness); materialType = MaterialType::COOK_TORRANCE; - } else if (tag[0] == 'm') { // Import texture + } else if (tag[0] == 'm') { // Import texture [map_*] const Texture2DPtr map = loadTexture(mtlFilePath, nextValue); if (map == nullptr) continue; - if (tag[4] == 'K') { // Standard maps + if (tag[4] == 'K') { // Standard maps [map_K*] if (tag[5] == 'd') // Diffuse/albedo map [map_Kd] material.getProgram().setTexture(map, MaterialTexture::BaseColor); else if (tag[5] == 'e') // Emissive map [map_Ke] @@ -88,7 +88,7 @@ inline void loadMtl(const FilePath& mtlFilePath, material.getProgram().setTexture(map, MaterialTexture::Ambient); else if (tag[5] == 's') // Specular map [map_Ks] material.getProgram().setTexture(map, MaterialTexture::Specular); - } else if (tag[4] == 'P') { // PBR maps + } else if (tag[4] == 'P') { // PBR maps [map_P*] if (tag[5] == 'm') // Metallic map [map_Pm] material.getProgram().setTexture(map, MaterialTexture::Metallic); else if (tag[5] == 'r') // Roughness map [map_Pr] @@ -96,11 +96,12 @@ inline void loadMtl(const FilePath& mtlFilePath, materialType = MaterialType::COOK_TORRANCE; } else if (tag[4] == 'd') { // Transparency map [map_d] + map->setFilter(TextureFilter::NEAREST, TextureFilter::NEAREST, TextureFilter::NEAREST); material.getProgram().setTexture(map, MaterialTexture::Transparency); } else if (tag[4] == 'b') { // Bump map [map_bump] material.getProgram().setTexture(map, MaterialTexture::Bump); } - } else if (tag[0] == 'd') { // Transparency factor + } else if (tag[0] == 'd') { // Transparency factor [d] material.getProgram().setAttribute(std::stof(nextValue), MaterialAttribute::Transparency); } else if (tag[0] == 'T') { if (tag[1] == 'r') // Transparency factor (alias, 1 - d) [Tr] diff --git a/src/RaZ/Render/Material.cpp b/src/RaZ/Render/Material.cpp index 187a055c..90fb7864 100644 --- a/src/RaZ/Render/Material.cpp +++ b/src/RaZ/Render/Material.cpp @@ -79,8 +79,11 @@ void Material::loadType(MaterialType type) { m_program.setTexture(Texture2D::create(ColorPreset::White), MaterialTexture::Ambient); if (!m_program.hasTexture(MaterialTexture::Specular)) m_program.setTexture(Texture2D::create(ColorPreset::White), MaterialTexture::Specular); - if (!m_program.hasTexture(MaterialTexture::Transparency)) - m_program.setTexture(Texture2D::create(ColorPreset::White), MaterialTexture::Transparency); + if (!m_program.hasTexture(MaterialTexture::Transparency)) { + auto transparencyMap = Texture2D::create(ColorPreset::White); + transparencyMap->setFilter(TextureFilter::NEAREST, TextureFilter::NEAREST, TextureFilter::NEAREST); + m_program.setTexture(std::move(transparencyMap), MaterialTexture::Transparency); + } if (!m_program.hasTexture(MaterialTexture::Bump)) m_program.setTexture(Texture2D::create(ColorPreset::White), MaterialTexture::Bump); diff --git a/src/RaZ/Render/RenderGraph.cpp b/src/RaZ/Render/RenderGraph.cpp index d8725e2c..3a7b4790 100644 --- a/src/RaZ/Render/RenderGraph.cpp +++ b/src/RaZ/Render/RenderGraph.cpp @@ -74,6 +74,9 @@ void RenderGraph::execute(RenderSystem& renderSystem) { renderSystem.sendInverseProjectionMatrix(camera.getInverseProjectionMatrix()); renderSystem.sendViewProjectionMatrix(camera.getProjectionMatrix() * camera.getViewMatrix()); + if (renderSystem.hasCubemap()) + renderSystem.getCubemap().draw(); + renderSystem.m_modelUbo.bind(); for (const Entity* entity : renderSystem.m_entities) { @@ -89,9 +92,6 @@ void RenderGraph::execute(RenderSystem& renderSystem) { meshRenderer.draw(); } - if (renderSystem.hasCubemap()) - renderSystem.getCubemap().draw(); - geometryFramebuffer.unbind(); #if !defined(USE_OPENGL_ES) diff --git a/src/RaZ/Render/RenderSystem.cpp b/src/RaZ/Render/RenderSystem.cpp index c52844e2..b2472efe 100644 --- a/src/RaZ/Render/RenderSystem.cpp +++ b/src/RaZ/Render/RenderSystem.cpp @@ -189,6 +189,7 @@ void RenderSystem::initialize() { // As such, if reaching here, the Renderer is necessarily already functional. Ideally, this call below should be the only one in the whole program Renderer::initialize(); Renderer::enable(Capability::CULL); + Renderer::enable(Capability::BLEND); Renderer::enable(Capability::DEPTH_TEST); Renderer::enable(Capability::STENCIL_TEST); #if !defined(USE_OPENGL_ES) diff --git a/src/RaZ/Render/Renderer.cpp b/src/RaZ/Render/Renderer.cpp index 6478c944..e6cc0a4d 100644 --- a/src/RaZ/Render/Renderer.cpp +++ b/src/RaZ/Render/Renderer.cpp @@ -304,6 +304,14 @@ void Renderer::setStencilMask(unsigned int mask, FaceOrientation orientation) { printConditionalErrors(); } +void Renderer::setBlendFunction(BlendFactor source, BlendFactor destination) { + assert("Error: The Renderer must be initialized before calling its functions." && isInitialized()); + + glBlendFunc(static_cast(source), static_cast(destination)); + + printConditionalErrors(); +} + void Renderer::setFaceCulling(FaceOrientation orientation) { assert("Error: The Renderer must be initialized before calling its functions." && isInitialized()); diff --git a/src/RaZ/Render/SsrRenderProcess.cpp b/src/RaZ/Render/SsrRenderProcess.cpp index b0625834..12143afe 100644 --- a/src/RaZ/Render/SsrRenderProcess.cpp +++ b/src/RaZ/Render/SsrRenderProcess.cpp @@ -1,5 +1,4 @@ #include "RaZ/Render/SsrRenderProcess.hpp" -#include "RaZ/Render/Renderer.hpp" #include "RaZ/Render/RenderGraph.hpp" #include "RaZ/Render/Texture.hpp"