diff --git a/drape_frontend/frontend_renderer.cpp b/drape_frontend/frontend_renderer.cpp index 26da40129e..a6ebd159f6 100644 --- a/drape_frontend/frontend_renderer.cpp +++ b/drape_frontend/frontend_renderer.cpp @@ -1,19 +1,27 @@ #include "frontend_renderer.hpp" +#include "message_subclasses.hpp" #include "../base/assert.hpp" #include "../base/stl_add.hpp" -#include "message_subclasses.hpp" -#include "render_thread.hpp" +#include "../geometry/any_rect2d.hpp" + #include "../std/bind.hpp" +#include "../std/cmath.hpp" namespace df { - FrontendRenderer::FrontendRenderer(RefPointer commutator) + FrontendRenderer::FrontendRenderer(RefPointer commutator + , RefPointer oglcontextfactory, int w, int h) : m_commutator(commutator) , m_gpuProgramManager(new GpuProgramManager()) + , m_contextFactory(oglcontextfactory) + , m_width(w) + , m_height(h) { + RefreshProjection(w, h); + RefreshModelView(0); StartThread(); } @@ -26,6 +34,7 @@ namespace df { switch (message->GetType()) { + case Message::FlushTile: { FlushTileMessage * msg = static_cast(message.GetRaw()); @@ -36,6 +45,7 @@ namespace df m_tileData.insert(make_pair(key, renderIterator)); break; } + case Message::DropTile: { DropTileMessage * msg = static_cast(message.GetRaw()); @@ -49,9 +59,32 @@ namespace df m_tileData.erase(range.first, range.second); break; } + case Message::DropCoverage: DeleteRenderData(); break; + + case Message::Resize: + { + ResizeMessage * rszMsg = static_cast(message.GetRaw()); + RefreshProjection(rszMsg->GetRect().SizeX(), rszMsg->GetRect().SizeY()); + break; + } + + case Message::Rotate: + { + RotateMessage * rtMsg = static_cast(message.GetRaw()); + RefreshModelView(rtMsg->GetDstAngle()); + + ScreenBase screen(m2::RectI(0, 0, m_width, m_height), + m2::AnyRectD(m2::PointD(0, 0), ang::AngleD(rtMsg->GetDstAngle()), + m2::RectD(0 ,0, 50, 50))); + + m_commutator->PostMessage(ThreadsCommutator::ResourceUploadThread, + MovePointer(new UpdateCoverageMessage(screen))); + break; + } + default: ASSERT(false, ()); } @@ -59,16 +92,71 @@ namespace df namespace { - void render_part(RefPointer manager , pair > & node) + void OrthoMatrix(float * m, float left, float right, float bottom, float top, float near, float far) { - ApplyState(node.first, manager->GetProgram(node.first.GetProgramIndex())); - node.second->Render(); + memset(m, 0, 16 * sizeof(float)); + m[0] = 2.0f / (right - left); + m[4] = - (right + left) / (right - left); + m[5] = 2.0f / (top - bottom); + m[9] = - (top + bottom) / (top - bottom); + m[10] = -2.0f / (far - near); + m[14] = - (far + near) / (far - near); + m[15] = 1.0; } } void FrontendRenderer::RenderScene() { - for_each(m_renderData.begin(), m_renderData.end(), bind(&render_part, m_gpuProgramManager.GetRefPointer(), _1)); + GLFunctions::glViewport(0, 0, m_width, m_height); + GLFunctions::glClearColor(0.65f, 0.65f, 0.65f, 1.f); + GLFunctions::glClear(); + + + for_each(m_renderData.begin(), m_renderData.end(), bind(&FrontendRenderer::RenderPartImpl, this, _1)); + } + + void FrontendRenderer::RefreshProjection(int w, int h) + { + if (w == 0) + w = 1; + + m_height = h; + m_width = w; + + float aspect = h / (float)w; + float m[4*4]; + + if (w >= h) + OrthoMatrix(m, -1.f/aspect, 2.f/aspect, -1.f, 2.f, -2.f, 2.f); + else + OrthoMatrix(m, -1.f, 2.f, -1.f*aspect, 2.f*aspect, -2.f, 2.f); + + m_generalUniforms.SetMatrix4x4Value("projection", m); + } + + void FrontendRenderer::RefreshModelView(float radians) + { + float c = cos(radians); + float s = sin(radians); + float model[16] = + { + c, -s, 0.0, 0.0, + s, c, 0.0, 0.0, + 0.0, 0.0, 1.0, 0.0, + 0.0, 0.0, 0.0, 1.0 + }; + + m_generalUniforms.SetMatrix4x4Value("modelView", model); + } + + void FrontendRenderer::RenderPartImpl(pair > & node) + { + RefPointer program = m_gpuProgramManager->GetProgram(node.first.GetProgramIndex()); + + ApplyState(node.first, program); + ApplyUniforms(m_generalUniforms, program); + + node.second->Render(); } void FrontendRenderer::StartThread() @@ -85,12 +173,17 @@ namespace df void FrontendRenderer::ThreadMain() { - InitRenderThread(); + OGLContext * context = m_contextFactory->getDrawContext(); + context->makeCurrent(); while (!IsCancelled()) { ProcessSingleMessage(false); - RenderScene(); + { + context->setDefaultFramebuffer(); + RenderScene(); + context->present(); + } } ReleaseResources(); diff --git a/drape_frontend/frontend_renderer.hpp b/drape_frontend/frontend_renderer.hpp index c1060cade0..4c99ee530b 100644 --- a/drape_frontend/frontend_renderer.hpp +++ b/drape_frontend/frontend_renderer.hpp @@ -11,6 +11,9 @@ #include "../drape/glstate.hpp" #include "../drape/vertex_array_buffer.hpp" #include "../drape/gpu_program_manager.hpp" +#include "../drape/oglcontextfactory.hpp" + +#include "../drape/uniform_values_storage.hpp" #include "../std/map.hpp" @@ -20,7 +23,10 @@ namespace df public threads::IRoutine { public: - FrontendRenderer(RefPointer commutator); + FrontendRenderer(RefPointer commutator + ,RefPointer oglcontextfactory + , int w, int h); + ~FrontendRenderer(); protected: @@ -28,6 +34,10 @@ namespace df private: void RenderScene(); + void RefreshProjection(int w, int h); + void RefreshModelView(float radians); + + void RenderPartImpl(pair > & node); private: void StartThread(); @@ -44,6 +54,7 @@ namespace df RefPointer m_commutator; MasterPointer m_gpuProgramManager; threads::Thread m_selfThread; + RefPointer m_contextFactory; private: typedef multimap > render_data_t; @@ -53,5 +64,9 @@ namespace df typedef pair tile_data_range_t; render_data_t m_renderData; tile_data_t m_tileData; + + UniformValuesStorage m_generalUniforms; + int m_width; + int m_height; }; }