日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Qt Scene graph画线

發布時間:2025/1/21 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Qt Scene graph画线 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

想要實現在QML中畫線,有幾種方式:
第一種,用在QML中用Canvas來實現畫線功能,經過實踐,效率比較低,折線非常嚴重,特別是在Android手機上運行。
第二種,通過QPainter來繪制,在C++中繼承QQuickItem,然后實現paintEvent事件去繪圖,然后在QML中顯示繪圖層,該方式在桌面端應用效果勉強能接受,但是在Android端效果也很差。
第三種方式就是通過Scene graph來畫線,這是基于OpenGL來渲染圖形,同樣是在C++中繼承QQuickItem,然后實現updatePaintNode函數,再到QML中顯示繪圖層。這種方式在桌面和移動端相對來說表現良好。
本文就來介紹第三種繪圖方式。
先來看看效果圖

正文

這里要實現的效果是,可以進行畫線和擦除,這兩種模式下的實現方式不太一樣,如果用QPainter繪制的話,只需要將線的寬度變大,然后改變繪制顏色和繪制方式,即可實現擦除效果,但是這里不行,因為用scane graph畫線的時候線條寬度不能加太粗,所以無法通過QPainter的模式來實現擦除效果。

來看源碼

頭文件

#include <QPainter> #include <QVector> #include <QPointF> #include <QLineF> #include <QPen> #include <QQuickItemGrabResult> #include <QSharedPointer> #include <QSGSimpleRectNode>class ElementGroup { public:ElementGroup(){}ElementGroup(const QPen &pen): m_pen(pen){}ElementGroup(const ElementGroup &e){m_lines = e.m_lines;m_pen = e.m_pen;}ElementGroup & operator=(const ElementGroup &e){if(this != &e){m_lines = e.m_lines;m_pen = e.m_pen;}return *this;}~ElementGroup(){}QVector<QLineF> m_lines;QPen m_pen; };class ALOpenGLDrawLine : public QQuickItem {Q_OBJECT public:explicit ALOpenGLDrawLine(QQuickItem *parent = 0);QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *);Q_INVOKABLE void setDrawMode(int mode);//設置畫線模式,0為畫線,1為擦除Q_INVOKABLE int getDrawMode(){return m_currentMode;}Q_PROPERTY(QColor penColor READ getPenColor WRITE setPenColor)QColor getPenColor() const {return m_penColor;}void setPenColor(const QColor &c){m_penColor = c;update();}Q_INVOKABLE void clearAll();protected:void mousePressEvent(QMouseEvent *event);void mouseMoveEvent(QMouseEvent *event);void mouseReleaseEvent(QMouseEvent *event);signals:void sigMousePress(QPointF curPoint);void sigMouseMove(QPointF curPoint);void sigMouseRelease(QPointF curPoint);private :QPointF m_lastPoint;QVector<ElementGroup*> m_elements;ElementGroup * m_element;bool m_bPressed;QPen m_pen;int lastlenth;QSGNode *nodeP;bool m_bFlag;int m_nPenWidth; //筆寬QColor m_penColor; //筆顏色int m_currentMode; //0->畫線 1->擦除 };

源文件

#include "alopengldrawline.h" #include <QtQuick/qsgnode.h> #include <QtQuick/qsgflatcolormaterial.h> #include <QFileInfo> #include <QDir> #include "smoothcolormaterial.h"namespace { struct Color4ub {unsigned char r, g, b, a; };inline Color4ub colorToColor4ub(const QColor &c) {Color4ub color = { uchar(c.redF() * c.alphaF() * 255),uchar(c.greenF() * c.alphaF() * 255),uchar(c.blueF() * c.alphaF() * 255),uchar(c.alphaF() * 255)};return color; }struct SmoothVertex {float x, y;Color4ub color;float dx, dy;void set(float nx, float ny, Color4ub ncolor, float ndx, float ndy){x = nx; y = ny; color = ncolor;dx = ndx; dy = ndy;} };const QSGGeometry::AttributeSet &smoothAttributeSet() {static QSGGeometry::Attribute data[] = {QSGGeometry::Attribute::create(0, 2, GL_FLOAT, true),QSGGeometry::Attribute::create(1, 4, GL_UNSIGNED_BYTE, false),QSGGeometry::Attribute::create(2, 2, GL_FLOAT, false)};static QSGGeometry::AttributeSet attrs = { 3, sizeof(SmoothVertex), data };return attrs; } }ALOpenGLDrawLine::ALOpenGLDrawLine(QQuickItem *parent) :QQuickItem(parent),nodeP(NULL),m_bFlag(false),m_nPenWidth(5),m_penColor(QColor(Qt::red)) {setAcceptedMouseButtons(Qt::LeftButton);setFlag(ItemHasContents, true);lastlenth=0;setSmooth(true);setAntialiasing(true);m_currentMode = 0; }QSGNode *ALOpenGLDrawLine::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) {if(!oldNode){nodeP = new QSGNode;}else{nodeP = static_cast<QSGNode *>(oldNode);}QSGGeometryNode *node = 0;QSGGeometry *geometry = 0;if(m_currentMode == 0){node = new QSGGeometryNode;geometry = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), 2);geometry->setLineWidth(m_nPenWidth);geometry->setDrawingMode(GL_LINE_STRIP);node->setGeometry(geometry);node->setFlag(QSGNode::OwnsGeometry);QSGFlatColorMaterial *material = new QSGFlatColorMaterial;material->setColor(m_penColor);node->setMaterial(material);node->setFlag(QSGNode::OwnsMaterial);QSGGeometry::Point2D *vertices ;vertices = geometry->vertexDataAsPoint2D();int size = m_elements.size();ElementGroup *element;for(int k = 0; k < size ; ++k){m_bFlag = true;element = m_elements.at(k);int currentIndex = 0;if(k == size -1){QVector<QLineF>::iterator i;for (i = element->m_lines.begin(); i != element->m_lines.end(); ++i) {currentIndex++;if(element->m_lines.size()>1){if(currentIndex == lastlenth){vertices[0].set(i->p1().rx(),i->p1().ry());}if(currentIndex == element->m_lines.size()){vertices[1].set(i->p1().rx(),i->p1().ry());}}else{vertices[0].set(i->p1().rx(),i->p1().ry());vertices[1].set(i->p2().rx(),i->p2().ry());}}lastlenth = element->m_lines.size();}}node->markDirty(QSGNode::DirtyGeometry);if(m_bFlag){nodeP->appendChildNode(node);m_bFlag = false;}}else{QSGSmoothColorMaterial *material;node = new QSGGeometryNode;geometry = new QSGGeometry(smoothAttributeSet(), 0);geometry->setDrawingMode(GL_TRIANGLE_STRIP);material = new QSGSmoothColorMaterial();node->setGeometry(geometry);node->setFlag(QSGNode::OwnsGeometry);node->setMaterial(material);node->setFlag(QSGNode::OwnsMaterial);int vertexStride = geometry->sizeOfVertex();int vertexCount = 8;geometry->allocate(vertexCount, 0);SmoothVertex *smoothVertices = reinterpret_cast<SmoothVertex *>(geometry->vertexData());memset(smoothVertices, 0, vertexCount * vertexStride);float lineWidth = 100;float tlX,tlY,blX,blY,trX,trY,brX,brY;float delta = lineWidth * 0.8f;Color4ub fillColor = colorToColor4ub(QColor(255,255,255,255));Color4ub transparent = { 0, 0, 0, 0 };int size = m_elements.size();ElementGroup *element;for(int k = 0; k < size ; ++k){element = m_elements.at(k);int currentIndex = 0;if(k == size -1){QVector<QLineF>::iterator i;for (i = element->m_lines.begin(); i != element->m_lines.end(); ++i) {currentIndex++;if(element->m_lines.size()>1){if(currentIndex == lastlenth){tlX = i->p1().rx();tlY = i->p1().ry();}if(currentIndex == element->m_lines.size()){trX = i->p1().rx();trY = i->p1().ry();}}else{tlX = i->p1().rx();tlY = i->p1().ry();trX = i->p2().rx();trY = i->p2().ry();}}lastlenth = element->m_lines.size();}}blX = tlX;blY = tlY + lineWidth;brX = trX;brY = trY + lineWidth;smoothVertices[0].set(trX, trY, transparent, delta, -delta);smoothVertices[1].set(tlX, tlY, transparent, -delta, -delta);smoothVertices[2].set(trX, trY, fillColor, -delta, delta);smoothVertices[3].set(tlX, tlY, fillColor, delta, delta);smoothVertices[4].set(brX, brY, fillColor, -delta, -delta);smoothVertices[5].set(blX, blY, fillColor, delta, -delta);smoothVertices[6].set(brX, brY, transparent, delta, delta);smoothVertices[7].set(blX, blY, transparent, -delta, delta);node->markDirty(QSGNode::DirtyGeometry);nodeP->appendChildNode(node);}return nodeP; }void ALOpenGLDrawLine::setDrawMode(int mode) {m_currentMode = mode;if(mode == 0){m_penColor = QColor(Qt::red);m_nPenWidth = 5;}else if(mode == 1){m_penColor = QColor(Qt::white);m_nPenWidth = 100;}update(); }void ALOpenGLDrawLine::clearAll() {if(nodeP->childCount() > 0){nodeP->removeAllChildNodes();m_elements.clear();update();} }void ALOpenGLDrawLine::mousePressEvent(QMouseEvent *event) {m_bPressed = true;m_element = new ElementGroup(m_pen);m_elements.append(m_element);m_lastPoint = event->localPos();event->setAccepted(true);emit sigMousePress(event->localPos()); }void ALOpenGLDrawLine::mouseMoveEvent(QMouseEvent *event) {if(m_bPressed){m_element->m_lines.append(QLineF(m_lastPoint, event->localPos()));m_lastPoint = event->localPos();update();emit sigMouseMove(event->localPos());}event->setAccepted(true); }void ALOpenGLDrawLine::mouseReleaseEvent(QMouseEvent *event) {m_bPressed = false;m_elements.removeFirst();emit sigMouseRelease(event->localPos());event->setAccepted(true); }

(部分代碼摘自網絡)
代碼中還用到了QSGSmoothColorMaterialShader這個類,這是實現類用于實現陰影效果的,主要針對擦除的模式。
來看看代碼
頭文件

class QSGSmoothColorMaterial : public QSGMaterial { public:QSGSmoothColorMaterial();int compare(const QSGMaterial *other) const; protected:virtual QSGMaterialType *type() const;virtual QSGMaterialShader *createShader() const; };//----------------------------------------------------------------------class QSGSmoothColorMaterialShader : public QSGMaterialShader { public:QSGSmoothColorMaterialShader();virtual void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect);virtual char const *const *attributeNames() const; private:void initialize();int m_matrixLoc;int m_opacityLoc;int m_pixelSizeLoc; };

源文件

#include "smoothcolormaterial.h"QSGSmoothColorMaterial::QSGSmoothColorMaterial() {setFlag(RequiresFullMatrixExceptTranslate, true);setFlag(Blending, true); }int QSGSmoothColorMaterial::compare(const QSGMaterial *other) const {Q_UNUSED(other)return 0; }QSGMaterialType *QSGSmoothColorMaterial::type() const {static QSGMaterialType type;return &type; }QSGMaterialShader *QSGSmoothColorMaterial::createShader() const {return new QSGSmoothColorMaterialShader(); }//----------------------------------------------------------------------QSGSmoothColorMaterialShader::QSGSmoothColorMaterialShader(): QSGMaterialShader() {setShaderSourceFile(QOpenGLShader::Vertex, QStringLiteral(":/shaders/smoothcolor.vert"));setShaderSourceFile(QOpenGLShader::Fragment, QStringLiteral(":/shaders/smoothcolor.frag")); }void QSGSmoothColorMaterialShader::updateState(const QSGMaterialShader::RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect) {Q_UNUSED(newEffect)if (state.isOpacityDirty())program()->setUniformValue(m_opacityLoc, state.opacity());if (state.isMatrixDirty())program()->setUniformValue(m_matrixLoc, state.combinedMatrix());if (oldEffect == 0) {// The viewport is constant, so set the pixel size uniform only once.QRect r = state.viewportRect();program()->setUniformValue(m_pixelSizeLoc, 2.0f / r.width(), 2.0f / r.height());} }const char * const *QSGSmoothColorMaterialShader::attributeNames() const {static char const *const attributes[] = {"vertex","vertexColor","vertexOffset",0};return attributes; }void QSGSmoothColorMaterialShader::initialize() {m_matrixLoc = program()->uniformLocation("matrix");m_opacityLoc = program()->uniformLocation("opacity");m_pixelSizeLoc = program()->uniformLocation("pixelSize"); }

main函數實現

#include <QGuiApplication> #include <QQmlApplicationEngine> #include <QQuickView> #include <QSurfaceFormat> #include "alopengldrawline.h"int main(int argc, char *argv[]) {QGuiApplication app(argc, argv);qmlRegisterType<ALOpenGLDrawLine>("OpenGLDrawLine", 1, 0, "OpenGLDrawLine");QQuickView view;QSurfaceFormat format = view.format();format.setSamples(16);view.setFormat(format);view.setResizeMode(QQuickView::SizeRootObjectToView);view.setSource(QUrl("qrc:/main.qml"));view.show();return app.exec(); }

main.qml實現

import QtQuick 2.6 import QtQuick.Window 2.2 import OpenGLDrawLine 1.0 import QtQuick.Controls 2.1Item {visible: truewidth: 800height: 600OpenGLDrawLine{id:drawLineanchors.fill: parent}Column{anchors.top: parent.topanchors.horizontalCenter: parent.horizontalCenterspacing: 15Button{width: 100height: 50text:"畫線"onClicked: {drawLine.setDrawMode(0)}}Button{width: 100height: 50text:"擦除"onClicked: {drawLine.setDrawMode(1)}}} }

完整工程在這里,點擊下載

與50位技術專家面對面20年技術見證,附贈技術全景圖

總結

以上是生活随笔為你收集整理的Qt Scene graph画线的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 国产精品久草 | 国产情侣酒店自拍 | 免费看的av | 日韩爱爱免费视频 | 欧美性大战久久久久xxx | 日本高清视频一区二区 | 成年人观看视频 | 久操伊人| 国产aa大片 | 伊人avav| 永久免费看片 | 久草福利资源 | 日韩成人在线影院 | 亚洲一区二区三区高清 | 免费一区二区在线观看 | 经典杯子蛋糕日剧在线观看免费 | 久久精品视频观看 | zzjj国产精品一区二区 | 国产精品theporn动漫 | 在线v | 91色啪| 日韩一区二区三区在线观看 | 日韩激情啪啪 | 色站综合| 99ri国产 | 美日韩三级 | 日本夜夜操 | 免费观看在线播放 | 亚洲精品成人无码毛片 | 亚洲最大av网站 | 思思99精品视频在线观看 | 欧洲精品一区二区 | 献给魔王伊伏洛基亚吧动漫在线观看 | 国内一区二区 | 蜜臀少妇久久久久久久高潮 | 羞视频在线观看 | 国产精品无码免费专区午夜 | 69日影院 | 国产精品理论片在线观看 | 欧美女同视频 | 99蜜桃臀久久久欧美精品网站 | 国产精品亚洲天堂 | av在线不卡网 | 快播在线视频 | 欧美综合一区二区三区 | 国产中文字幕一区 | 青青草原亚洲视频 | 欧美日韩黄色一级片 | 免费操人视频 | 国产欧美a | 国产精品夜夜夜爽阿娇 | 成都免费高清电影 | 亚洲色图25p| 久色视频在线观看 | 欧美日韩精品一区二区三区蜜桃 | 不卡视频在线观看 | 色姑娘天天操 | 午夜香蕉 | 少妇视频 | 樱花影院电视剧免费 | 亚洲色图13p| 亚洲日本网站 | 成人区人妻精品一区 | 中国美女一级片 | 欧美视频91 | 国产吞精囗交免费视频 | 在线不卡日韩 | 三级黄色在线播放 | 中文字幕一区在线 | 夜夜爽妓女8888视频免费观看 | 色插综合 | 国产一级做a爰片久久毛片男男 | 成人77777| 一道本av | 污免费在线观看 | 丰满少妇一区二区三区专区 | 亚洲AV无码一区二区伊人久久 | 天堂视频一区 | 高清性爱视频 | jizz免费观看 | 久久一区二区三 | 香蕉在线播放 | 欧美久久一区二区三区 | 国产黄色录像片 | 国产亚洲精品久久久久婷婷瑜伽 | 国产视频日韩 | 成人网页在线观看 | a天堂视频 | 中出视频在线观看 | 国产av不卡一区二区 | 午夜性| 久久y| 国产三级麻豆 | 免费a v视频| 日韩免费影院 | 国产精品女人久久久 | 午夜裸体性播放 | 婷婷射丁香 | 欧美黄色aaa|