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:
Daria Volvenkova 2015-10-14 14:45:27 +03:00
parent ed9db0ba8e
commit 34b9b39525
8 changed files with 110 additions and 36 deletions

View file

@ -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);
}

View file

@ -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:

View file

@ -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)

View file

@ -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;

View file

@ -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

View file

@ -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;

View file

@ -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];
};
}

View file

@ -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();
}