forked from organicmaps/organicmaps-tmp
Rendering 3d buildings in isometric projection.
This commit is contained in:
parent
b4cdfc11d1
commit
535c6b8502
11 changed files with 73 additions and 47 deletions
|
@ -97,7 +97,8 @@ void BackendRenderer::AcceptMessage(ref_ptr<Message> message)
|
|||
if (!tiles.empty())
|
||||
{
|
||||
ScreenBase const screen = m_requestedTiles->GetScreen();
|
||||
m_readManager->UpdateCoverage(screen, tiles, m_texMng);
|
||||
bool const is3dBuildings = m_requestedTiles->Is3dBuildings();
|
||||
m_readManager->UpdateCoverage(screen, is3dBuildings, tiles, m_texMng);
|
||||
|
||||
gui::CountryStatusHelper & helper = gui::DrapeGui::Instance().GetCountryStatusHelper();
|
||||
if ((*tiles.begin()).m_zoomLevel > scales::GetUpperWorldScale())
|
||||
|
|
|
@ -429,14 +429,15 @@ gui::TWidgetsSizeInfo const & DrapeEngine::GetWidgetSizes()
|
|||
return m_widgetSizes;
|
||||
}
|
||||
|
||||
void DrapeEngine::Allow3dMode(bool allow3d, bool allow3dBuildings, double rotationAngle, double angleFOV)
|
||||
void DrapeEngine::Allow3dMode(bool allowPerspectiveInNavigation, bool allow3dBuildings, double rotationAngle, double angleFOV)
|
||||
{
|
||||
m_threadCommutator->PostMessage(ThreadsCommutator::ResourceUploadThread,
|
||||
make_unique_dp<Allow3dBuildingsMessage>(allow3d && allow3dBuildings),
|
||||
make_unique_dp<Allow3dBuildingsMessage>(allow3dBuildings),
|
||||
MessagePriority::Normal);
|
||||
|
||||
m_threadCommutator->PostMessage(ThreadsCommutator::RenderThread,
|
||||
make_unique_dp<Allow3dModeMessage>(allow3d, rotationAngle, angleFOV),
|
||||
make_unique_dp<Allow3dModeMessage>(allowPerspectiveInNavigation, allow3dBuildings,
|
||||
rotationAngle, angleFOV),
|
||||
MessagePriority::Normal);
|
||||
}
|
||||
|
||||
|
|
|
@ -114,7 +114,7 @@ public:
|
|||
void SetWidgetLayout(gui::TWidgetsLayoutInfo && info);
|
||||
gui::TWidgetsSizeInfo const & GetWidgetSizes();
|
||||
|
||||
void Allow3dMode(bool allow3d, bool allow3dBuildings, double rotationAngle, double angleFOV);
|
||||
void Allow3dMode(bool allowPerspectiveInNavigation, bool allow3dBuildings, double rotationAngle, double angleFOV);
|
||||
void EnablePerspective(double rotationAngle, double angleFOV);
|
||||
|
||||
private:
|
||||
|
|
|
@ -47,7 +47,9 @@ FrontendRenderer::FrontendRenderer(Params const & params)
|
|||
, m_framebuffer(new Framebuffer())
|
||||
, m_transparentLayer(new TransparentLayer())
|
||||
, m_overlayTree(new dp::OverlayTree())
|
||||
, m_enable3dInNavigation(false)
|
||||
, m_enablePerspectiveInNavigation(false)
|
||||
, m_enable3dBuildings(false)
|
||||
, m_isIsometry(false)
|
||||
, m_viewport(params.m_viewport)
|
||||
, m_userEventStream(params.m_isCountryLoadedFn)
|
||||
, m_modelViewChangedFn(params.m_modelViewChangedFn)
|
||||
|
@ -197,7 +199,7 @@ void FrontendRenderer::AcceptMessage(ref_ptr<Message> message)
|
|||
MessagePriority::High);
|
||||
blocker.Wait();
|
||||
|
||||
m_requestedTiles->Set(screen, move(tiles));
|
||||
m_requestedTiles->Set(screen, m_isIsometry || screen.isPerspective(), move(tiles));
|
||||
m_commutator->PostMessage(ThreadsCommutator::ResourceUploadThread,
|
||||
make_unique_dp<UpdateReadManagerMessage>(),
|
||||
MessagePriority::UberHighSingleton);
|
||||
|
@ -403,7 +405,7 @@ void FrontendRenderer::AcceptMessage(ref_ptr<Message> message)
|
|||
{
|
||||
m_myPositionController->DeactivateRouting();
|
||||
m_overlayTree->SetFollowingMode(false);
|
||||
if (m_enable3dInNavigation)
|
||||
if (m_enablePerspectiveInNavigation)
|
||||
DisablePerspective();
|
||||
}
|
||||
break;
|
||||
|
@ -412,10 +414,10 @@ void FrontendRenderer::AcceptMessage(ref_ptr<Message> message)
|
|||
case Message::FollowRoute:
|
||||
{
|
||||
ref_ptr<FollowRouteMessage> const msg = message;
|
||||
m_myPositionController->NextMode(!m_enable3dInNavigation ? msg->GetPreferredZoomLevel()
|
||||
m_myPositionController->NextMode(!m_enablePerspectiveInNavigation ? msg->GetPreferredZoomLevel()
|
||||
: msg->GetPreferredZoomLevelIn3d());
|
||||
m_overlayTree->SetFollowingMode(true);
|
||||
if (m_enable3dInNavigation)
|
||||
if (m_enablePerspectiveInNavigation)
|
||||
{
|
||||
bool immediatelyStart = !m_myPositionController->IsRotationActive();
|
||||
AddUserEvent(EnablePerspectiveEvent(msg->GetRotationAngle(), msg->GetAngleFOV(),
|
||||
|
@ -428,7 +430,7 @@ void FrontendRenderer::AcceptMessage(ref_ptr<Message> message)
|
|||
{
|
||||
m_myPositionController->DeactivateRouting();
|
||||
m_overlayTree->SetFollowingMode(false);
|
||||
if (m_enable3dInNavigation)
|
||||
if (m_enablePerspectiveInNavigation)
|
||||
DisablePerspective();
|
||||
break;
|
||||
}
|
||||
|
@ -495,7 +497,7 @@ void FrontendRenderer::AcceptMessage(ref_ptr<Message> message)
|
|||
}
|
||||
|
||||
// Request new tiles.
|
||||
m_requestedTiles->Set(screen, move(tiles));
|
||||
m_requestedTiles->Set(screen, m_isIsometry || screen.isPerspective(), move(tiles));
|
||||
m_commutator->PostMessage(ThreadsCommutator::ResourceUploadThread,
|
||||
make_unique_dp<UpdateReadManagerMessage>(),
|
||||
MessagePriority::UberHighSingleton);
|
||||
|
@ -518,27 +520,28 @@ void FrontendRenderer::AcceptMessage(ref_ptr<Message> message)
|
|||
ref_ptr<Allow3dModeMessage> const msg = message;
|
||||
bool const isPerspective = m_userEventStream.GetCurrentScreen().isPerspective();
|
||||
#ifdef OMIM_OS_DESKTOP
|
||||
if (m_enable3dInNavigation == msg->Allow() &&
|
||||
m_enable3dInNavigation != isPerspective)
|
||||
if (m_enablePerspectiveInNavigation == msg->AllowPerspective() &&
|
||||
m_enablePerspectiveInNavigation != isPerspective)
|
||||
{
|
||||
|
||||
if (m_enable3dInNavigation)
|
||||
if (m_enablePerspectiveInNavigation)
|
||||
AddUserEvent(EnablePerspectiveEvent(msg->GetRotationAngle(), msg->GetAngleFOV(),
|
||||
false /* animated */, true /* immediately start */));
|
||||
else
|
||||
AddUserEvent(DisablePerspectiveEvent());
|
||||
}
|
||||
#endif
|
||||
m_enable3dInNavigation = msg->Allow();
|
||||
m_enablePerspectiveInNavigation = msg->AllowPerspective();
|
||||
m_enable3dBuildings = msg->Allow3dBuildings();
|
||||
|
||||
if (m_myPositionController->IsInRouting())
|
||||
{
|
||||
if (m_enable3dInNavigation && !isPerspective && !m_perspectiveDiscarded)
|
||||
if (m_enablePerspectiveInNavigation && !isPerspective && !m_perspectiveDiscarded)
|
||||
{
|
||||
AddUserEvent(EnablePerspectiveEvent(msg->GetRotationAngle(), msg->GetAngleFOV(),
|
||||
true /* animated */, true /* immediately start */));
|
||||
}
|
||||
else if (!m_enable3dInNavigation && (isPerspective || m_perspectiveDiscarded))
|
||||
else if (!m_enablePerspectiveInNavigation && (isPerspective || m_perspectiveDiscarded))
|
||||
{
|
||||
DisablePerspective();
|
||||
}
|
||||
|
@ -574,8 +577,7 @@ void FrontendRenderer::OnResize(ScreenBase const & screen)
|
|||
RefreshProjection(screen);
|
||||
RefreshPivotTransform(screen);
|
||||
|
||||
if (screen.isPerspective())
|
||||
m_framebuffer->SetSize(viewportRect.SizeX(), viewportRect.SizeY());
|
||||
m_framebuffer->SetSize(viewportRect.SizeX(), viewportRect.SizeY());
|
||||
}
|
||||
|
||||
void FrontendRenderer::AddToRenderGroup(vector<drape_ptr<RenderGroup>> & groups,
|
||||
|
@ -780,7 +782,7 @@ void FrontendRenderer::RenderScene(ScreenBase const & modelView)
|
|||
|
||||
dp::GLState const & state = group->GetState();
|
||||
|
||||
if (isPerspective && state.GetProgram3dIndex() == gpu::AREA_3D_PROGRAM)
|
||||
if ((isPerspective || m_isIsometry) && state.GetProgram3dIndex() == gpu::AREA_3D_PROGRAM)
|
||||
{
|
||||
if (!has3dAreas)
|
||||
{
|
||||
|
@ -822,7 +824,7 @@ void FrontendRenderer::RenderScene(ScreenBase const & modelView)
|
|||
m_myPositionController->Render(MyPositionController::RenderAccuracy,
|
||||
modelView, make_ref(m_gpuProgramManager), m_generalUniforms);
|
||||
|
||||
if (isPerspective && has3dAreas)
|
||||
if (has3dAreas)
|
||||
{
|
||||
m_framebuffer->Enable();
|
||||
GLFunctions::glClear();
|
||||
|
@ -938,8 +940,18 @@ void FrontendRenderer::RefreshPivotTransform(ScreenBase const & screen)
|
|||
math::Matrix<float, 4, 4> transform(screen.Pto3dMatrix());
|
||||
m_generalUniforms.SetMatrix4x4Value("pivotTransform", transform.m_data);
|
||||
}
|
||||
else if (m_isIsometry)
|
||||
{
|
||||
math::Matrix<float, 4, 4> transform(math::Identity<float, 4>());
|
||||
transform(2, 1) = -1.0f/tan(M_PI * 80.0f / 180.0f);
|
||||
transform(2, 2) = 1.0f / screen.GetHeight();
|
||||
m_generalUniforms.SetMatrix4x4Value("pivotTransform", transform.m_data);
|
||||
}
|
||||
else
|
||||
m_generalUniforms.SetMatrix4x4Value("pivotTransform", math::Identity<float, 4>().m_data);
|
||||
{
|
||||
math::Matrix<float, 4, 4> transform(math::Identity<float, 4>());
|
||||
m_generalUniforms.SetMatrix4x4Value("pivotTransform", transform.m_data);
|
||||
}
|
||||
}
|
||||
|
||||
void FrontendRenderer::RefreshBgColor()
|
||||
|
@ -968,11 +980,13 @@ void FrontendRenderer::DisablePerspective()
|
|||
|
||||
void FrontendRenderer::CheckMinAllowableIn3dScale()
|
||||
{
|
||||
if (!m_enable3dInNavigation ||
|
||||
m_userEventStream.IsInPerspectiveAnimation())
|
||||
bool const isScaleAllowableIn3d = UserEventStream::IsScaleAllowableIn3d(m_currentZoomLevel);
|
||||
m_isIsometry = m_enable3dBuildings && isScaleAllowableIn3d;
|
||||
|
||||
if (!m_enablePerspectiveInNavigation || m_userEventStream.IsInPerspectiveAnimation())
|
||||
return;
|
||||
|
||||
bool const switchTo2d = !UserEventStream::IsScaleAllowableIn3d(m_currentZoomLevel);
|
||||
bool const switchTo2d = !isScaleAllowableIn3d;
|
||||
if ((!switchTo2d && !m_perspectiveDiscarded) ||
|
||||
(switchTo2d && !m_userEventStream.GetCurrentScreen().isPerspective()))
|
||||
return;
|
||||
|
@ -1328,7 +1342,7 @@ void FrontendRenderer::UpdateScene(ScreenBase const & modelView)
|
|||
};
|
||||
RemoveRenderGroups(removePredicate);
|
||||
|
||||
m_requestedTiles->Set(modelView, move(tiles));
|
||||
m_requestedTiles->Set(modelView, m_isIsometry || modelView.isPerspective(), move(tiles));
|
||||
m_commutator->PostMessage(ThreadsCommutator::ResourceUploadThread,
|
||||
make_unique_dp<UpdateReadManagerMessage>(),
|
||||
MessagePriority::UberHighSingleton);
|
||||
|
|
|
@ -234,7 +234,9 @@ private:
|
|||
|
||||
dp::UniformValuesStorage m_generalUniforms;
|
||||
|
||||
bool m_enable3dInNavigation;
|
||||
bool m_enablePerspectiveInNavigation;
|
||||
bool m_enable3dBuildings;
|
||||
bool m_isIsometry;
|
||||
|
||||
Viewport m_viewport;
|
||||
UserEventStream m_userEventStream;
|
||||
|
|
|
@ -656,19 +656,22 @@ public:
|
|||
class Allow3dModeMessage : public Message
|
||||
{
|
||||
public:
|
||||
Allow3dModeMessage(bool allow, double rotationAngle, double angleFOV)
|
||||
: m_allow(allow)
|
||||
Allow3dModeMessage(bool allowPerspective, bool allow3dBuildings, double rotationAngle, double angleFOV)
|
||||
: m_allowPerspective(allowPerspective)
|
||||
, m_allow3dBuildings(allow3dBuildings)
|
||||
, m_rotationAngle(rotationAngle)
|
||||
, m_angleFOV(angleFOV)
|
||||
{}
|
||||
|
||||
Type GetType() const override { return Message::Allow3dMode; }
|
||||
bool Allow() const { return m_allow; }
|
||||
bool AllowPerspective() const { return m_allowPerspective; }
|
||||
bool Allow3dBuildings() const { return m_allow3dBuildings; }
|
||||
double GetRotationAngle() const { return m_rotationAngle; }
|
||||
double GetAngleFOV() const { return m_angleFOV; }
|
||||
|
||||
private:
|
||||
bool const m_allow;
|
||||
bool const m_allowPerspective;
|
||||
bool const m_allow3dBuildings;
|
||||
double const m_rotationAngle;
|
||||
double const m_angleFOV;
|
||||
};
|
||||
|
|
|
@ -36,8 +36,8 @@ ReadManager::ReadManager(ref_ptr<ThreadsCommutator> commutator, MapDataProvider
|
|||
, m_model(model)
|
||||
, m_pool(make_unique_dp<threads::ThreadPool>(ReadCount(), bind(&ReadManager::OnTaskFinished, this, _1)))
|
||||
, m_forceUpdate(true)
|
||||
, m_is3d(false)
|
||||
, m_is3dBuildings(false)
|
||||
, m_need3dBuildings(false)
|
||||
, m_allow3dBuildings(false)
|
||||
, m_modeChanged(false)
|
||||
, myPool(64, ReadMWMTaskFactory(m_memIndex, m_model))
|
||||
, m_counter(0)
|
||||
|
@ -73,14 +73,15 @@ void ReadManager::OnTaskFinished(threads::IRoutine * task)
|
|||
myPool.Return(t);
|
||||
}
|
||||
|
||||
void ReadManager::UpdateCoverage(ScreenBase const & screen, TTilesCollection const & tiles, ref_ptr<dp::TextureManager> texMng)
|
||||
void ReadManager::UpdateCoverage(ScreenBase const & screen, bool is3dBuildings,
|
||||
TTilesCollection const & tiles, ref_ptr<dp::TextureManager> texMng)
|
||||
{
|
||||
if (screen == m_currentViewport && !m_forceUpdate)
|
||||
return;
|
||||
|
||||
m_forceUpdate = false;
|
||||
m_is3d = screen.isPerspective();
|
||||
m_modeChanged |= m_is3dBuildings && (m_is3d != m_currentViewport.isPerspective());
|
||||
m_modeChanged |= m_need3dBuildings != is3dBuildings;
|
||||
m_need3dBuildings = is3dBuildings;
|
||||
|
||||
if (m_modeChanged || MustDropAllTiles(screen))
|
||||
{
|
||||
|
@ -188,7 +189,7 @@ void ReadManager::PushTaskBackForTileKey(TileKey const & tileKey, ref_ptr<dp::Te
|
|||
{
|
||||
shared_ptr<TileInfo> tileInfo(new TileInfo(make_unique_dp<EngineContext>(TileKey(tileKey, m_generationCounter),
|
||||
m_commutator, texMng)));
|
||||
tileInfo->Set3dBuildings(m_is3d && m_is3dBuildings);
|
||||
tileInfo->Set3dBuildings(m_need3dBuildings && m_allow3dBuildings);
|
||||
m_tileInfos.insert(tileInfo);
|
||||
ReadMWMTask * task = myPool.Get();
|
||||
task->Init(tileInfo);
|
||||
|
@ -197,7 +198,7 @@ void ReadManager::PushTaskBackForTileKey(TileKey const & tileKey, ref_ptr<dp::Te
|
|||
|
||||
void ReadManager::PushTaskFront(shared_ptr<TileInfo> const & tileToReread)
|
||||
{
|
||||
tileToReread->Set3dBuildings(m_is3d && m_is3dBuildings);
|
||||
tileToReread->Set3dBuildings(m_need3dBuildings && m_allow3dBuildings);
|
||||
ReadMWMTask * task = myPool.Get();
|
||||
task->Init(tileToReread);
|
||||
m_pool->PushFront(task);
|
||||
|
@ -222,11 +223,11 @@ void ReadManager::IncreaseCounter(int value)
|
|||
|
||||
void ReadManager::Allow3dBuildings(bool allow3dBuildings)
|
||||
{
|
||||
if (m_is3dBuildings != allow3dBuildings)
|
||||
if (m_allow3dBuildings != allow3dBuildings)
|
||||
{
|
||||
m_modeChanged = true;
|
||||
m_forceUpdate = true;
|
||||
m_is3dBuildings = allow3dBuildings;
|
||||
m_allow3dBuildings = allow3dBuildings;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ class ReadManager
|
|||
public:
|
||||
ReadManager(ref_ptr<ThreadsCommutator> commutator, MapDataProvider & model);
|
||||
|
||||
void UpdateCoverage(ScreenBase const & screen, TTilesCollection const & tiles,
|
||||
void UpdateCoverage(ScreenBase const & screen, bool is3dBuildings, TTilesCollection const & tiles,
|
||||
ref_ptr<dp::TextureManager> texMng);
|
||||
void Invalidate(TTilesCollection const & keyStorage);
|
||||
void Stop();
|
||||
|
@ -57,8 +57,8 @@ private:
|
|||
|
||||
ScreenBase m_currentViewport;
|
||||
bool m_forceUpdate;
|
||||
bool m_is3d;
|
||||
bool m_is3dBuildings;
|
||||
bool m_need3dBuildings;
|
||||
bool m_allow3dBuildings;
|
||||
bool m_modeChanged;
|
||||
|
||||
struct LessByTileInfo
|
||||
|
|
|
@ -181,7 +181,8 @@ void RenderGroup::Disappear()
|
|||
//else
|
||||
{
|
||||
// Create separate disappearing animation for area objects to eliminate flickering.
|
||||
if (m_state.GetProgramIndex() == gpu::AREA_PROGRAM)
|
||||
if (m_state.GetProgramIndex() == gpu::AREA_PROGRAM ||
|
||||
m_state.GetProgramIndex() == gpu::AREA_3D_PROGRAM)
|
||||
m_disappearAnimation = make_unique<OpacityAnimation>(0.01 /* duration */, 0.25 /* delay */,
|
||||
1.0 /* startOpacity */, 1.0 /* endOpacity */);
|
||||
}
|
||||
|
|
|
@ -3,11 +3,12 @@
|
|||
namespace df
|
||||
{
|
||||
|
||||
void RequestedTiles::Set(ScreenBase const & screen, TTilesCollection && tiles)
|
||||
void RequestedTiles::Set(ScreenBase const & screen, bool is3dBuildings, TTilesCollection && tiles)
|
||||
{
|
||||
lock_guard<mutex> lock(m_mutex);
|
||||
m_tiles = move(tiles);
|
||||
m_screen = screen;
|
||||
m_is3dBuildings = is3dBuildings;
|
||||
}
|
||||
|
||||
TTilesCollection RequestedTiles::GetTiles()
|
||||
|
|
|
@ -13,14 +13,16 @@ class RequestedTiles
|
|||
{
|
||||
public:
|
||||
RequestedTiles() = default;
|
||||
void Set(ScreenBase const & screen, TTilesCollection && tiles);
|
||||
void Set(ScreenBase const & screen, bool is3dBuildings, TTilesCollection && tiles);
|
||||
TTilesCollection GetTiles();
|
||||
ScreenBase GetScreen();
|
||||
bool Is3dBuildings() const { return m_is3dBuildings; }
|
||||
bool CheckTileKey(TileKey const & tileKey) const;
|
||||
|
||||
private:
|
||||
TTilesCollection m_tiles;
|
||||
ScreenBase m_screen;
|
||||
bool m_is3dBuildings = false;
|
||||
mutable mutex m_mutex;
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue