Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/drape
diff options
context:
space:
mode:
authorDaria Volvenkova <d.volvenkova@corp.mail.ru>2018-08-15 15:53:42 +0300
committerRoman Kuznetsov <r.kuznetsow@gmail.com>2018-08-17 13:11:53 +0300
commit5ab189afac15e9e97aef702e69e0d883bc8532b9 (patch)
treea6f705150dff1cfa2e63616c8a77f03bafe69ce6 /drape
parentd4673530fedab33c81e0a5453c43001a2b4ac983 (diff)
Framebuffer and render state refactoring.
Diffstat (limited to 'drape')
-rw-r--r--drape/CMakeLists.txt3
-rw-r--r--drape/binding_info.hpp3
-rw-r--r--drape/debug_rect_renderer.cpp122
-rw-r--r--drape/debug_rect_renderer.hpp48
-rw-r--r--drape/debug_renderer.hpp19
-rw-r--r--drape/framebuffer.cpp70
-rw-r--r--drape/framebuffer.hpp19
-rw-r--r--drape/graphics_context.hpp39
-rw-r--r--drape/hw_texture.cpp29
-rw-r--r--drape/mesh_object.cpp113
-rw-r--r--drape/mesh_object.hpp35
-rw-r--r--drape/oglcontext.cpp81
-rw-r--r--drape/oglcontext.hpp6
-rw-r--r--drape/overlay_tree.cpp9
-rw-r--r--drape/overlay_tree.hpp5
-rw-r--r--drape/render_bucket.cpp16
-rw-r--r--drape/render_bucket.hpp5
-rw-r--r--drape/render_state.cpp121
-rw-r--r--drape/render_state.hpp37
-rw-r--r--drape/texture_types.hpp4
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;