diff --git a/drape_frontend/drape_engine.cpp b/drape_frontend/drape_engine.cpp index 2b0b5955b6..70017bb556 100644 --- a/drape_frontend/drape_engine.cpp +++ b/drape_frontend/drape_engine.cpp @@ -429,10 +429,10 @@ gui::TWidgetsSizeInfo const & DrapeEngine::GetWidgetSizes() return m_widgetSizes; } -void DrapeEngine::Enable3dMode(float angleFOV, float angleX, float deltaZ) +void DrapeEngine::Enable3dMode(float angleFOV, float angleX) { m_threadCommutator->PostMessage(ThreadsCommutator::RenderThread, - make_unique_dp(angleFOV, angleX, deltaZ), + make_unique_dp(angleFOV, angleX), MessagePriority::Normal); } diff --git a/drape_frontend/drape_engine.hpp b/drape_frontend/drape_engine.hpp index 57f82e617f..340b106c65 100644 --- a/drape_frontend/drape_engine.hpp +++ b/drape_frontend/drape_engine.hpp @@ -114,7 +114,7 @@ public: void SetWidgetLayout(gui::TWidgetsLayoutInfo && info); gui::TWidgetsSizeInfo const & GetWidgetSizes(); - void Enable3dMode(float angleFOV, float angleX, float deltaZ); + void Enable3dMode(float angleFOV, float angleX); void Disable3dMode(); private: diff --git a/drape_frontend/frontend_renderer.cpp b/drape_frontend/frontend_renderer.cpp index dae78fe5e5..dc48cd6969 100755 --- a/drape_frontend/frontend_renderer.cpp +++ b/drape_frontend/frontend_renderer.cpp @@ -44,7 +44,8 @@ FrontendRenderer::FrontendRenderer(Params const & params) , m_gpuProgramManager(new dp::GpuProgramManager()) , m_routeRenderer(new RouteRenderer()) , m_overlayTree(new dp::OverlayTree()) - , m_useFramebuffer(true) + , m_useFramebuffer(false) + , m_3dModeChanged(false) , m_framebuffer(new Framebuffer()) , m_renderer3d(new Renderer3d()) , m_viewport(params.m_viewport) @@ -466,14 +467,15 @@ void FrontendRenderer::AcceptMessage(ref_ptr message) ref_ptr msg = message; m_renderer3d->SetVerticalFOV(msg->GetAngleFOV()); m_renderer3d->SetPlaneAngleX(msg->GetAngleX()); - m_renderer3d->SetPlaneOffsetZ(msg->GetDeltaZ()); m_useFramebuffer = true; + m_3dModeChanged = true; break; } case Message::Disable3dMode: { m_useFramebuffer = false; + m_3dModeChanged = true; break; } @@ -1134,7 +1136,26 @@ ScreenBase const & FrontendRenderer::ProcessEvents(bool & modelViewChanged, bool { ScreenBase const & modelView = m_userEventStream.ProcessEvents(modelViewChanged, viewportChanged); gui::DrapeGui::Instance().SetInUserAction(m_userEventStream.IsInUserAction()); - return modelView; + + ScreenBase modelView2 = modelView; + + modelViewChanged = modelViewChanged || m_3dModeChanged; + viewportChanged = viewportChanged || m_3dModeChanged; + if (m_useFramebuffer && modelViewChanged) + { + double scale = max(m_renderer3d->GetScaleX(), m_renderer3d->GetScaleY()); + + int w = modelView2.GetWidth(); + int h = modelView2.GetHeight(); + + m2::AnyRectD rectG = modelView2.GlobalRect(); + double dyG = rectG.GetLocalRect().SizeY() * (scale - 1.0); + modelView2.Scale(1.0/scale); + modelView2.MoveG(m2::PointD(0, -dyG / 2.0)); + } + m_3dModeChanged = false; + + return modelView2; } void FrontendRenderer::PrepareScene(ScreenBase const & modelView) diff --git a/drape_frontend/frontend_renderer.hpp b/drape_frontend/frontend_renderer.hpp index de798137ca..2b7a23c528 100755 --- a/drape_frontend/frontend_renderer.hpp +++ b/drape_frontend/frontend_renderer.hpp @@ -227,6 +227,7 @@ private: dp::UniformValuesStorage m_generalUniforms; bool m_useFramebuffer; + bool m_3dModeChanged; drape_ptr m_framebuffer; drape_ptr m_renderer3d; diff --git a/drape_frontend/message_subclasses.hpp b/drape_frontend/message_subclasses.hpp index 9f0fbc828d..d9aa07bc56 100644 --- a/drape_frontend/message_subclasses.hpp +++ b/drape_frontend/message_subclasses.hpp @@ -633,22 +633,19 @@ public: class Enable3dModeMessage : public Message { public: - Enable3dModeMessage(float angleFOV, float angleX, float deltaZ) + Enable3dModeMessage(float angleFOV, float angleX) : m_angleFOV(angleFOV) , m_angleX(angleX) - , m_deltaZ(deltaZ) {} Type GetType() const override { return Message::Enable3dMode; } float GetAngleFOV() const { return m_angleFOV; } float GetAngleX() const { return m_angleX; } - float GetDeltaZ() const { return m_deltaZ; } private: float m_angleFOV; float m_angleX; - float m_deltaZ; }; class Disable3dModeMessage : public Message diff --git a/drape_frontend/renderer3d.cpp b/drape_frontend/renderer3d.cpp index deb55babff..5efc08022b 100644 --- a/drape_frontend/renderer3d.cpp +++ b/drape_frontend/renderer3d.cpp @@ -17,13 +17,17 @@ Renderer3d::Renderer3d() , m_height(0) , m_fov(M_PI / 3.0f) , m_angleX(-M_PI_4) - , m_offsetZ(0.5f) + , m_offsetZ(0.0f) + , m_offsetY(0.0f) + , m_offsetX(0.0f) + , m_scaleX(1.0) + , m_scaleY(1.0) , m_VAO(0) , m_bufferId(0) { - UpdateProjectionMatrix(); - UpdateRotationMatrix(); - UpdateTranslationMatrix(); + SetPlaneAngleX(m_angleX); + SetVerticalFOV(m_fov); + CalculateGeometry(); } Renderer3d::~Renderer3d() @@ -46,21 +50,65 @@ void Renderer3d::SetVerticalFOV(float fov) { m_fov = fov; + CalculateGeometry(); UpdateProjectionMatrix(); } +void Renderer3d::CalculateGeometry() +{ + m_offsetZ = 1 / tan(m_fov / 2.0) + sin(-m_angleX); + m_offsetY = -1 + cos(-m_angleX); + + m_scaleY = cos(-m_angleX) + sin(-m_angleX) * tan(m_fov / 2.0 - m_angleX); + m_scaleX = 1.0 + 2*sin(-m_angleX) * cos(m_fov / 2.0) / (m_offsetZ * cos(m_fov / 2.0 - m_angleX)); + m_scaleX = m_scaleY; +/* + const float vertices[] = + { + -1.0f, 1.0f, 0.0f, 1.0f, + 1.0f, 1.0f, 1.0f, 1.0f, + -1.0f, -1.0f, 0.0f, 0.0f, + 1.0f, -1.0f, 1.0f, 0.0f + }; +*/ + m_vertices[0] = -1.0f * m_scaleX; + m_vertices[1] = 2.0f * m_scaleY - 1.0f; + m_vertices[2] = 0.0f; + m_vertices[3] = 1.0f; + + m_vertices[4] = 1.0f * m_scaleX; + m_vertices[5] = 2.0f * m_scaleY - 1.0f; + m_vertices[6] = 1.0f; + m_vertices[7] = 1.0f; + + m_vertices[8] = -1.0f * m_scaleX; + m_vertices[9] = -1.0f; + m_vertices[10] = 0.0f; + m_vertices[11] = 0.0f; + + m_vertices[12] = 1.0f * m_scaleX; + m_vertices[13] = -1.0f; + m_vertices[14] = 1.0f; + m_vertices[15] = 0.0f; + + UpdateRotationMatrix(); + UpdateTranslationMatrix(); +} + +float Renderer3d::GetScaleX() const +{ + return m_scaleX; +} + +float Renderer3d::GetScaleY() const +{ + return m_scaleY; +} + void Renderer3d::SetPlaneAngleX(float angleX) { m_angleX = angleX; - - UpdateRotationMatrix(); -} - -void Renderer3d::SetPlaneOffsetZ(float offsetZ) -{ - m_offsetZ = offsetZ; - - UpdateTranslationMatrix(); + CalculateGeometry(); } void Renderer3d::Build(ref_ptr prg) @@ -82,15 +130,6 @@ void Renderer3d::Build(ref_ptr prg) GLFunctions::glEnableVertexAttribute(attributeLocation); GLFunctions::glVertexAttributePointer(attributeLocation, 2, gl_const::GLFloatType, false, sizeof(float) * 4, sizeof(float) * 2); - - const float vertices[] = - { - -1.0f, 1.0f, 0.0f, 1.0f, - 1.0f, 1.0f, 1.0f, 1.0f, - -1.0f, -1.0f, 0.0f, 0.0f, - 1.0f, -1.0f, 1.0f, 0.0f - }; - GLFunctions::glBufferData(gl_const::GLArrayBuffer, sizeof(vertices), vertices, gl_const::GLStaticDraw); } void Renderer3d::Render(uint32_t textureId, ref_ptr mng) @@ -116,6 +155,11 @@ void Renderer3d::Render(uint32_t textureId, ref_ptr mng) GLFunctions::glBindBuffer(m_bufferId, gl_const::GLArrayBuffer); GLFunctions::glBindVertexArray(m_VAO); + + + GLFunctions::glBufferData(gl_const::GLArrayBuffer, sizeof(m_vertices), m_vertices, gl_const::GLStaticDraw); + + GLFunctions::glViewport(0, 0, m_width, m_height); GLFunctions::glClear(); GLFunctions::glDrawArrays(gl_const::GLTriangleStrip, 0, 4); @@ -128,7 +172,7 @@ void Renderer3d::Render(uint32_t textureId, ref_ptr mng) void Renderer3d::UpdateProjectionMatrix() { float ctg_fovy = 1.0/tanf(m_fov/2.0f); - float aspect = (float)m_width / m_height; + float aspect = 1.0; float near = 0.1f; float far = 100.0f; @@ -158,7 +202,7 @@ void Renderer3d::UpdateTranslationMatrix() m_translationMatrix.fill(0.0f); float dx = 0.0f; - float dy = 0.0f; + float dy = m_offsetY; float dz = m_offsetZ; m_translationMatrix[0] = 1.0f; diff --git a/drape_frontend/renderer3d.hpp b/drape_frontend/renderer3d.hpp index 0898fee245..9168c1976f 100644 --- a/drape_frontend/renderer3d.hpp +++ b/drape_frontend/renderer3d.hpp @@ -15,13 +15,17 @@ public: void SetSize(uint32_t width, uint32_t height); void SetVerticalFOV(float fov); void SetPlaneAngleX(float angleX); - void SetPlaneOffsetZ(float offsetZ); + + float GetScaleX() const; + float GetScaleY() const; void Render(uint32_t textureId, ref_ptr mng); private: void Build(ref_ptr prg); + void CalculateGeometry(); + void UpdateRotationMatrix(); void UpdateTranslationMatrix(); void UpdateProjectionMatrix(); @@ -31,14 +35,21 @@ private: float m_fov; float m_angleX; + float m_offsetX; + float m_offsetY; float m_offsetZ; + float m_scaleX; + float m_scaleY; + array m_rotationMatrix; array m_translationMatrix; array m_projectionMatrix; uint32_t m_VAO; uint32_t m_bufferId; + + float m_vertices[16]; }; } diff --git a/map/framework.cpp b/map/framework.cpp index 5a7a8d3e4f..1bad5a41b0 100644 --- a/map/framework.cpp +++ b/map/framework.cpp @@ -2051,7 +2051,7 @@ void Framework::Enable3dMode(bool enable) { ASSERT(m_drapeEngine != nullptr, ()); if (enable) - m_drapeEngine->Enable3dMode(M_PI / 3.0f, -M_PI_4, 0.5f); + m_drapeEngine->Enable3dMode(M_PI / 3.0f, -M_PI_4); else m_drapeEngine->Disable3dMode(); }