void update(float _dt) { g_time += _dt; for (auto& ease : m_eases) { if (!ease.finished()) { ease.update(_dt); } } m_inputHandler->update(_dt); m_view->update(); { std::lock_guard<std::mutex> lock(m_tilesMutex); ViewState viewState { m_view->getMapProjection(), m_view->changedOnLastUpdate(), glm::dvec2{m_view->getPosition().x, -m_view->getPosition().y }, m_view->getZoom() }; m_tileManager->updateTileSets(viewState, m_view->getVisibleTiles()); bool updateLabels = m_labels->needUpdate(); auto& tiles = m_tileManager->getVisibleTiles(); if (m_view->changedOnLastUpdate() || m_tileManager->hasTileSetChanged()) { for (const auto& tile : tiles) { tile->update(_dt, *m_view); } updateLabels = true; } if (updateLabels) { auto& cache = m_tileManager->getTileCache(); m_labels->update(*m_view, _dt, m_scene->styles(), tiles, cache); } bool animated = false; for (const auto& style : m_scene->styles()) { if (style->isAnimated()) { animated = true; break; } } if (animated != isContinuousRendering()) { setContinuousRendering(animated); } } }
void render() { // Set up openGL for new frame RenderState::depthWrite(GL_TRUE); auto& color = m_scene->background(); RenderState::clearColor(color.r / 255.f, color.g / 255.f, color.b / 255.f, color.a / 255.f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); { std::lock_guard<std::mutex> lock(m_tilesMutex); // Loop over all styles for (const auto& style : m_scene->styles()) { // Set time uniforms style's shader programs style->getShaderProgram()->setUniformf("u_time", g_time); style->onBeginDrawFrame(*m_view, *m_scene); // Loop over all tiles in m_tileSet for (const auto& tile : m_tileManager->getVisibleTiles()) { tile->draw(*style, *m_view); } style->onEndDrawFrame(); } } m_labels->drawDebug(*m_view); while (Error::hadGlError("Tangram::render()")) {} }
void setPixelScale(float _pixelsPerPoint) { if (m_view) { m_view->setPixelScale(_pixelsPerPoint); } for (auto& style : m_scene->styles()) { style->setPixelScale(_pixelsPerPoint); } }
TileBuilder::TileBuilder(std::shared_ptr<Scene> _scene) : m_scene(_scene) { m_styleContext.initFunctions(*_scene); // Initialize StyleBuilders for (auto& style : _scene->styles()) { m_styleBuilder[style->getName()] = style->createBuilder(); } }
void TileBuilder::setScene(std::shared_ptr<Scene> _scene) { m_scene = _scene; m_styleContext.initFunctions(*_scene); // Initialize StyleBuilders m_styleBuilder.clear(); for (auto& style : _scene->styles()) { m_styleBuilder[style->getName()] = style->createBuilder(); } }
void render() { FrameInfo::beginFrame(); // Invalidate render states for new frame if (!g_cacheGlState) { RenderState::invalidate(); } // Set up openGL for new frame RenderState::depthWrite(GL_TRUE); auto& color = m_scene->background(); RenderState::clearColor(color.r / 255.f, color.g / 255.f, color.b / 255.f, color.a / 255.f); GL_CHECK(glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)); for (const auto& style : m_scene->styles()) { style->onBeginFrame(); } { std::lock_guard<std::mutex> lock(m_tilesMutex); // Loop over all styles for (const auto& style : m_scene->styles()) { style->onBeginDrawFrame(*m_view, *m_scene); // Loop over all tiles in m_tileSet for (const auto& tile : m_tileManager->getVisibleTiles()) { style->draw(*tile); } style->onEndDrawFrame(); } } m_labels->drawDebug(*m_view); FrameInfo::draw(*m_view, *m_tileManager); }
void setScene(std::shared_ptr<Scene>& _scene) { { std::lock_guard<std::mutex> lock(m_sceneMutex); m_scene = _scene; } auto& camera = m_scene->camera(); m_view->setCameraType(camera.type); switch (camera.type) { case CameraType::perspective: m_view->setVanishingPoint(camera.vanishingPoint.x, camera.vanishingPoint.y); if (camera.fovStops) { m_view->setFieldOfViewStops(camera.fovStops); } else { m_view->setFieldOfView(camera.fieldOfView); } break; case CameraType::isometric: m_view->setObliqueAxis(camera.obliqueAxis.x, camera.obliqueAxis.y); break; case CameraType::flat: break; } if (m_scene->useScenePosition) { glm::dvec2 projPos = m_view->getMapProjection().LonLatToMeters(m_scene->startPosition); m_view->setPosition(projPos.x, projPos.y); m_view->setZoom(m_scene->startZoom); } m_inputHandler->setView(m_view); m_tileManager->setDataSources(_scene->dataSources()); m_tileWorker->setScene(_scene); setPixelScale(m_view->pixelScale()); bool animated = m_scene->animated() == Scene::animate::yes; if (m_scene->animated() == Scene::animate::none) { for (const auto& style : m_scene->styles()) { animated |= style->isAnimated(); } } if (animated != isContinuousRendering()) { setContinuousRendering(animated); } }
void update(float _dt) { g_time += _dt; m_inputHandler->update(_dt); m_view->update(); { std::lock_guard<std::mutex> lock(m_tilesMutex); m_tileManager->updateTileSets(); if (m_view->changedOnLastUpdate() || m_tileManager->hasTileSetChanged() || m_labels->needUpdate()) { auto& tiles = m_tileManager->getVisibleTiles(); for (const auto& tile : tiles) { tile->update(_dt, *m_view); } m_labels->update(*m_view, _dt, m_scene->styles(), tiles); } bool animated = false; for (const auto& style : m_scene->styles()) { if (style->isAnimated()) { animated = true; break; } } if (animated != isContinuousRendering()) { setContinuousRendering(animated); } } }
void resize(int _newWidth, int _newHeight) { LOG("resize: %d x %d", _newWidth, _newHeight); glViewport(0, 0, _newWidth, _newHeight); if (m_view) { m_view->setSize(_newWidth, _newHeight); } for (auto& style : m_scene->styles()) { style->viewportHasChanged(); } Primitives::setResolution(_newWidth, _newHeight); while (Error::hadGlError("Tangram::resize()")) {} }
void setupGL() { LOG("setup GL"); if (m_tileManager) { m_tileManager->clearTileSets(); for (auto& style : m_scene->styles()) { style->notifyGLContextLost(); } } // The OpenGL context has been destroyed since the last time resources were created, // so we invalidate all data that depends on OpenGL object handles. // ShaderPrograms are invalidated and immediately rebuilt ShaderProgram::invalidateAllPrograms(); // Buffer objects are invalidated and re-uploaded the next time they are used VboMesh::invalidateAllVBOs(); // Texture objects are invalidated and re-uploaded the next time they are updated Texture::invalidateAllTextures(); // Reconfigure the render states RenderState::configure(); // Set default primitive render color Primitives::setColor(0xffffff); // Load GL extensions GLExtensions::load(); GLExtensions::printAvailableExtensions(); while (Error::hadGlError("Tangram::setupGL()")) {} }
const std::vector<TouchItem>& pickFeaturesAt(float _x, float _y) { return m_labels->getFeaturesAtPoint(*m_view, 0, m_scene->styles(), m_tileManager->getVisibleTiles(), _x, _y); }
bool update(float _dt) { FrameInfo::beginUpdate(); g_time += _dt; bool viewComplete = true; for (auto& ease : m_eases) { if (!ease.finished()) { ease.update(_dt); viewComplete = false; } } size_t nTasks = 0; { std::lock_guard<std::mutex> lock(m_tasksMutex); nTasks = m_tasks.size(); } while (nTasks-- > 0) { std::function<void()> task; { std::lock_guard<std::mutex> lock(m_tasksMutex); task = m_tasks.front(); m_tasks.pop(); } task(); } m_inputHandler->update(_dt); m_view->update(); for (const auto& style : m_scene->styles()) { style->onBeginUpdate(); } { std::lock_guard<std::mutex> lock(m_tilesMutex); ViewState viewState { m_view->getMapProjection(), m_view->changedOnLastUpdate(), glm::dvec2{m_view->getPosition().x, -m_view->getPosition().y }, m_view->getZoom() }; m_tileManager->updateTileSets(viewState, m_view->getVisibleTiles()); auto& tiles = m_tileManager->getVisibleTiles(); if (m_view->changedOnLastUpdate() || m_tileManager->hasTileSetChanged()) { for (const auto& tile : tiles) { tile->update(_dt, *m_view); } m_labels->updateLabelSet(*m_view, _dt, m_scene->styles(), tiles, m_tileManager->getTileCache()); } else { m_labels->updateLabels(*m_view, _dt, m_scene->styles(), tiles); } } FrameInfo::endUpdate(); bool viewChanged = m_view->changedOnLastUpdate(); bool tilesChanged = m_tileManager->hasTileSetChanged(); bool tilesLoading = m_tileManager->hasLoadingTiles(); bool labelsNeedUpdate = m_labels->needUpdate(); bool resourceLoading = (m_scene->m_resourceLoad > 0); bool nextScene = bool(m_nextScene); if (viewChanged || tilesChanged || tilesLoading || labelsNeedUpdate || resourceLoading || nextScene) { viewComplete = false; } // Request for render if labels are in fading in/out states if (m_labels->needUpdate()) { requestRender(); } return viewComplete; }
#include "scene/sceneLoader.h" #include "style/material.h" #include "style/polylineStyle.h" #include "style/polygonStyle.h" #include "style/style.h" #include "yaml-cpp/yaml.h" using namespace Tangram; using YAML::Node; TEST_CASE("Style with the same name as a built-in style are ignored") { std::shared_ptr<Platform> platform = std::make_shared<MockPlatform>(); std::shared_ptr<Scene> scene = std::make_shared<Scene>(platform, Url()); SceneLoader::loadStyle(platform, "polygons", Node(), scene); REQUIRE(scene->styles().size() == 0); } TEST_CASE("Correctly instantiate a style from a YAML configuration") { std::shared_ptr<Platform> platform = std::make_shared<MockPlatform>(); std::shared_ptr<Scene> scene = std::make_shared<Scene>(platform, Url()); scene->styles().emplace_back(new PolygonStyle("polygons")); scene->styles().emplace_back(new PolylineStyle("lines")); YAML::Node node = YAML::Load(R"END( animated: true texcoords: true base: lines mix: tools
void render() { clock_t start, end; if (Tangram::getDebugFlag(Tangram::DebugFlags::tangram_infos)) { start = clock(); } // Set up openGL for new frame RenderState::depthWrite(GL_TRUE); auto& color = m_scene->background(); RenderState::clearColor(color.r / 255.f, color.g / 255.f, color.b / 255.f, color.a / 255.f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); { std::lock_guard<std::mutex> lock(m_tilesMutex); // Loop over all styles for (const auto& style : m_scene->styles()) { // Set time uniforms style's shader programs style->getShaderProgram()->setUniformf("u_time", g_time); style->onBeginDrawFrame(*m_view, *m_scene); // Loop over all tiles in m_tileSet for (const auto& tile : m_tileManager->getVisibleTiles()) { tile->draw(*style, *m_view); } style->onEndDrawFrame(); } } m_labels->drawDebug(*m_view); if (Tangram::getDebugFlag(Tangram::DebugFlags::tangram_infos)) { // Force opengl to finish commands (for accurate frame time) glFinish(); end = clock(); static int cpt = 0; static float totaltime = 0; static float time = 0.f; // Only compute average frame time every 60 frames if (cpt++ > 60) { time = totaltime / float(cpt); totaltime = 0.f; cpt = 0; } totaltime += (float(end - start) / CLOCKS_PER_SEC) * 1000.f; std::vector<std::string> debuginfos; debuginfos.push_back("zoom:" + std::to_string(m_view->getZoom())); debuginfos.push_back("pos:" + std::to_string(m_view->getPosition().x) + "/" + std::to_string(m_view->getPosition().y)); debuginfos.push_back("visible tiles:" + std::to_string(m_tileManager->getVisibleTiles().size())); debuginfos.push_back("tile cache size:" + std::to_string(m_tileManager->getTileCache()->getMemoryUsage() / 1024) + "kb"); debuginfos.push_back("avg frame render time:" + std::to_string(time) + "ms"); size_t memused = 0; for (const auto& tile : m_tileManager->getVisibleTiles()) { memused += tile->getMemoryUsage(); } debuginfos.push_back("tile size:" + std::to_string(memused / 1024) + "kb"); debuginfos.push_back("number of styles:"+ std::to_string(m_scene->styles().size())); TextDisplay::Instance().draw(debuginfos); } while (Error::hadGlError("Tangram::render()")) {} }