void Painter::drawClippingMasks(PaintParameters& parameters, const std::map<UnwrappedTileID, ClipID>& stencils) { MBGL_DEBUG_GROUP("clipping masks"); auto& plainShader = parameters.shaders.plain; auto& arrayCoveringPlain = parameters.shaders.coveringPlainArray; mat4 matrix; const GLuint mask = 0b11111111; config.program = plainShader.getID(); config.stencilOp.reset(); config.stencilTest = GL_TRUE; config.depthTest = GL_FALSE; config.depthMask = GL_FALSE; config.colorMask = { GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE }; config.stencilMask = mask; arrayCoveringPlain.bind(plainShader, tileStencilBuffer, BUFFER_OFFSET_0, store); for (const auto& stencil : stencils) { const auto& id = stencil.first; const auto& clip = stencil.second; MBGL_DEBUG_GROUP(std::string{ "mask: " } + util::toString(id)); state.matrixFor(matrix, id); matrix::multiply(matrix, projMatrix, matrix); plainShader.u_matrix = matrix; const GLint ref = (GLint)(clip.reference.to_ulong()); config.stencilFunc = { GL_ALWAYS, ref, mask }; MBGL_CHECK_ERROR(glDrawArrays(GL_TRIANGLES, 0, (GLsizei)tileStencilBuffer.index())); } }
void Painter::renderTileDebug(const RenderTile& renderTile) { if (frame.debugOptions == MapDebugOptions::NoDebug) return; MBGL_DEBUG_GROUP(std::string { "debug " } + util::toString(renderTile.id)); auto draw = [&] (Color color, const auto& vertexBuffer, const auto& indexBuffer, const auto& segments, auto drawMode) { programs->debug.draw( context, drawMode, gl::DepthMode::disabled(), stencilModeForClipping(renderTile.clip), gl::ColorMode::unblended(), DebugProgram::UniformValues { uniforms::u_matrix::Value{ renderTile.matrix }, uniforms::u_color::Value{ color } }, vertexBuffer, indexBuffer, segments ); }; if (frame.debugOptions & (MapDebugOptions::Timestamps | MapDebugOptions::ParseStatus)) { Tile& tile = renderTile.tile; if (!tile.debugBucket || tile.debugBucket->renderable != tile.isRenderable() || tile.debugBucket->complete != tile.isComplete() || !(tile.debugBucket->modified == tile.modified) || !(tile.debugBucket->expires == tile.expires) || tile.debugBucket->debugMode != frame.debugOptions) { tile.debugBucket = std::make_unique<DebugBucket>( tile.id, tile.isRenderable(), tile.isComplete(), tile.modified, tile.expires, frame.debugOptions, context); } draw(Color::white(), *tile.debugBucket->vertexBuffer, *tile.debugBucket->indexBuffer, tile.debugBucket->segments, gl::Lines { 4.0f * frame.pixelRatio }); draw(Color::black(), *tile.debugBucket->vertexBuffer, *tile.debugBucket->indexBuffer, tile.debugBucket->segments, gl::Lines { 2.0f * frame.pixelRatio }); } if (frame.debugOptions & MapDebugOptions::TileBorders) { draw(Color::red(), tileVertexBuffer, tileBorderIndexBuffer, tileBorderSegments, gl::LineStrip { 4.0f * frame.pixelRatio }); } }
void Painter::renderTileDebug(const RenderTile& tile) { MBGL_DEBUG_GROUP(std::string { "debug " } + util::toString(tile.id)); if (frame.debugOptions != MapDebugOptions::NoDebug) { setClipping(tile.clip); if (frame.debugOptions & (MapDebugOptions::Timestamps | MapDebugOptions::ParseStatus)) { renderDebugText(tile.tile, tile.matrix); } if (frame.debugOptions & MapDebugOptions::TileBorders) { renderDebugFrame(tile.matrix); } } }
void Painter::renderDebugFrame(const mat4 &matrix) { MBGL_DEBUG_GROUP("debug frame"); // Disable depth test and don't count this towards the depth buffer, // but *don't* disable stencil test, as we want to clip the red tile border // to the tile viewport. config.depthTest = GL_FALSE; config.stencilOp.reset(); config.stencilTest = GL_TRUE; auto& plainShader = *shader.plain; config.program = plainShader.getID(); plainShader.u_matrix = matrix; plainShader.u_opacity = 1.0f; // draw tile outline tileBorderArray.bind(plainShader, tileBorderBuffer, BUFFER_OFFSET_0, store); plainShader.u_color = { 1.0f, 0.0f, 0.0f, 1.0f }; config.lineWidth = 4.0f * frame.pixelRatio; MBGL_CHECK_ERROR(glDrawArrays(GL_LINE_STRIP, 0, (GLsizei)tileBorderBuffer.index())); }
void Painter::renderDebugText(Tile& tile, const mat4 &matrix) { MBGL_DEBUG_GROUP("debug text"); config.depthTest = GL_FALSE; if (!tile.debugBucket || tile.debugBucket->renderable != tile.isRenderable() || tile.debugBucket->complete != tile.isComplete() || !(tile.debugBucket->modified == tile.modified) || !(tile.debugBucket->expires == tile.expires) || tile.debugBucket->debugMode != frame.debugOptions) { tile.debugBucket = std::make_unique<DebugBucket>( tile.id, tile.isRenderable(), tile.isComplete(), tile.modified, tile.expires, frame.debugOptions); } auto& plainShader = *shader.plain; config.program = plainShader.getID(); plainShader.u_matrix = matrix; plainShader.u_opacity = 1.0f; // Draw white outline plainShader.u_color = Color::white(); config.lineWidth = 4.0f * frame.pixelRatio; tile.debugBucket->drawLines(plainShader, store); #ifndef GL_ES_VERSION_2_0 // Draw line "end caps" MBGL_CHECK_ERROR(glPointSize(2)); tile.debugBucket->drawPoints(plainShader, store); #endif // Draw black text. plainShader.u_color = Color::black(); config.lineWidth = 2.0f * frame.pixelRatio; tile.debugBucket->drawLines(plainShader, store); config.depthFunc.reset(); config.depthTest = GL_TRUE; }