void Painter::render(const Style& style, const std::set<util::ptr<StyleSource>>& sources, TransformState state_, std::chrono::steady_clock::time_point time) { state = state_; clear(); resize(); changeMatrix(); // Update all clipping IDs. ClipIDGenerator generator; for (const auto& source : sources) { generator.update(source->source->getLoadedTiles()); source->source->updateMatrices(projMatrix, state); } drawClippingMasks(sources); frameHistory.record(time, state.getNormalizedZoom()); // Actually render the layers if (debug::renderTree) { Log::Info(Event::Render, "{"); indent++; } if (style.layers) { renderLayers(*style.layers); } if (debug::renderTree) { Log::Info(Event::Render, "}"); indent--; } // Finalize the rendering, e.g. by calling debug render calls per tile. // This guarantees that we have at least one function per tile called. // When only rendering layers via the stylesheet, it's possible that we don't // ever visit a tile during rendering. for (const auto& source : sources) { source->source->finishRender(*this); } }
void Map::updateRenderState() { // Update all clipping IDs. ClipIDGenerator generator; for (const std::shared_ptr<StyleSource> &source : getActiveSources()) { generator.update(source->source->getLoadedTiles()); source->source->updateMatrices(painter.projMatrix, state); } }
void Painter::render(const Style& style, TransformState state_, const FrameData& frame_) { state = state_; frame = frame_; glyphAtlas = style.glyphAtlas.get(); spriteAtlas = style.spriteAtlas.get(); lineAtlas = style.lineAtlas.get(); std::set<Source*> sources; for (const auto& source : style.sources) { if (source->enabled) { sources.insert(source.get()); } } resize(); changeMatrix(); // - UPLOAD PASS ------------------------------------------------------------------------------- // Uploads all required buffers and images before we do any actual rendering. { MBGL_DEBUG_GROUP("upload"); tileStencilBuffer.upload(); tileBorderBuffer.upload(); spriteAtlas->upload(); lineAtlas->upload(); glyphAtlas->upload(); for (const auto& item : order) { if (item.bucket && item.bucket->needsUpload()) { item.bucket->upload(); } } } // - CLIPPING MASKS ---------------------------------------------------------------------------- // Draws the clipping masks to the stencil buffer. { MBGL_DEBUG_GROUP("clip"); // Update all clipping IDs. ClipIDGenerator generator; for (const auto& source : sources) { generator.update(source->getLoadedTiles()); source->updateMatrices(projMatrix, state); } clear(); drawClippingMasks(sources); } frameHistory.record(data.getAnimationTime(), state.getNormalizedZoom()); // Actually render the layers if (debug::renderTree) { Log::Info(Event::Render, "{"); indent++; } // TODO: Correctly compute the number of layers recursively beforehand. depthRangeSize = 1 - (order.size() + 2) * numSublayers * depthEpsilon; // - OPAQUE PASS ------------------------------------------------------------------------------- // Render everything top-to-bottom by using reverse iterators. Render opaque objects first. renderPass(RenderPass::Opaque, order.rbegin(), order.rend(), 0, 1); // - TRANSLUCENT PASS -------------------------------------------------------------------------- // Make a second pass, rendering translucent objects. This time, we render bottom-to-top. renderPass(RenderPass::Translucent, order.begin(), order.end(), static_cast<GLsizei>(order.size()) - 1, -1); if (debug::renderTree) { Log::Info(Event::Render, "}"); indent--; } // - DEBUG PASS -------------------------------------------------------------------------------- // Renders debug overlays. { MBGL_DEBUG_GROUP("debug"); // Finalize the rendering, e.g. by calling debug render calls per tile. // This guarantees that we have at least one function per tile called. // When only rendering layers via the stylesheet, it's possible that we don't // ever visit a tile during rendering. for (const auto& source : sources) { source->finishRender(*this); } } // TODO: Find a better way to unbind VAOs after we're done with them without introducing // unnecessary bind(0)/bind(N) sequences. { MBGL_DEBUG_GROUP("cleanup"); MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, 0)); MBGL_CHECK_ERROR(VertexArrayObject::Unbind()); } if (data.contextMode == GLContextMode::Shared) { config.setDirty(); } }
void Painter::render(const Style& style, const FrameData& frame_, SpriteAtlas& annotationSpriteAtlas) { frame = frame_; glyphAtlas = style.glyphAtlas.get(); spriteAtlas = style.spriteAtlas.get(); lineAtlas = style.lineAtlas.get(); RenderData renderData = style.getRenderData(); const std::vector<RenderItem>& order = renderData.order; const std::set<Source*>& sources = renderData.sources; const Color& background = renderData.backgroundColor; // Update the default matrices to the current viewport dimensions. state.getProjMatrix(projMatrix); // The extrusion matrix. matrix::ortho(extrudeMatrix, 0, state.getWidth(), state.getHeight(), 0, 0, -1); // The native matrix is a 1:1 matrix that paints the coordinates at the // same screen position as the vertex specifies. matrix::identity(nativeMatrix); matrix::multiply(nativeMatrix, projMatrix, nativeMatrix); // - UPLOAD PASS ------------------------------------------------------------------------------- // Uploads all required buffers and images before we do any actual rendering. { MBGL_DEBUG_GROUP("upload"); tileStencilBuffer.upload(glObjectStore); tileBorderBuffer.upload(glObjectStore); spriteAtlas->upload(glObjectStore); lineAtlas->upload(glObjectStore); glyphAtlas->upload(glObjectStore); annotationSpriteAtlas.upload(glObjectStore); for (const auto& item : order) { if (item.bucket && item.bucket->needsUpload()) { item.bucket->upload(glObjectStore); } } } // - CLEAR ------------------------------------------------------------------------------------- // Renders the backdrop of the OpenGL view. This also paints in areas where we don't have any // tiles whatsoever. { MBGL_DEBUG_GROUP("clear"); config.stencilFunc.reset(); config.stencilTest = GL_TRUE; config.stencilMask = 0xFF; config.depthTest = GL_FALSE; config.depthMask = GL_TRUE; config.colorMask = { GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE }; config.clearColor = { background[0], background[1], background[2], background[3] }; config.clearStencil = 0; config.clearDepth = 1; MBGL_CHECK_ERROR(glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)); } // - CLIPPING MASKS ---------------------------------------------------------------------------- // Draws the clipping masks to the stencil buffer. { MBGL_DEBUG_GROUP("clip"); // Update all clipping IDs. ClipIDGenerator generator; for (const auto& source : sources) { generator.update(source->getLoadedTiles()); source->updateMatrices(projMatrix, state); } drawClippingMasks(generator.getStencils()); } frameHistory.record(data.getAnimationTime(), state.getZoom()); // Actually render the layers if (debug::renderTree) { Log::Info(Event::Render, "{"); indent++; } // TODO: Correctly compute the number of layers recursively beforehand. depthRangeSize = 1 - (order.size() + 2) * numSublayers * depthEpsilon; // - OPAQUE PASS ------------------------------------------------------------------------------- // Render everything top-to-bottom by using reverse iterators. Render opaque objects first. renderPass(RenderPass::Opaque, order.rbegin(), order.rend(), 0, 1); // - TRANSLUCENT PASS -------------------------------------------------------------------------- // Make a second pass, rendering translucent objects. This time, we render bottom-to-top. renderPass(RenderPass::Translucent, order.begin(), order.end(), static_cast<GLsizei>(order.size()) - 1, -1); if (debug::renderTree) { Log::Info(Event::Render, "}"); indent--; } // - DEBUG PASS -------------------------------------------------------------------------------- // Renders debug overlays. { MBGL_DEBUG_GROUP("debug"); // Finalize the rendering, e.g. by calling debug render calls per tile. // This guarantees that we have at least one function per tile called. // When only rendering layers via the stylesheet, it's possible that we don't // ever visit a tile during rendering. for (const auto& source : sources) { source->finishRender(*this); } } // TODO: Find a better way to unbind VAOs after we're done with them without introducing // unnecessary bind(0)/bind(N) sequences. { MBGL_DEBUG_GROUP("cleanup"); MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, 0)); MBGL_CHECK_ERROR(VertexArrayObject::Unbind()); } if (data.contextMode == GLContextMode::Shared) { config.setDirty(); } }
void updateClipIDs(ClipIDGenerator& generator) { generator.update(tiles); }