使用QSGGeometry绘制圆角矩形填充异常的问题求助
QSGGeometry绘制圆角矩形填充异常的问题排查与修复
问题描述
使用QSGGeometry/QSGFlatColorMaterial绘制直角矩形时显示正常,但绘制圆角矩形时无法正确填充内部区域。尝试设置DrawTriangleFan绘制模式并在多边形开头添加QPointF(150, 150),结果仍不符合预期。
原因分析
- 默认绘制模式不匹配:
QSGGeometry默认使用DrawTriangleStrip模式,该模式仅能正确填充简单凸多边形(如直角矩形),但无法处理带圆弧轮廓的圆角矩形——这类复杂轮廓的顶点序列无法通过三角条带模式生成正确的填充面。 DrawTriangleFan使用错误:之前添加的中心顶点位置(150,150)并非圆角矩形的实际中心,且顶点序列的排列逻辑未匹配扇形绘制的要求(需以中心为起点,外围顶点按统一顺/逆时针顺序排列,无需重复起点)。
修复方案
推荐两种可靠的修复方式:
方式一:正确使用DrawTriangleFan模式
- 以圆角矩形的中心作为第一个顶点
- 按顺时针(或逆时针)顺序排列所有外围顶点(无需重复起点)
- 将几何的绘制模式设置为
QSGGeometry::DrawTriangleFan
示例代码:
QPolygonF polygon; // 添加中心顶点(圆角矩形中心:(115, 115),对应230x230的矩形) polygon << QPointF(115, 115); // 按顺时针顺序添加圆角矩形外围顶点 polygon << QPointF(0, 10) << QPointF(0.78585, 6.10755) << QPointF(2.92893, 2.92893) << QPointF(6.10755, 0.78585) << QPointF(10, 0) << QPointF(220, 0) << QPointF(223.892, 0.78585) << QPointF(227.071, 2.92893) << QPointF(229.214, 6.10755) << QPointF(230, 10) << QPointF(230, 220) << QPointF(229.214, 223.892) << QPointF(227.071, 227.071) << QPointF(223.892, 229.214) << QPointF(220, 230) << QPointF(10, 230) << QPointF(6.10755, 229.214) << QPointF(2.92893, 227.071) << QPointF(0.78585, 223.892) << QPointF(0, 220); QSGGeometry *geometry = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), polygon.count()); // 设置绘制模式为TriangleFan geometry->setDrawingMode(QSGGeometry::DrawTriangleFan); QSGFlatColorMaterial *material = new QSGFlatColorMaterial(); material->setColor(QColor("red")); QSGGeometry::Point2D *vertices = geometry->vertexDataAsPoint2D(); for (int i = 0; i < polygon.count(); i++) { QPointF point = polygon.at(i); vertices[i].set(point.x(), point.y()); }
方式二:使用QPainterPath生成三角化几何数据(更通用)
对于更复杂的图形,直接使用QPainterPath创建圆角矩形,再将路径转换为三角化的顶点数据,确保填充正确:
QPainterPath path; // 创建圆角矩形:x=0, y=0, width=230, height=230, radius=10 path.addRoundedRect(QRectF(0, 0, 230, 230), 10, 10); // 将路径转换为三角化的顶点序列 QList<QSGGeometry::Point2D> vertices; QVector<QPolygonF> polygons = path.toSubpathPolygons(); for (const QPolygonF &poly : polygons) { if (poly.size() > 2) { // 添加子路径的中心顶点 QPointF center = poly.boundingRect().center(); vertices.append(QSGGeometry::Point2D(center.x(), center.y())); // 添加子路径的外围顶点 for (const QPointF &p : poly) { vertices.append(QSGGeometry::Point2D(p.x(), p.y())); } } } QSGGeometry *geometry = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), vertices.size()); geometry->setDrawingMode(QSGGeometry::DrawTriangleFan); memcpy(geometry->vertexData(), vertices.data(), vertices.size() * sizeof(QSGGeometry::Point2D)); QSGFlatColorMaterial *material = new QSGFlatColorMaterial(); material->setColor(QColor("red"));
关键注意点
- 所有填充类的几何绘制,必须确保顶点序列能被当前绘制模式正确解析:
DrawTriangleStrip仅适用于凸多边形,DrawTriangleFan需要中心顶点+有序外围顶点,复杂图形建议使用三角剖分。 - 顶点顺序必须保持统一的顺时针或逆时针方向,避免出现交叉顶点导致填充错误。
内容的提问来源于stack exchange,提问作者posix
相关产品推荐
相关产品推荐

