forked from organicmaps/organicmaps
Saving the map's scale and position if it is in perspective mode. Expanding the map's rect to see farther ahead.
This commit is contained in:
parent
ed9db0ba8e
commit
34b9b39525
8 changed files with 110 additions and 36 deletions
|
@ -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<Enable3dModeMessage>(angleFOV, angleX, deltaZ),
|
||||
make_unique_dp<Enable3dModeMessage>(angleFOV, angleX),
|
||||
MessagePriority::Normal);
|
||||
}
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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> message)
|
|||
ref_ptr<Enable3dModeMessage> 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)
|
||||
|
|
|
@ -227,6 +227,7 @@ private:
|
|||
dp::UniformValuesStorage m_generalUniforms;
|
||||
|
||||
bool m_useFramebuffer;
|
||||
bool m_3dModeChanged;
|
||||
drape_ptr<Framebuffer> m_framebuffer;
|
||||
drape_ptr<Renderer3d> m_renderer3d;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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<dp::GpuProgram> prg)
|
||||
|
@ -82,15 +130,6 @@ void Renderer3d::Build(ref_ptr<dp::GpuProgram> 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<dp::GpuProgramManager> mng)
|
||||
|
@ -116,6 +155,11 @@ void Renderer3d::Render(uint32_t textureId, ref_ptr<dp::GpuProgramManager> 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<dp::GpuProgramManager> 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;
|
||||
|
|
|
@ -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<dp::GpuProgramManager> mng);
|
||||
|
||||
private:
|
||||
void Build(ref_ptr<dp::GpuProgram> 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<float, 16> m_rotationMatrix;
|
||||
array<float, 16> m_translationMatrix;
|
||||
array<float, 16> m_projectionMatrix;
|
||||
|
||||
uint32_t m_VAO;
|
||||
uint32_t m_bufferId;
|
||||
|
||||
float m_vertices[16];
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue