日韩性视频-久久久蜜桃-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画线的全部內容,希望文章能夠幫你解決所遇到的問題。

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

主站蜘蛛池模板: 强伦轩人妻一区二区电影 | 欧美日韩综合 | 一本亚洲 | 三年在线观看视频 | 日本亚洲视频 | 香蕉色网 | 91视频最新 | 男女啪啪在线观看 | 亚洲黄色小说图片 | 日本黄色不卡视频 | 国产成人精品免费网站 | 国产精品免费av | 日日夜夜艹| 日韩啊v | 青青草草视频 | 天堂av2019| 国产精品午夜福利视频234区 | 欧美成人免费看 | 欧美成人图区 | 午夜理伦三级理论 | 欧洲精品一区二区三区 | 亚洲欧美偷拍视频 | 中文字幕 日韩 欧美 | 欧美vieox另类极品 | 国产l精品国产亚洲区久久 午夜青青草 | 免费看av的网址 | 黑丝美女av | 夜夜成人| 嫩草私人影院 | 波多野结衣不卡 | 看黄色一级片 | 丰满孕妇性春猛交xx大陆 | 欧美大片免费观看网址 | 777毛片| 91毛片网站 | www.成人在线 | 五月婷婷在线观看视频 | av之家在线 | 侵犯女教师一区二区三区 | 成人午夜淫片100集 伊人久久国产 | 黄色一级播放 | 成人激情开心网 | 欧美成人一区二区视频 | 久草精品在线观看视频 | 午夜av电影在线观看 | 日本学生初尝黑人巨免费视频 | 国产免费激情 | 久久久久亚洲AV成人无在 | 久草香蕉在线 | 黄色性生活一级片 | 久久国产小视频 | 欧美理伦少妇2做爰 | 国产高清在线视频观看 | 中文字幕一区二区三区乱码 | 国产成人免费网站 | 成年人免费在线观看网站 | 久久伊人婷婷 | 亚洲天堂999| 自慰无码一区二区三区 | 亚洲a级精品 | 韩国裸体网站 | 蜜桃臀一区二区三区 | 日韩精品片 | 日韩精品一区二区三区视频 | 日韩欧美不卡在线 | 亚洲AV无码久久精品色三人行 | 免费观看成年人视频 | 欧美9999 | 亚洲精品日本 | 风流少妇 | 白石茉莉奈中文字幕在 | 日本啪啪网 | 亚洲综合区 | 91爱国产 | 污污视频网站免费观看 | 高h捆绑拘束调教小说 | 超污巨黄的小短文 | 蓝牛av| 又污又黄的网站 | 国产精品老熟女视频一区二区 | av短片| 国产区在线看 | 欧美老司机 | 五月天婷婷在线观看 | 欧美性久久久 | 亚洲视频免费观看 | 天天摸天天做天天爽水多 | 毛片基地视频 | 91激情| 国产视频久久久 | 亚洲va韩国va欧美va精品 | 欧美激情爱爱 | 国产精品伦理一区 | 久久亚洲精精品中文字幕早川悠里 | 网址在线观看你懂的 | 精品人妻二区中文字幕 | 日本黄色xxx | 欧美丰满熟妇xxxx | 中文字幕码精品视频网站 |