diff options
author | Daria Volvenkova <d.volvenkova@corp.mail.ru> | 2018-08-15 15:53:42 +0300 |
---|---|---|
committer | Roman Kuznetsov <r.kuznetsow@gmail.com> | 2018-08-17 13:11:53 +0300 |
commit | 5ab189afac15e9e97aef702e69e0d883bc8532b9 (patch) | |
tree | a6f705150dff1cfa2e63616c8a77f03bafe69ce6 /drape | |
parent | d4673530fedab33c81e0a5453c43001a2b4ac983 (diff) |
Framebuffer and render state refactoring.
Diffstat (limited to 'drape')
-rw-r--r-- | drape/CMakeLists.txt | 3 | ||||
-rw-r--r-- | drape/binding_info.hpp | 3 | ||||
-rw-r--r-- | drape/debug_rect_renderer.cpp | 122 | ||||
-rw-r--r-- | drape/debug_rect_renderer.hpp | 48 | ||||
-rw-r--r-- | drape/debug_renderer.hpp | 19 | ||||
-rw-r--r-- | drape/framebuffer.cpp | 70 | ||||
-rw-r--r-- | drape/framebuffer.hpp | 19 | ||||
-rw-r--r-- | drape/graphics_context.hpp | 39 | ||||
-rw-r--r-- | drape/hw_texture.cpp | 29 | ||||
-rw-r--r-- | drape/mesh_object.cpp | 113 | ||||
-rw-r--r-- | drape/mesh_object.hpp | 35 | ||||
-rw-r--r-- | drape/oglcontext.cpp | 81 | ||||
-rw-r--r-- | drape/oglcontext.hpp | 6 | ||||
-rw-r--r-- | drape/overlay_tree.cpp | 9 | ||||
-rw-r--r-- | drape/overlay_tree.hpp | 5 | ||||
-rw-r--r-- | drape/render_bucket.cpp | 16 | ||||
-rw-r--r-- | drape/render_bucket.hpp | 5 | ||||
-rw-r--r-- | drape/render_state.cpp | 121 | ||||
-rw-r--r-- | drape/render_state.hpp | 37 | ||||
-rw-r--r-- | drape/texture_types.hpp | 4 |
20 files changed, 447 insertions, 337 deletions
diff --git a/drape/CMakeLists.txt b/drape/CMakeLists.txt index cc0acb13d9..4ecf970658 100644 --- a/drape/CMakeLists.txt +++ b/drape/CMakeLists.txt @@ -35,8 +35,7 @@ set( ${DRAPE_ROOT}/data_buffer.cpp ${DRAPE_ROOT}/data_buffer.hpp ${DRAPE_ROOT}/data_buffer_impl.hpp - ${DRAPE_ROOT}/debug_rect_renderer.cpp - ${DRAPE_ROOT}/debug_rect_renderer.hpp + ${DRAPE_ROOT}/debug_renderer.hpp ${DRAPE_ROOT}/drape_diagnostics.hpp ${DRAPE_ROOT}/drape_global.hpp ${DRAPE_ROOT}/drape_routine.hpp diff --git a/drape/binding_info.hpp b/drape/binding_info.hpp index eee6513df2..5b9bbe49ee 100644 --- a/drape/binding_info.hpp +++ b/drape/binding_info.hpp @@ -1,6 +1,7 @@ #pragma once -#include "drape/glfunctions.hpp" +#include "drape/glconstants.hpp" +#include "drape/glsl_func.hpp" #include "drape/glsl_types.hpp" #include "std/string.hpp" diff --git a/drape/debug_rect_renderer.cpp b/drape/debug_rect_renderer.cpp deleted file mode 100644 index e7b4179a05..0000000000 --- a/drape/debug_rect_renderer.cpp +++ /dev/null @@ -1,122 +0,0 @@ -#include "drape/debug_rect_renderer.hpp" - -#include "drape/glextensions_list.hpp" -#include "drape/glfunctions.hpp" - -#include <vector> - -namespace dp -{ -namespace -{ -void PixelPointToScreenSpace(ScreenBase const & screen, m2::PointF const & pt, std::vector<float> & buffer) -{ - auto const szX = static_cast<float>(screen.PixelRectIn3d().SizeX()); - auto const szY = static_cast<float>(screen.PixelRectIn3d().SizeY()); - - buffer.push_back(2.0f * (pt.x / szX - 0.5f)); - buffer.push_back(2.0f * (-pt.y / szY + 0.5f)); -} -} // namespace - -DebugRectRenderer & DebugRectRenderer::Instance() -{ - static DebugRectRenderer renderer; - return renderer; -} - -DebugRectRenderer::DebugRectRenderer() - : TBase(DrawPrimitive::LineStrip) -{ - SetBuffer(0 /*bufferInd*/, {} /* vertices */, static_cast<uint32_t>(sizeof(float) * 2)); - SetAttribute("a_position", 0 /* bufferInd*/, 0.0f /* offset */, 2 /* componentsCount */); -} - -DebugRectRenderer::~DebugRectRenderer() -{ - ASSERT(!IsInitialized(), ()); -} - -void DebugRectRenderer::Init(ref_ptr<dp::GpuProgram> program, ParamsSetter && paramsSetter) -{ - m_program = program; - m_paramsSetter = std::move(paramsSetter); -} - -void DebugRectRenderer::Destroy() -{ - Reset(); -} - -bool DebugRectRenderer::IsEnabled() const -{ - return m_isEnabled; -} - -void DebugRectRenderer::SetEnabled(bool enabled) -{ - m_isEnabled = enabled; -} - -void DebugRectRenderer::SetArrow(m2::PointF const & arrowStart, m2::PointF const & arrowEnd, - dp::Color const & arrowColor, ScreenBase const & screen) -{ - std::vector<float> vertices; - m2::PointF const dir = (arrowEnd - arrowStart).Normalize(); - m2::PointF const side = m2::PointF(-dir.y, dir.x); - PixelPointToScreenSpace(screen, arrowStart, vertices); - PixelPointToScreenSpace(screen, arrowEnd, vertices); - PixelPointToScreenSpace(screen, arrowEnd - dir * 20 + side * 10, vertices); - PixelPointToScreenSpace(screen, arrowEnd, vertices); - PixelPointToScreenSpace(screen, arrowEnd - dir * 20 - side * 10, vertices); - - UpdateBuffer(0 /* bufferInd */, std::move(vertices)); -} - -void DebugRectRenderer::SetRect(m2::RectF const & rect, ScreenBase const & screen) -{ - std::vector<float> vertices; - PixelPointToScreenSpace(screen, rect.LeftBottom(), vertices); - PixelPointToScreenSpace(screen, rect.LeftTop(), vertices); - PixelPointToScreenSpace(screen, rect.RightTop(), vertices); - PixelPointToScreenSpace(screen, rect.RightBottom(), vertices); - PixelPointToScreenSpace(screen, rect.LeftBottom(), vertices); - - UpdateBuffer(0 /* bufferInd */, std::move(vertices)); -} - -void DebugRectRenderer::DrawRect(ScreenBase const & screen, m2::RectF const & rect, - dp::Color const & color) -{ - if (!m_isEnabled) - return; - - SetRect(rect, screen); - - auto const preRenderFn = [this, color]() - { - if (m_paramsSetter) - m_paramsSetter(m_program, color); - }; - Render(m_program, preRenderFn, nullptr); -} - -void DebugRectRenderer::DrawArrow(ScreenBase const & screen, - OverlayTree::DisplacementData const & data) -{ - if (!m_isEnabled) - return; - - if (data.m_arrowStart.EqualDxDy(data.m_arrowEnd, 1e-5)) - return; - - SetArrow(data.m_arrowStart, data.m_arrowEnd, data.m_arrowColor, screen); - - auto const preRenderFn = [this, data]() - { - if (m_paramsSetter) - m_paramsSetter(m_program, data.m_arrowColor); - }; - Render(m_program, preRenderFn, nullptr); -} -} // namespace dp diff --git a/drape/debug_rect_renderer.hpp b/drape/debug_rect_renderer.hpp deleted file mode 100644 index 63a02b08ec..0000000000 --- a/drape/debug_rect_renderer.hpp +++ /dev/null @@ -1,48 +0,0 @@ -#pragma once - -#include "drape/gpu_program.hpp" -#include "drape/mesh_object.hpp" -#include "drape/overlay_tree.hpp" - -#include "geometry/rect2d.hpp" -#include "geometry/screenbase.hpp" - -#include <functional> - -#ifdef BUILD_DESIGNER -#define RENDER_DEBUG_RECTS -#endif // BUILD_DESIGNER - -namespace dp -{ -class DebugRectRenderer: public dp::MeshObject -{ - using TBase = dp::MeshObject; -public: - static DebugRectRenderer & Instance(); - - using ParamsSetter = std::function<void(ref_ptr<dp::GpuProgram> program, dp::Color const & color)>; - - void Init(ref_ptr<dp::GpuProgram> program, ParamsSetter && paramsSetter); - void Destroy(); - - bool IsEnabled() const; - void SetEnabled(bool enabled); - - void DrawRect(ScreenBase const & screen, m2::RectF const & rect, dp::Color const & color); - void DrawArrow(ScreenBase const & screen, OverlayTree::DisplacementData const & data); - -private: - DebugRectRenderer(); - ~DebugRectRenderer() override; - - void SetArrow(m2::PointF const & arrowStart, m2::PointF const & arrowEnd, dp::Color const & arrowColor, - ScreenBase const & screen); - void SetRect(m2::RectF const & rect, ScreenBase const & screen); - - ParamsSetter m_paramsSetter; - ref_ptr<dp::GpuProgram> m_program; - bool m_isEnabled = false; -}; -} // namespace dp - diff --git a/drape/debug_renderer.hpp b/drape/debug_renderer.hpp new file mode 100644 index 0000000000..39e82d3317 --- /dev/null +++ b/drape/debug_renderer.hpp @@ -0,0 +1,19 @@ +#pragma once + +#include "drape/color.hpp" +#include "drape/overlay_tree.hpp" + +namespace dp +{ +class GraphicsContext; + +class IDebugRenderer +{ +public: + virtual bool IsEnabled() const = 0; + virtual void DrawRect(ref_ptr<GraphicsContext> context, ScreenBase const & screen, + m2::RectF const & rect, Color const & color) = 0; + virtual void DrawArrow(ref_ptr<GraphicsContext> context, ScreenBase const & screen, + OverlayTree::DisplacementData const & data) = 0; +}; +} // namespace dp diff --git a/drape/framebuffer.cpp b/drape/framebuffer.cpp index 1b22c0fd34..72fed7f05d 100644 --- a/drape/framebuffer.cpp +++ b/drape/framebuffer.cpp @@ -1,5 +1,6 @@ #include "drape/framebuffer.hpp" #include "drape/glfunctions.hpp" +#include "drape/texture.hpp" #include "base/assert.hpp" #include "base/logging.hpp" @@ -39,50 +40,49 @@ void Framebuffer::DepthStencil::SetSize(uint32_t width, uint32_t height) { Destroy(); - m_textureId = GLFunctions::glGenTexture(); - GLFunctions::glBindTexture(m_textureId); - GLFunctions::glTexImage2D(width, height, m_layout, m_pixelType, nullptr); - if (GLFunctions::CurrentApiVersion == dp::ApiVersion::OpenGLES3) - { - GLFunctions::glTexParameter(gl_const::GLMagFilter, gl_const::GLNearest); - GLFunctions::glTexParameter(gl_const::GLMinFilter, gl_const::GLNearest); - GLFunctions::glTexParameter(gl_const::GLWrapT, gl_const::GLClampToEdge); - GLFunctions::glTexParameter(gl_const::GLWrapS, gl_const::GLClampToEdge); - } + Texture::Params params; + params.m_width = width; + params.m_height = height; + if (m_depthEnabled && m_stencilEnabled) + params.m_format = TextureFormat::DepthStencil; + else if (m_depthEnabled) + params.m_format = TextureFormat::Depth; + params.m_allocator = GetDefaultAllocator(); + + m_texture = make_unique_dp<FramebufferTexture>(); + m_texture->Create(params); } void Framebuffer::DepthStencil::Destroy() { - if (m_textureId != 0) - { - GLFunctions::glDeleteTexture(m_textureId); - m_textureId = 0; - } + m_texture.reset(); } uint32_t Framebuffer::DepthStencil::GetDepthAttachmentId() const { - return m_textureId; + ASSERT(m_texture != nullptr, ()); + return m_texture->GetID(); } uint32_t Framebuffer::DepthStencil::GetStencilAttachmentId() const { - return m_stencilEnabled ? m_textureId : 0; + ASSERT(m_stencilEnabled ? m_texture != nullptr : true, ()); + return m_stencilEnabled ? m_texture->GetID() : 0; } Framebuffer::Framebuffer() - : m_colorFormat(gl_const::GLRGBA) + : m_colorFormat(TextureFormat::RGBA8) { ApplyOwnDepthStencil(); } -Framebuffer::Framebuffer(uint32_t colorFormat) +Framebuffer::Framebuffer(TextureFormat colorFormat) : m_colorFormat(colorFormat) { ApplyOwnDepthStencil(); } -Framebuffer::Framebuffer(uint32_t colorFormat, bool depthEnabled, bool stencilEnabled) +Framebuffer::Framebuffer(TextureFormat colorFormat, bool depthEnabled, bool stencilEnabled) : m_depthStencil(make_unique_dp<dp::Framebuffer::DepthStencil>(depthEnabled, stencilEnabled)) , m_colorFormat(colorFormat) { @@ -96,11 +96,7 @@ Framebuffer::~Framebuffer() void Framebuffer::Destroy() { - if (m_colorTextureId != 0) - { - GLFunctions::glDeleteTexture(m_colorTextureId); - m_colorTextureId = 0; - } + m_colorTexture.reset(); if (m_depthStencil != nullptr) m_depthStencil->Destroy(); @@ -130,14 +126,14 @@ void Framebuffer::SetSize(uint32_t width, uint32_t height) Destroy(); - m_colorTextureId = GLFunctions::glGenTexture(); - GLFunctions::glBindTexture(m_colorTextureId); - GLFunctions::glTexImage2D(m_width, m_height, m_colorFormat, gl_const::GLUnsignedByteType, - nullptr); - GLFunctions::glTexParameter(gl_const::GLMagFilter, gl_const::GLLinear); - GLFunctions::glTexParameter(gl_const::GLMinFilter, gl_const::GLLinear); - GLFunctions::glTexParameter(gl_const::GLWrapT, gl_const::GLClampToEdge); - GLFunctions::glTexParameter(gl_const::GLWrapS, gl_const::GLClampToEdge); + Texture::Params params; + params.m_width = width; + params.m_height = height; + params.m_format = m_colorFormat; + params.m_allocator = GetDefaultAllocator(); + + m_colorTexture = make_unique_dp<FramebufferTexture>(); + m_colorTexture->Create(params); glConst depthAttachmentId = 0; glConst stencilAttachmentId = 0; @@ -149,12 +145,10 @@ void Framebuffer::SetSize(uint32_t width, uint32_t height) stencilAttachmentId = m_depthStencilRef->GetStencilAttachmentId(); } - GLFunctions::glBindTexture(0); - GLFunctions::glGenFramebuffer(&m_framebufferId); GLFunctions::glBindFramebuffer(m_framebufferId); - GLFunctions::glFramebufferTexture2D(gl_const::GLColorAttachment, m_colorTextureId); + GLFunctions::glFramebufferTexture2D(gl_const::GLColorAttachment, m_colorTexture->GetID()); if (depthAttachmentId != stencilAttachmentId) { GLFunctions::glFramebufferTexture2D(gl_const::GLDepthAttachment, depthAttachmentId); @@ -200,9 +194,9 @@ void Framebuffer::Disable() m_framebufferFallback(); } -uint32_t Framebuffer::GetTextureId() const +ref_ptr<Texture> Framebuffer::GetTexture() const { - return m_colorTextureId; + return make_ref(m_colorTexture); } ref_ptr<Framebuffer::DepthStencil> Framebuffer::GetDepthStencilRef() const diff --git a/drape/framebuffer.hpp b/drape/framebuffer.hpp index 60c98decc0..c2c15ff4a7 100644 --- a/drape/framebuffer.hpp +++ b/drape/framebuffer.hpp @@ -1,12 +1,19 @@ #pragma once #include "drape/pointers.hpp" +#include "drape/texture.hpp" #include <cstdint> #include <functional> namespace dp { +class FramebufferTexture: public Texture +{ +public: + ref_ptr<ResourceInfo> FindResource(Key const & key, bool & newResource) override { return nullptr; } +}; + using FramebufferFallback = std::function<bool()>; class Framebuffer @@ -26,12 +33,12 @@ public: bool const m_stencilEnabled = false; uint32_t m_layout = 0; uint32_t m_pixelType = 0; - uint32_t m_textureId = 0; + drape_ptr<FramebufferTexture> m_texture; }; Framebuffer(); - explicit Framebuffer(uint32_t colorFormat); - Framebuffer(uint32_t colorFormat, bool depthEnabled, bool stencilEnabled); + explicit Framebuffer(TextureFormat colorFormat); + Framebuffer(TextureFormat colorFormat, bool depthEnabled, bool stencilEnabled); ~Framebuffer(); void SetFramebufferFallback(FramebufferFallback && fallback); @@ -42,7 +49,7 @@ public: void Enable(); void Disable(); - uint32_t GetTextureId() const; + ref_ptr<Texture> GetTexture() const; ref_ptr<DepthStencil> GetDepthStencilRef() const; bool IsSupported() const { return m_isSupported; } @@ -51,11 +58,11 @@ private: drape_ptr<DepthStencil> m_depthStencil; ref_ptr<DepthStencil> m_depthStencilRef; + drape_ptr<FramebufferTexture> m_colorTexture; uint32_t m_width = 0; uint32_t m_height = 0; - uint32_t m_colorTextureId = 0; uint32_t m_framebufferId = 0; - uint32_t m_colorFormat; + TextureFormat m_colorFormat; FramebufferFallback m_framebufferFallback; bool m_isSupported = true; }; diff --git a/drape/graphics_context.hpp b/drape/graphics_context.hpp index 39026eea3b..c78184cd8a 100644 --- a/drape/graphics_context.hpp +++ b/drape/graphics_context.hpp @@ -11,6 +11,37 @@ enum ClearBits: uint32_t StencilBit = 1 << 2 }; +enum class TestFunction : uint8_t +{ + Never, + Less, + Equal, + LessOrEqual, + Greater, + NotEqual, + GreaterOrEqual, + Always +}; + +enum class StencilFace : uint8_t +{ + Front, + Back, + FrontAndBack +}; + +enum class StencilAction : uint8_t +{ + Keep, + Zero, + Replace, + Incr, + IncrWrap, + Decr, + DecrWrap, + Invert +}; + class GraphicsContext { public: @@ -29,5 +60,13 @@ public: virtual void SetClearColor(dp::Color const & color) = 0; virtual void Clear(uint32_t clearBits) = 0; virtual void Flush() = 0; + virtual void SetDepthTestEnabled(bool enabled) = 0; + virtual void SetDepthTestFunction(TestFunction depthFunction) = 0; + virtual void SetStencilTestEnabled(bool enabled) = 0; + virtual void SetStencilFunction(StencilFace face, TestFunction stencilFunction) = 0; + virtual void SetStencilActions(StencilFace face, StencilAction stencilFailAction, StencilAction depthFailAction, + StencilAction passAction) = 0; + + }; } // namespace dp diff --git a/drape/hw_texture.cpp b/drape/hw_texture.cpp index edd858eae8..2fa4e7bc99 100644 --- a/drape/hw_texture.cpp +++ b/drape/hw_texture.cpp @@ -23,22 +23,39 @@ namespace dp { void UnpackFormat(TextureFormat format, glConst & layout, glConst & pixelType) { - // Now we support only 1-byte-per-channel textures. - pixelType = gl_const::GL8BitOnChannel; - switch (format) { - case TextureFormat::RGBA8: layout = gl_const::GLRGBA; return; + case TextureFormat::RGBA8: + layout = gl_const::GLRGBA; + pixelType = gl_const::GL8BitOnChannel; + return; + case TextureFormat::Alpha: // On OpenGL ES3 GLAlpha is not supported, we use GLRed instead. layout = GLFunctions::CurrentApiVersion == dp::ApiVersion::OpenGLES2 ? gl_const::GLAlpha : gl_const::GLRed; + pixelType = gl_const::GL8BitOnChannel; return; + case TextureFormat::RedGreen: // On OpenGL ES2 2-channel textures are not supported. layout = GLFunctions::CurrentApiVersion == dp::ApiVersion::OpenGLES2 ? gl_const::GLRGBA : gl_const::GLRedGreen; + pixelType = gl_const::GL8BitOnChannel; return; + + case TextureFormat::DepthStencil: + // OpenGLES2 does not support texture-based depth-stencil. + CHECK(GLFunctions::CurrentApiVersion != dp::ApiVersion::OpenGLES2, ()); + layout = gl_const::GLDepthStencil; + pixelType = gl_const::GLUnsignedInt24_8Type; + return; + + case TextureFormat::Depth: + layout = gl_const::GLDepthComponent; + pixelType = gl_const::GLUnsignedIntType; + return; + case TextureFormat::Unspecified: CHECK(false, ()); return; @@ -163,8 +180,8 @@ void OpenGLHWTexture::Create(Params const & params, ref_ptr<void> data) { TBase::Create(params, data); - ASSERT(glm::isPowerOfTwo(static_cast<int>(m_width)), (m_width)); - ASSERT(glm::isPowerOfTwo(static_cast<int>(m_height)), (m_height)); + //ASSERT(glm::isPowerOfTwo(static_cast<int>(m_width)), (m_width)); + //ASSERT(glm::isPowerOfTwo(static_cast<int>(m_height)), (m_height)); m_textureID = GLFunctions::glGenTexture(); Bind(); diff --git a/drape/mesh_object.cpp b/drape/mesh_object.cpp index 2313a97bea..3013c0a26c 100644 --- a/drape/mesh_object.cpp +++ b/drape/mesh_object.cpp @@ -73,11 +73,10 @@ void MeshObject::Reset() void MeshObject::UpdateBuffer(uint32_t bufferInd, std::vector<float> && vertices) { - if (!m_initialized) - Build(); - + CHECK(m_initialized, ()); CHECK_LESS(bufferInd, static_cast<uint32_t>(m_buffers.size()), ()); CHECK(m_buffers[bufferInd].m_bufferId != 0, ()); + CHECK(!vertices.empty(), ()); auto & buffer = m_buffers[bufferInd]; buffer.m_data = std::move(vertices); @@ -88,11 +87,12 @@ void MeshObject::UpdateBuffer(uint32_t bufferInd, std::vector<float> && vertices GLFunctions::glBindBuffer(0, gl_const::GLArrayBuffer); } -void MeshObject::Build() +void MeshObject::Build(ref_ptr<dp::GpuProgram> program) { Reset(); - if (dp::GLExtensionsList::Instance().IsSupported(dp::GLExtensionsList::VertexArrayObject)) + bool const isVAOSupported = dp::GLExtensionsList::Instance().IsSupported(dp::GLExtensionsList::VertexArrayObject); + if (isVAOSupported) { m_VAO = GLFunctions::glGenVertexArray(); GLFunctions::glBindVertexArray(m_VAO); @@ -102,60 +102,111 @@ void MeshObject::Build() { buffer.m_bufferId = GLFunctions::glGenBuffer(); GLFunctions::glBindBuffer(buffer.m_bufferId, gl_const::GLArrayBuffer); - if (buffer.m_data.empty()) - continue; - GLFunctions::glBufferData(gl_const::GLArrayBuffer, - static_cast<uint32_t>(buffer.m_data.size()) * sizeof(buffer.m_data[0]), - buffer.m_data.data(), gl_const::GLStaticDraw); + + if (!buffer.m_data.empty()) + { + GLFunctions::glBufferData(gl_const::GLArrayBuffer, + static_cast<uint32_t>(buffer.m_data.size()) * sizeof(buffer.m_data[0]), + buffer.m_data.data(), gl_const::GLStaticDraw); + } + + if (isVAOSupported) + { + for (auto const & attribute : buffer.m_attributes) + { + int8_t const attributePosition = program->GetAttributeLocation(attribute.m_attributeName); + ASSERT_NOT_EQUAL(attributePosition, -1, ()); + GLFunctions::glEnableVertexAttribute(attributePosition); + GLFunctions::glVertexAttributePointer(attributePosition, attribute.m_componentsCount, + gl_const::GLFloatType, false, + buffer.m_stride, attribute.m_offset); + } + } } - if (dp::GLExtensionsList::Instance().IsSupported(dp::GLExtensionsList::VertexArrayObject)) + if (isVAOSupported) GLFunctions::glBindVertexArray(0); GLFunctions::glBindBuffer(0, gl_const::GLArrayBuffer); m_initialized = true; } -void MeshObject::Render(ref_ptr<dp::GpuProgram> program, PreRenderFn const & preRenderFn, - PostRenderFn const & postRenderFn) +void MeshObject::Bind(ref_ptr<dp::GpuProgram> program) { program->Bind(); if (!m_initialized) - Build(); + Build(program); if (dp::GLExtensionsList::Instance().IsSupported(dp::GLExtensionsList::VertexArrayObject)) + { GLFunctions::glBindVertexArray(m_VAO); - - uint32_t verticesCount = 0; - for (auto const & buffer : m_buffers) + } + else { - verticesCount = static_cast<uint32_t>(buffer.m_data.size() * sizeof(buffer.m_data[0]) / buffer.m_stride); - GLFunctions::glBindBuffer(buffer.m_bufferId, gl_const::GLArrayBuffer); - for (auto const & attribute : buffer.m_attributes) + for (auto const & buffer : m_buffers) { - int8_t const attributePosition = program->GetAttributeLocation(attribute.m_attributeName); - ASSERT_NOT_EQUAL(attributePosition, -1, ()); - GLFunctions::glEnableVertexAttribute(attributePosition); - GLFunctions::glVertexAttributePointer(attributePosition, attribute.m_componentsCount, - gl_const::GLFloatType, false, - buffer.m_stride, attribute.m_offset); + GLFunctions::glBindBuffer(buffer.m_bufferId, gl_const::GLArrayBuffer); + for (auto const & attribute : buffer.m_attributes) + { + int8_t const attributePosition = program->GetAttributeLocation(attribute.m_attributeName); + ASSERT_NOT_EQUAL(attributePosition, -1, ()); + GLFunctions::glEnableVertexAttribute(attributePosition); + GLFunctions::glVertexAttributePointer(attributePosition, attribute.m_componentsCount, + gl_const::GLFloatType, false, + buffer.m_stride, attribute.m_offset); + } } } +} - if (preRenderFn) - preRenderFn(); +void MeshObject::DrawPrimitives() +{ + if (m_buffers.empty()) + return; - GLFunctions::glDrawArrays(GetGLDrawPrimitive(m_drawPrimitive), 0, verticesCount); + auto const & buffer = m_buffers[0]; + auto const verticesCount = static_cast<uint32_t>(buffer.m_data.size() * sizeof(buffer.m_data[0]) / buffer.m_stride); - if (postRenderFn) - postRenderFn(); + GLFunctions::glDrawArrays(GetGLDrawPrimitive(m_drawPrimitive), 0, verticesCount); +} +void MeshObject::Unbind(ref_ptr<dp::GpuProgram> program) +{ program->Unbind(); if (dp::GLExtensionsList::Instance().IsSupported(dp::GLExtensionsList::VertexArrayObject)) GLFunctions::glBindVertexArray(0); GLFunctions::glBindBuffer(0, gl_const::GLArrayBuffer); } + +// static +void MeshObject::GenerateNormalsForTriangles(std::vector<float> const & vertices, size_t componentsCount, + std::vector<float> & normals) +{ + auto const trianglesCount = vertices.size() / (3 * componentsCount); + normals.clear(); + normals.reserve(trianglesCount * 9); + for (size_t triangle = 0; triangle < trianglesCount; ++triangle) + { + glsl::vec3 v[3]; + for (size_t vertex = 0; vertex < 3; ++vertex) + { + size_t const offset = triangle * componentsCount * 3 + vertex * componentsCount; + v[vertex] = glsl::vec3(vertices[offset], vertices[offset + 1], vertices[offset + 2]); + } + + glsl::vec3 normal = glsl::cross(glsl::vec3(v[1].x - v[0].x, v[1].y - v[0].y, v[1].z - v[0].z), + glsl::vec3(v[2].x - v[0].x, v[2].y - v[0].y, v[2].z - v[0].z)); + normal = glsl::normalize(normal); + + for (size_t vertex = 0; vertex < 3; ++vertex) + { + normals.push_back(normal.x); + normals.push_back(normal.y); + normals.push_back(normal.z); + } + } +} } // namespace dp diff --git a/drape/mesh_object.hpp b/drape/mesh_object.hpp index fa5c56a7f3..211dbfe6a3 100644 --- a/drape/mesh_object.hpp +++ b/drape/mesh_object.hpp @@ -1,14 +1,22 @@ #pragma once +#include "drape/graphics_context.hpp" #include "drape/render_state.hpp" #include "drape/pointers.hpp" #include <functional> +#include <vector> namespace dp { class GpuProgram; +class RenderParamsHolder +{ +public: + virtual void ApplyProgramParams() = 0; +}; + class MeshObject { public: @@ -19,9 +27,6 @@ public: LineStrip }; - using PreRenderFn = std::function<void()>; - using PostRenderFn = std::function<void()>; - MeshObject(DrawPrimitive drawPrimitive); virtual ~MeshObject(); @@ -30,15 +35,29 @@ public: void UpdateBuffer(uint32_t bufferInd, std::vector<float> && vertices); - void Render(ref_ptr<dp::GpuProgram> program, - PreRenderFn const & preRenderFn, PostRenderFn const & postRenderFn); + template<typename TParamsSetter, typename TParams> + void Render(ref_ptr<dp::GraphicsContext> context, ref_ptr<dp::GpuProgram> program, dp::RenderState const & state, + ref_ptr<TParamsSetter> paramsSetter, TParams const & params) + { + Bind(program); + + ApplyState(state, context, program); + paramsSetter->Apply(program, params); + + DrawPrimitives(); + + Unbind(program); + }; uint32_t GetNextBufferIndex() const { return static_cast<uint32_t>(m_buffers.size()); } bool IsInitialized() const { return m_initialized; } - void Build(); + void Build(ref_ptr<dp::GpuProgram> program); void Reset(); + static void GenerateNormalsForTriangles(std::vector<float> const & vertices, size_t componentsCount, + std::vector<float> & normals); + private: struct AttributeMapping { @@ -71,6 +90,10 @@ private: std::vector<AttributeMapping> m_attributes; }; + void Bind(ref_ptr<dp::GpuProgram> program); + void Unbind(ref_ptr<dp::GpuProgram> program); + void DrawPrimitives(); + std::vector<VertexBuffer> m_buffers; DrawPrimitive m_drawPrimitive = DrawPrimitive::Triangles; diff --git a/drape/oglcontext.cpp b/drape/oglcontext.cpp index d8ac0a62b5..7543b0fbeb 100644 --- a/drape/oglcontext.cpp +++ b/drape/oglcontext.cpp @@ -3,6 +3,52 @@ namespace dp { +namespace +{ +glConst DecodeTestFunction(TestFunction depthFunction) +{ + switch (depthFunction) + { + case TestFunction::Never: return gl_const::GLNever; + case TestFunction::Less: return gl_const::GLLess; + case TestFunction::Equal: return gl_const::GLEqual; + case TestFunction::LessOrEqual: return gl_const::GLLessOrEqual; + case TestFunction::Greater: return gl_const::GLGreat; + case TestFunction::NotEqual: return gl_const::GLNotEqual; + case TestFunction::GreaterOrEqual: return gl_const::GLGreatOrEqual; + case TestFunction::Always: return gl_const::GLAlways; + } + ASSERT(false, ()); +} + +glConst DecodeStencilFace(StencilFace stencilFace) +{ + switch (stencilFace) + { + case StencilFace::Front: return gl_const::GLFront; + case StencilFace::Back: return gl_const::GLBack; + case StencilFace::FrontAndBack: return gl_const::GLFrontAndBack; + } + ASSERT(false, ()); +} + +glConst DecodeStencilAction(StencilAction stencilAction) +{ + switch (stencilAction) + { + case StencilAction::Keep: return gl_const::GLKeep; + case StencilAction::Zero: return gl_const::GLZero; + case StencilAction::Replace: return gl_const::GLReplace; + case StencilAction::Incr: return gl_const::GLIncr; + case StencilAction::IncrWrap: return gl_const::GLIncrWrap; + case StencilAction::Decr: return gl_const::GLDecr; + case StencilAction::DecrWrap: return gl_const::GLDecrWrap; + case StencilAction::Invert: return gl_const::GLInvert; + } + ASSERT(false, ()); +} +} // namespace + void OGLContext::Init(ApiVersion apiVersion) { GLFunctions::Init(apiVersion); @@ -41,4 +87,39 @@ void OGLContext::Flush() { GLFunctions::glFlush(); } + +void OGLContext::SetDepthTestEnabled(bool enabled) +{ + if (enabled) + GLFunctions::glEnable(gl_const::GLDepthTest); + else + GLFunctions::glDisable(gl_const::GLDepthTest); +} + +void OGLContext::SetDepthTestFunction(TestFunction depthFunction) +{ + GLFunctions::glDepthFunc(DecodeTestFunction(depthFunction)); +}; + +void OGLContext::SetStencilTestEnabled(bool enabled) +{ + if (enabled) + GLFunctions::glEnable(gl_const::GLStencilTest); + else + GLFunctions::glDisable(gl_const::GLStencilTest); +} + +void OGLContext::SetStencilFunction(StencilFace face, TestFunction stencilFunction) +{ + GLFunctions::glStencilFuncSeparate(DecodeStencilFace(face), DecodeTestFunction(stencilFunction), 1, 1); +} + +void OGLContext::SetStencilActions(StencilFace face, StencilAction stencilFailAction, StencilAction depthFailAction, + StencilAction passAction) +{ + GLFunctions::glStencilOpSeparate(DecodeStencilFace(face), + DecodeStencilAction(stencilFailAction), + DecodeStencilAction(depthFailAction), + DecodeStencilAction(passAction)); +} } // namespace dp diff --git a/drape/oglcontext.hpp b/drape/oglcontext.hpp index 4d6aa91fda..129e76c09b 100644 --- a/drape/oglcontext.hpp +++ b/drape/oglcontext.hpp @@ -11,5 +11,11 @@ public: void SetClearColor(dp::Color const & color) override; void Clear(uint32_t clearBits) override; void Flush() override; + void SetDepthTestEnabled(bool enabled) override; + void SetDepthTestFunction(TestFunction depthFunction) override; + void SetStencilTestEnabled(bool enabled) override; + void SetStencilFunction(StencilFace face, TestFunction stencilFunction) override; + void SetStencilActions(StencilFace face, StencilAction stencilFailAction, StencilAction depthFailAction, + StencilAction passAction) override; }; } // namespace dp diff --git a/drape/overlay_tree.cpp b/drape/overlay_tree.cpp index 9530534d65..7f44e37223 100644 --- a/drape/overlay_tree.cpp +++ b/drape/overlay_tree.cpp @@ -1,7 +1,7 @@ #include "drape/overlay_tree.hpp" #include "drape/constants.hpp" -#include "drape/debug_rect_renderer.hpp" +#include "drape/debug_renderer.hpp" #include <algorithm> @@ -453,6 +453,11 @@ OverlayTree::TDisplacementInfo const & OverlayTree::GetDisplacementInfo() const return m_displacementInfo; } +void OverlayTree::SetDebugRectRenderer(ref_ptr<IDebugRenderer> debugRectRenderer) +{ + m_debugRectRenderer = debugRectRenderer; +} + void OverlayTree::StoreDisplacementInfo(int caseIndex, ref_ptr<OverlayHandle> displacerHandle, ref_ptr<OverlayHandle> displacedHandle) { @@ -468,7 +473,7 @@ void OverlayTree::StoreDisplacementInfo(int caseIndex, ref_ptr<OverlayHandle> di UNUSED_VALUE(caseIndex); #endif - if (!dp::DebugRectRenderer::Instance().IsEnabled()) + if (!m_debugRectRenderer || !m_debugRectRenderer->IsEnabled()) return; m_displacementInfo.emplace_back(m2::PointF(displacerHandle->GetExtendedPixelRect(modelView).Center()), m2::PointF(displacedHandle->GetExtendedPixelRect(modelView).Center()), diff --git a/drape/overlay_tree.hpp b/drape/overlay_tree.hpp index c5c71b45c8..d52b48a2d0 100644 --- a/drape/overlay_tree.hpp +++ b/drape/overlay_tree.hpp @@ -49,6 +49,8 @@ struct OverlayHasher }; } // namespace detail +class IDebugRenderer; + using TOverlayContainer = buffer_vector<ref_ptr<OverlayHandle>, 8>; class OverlayTree : public m4::Tree<ref_ptr<OverlayHandle>, detail::OverlayTraits> @@ -93,6 +95,8 @@ public: using TDisplacementInfo = std::vector<DisplacementData>; TDisplacementInfo const & GetDisplacementInfo() const; + void SetDebugRectRenderer(ref_ptr<IDebugRenderer> debugRectRenderer); + private: ScreenBase const & GetModelView() const { return m_traits.GetModelView(); } void InsertHandle(ref_ptr<OverlayHandle> handle, int currentRank, @@ -115,6 +119,7 @@ private: FeatureID m_selectedFeatureID; TDisplacementInfo m_displacementInfo; + ref_ptr<IDebugRenderer> m_debugRectRenderer; HandlesCache m_displacers; uint32_t m_frameUpdatePeriod; diff --git a/drape/render_bucket.cpp b/drape/render_bucket.cpp index b36243d912..8682278b48 100644 --- a/drape/render_bucket.cpp +++ b/drape/render_bucket.cpp @@ -1,7 +1,7 @@ #include "drape/render_bucket.hpp" #include "drape/attribute_buffer_mutator.hpp" -#include "drape/debug_rect_renderer.hpp" +#include "drape/debug_renderer.hpp" #include "drape/overlay_handle.hpp" #include "drape/overlay_tree.hpp" #include "drape/vertex_array_buffer.hpp" @@ -133,9 +133,10 @@ void RenderBucket::SetFeatureMinZoom(int minZoom) m_featuresMinZoom = minZoom; } -void RenderBucket::RenderDebug(ScreenBase const & screen) const +void RenderBucket::RenderDebug(ScreenBase const & screen, ref_ptr<GraphicsContext> context, + ref_ptr<IDebugRenderer> debugRectRenderer) const { - if (!DebugRectRenderer::Instance().IsEnabled() || m_overlay.empty()) + if (!debugRectRenderer || !debugRectRenderer->IsEnabled() || m_overlay.empty()) return; for (auto const & handle : m_overlay) @@ -149,10 +150,11 @@ void RenderBucket::RenderDebug(ScreenBase const & screen) const if (screen.isPerspective() && !screen.PixelRectIn3d().IsIntersect(m2::RectD(rect))) continue; - DebugRectRenderer::Instance().DrawRect(screen, rect, handle->IsVisible() ? - dp::Color::Green() : - (handle->IsReady() ? dp::Color::Red() : - dp::Color::Yellow())); + auto color = dp::Color::Green(); + if (!handle->IsVisible()) + color = handle->IsReady() ? dp::Color::Red() : dp::Color::Yellow(); + + debugRectRenderer->DrawRect(context, screen, rect, color); } } } diff --git a/drape/render_bucket.hpp b/drape/render_bucket.hpp index a5ff46e373..faab8425e3 100644 --- a/drape/render_bucket.hpp +++ b/drape/render_bucket.hpp @@ -16,6 +16,8 @@ class BatchMergeHelper; namespace dp { +class GraphicsContext; +class IDebugRenderer; class OverlayHandle; class OverlayTree; class VertexArrayBuffer; @@ -43,7 +45,8 @@ public: void Render(bool drawAsLine); // Only for testing! Don't use this function in production code! - void RenderDebug(ScreenBase const & screen) const; + void RenderDebug(ScreenBase const & screen, ref_ptr<GraphicsContext> context, + ref_ptr<IDebugRenderer> debugRectRenderer) const; // Only for testing! Don't use this function in production code! template <typename ToDo> diff --git a/drape/render_state.cpp b/drape/render_state.cpp index ca55f3a95f..93ea2a52f1 100644 --- a/drape/render_state.cpp +++ b/drape/render_state.cpp @@ -7,18 +7,21 @@ namespace dp { namespace { -glConst DecodeDepthFunction(DepthFunction depthFunction) +std::string const kColorTextureName = "u_colorTex"; +std::string const kMaskTextureName = "u_maskTex"; + +glConst DecodeTestFunction(TestFunction depthFunction) { switch (depthFunction) { - case DepthFunction::Never: return gl_const::GLNever; - case DepthFunction::Less: return gl_const::GLLess; - case DepthFunction::Equal: return gl_const::GLEqual; - case DepthFunction::LessOrEqual: return gl_const::GLLessOrEqual; - case DepthFunction::Great: return gl_const::GLGreat; - case DepthFunction::NotEqual: return gl_const::GLNotEqual; - case DepthFunction::GreatOrEqual: return gl_const::GLGreatOrEqual; - case DepthFunction::Always: return gl_const::GLAlways; + case TestFunction::Never: return gl_const::GLNever; + case TestFunction::Less: return gl_const::GLLess; + case TestFunction::Equal: return gl_const::GLEqual; + case TestFunction::LessOrEqual: return gl_const::GLLessOrEqual; + case TestFunction::Greater: return gl_const::GLGreat; + case TestFunction::NotEqual: return gl_const::GLNotEqual; + case TestFunction::GreaterOrEqual: return gl_const::GLGreatOrEqual; + case TestFunction::Always: return gl_const::GLAlways; } CHECK_SWITCH(); } @@ -47,12 +50,56 @@ bool Blending::operator<(Blending const & other) const { return m_isEnabled < ot bool Blending::operator==(Blending const & other) const { return m_isEnabled == other.m_isEnabled; } -DepthFunction RenderState::GetDepthFunction() const +void RenderState::SetColorTexture(ref_ptr<Texture> tex) +{ + m_textures[kColorTextureName] = tex; +} + +ref_ptr<Texture> RenderState::GetColorTexture() const +{ + auto const it = m_textures.find(kColorTextureName); + if (it != m_textures.end()) + return it->second; + return nullptr; +} + +void RenderState::SetMaskTexture(ref_ptr<Texture> tex) +{ + m_textures[kMaskTextureName] = tex; +} + +ref_ptr<Texture> RenderState::GetMaskTexture() const +{ + auto const it = m_textures.find(kMaskTextureName); + if (it != m_textures.end()) + return it->second; + return nullptr; +} + +void RenderState::SetTexture(std::string const & name, ref_ptr<Texture> tex) +{ + m_textures[name] = tex; +} + +ref_ptr<Texture> RenderState::GetTexture(std::string const & name) const +{ + auto const it = m_textures.find(name); + if (it != m_textures.end()) + return it->second; + return nullptr; +} + +std::map<std::string, ref_ptr<Texture>> const & RenderState::GetTextures() const +{ + return m_textures; +} + +TestFunction RenderState::GetDepthFunction() const { return m_depthFunction; } -void RenderState::SetDepthFunction(DepthFunction depthFunction) +void RenderState::SetDepthFunction(TestFunction depthFunction) { m_depthFunction = depthFunction; } @@ -109,10 +156,8 @@ bool RenderState::operator<(RenderState const & other) const return m_gpuProgram3d < other.m_gpuProgram3d; if (m_depthFunction != other.m_depthFunction) return m_depthFunction < other.m_depthFunction; - if (m_colorTexture != other.m_colorTexture) - return m_colorTexture < other.m_colorTexture; - if (m_maskTexture != other.m_maskTexture) - return m_maskTexture < other.m_maskTexture; + if (m_textures != other.m_textures) + return m_textures < other.m_textures; if (m_textureFilter != other.m_textureFilter) return m_textureFilter < other.m_textureFilter; if (m_drawAsLine != other.m_drawAsLine) @@ -127,8 +172,7 @@ bool RenderState::operator==(RenderState const & other) const m_gpuProgram == other.m_gpuProgram && m_gpuProgram3d == other.m_gpuProgram3d && m_blending == other.m_blending && - m_colorTexture == other.m_colorTexture && - m_maskTexture == other.m_maskTexture && + m_textures == other.m_textures && m_textureFilter == other.m_textureFilter && m_depthFunction == other.m_depthFunction && m_drawAsLine == other.m_drawAsLine && @@ -146,26 +190,18 @@ void TextureState::ApplyTextures(RenderState const & state, ref_ptr<GpuProgram> { m_usedSlots = 0; - ref_ptr<Texture> tex = state.GetColorTexture(); - int8_t colorTexLoc = -1; - if (tex != nullptr && (colorTexLoc = program->GetUniformLocation("u_colorTex")) >= 0) + for (auto const & texture : state.GetTextures()) { - GLFunctions::glActiveTexture(gl_const::GLTexture0); - tex->Bind(); - GLFunctions::glUniformValuei(colorTexLoc, 0); - tex->SetFilter(state.GetTextureFilter()); - m_usedSlots++; - } - - tex = state.GetMaskTexture(); - int8_t maskTexLoc = -1; - if (tex != nullptr && (maskTexLoc = program->GetUniformLocation("u_maskTex")) >= 0) - { - GLFunctions::glActiveTexture(gl_const::GLTexture0 + 1); - tex->Bind(); - GLFunctions::glUniformValuei(maskTexLoc, 1); - tex->SetFilter(state.GetTextureFilter()); - m_usedSlots++; + auto const tex = texture.second; + int8_t texLoc = -1; + if (tex != nullptr && (texLoc = program->GetUniformLocation(texture.first)) >= 0) + { + GLFunctions::glActiveTexture(gl_const::GLTexture0 + m_usedSlots); + tex->Bind(); + GLFunctions::glUniformValuei(texLoc, m_usedSlots); + tex->SetFilter(state.GetTextureFilter()); + m_usedSlots++; + } } } @@ -179,19 +215,14 @@ void ApplyBlending(RenderState const & state) state.GetBlending().Apply(); } -void ApplyState(RenderState const & state, ref_ptr<GpuProgram> program) +void ApplyState(RenderState const & state, ref_ptr<GraphicsContext> context, ref_ptr<GpuProgram> program) { TextureState::ApplyTextures(state, program); ApplyBlending(state); + context->SetDepthTestEnabled(state.GetDepthTestEnabled()); if (state.GetDepthTestEnabled()) - { - GLFunctions::glEnable(gl_const::GLDepthTest); - GLFunctions::glDepthFunc(DecodeDepthFunction(state.GetDepthFunction())); - } - else - { - GLFunctions::glDisable(gl_const::GLDepthTest); - } + context->SetDepthTestFunction(state.GetDepthFunction()); + ASSERT_GREATER_OR_EQUAL(state.GetLineWidth(), 0, ()); GLFunctions::glLineWidth(static_cast<uint32_t>(state.GetLineWidth())); } diff --git a/drape/render_state.hpp b/drape/render_state.hpp index f8b41d84e1..27bb0a74d9 100644 --- a/drape/render_state.hpp +++ b/drape/render_state.hpp @@ -1,11 +1,13 @@ #pragma once #include "drape/gpu_program.hpp" +#include "drape/graphics_context.hpp" #include "drape/pointers.hpp" #include "drape/texture.hpp" #include "base/assert.hpp" +#include <map> #include <utility> namespace dp @@ -27,18 +29,6 @@ struct Blending bool m_isEnabled; }; -enum class DepthFunction : uint8_t -{ - Never, - Less, - Equal, - LessOrEqual, - Great, - NotEqual, - GreatOrEqual, - Always -}; - class BaseRenderStateExtension { public: @@ -66,11 +56,15 @@ public: return make_ref(static_cast<RenderStateExtensionType *>(m_renderStateExtension.get())); } - void SetColorTexture(ref_ptr<Texture> tex) { m_colorTexture = tex; } - ref_ptr<Texture> GetColorTexture() const { return m_colorTexture; } + void SetColorTexture(ref_ptr<Texture> tex); + ref_ptr<Texture> GetColorTexture() const; + + void SetMaskTexture(ref_ptr<Texture> tex); + ref_ptr<Texture> GetMaskTexture() const; - void SetMaskTexture(ref_ptr<Texture> tex) { m_maskTexture = tex; } - ref_ptr<Texture> GetMaskTexture() const { return m_maskTexture; } + void SetTexture(std::string const & name, ref_ptr<Texture> tex); + ref_ptr<Texture> GetTexture(std::string const & name) const; + std::map<std::string, ref_ptr<Texture>> const & GetTextures() const; void SetBlending(Blending const & blending) { m_blending = blending; } Blending const & GetBlending() const { return m_blending; } @@ -84,8 +78,8 @@ public: template<typename ProgramType> ProgramType GetProgram3d() const { return static_cast<ProgramType>(m_gpuProgram3d); } - DepthFunction GetDepthFunction() const; - void SetDepthFunction(DepthFunction depthFunction); + TestFunction GetDepthFunction() const; + void SetDepthFunction(TestFunction depthFunction); bool GetDepthTestEnabled() const; void SetDepthTestEnabled(bool enabled); @@ -109,12 +103,11 @@ private: Blending m_blending; bool m_depthTestEnabled = true; - DepthFunction m_depthFunction = DepthFunction::LessOrEqual; + TestFunction m_depthFunction = TestFunction::LessOrEqual; TextureFilter m_textureFilter = TextureFilter::Linear; - ref_ptr<Texture> m_colorTexture; - ref_ptr<Texture> m_maskTexture; + std::map<std::string, ref_ptr<Texture>> m_textures; bool m_drawAsLine = false; int m_lineWidth = 1; @@ -130,6 +123,6 @@ private: static uint8_t m_usedSlots; }; -void ApplyState(RenderState const & state, ref_ptr<GpuProgram> program); +void ApplyState(RenderState const & state, ref_ptr<GraphicsContext> context, ref_ptr<GpuProgram> program); void ApplyBlending(RenderState const & state); } // namespace dp diff --git a/drape/texture_types.hpp b/drape/texture_types.hpp index 20b1cc8ad6..ae08bc1426 100644 --- a/drape/texture_types.hpp +++ b/drape/texture_types.hpp @@ -11,6 +11,8 @@ enum class TextureFormat : uint8_t RGBA8, Alpha, RedGreen, + DepthStencil, + Depth, Unspecified }; @@ -34,6 +36,8 @@ inline uint8_t GetBytesPerPixel(TextureFormat format) case TextureFormat::RGBA8: result = 4; break; case TextureFormat::Alpha: result = 1; break; case TextureFormat::RedGreen: result = 2; break; + case TextureFormat::DepthStencil: result = 4; break; + case TextureFormat::Depth: result = 4; break; default: ASSERT(false, ()); break; } return result; |