void PEQGraph::_drawHumpSolid(QSGNode * parentNode, int n, QColor color) { //Transparent shaded part// QSGGeometryNode * solidNode = new QSGGeometryNode(); QSGGeometry * solidGeom = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), 2 * (HorizontalDivisions + 1)); QSGFlatColorMaterial *material = new QSGFlatColorMaterial; material->setColor(color); material->setFlag(QSGMaterial::Blending); solidNode->setMaterial(material); solidNode->setFlag(QSGNode::OwnsGeometry); solidNode->setFlag(QSGNode::OwnedByParent); solidNode->setFlag(QSGNode::OwnsMaterial); solidGeom->setDrawingMode(GL_TRIANGLE_STRIP); QSGGeometry::Point2D* point = solidGeom->vertexDataAsPoint2D(); float left = graphToNodeX(xAxis.min); float mid = graphToNodeY(0); float width = graphToNodeX(xAxis.max) - graphToNodeX(xAxis.min); float stride = width / HorizontalDivisions; for (int i = 0; i < HorizontalDivisions + 1; i++) { point->set(left + i*stride, mid); point++; point->set(left + i*stride, graphToNodeY(computedData[i][n])); point++; } solidNode->setGeometry(solidGeom); parentNode->appendChildNode(solidNode); }
void PEQGraph::_drawHumpOutline(QSGNode * parentNode, int n, QColor color) { //Solid Outline QSGGeometryNode * lineNode = new QSGGeometryNode(); QSGGeometry * lineGeom = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), (HorizontalDivisions)); QSGFlatColorMaterial *material2 = new QSGFlatColorMaterial; material2->setColor(color); material2->setFlag(QSGMaterial::Blending); lineNode->setMaterial(material2); lineNode->setFlag(QSGNode::OwnsGeometry); lineNode->setFlag(QSGNode::OwnedByParent); lineNode->setFlag(QSGNode::OwnsMaterial); lineGeom->setDrawingMode(GL_LINE_STRIP); glLineWidth(2.0f); QSGGeometry::Point2D* point2 = lineGeom->vertexDataAsPoint2D(); float left = graphToNodeX(xAxis.min); float width = graphToNodeX(xAxis.max) - graphToNodeX(xAxis.min); float stride = width / HorizontalDivisions; for (int i = 0; i < HorizontalDivisions; i++) { float x1 = left + (i)*stride; float y1 = graphToNodeY(computedData[i][n]); point2->set(x1, y1); point2++; } lineNode->setGeometry(lineGeom); parentNode->appendChildNode(lineNode); }
QSGNode *PhosphorRender::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) { if (!m_ybuffer) { return 0; } QSGGeometryNode *node = 0; QSGGeometry *geometry = 0; Material *material = 0; unsigned n_points; if (m_xbuffer) { n_points = std::min(m_xbuffer->size(), m_ybuffer->size()); } else { n_points = m_ybuffer->countPointsBetween(m_xmin, m_xmax); } n_points = std::min(n_points,(unsigned) 65767); if (!oldNode) { node = new QSGGeometryNode; geometry = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), n_points); geometry->setDrawingMode(GL_POINTS); node->setGeometry(geometry); node->setFlag(QSGNode::OwnsGeometry); material = new Material; material->setFlag(QSGMaterial::Blending); node->setMaterial(material); node->setFlag(QSGNode::OwnsMaterial); } else { node = static_cast<QSGGeometryNode *>(oldNode); geometry = node->geometry(); geometry->allocate(n_points); geometry->setLineWidth(m_pointSize); material = static_cast<Material*>(node->material()); } QRectF bounds = boundingRect(); material->transformation.setToIdentity(); material->transformation.scale(bounds.width()/(m_xmax - m_xmin), bounds.height()/(m_ymin - m_ymax)); material->transformation.translate(-m_xmin, -m_ymax); material->pointSize = m_pointSize; material->color = m_color; auto verticies = geometry->vertexDataAsPoint2D(); if (m_xbuffer) { for (unsigned i=0; i<n_points; i++) { verticies[i].set(m_xbuffer->get(i), m_ybuffer->get(i)); } } else { m_ybuffer->toVertexData(m_xmin, m_xmax, verticies, n_points); } node->markDirty(QSGNode::DirtyGeometry | QSGNode::DirtyMaterial); return node; }
/*------------------------------------------------------------------------------ | OMX_CameraSurfaceElement::updatePaintNode +-----------------------------------------------------------------------------*/ QSGNode* OMX_CameraSurfaceElement::updatePaintNode(QSGNode* oldNode, UpdatePaintNodeData*) { QSGGeometryNode* node = 0; QSGGeometry* geometry = 0; if (!oldNode) { // Create the node. node = new QSGGeometryNode; geometry = new QSGGeometry(QSGGeometry::defaultAttributes_TexturedPoint2D(), 4); geometry->setDrawingMode(GL_TRIANGLE_STRIP); node->setGeometry(geometry); node->setFlag(QSGNode::OwnsGeometry); // TODO: Who is freeing this? // TODO: I cannot know the texture size here. QSGOpaqueTextureMaterial* material = new QSGOpaqueTextureMaterial; m_sgtexture = new OMX_SGTexture(0, QSize(640, 480)); material->setTexture(m_sgtexture); node->setMaterial(material); node->setFlag(QSGNode::OwnsMaterial); QtConcurrent::run(this, &OMX_CameraSurfaceElement::videoAcquire); } else { node = static_cast<QSGGeometryNode*>(oldNode); geometry = node->geometry(); geometry->allocate(4); // Update texture in the node if needed. QSGOpaqueTextureMaterial* material = (QSGOpaqueTextureMaterial*)node->material(); QElapsedTimer timer; timer.start(); QSGTexture* texture = window()->createTextureFromImage(m_frame); LOG_VERBOSE(LOG_TAG, "Timer tex: %lld.", timer.elapsed()); material->setTexture(texture); m_semAcquire.release(); #if 0 if (m_texture != (GLuint)material->texture()->textureId()) { // TODO: Does setTextureId frees the prev texture? // TODO: I should the given the texture size. LOG_ERROR(LOG_TAG, "Updating texture to %u!", m_texture); material = new QSGOpaqueTextureMaterial; m_sgtexture->setTexture(m_texture, QSize(1920, 1080)); } #endif } // Create the vertices and map to texture. QRectF bounds = boundingRect(); QSGGeometry::TexturedPoint2D* vertices = geometry->vertexDataAsTexturedPoint2D(); vertices[0].set(bounds.x(), bounds.y() + bounds.height(), 0.0f, 0.0f); vertices[1].set(bounds.x() + bounds.width(), bounds.y() + bounds.height(), 1.0f, 0.0f); vertices[2].set(bounds.x(), bounds.y(), 0.0f, 1.0f); vertices[3].set(bounds.x() + bounds.width(), bounds.y(), 1.0f, 1.0f); return node; }
QSGNode * QQuickLineItem::updatePaintNode(QSGNode *prev_node, UpdatePaintNodeData *upd_data) { Q_UNUSED(upd_data); QSGGeometryNode * node = static_cast<QSGGeometryNode*>(prev_node); QSGGeometry * geometry = NULL; QSGFlatColorMaterial * material = NULL; if(!node) { // http://qt-project.org/doc/qt-5/qsggeometrynode.html node = new QSGGeometryNode; geometry = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(),4); geometry->setDrawingMode(GL_TRIANGLE_STRIP); node->setGeometry(geometry); node->setFlag(QSGNode::OwnsGeometry); material = new QSGFlatColorMaterial; material->setColor(m_color); node->setMaterial(material); node->setFlag(QSGNode::OwnsMaterial); } else { geometry = node->geometry(); geometry->allocate(4); // we have to call allocate to invalidate // the older vertex buffer material = static_cast<QSGFlatColorMaterial*>(node->material()); } // geometry std::vector<QPointF> list_vx; if(!calcTriStrip(list_vx)) { list_vx.clear(); list_vx.push_back(QPointF(0,0)); list_vx.push_back(QPointF(0,0)); list_vx.push_back(QPointF(0,0)); list_vx.push_back(QPointF(0,0)); } QSGGeometry::Point2D * vertices = geometry->vertexDataAsPoint2D(); for(size_t i=0; i < list_vx.size(); i++) { vertices[i].set(list_vx[i].x(), list_vx[i].y()); } node->markDirty(QSGNode::DirtyGeometry); // material material->setColor(m_color); node->markDirty(QSGNode::DirtyMaterial); return node; }
void SceneGraphDeviceContext::DrawComplexBezierPath(vrv::Point bezier1[4], vrv::Point bezier2[4]) { // Note: No support for vertex antialiasing. Use a top-level QQuickView with multisample antialiasing. // TODO: Add vertex antialiasing, refer to // 1) Qt sources for "void QSGBasicInternalRectangleNode::updateGeometry()" in // qtdeclarative/src/quick/scenegraph/qsgbasicinternalrectanglenode.cpp // 2) https://stackoverflow.com/questions/28125425/smooth-painting-in-custom-qml-element vrv::Pen currentPen = m_penStack.top(); int segmentCount = 16; QSGGeometryNode *node = new QSGGeometryNode; QSGGeometry *geometry = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), 2 * segmentCount); geometry->setDrawingMode(QSGGeometry::DrawTriangleStrip); node->setGeometry(geometry); node->setFlag(QSGNode::OwnsGeometry); QSGFlatColorMaterial *material = new QSGFlatColorMaterial; material->setColor(static_cast<QRgb>(currentPen.GetColour())); node->setMaterial(material); node->setFlag(QSGNode::OwnsMaterial); auto calculateCubicBezierPoint = [](vrv::Point p[4], float t) -> std::tuple<float, float> { auto invt = 1 - t; auto x = invt * invt * invt * p[0].x + 3 * invt * invt * t * p[1].x + 3 * invt * t * t * p[2].x + t * t * t * p[3].x; auto y = invt * invt * invt * p[0].y + 3 * invt * invt * t * p[1].y + 3 * invt * t * t * p[2].y + t * t * t * p[3].y; return std::make_tuple(x, y); }; // This loop calculates the bezier points for the inner and the outer line and add them as vertices. The list of // vertices is built so that points from the inner and outer line are alternating. This allows to draw a filled area // with DrawTriangleStrip. QSGGeometry::Point2D *vertices = geometry->vertexDataAsPoint2D(); for (int i = 0; i < segmentCount; ++i) { float bezierPointX = 0; float bezierPointY = 0; float currentSegment = i / static_cast<float>(segmentCount - 1); // Calculate bezier point on bezier1 std::tie(bezierPointX, bezierPointY) = calculateCubicBezierPoint(bezier1, currentSegment); vertices[i * 2].set(translateX(bezierPointX), translateY(bezierPointY)); // Calculate bezier point on bezier2 std::tie(bezierPointX, bezierPointY) = calculateCubicBezierPoint(bezier2, currentSegment); vertices[i * 2 + 1].set(translateX(bezierPointX), translateY(bezierPointY)); } node->markDirty(QSGNode::DirtyGeometry); AddGeometryNode(node); }
//! [4] QSGNode *BezierCurve::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) { QSGGeometryNode *node = 0; QSGGeometry *geometry = 0; if (!oldNode) { node = new QSGGeometryNode; //! [4] //! [5] geometry = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), m_segmentCount); geometry->setLineWidth(2); geometry->setDrawingMode(GL_LINE_STRIP); node->setGeometry(geometry); node->setFlag(QSGNode::OwnsGeometry); //! [5] //! [6] QSGFlatColorMaterial *material = new QSGFlatColorMaterial; material->setColor(QColor(255, 0, 0)); node->setMaterial(material); node->setFlag(QSGNode::OwnsMaterial); //! [6] //! [7] } else { node = static_cast<QSGGeometryNode *>(oldNode); geometry = node->geometry(); geometry->allocate(m_segmentCount); } //! [7] //! [8] QRectF bounds = boundingRect(); QSGGeometry::Point2D *vertices = geometry->vertexDataAsPoint2D(); for (int i = 0; i < m_segmentCount; ++i) { qreal t = i / qreal(m_segmentCount - 1); qreal invt = 1 - t; QPointF pos = invt * invt * invt * m_p1 + 3 * invt * invt * t * m_p2 + 3 * invt * t * t * m_p3 + t * t * t * m_p4; float x = bounds.x() + pos.x() * bounds.width(); float y = bounds.y() + pos.y() * bounds.height(); vertices[i].set(x, y); } node->markDirty(QSGNode::DirtyGeometry); //! [8] //! [9] return node; }
void DynamicController::drawGateCompressor(QSGNode * rootNode) { if (knobs.count() == 0) { return; } //Update knobs if (!this->simple()) { QObject * gateKnob = knobs[0]; QObject * compThreshKnob = knobs[1]; QObject * compRatioKnob = knobs[2]; gateKnob->setProperty("x", graphToNodeX(_tempModel["gatex"])); gateKnob->setProperty("y", graphToNodeY(_tempModel["gatey"])); compThreshKnob->setProperty("x", graphToNodeX(_tempModel["compx"])); compThreshKnob->setProperty("y", graphToNodeY(_tempModel["compy"])); compRatioKnob->setProperty("x", graphToNodeX(xAxis.max)); compRatioKnob->setProperty("y", graphToNodeY(_tempModel["compy"]) * (1 - _tempModel["ratio"])); } QSGGeometryNode * lineNode = new QSGGeometryNode(); QSGGeometry * lineGeom = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), (4)); QSGFlatColorMaterial *material = new QSGFlatColorMaterial; material->setColor(this->curveColor()); material->setFlag(QSGMaterial::Blending); lineNode->setMaterial(material); lineNode->setFlag(QSGNode::OwnsGeometry); lineNode->setFlag(QSGNode::OwnedByParent); lineNode->setFlag(QSGNode::OwnsMaterial); lineGeom->setDrawingMode(GL_LINE_STRIP); glLineWidth(2.0f); QSGGeometry::Point2D* points = lineGeom->vertexDataAsPoint2D(); QRectF bounds = boundingRect(); points->set(graphToNodeX(_tempModel["gatex"]), bounds.bottom()); points++; points->set(graphToNodeX(_tempModel["gatex"]), graphToNodeY(_tempModel["gatey"])); points++; points->set(graphToNodeX(_tempModel["compx"]), graphToNodeY(_tempModel["compy"])); points++; points->set(graphToNodeX(xAxis.max), graphToNodeY(_tempModel["compy"]) * (1 - _tempModel["ratio"])); points++; lineNode->setGeometry(lineGeom); rootNode->appendChildNode(lineNode); }
QSGGeometryNode *createSelectionNode(QSGMaterial *material) { QSGGeometryNode *selectionNode = new QSGGeometryNode; selectionNode->setMaterial(material); selectionNode->setFlag(QSGNode::OwnsMaterial, false); QSGGeometry *geometry = new QSGGeometry(OpaqueColoredPoint2DWithSize::attributes(), 4); geometry->setDrawingMode(GL_TRIANGLE_STRIP); OpaqueColoredPoint2DWithSize *v = OpaqueColoredPoint2DWithSize::fromVertexData(geometry); for (int i = 0; i < 4; ++i) v[i].set(0, 0, 0, 0, 0, 0, 0, 0); selectionNode->setGeometry(geometry); selectionNode->setFlag(QSGNode::OwnsGeometry, true); selectionNode->setFlag(QSGNode::OwnedByParent, false); return selectionNode; }
QSGGeometryNode *TimelineNotesRenderPassState::createNode() { QSGGeometryNode *node = new QSGGeometryNode; node->setGeometry(&m_nullGeometry); node->setMaterial(&m_material); node->setFlag(QSGNode::OwnedByParent, false); return node; }
void SceneGraphDeviceContext::DrawPolygon(int n, vrv::Point points[], int xoffset, int yoffset, int) { // Note: No support for vertex antialiasing. Use a top-level QQuickView with multisample antialiasing. // TODO: Add vertex antialiasing, refer to // 1) Qt sources for "void QSGBasicInternalRectangleNode::updateGeometry()" in // qtdeclarative/src/quick/scenegraph/qsgbasicinternalrectanglenode.cpp // 2) https://stackoverflow.com/questions/28125425/smooth-painting-in-custom-qml-element // TODO: This function only works for convex polygons. At the moment verovio calls this function only with n = 4. // Maybe this function should be renamed to DrawConvexPolygon vrv::Pen currentPen = m_penStack.top(); QSGGeometry *geometry; geometry = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), n); geometry->setDrawingMode(QSGGeometry::DrawTriangleStrip); QSGFlatColorMaterial *material = new QSGFlatColorMaterial; material->setColor(static_cast<QRgb>(currentPen.GetColour())); // Reorder points so that they can be drawn with DrawTriangleStrip. int counter1 = 0; int counter2 = n - 1; for (int i = 0; i < n; i++) { if (i % 2 == 0) { geometry->vertexDataAsPoint2D()[i].set( translateX(points[counter1].x + xoffset), translateY(points[counter1].y + yoffset)); counter1++; } else { geometry->vertexDataAsPoint2D()[i].set( translateX(points[counter2].x + xoffset), translateY(points[counter2].y + yoffset)); counter2--; } } QSGGeometryNode *node = new QSGGeometryNode; node->setGeometry(geometry); node->setFlag(QSGNode::OwnsGeometry); node->setMaterial(material); node->setFlag(QSGNode::OwnsMaterial); AddGeometryNode(node); }
void DynamicController::drawCompressor(QSGNode * rootNode) { //Update knobs if (!this->simple()) { QObject * threshKnob = knobs[0]; QObject * ratKnob = knobs[1]; threshKnob->setProperty("x", graphToNodeX(_tempModel["compx"])); threshKnob->setProperty("y", graphToNodeY(_tempModel["compy"])); ratKnob->setProperty("x", graphToNodeX(yAxis.max)); ratKnob->setProperty("y", graphToNodeY(_tempModel["compy"]) * (1 - _tempModel["ratio"])); } QSGGeometryNode * lineNode = new QSGGeometryNode(); QSGGeometry * lineGeom = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), (3)); QSGFlatColorMaterial *material = new QSGFlatColorMaterial; material->setColor(this->curveColor()); material->setFlag(QSGMaterial::Blending); lineNode->setMaterial(material); lineNode->setFlag(QSGNode::OwnsGeometry); lineNode->setFlag(QSGNode::OwnedByParent); lineNode->setFlag(QSGNode::OwnsMaterial); lineGeom->setDrawingMode(GL_LINE_STRIP); glLineWidth(2.0f); QSGGeometry::Point2D* points = lineGeom->vertexDataAsPoint2D(); QRectF bounds = boundingRect(); points->set(bounds.left(), bounds.bottom()); points++; for (int i = 0; i < 2; i++) { QQuickItem * q = qobject_cast<QQuickItem*>(knobs[i]); points->set(q->x(), q->y()); points++; } lineNode->setGeometry(lineGeom); rootNode->appendChildNode(lineNode); }
void SceneGraphDeviceContext::DrawLine(int x1, int y1, int x2, int y2) { vrv::Pen currentPen = m_penStack.top(); QSGGeometry *geometry = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), 2); geometry->setDrawingMode(GL_LINES); geometry->setLineWidth(translate(currentPen.GetWidth())); geometry->vertexDataAsPoint2D()[0].set(translateX(x1), translateY(y1)); geometry->vertexDataAsPoint2D()[1].set(translateX(x2), translateY(y2)); QSGFlatColorMaterial *material = new QSGFlatColorMaterial; material->setColor(static_cast<QRgb>(currentPen.GetColour())); QSGGeometryNode *node = new QSGGeometryNode; node->setGeometry(geometry); node->setFlag(QSGNode::OwnsGeometry); node->setMaterial(material); node->setFlag(QSGNode::OwnsMaterial); AddGeometryNode(node); }
QSGNode *QPScrollingCurve::updatePaintNode(QSGNode *oldNode, QQuickItem::UpdatePaintNodeData *) { QSGGeometryNode *node = 0; QSGGeometry *geometry = 0; QSGFlatColorMaterial *material = 0; if (!oldNode) { node = new QSGGeometryNode; geometry = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), m_data.size()); geometry->setLineWidth(2); geometry->setDrawingMode(GL_LINE_STRIP); node->setGeometry(geometry); node->setFlag(QSGNode::OwnsGeometry); material = new QSGFlatColorMaterial; material->setColor(m_color); node->setMaterial(material); node->setFlag(QSGNode::OwnsMaterial); node->markDirty(QSGNode::DirtyMaterial); } else { node = static_cast<QSGGeometryNode *>(oldNode); geometry = node->geometry(); geometry->allocate(m_data.size()); material = static_cast<QSGFlatColorMaterial*>(node->material()); if (material->color() != m_color) { material->setColor(m_color); node->markDirty(QSGNode::DirtyMaterial); } } QSGGeometry::Point2D *vertices = geometry->vertexDataAsPoint2D(); for (uint i = 0; i < m_data.size(); ++i) { QPointF p(i, m_data[i]); vertices[i].set(p.x(), p.y()); } node->markDirty(QSGNode::DirtyGeometry); return node; }
QSGNode* drawRect(const QRect& rect, QSGNode* oldNode) { QSGGeometryNode* node; if (oldNode == nullptr) { node = new QSGGeometryNode; QSGGeometry* geometry = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), 8); geometry->setDrawingMode(GL_LINES); geometry->setLineWidth(1); QSGFlatColorMaterial* material = new QSGFlatColorMaterial; material->setColor(QGuiApplication::palette().color(QPalette::Normal, QPalette::WindowText)); node->setGeometry(geometry); node->setFlag(QSGNode::OwnsGeometry); node->setMaterial(material); node->setFlag(QSGNode::OwnsMaterial); } else { node = static_cast<QSGGeometryNode*>(oldNode); } QSGGeometry* geometry = node->geometry(); // FIXME: check if these really have to be updated geometry->vertexDataAsPoint2D()[0].set(rect.topLeft().x(), rect.topLeft().y()); geometry->vertexDataAsPoint2D()[1].set(rect.topRight().x(), rect.topRight().y()); geometry->vertexDataAsPoint2D()[2].set(rect.topRight().x(), rect.topRight().y()); geometry->vertexDataAsPoint2D()[3].set(rect.bottomRight().x(), rect.bottomRight().y()); geometry->vertexDataAsPoint2D()[4].set(rect.bottomRight().x(), rect.bottomRight().y()); geometry->vertexDataAsPoint2D()[5].set(rect.bottomLeft().x(), rect.bottomLeft().y()); geometry->vertexDataAsPoint2D()[6].set(rect.bottomLeft().x(), rect.bottomLeft().y()); geometry->vertexDataAsPoint2D()[7].set(rect.topLeft().x(), rect.topLeft().y()); node->markDirty(QSGNode::DirtyGeometry); return node; }
void BindlingLoopsGeometry::allocate(QSGMaterial *material) { QSGGeometry *geometry = new QSGGeometry(BindlingLoopsGeometry::point2DWithOffset(), usedVertices); geometry->setIndexDataPattern(QSGGeometry::StaticPattern); geometry->setVertexDataPattern(QSGGeometry::StaticPattern); node = new QSGGeometryNode; node->setGeometry(geometry); node->setFlag(QSGNode::OwnsGeometry, true); node->setMaterial(material); allocatedVertices = usedVertices; usedVertices = 0; }
void SceneGraphDeviceContext::DrawCircle(int x, int y, int radius) { // Note: No support for vertex antialiasing. Use a top-level QQuickView with multisample antialiasing. // TODO: Add vertex antialiasing, refer to // 1) Qt sources for "void QSGBasicInternalRectangleNode::updateGeometry()" in // qtdeclarative/src/quick/scenegraph/qsgbasicinternalrectanglenode.cpp // 2) https://stackoverflow.com/questions/28125425/smooth-painting-in-custom-qml-element vrv::Pen currentPen = m_penStack.top(); int segmentCount = 16; QSGGeometryNode *node = new QSGGeometryNode(); QSGGeometry *geometry = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), segmentCount); geometry->setDrawingMode(QSGGeometry::DrawTriangleFan); node->setGeometry(geometry); node->setFlag(QSGNode::OwnsGeometry); QSGFlatColorMaterial *material = new QSGFlatColorMaterial; material->setColor(static_cast<QRgb>(currentPen.GetColour())); node->setMaterial(material); node->setFlag(QSGNode::OwnsMaterial); // This draws individual triangles from the first point (center) to every outer point by using DrawTriangleFan. QSGGeometry::Point2D *vertices = geometry->vertexDataAsPoint2D(); int numPoints = geometry->vertexCount(); vertices[0].x = translateX(x); vertices[0].y = translateY(y); for (int i = 1; i < numPoints; ++i) { double theta = i * 2 * M_PI / (numPoints - 2); vertices[i].x = translateX(x + radius * static_cast<float>(std::cos(theta))); vertices[i].y = translateY(y - radius * static_cast<float>(std::sin(theta))); } node->markDirty(QSGNode::DirtyGeometry); AddGeometryNode(node); }
void DynamicController::drawGate(QSGNode * rootNode) { //Update knobs if (!this->simple()) { QObject * gateKnob = knobs[0]; gateKnob->setProperty("x", graphToNodeX(_tempModel["gatex"])); gateKnob->setProperty("y", graphToNodeY(_tempModel["gatey"])); } QSGGeometryNode * lineNode = new QSGGeometryNode(); QSGGeometry * lineGeom = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), (3)); QSGFlatColorMaterial *material = new QSGFlatColorMaterial; material->setColor(this->curveColor()); material->setFlag(QSGMaterial::Blending); lineNode->setMaterial(material); lineNode->setFlag(QSGNode::OwnsGeometry); lineNode->setFlag(QSGNode::OwnedByParent); lineNode->setFlag(QSGNode::OwnsMaterial); lineGeom->setDrawingMode(GL_LINE_STRIP); glLineWidth(2.0f); QSGGeometry::Point2D* points = lineGeom->vertexDataAsPoint2D(); QRectF bounds = boundingRect(); points->set(graphToNodeX(_tempModel["gatex"]), bounds.bottom()); points++; points->set(graphToNodeX(_tempModel["gatex"]), graphToNodeX(_tempModel["gatey"])); points++; points->set(bounds.right(), bounds.top()); points++; lineNode->setGeometry(lineGeom); rootNode->appendChildNode(lineNode); }
QSGNode * DataSetView::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) { if (width() <= 0 || height() <= 0) { delete oldNode; return 0; } //if(recalculateCellSizes) calculateCellContentSizes(); const QRectF rect = boundingRect(); const int linesPerNode = 1000; //Or something? should be multiple of 2 though if(!oldNode) oldNode = new QSGNode(); QSGGeometryNode * currentNode = static_cast<QSGGeometryNode*>(oldNode->firstChild()); for(int lineIndex=0; lineIndex<_lines.size();) { if(currentNode == NULL) { currentNode = new QSGGeometryNode; currentNode->setFlag(QSGNode::OwnsMaterial, false); currentNode->setFlag(QSGNode::OwnsGeometry, true); currentNode->setMaterial(&material); oldNode->appendChildNode(currentNode); } int geomSize = std::min(linesPerNode, (int)(_lines.size() - lineIndex)); geomSize *= 2; QSGGeometry *geometry = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), geomSize); geometry->setLineWidth(1); geometry->setDrawingMode(GL_LINES); QSGGeometry::Point2D *points = geometry->vertexDataAsPoint2D(); for(int geomIndex=0; geomIndex<geomSize; geomIndex+=2) { points[geomIndex ].x = _lines[lineIndex].first.x() + rect.left(); points[geomIndex ].y = _lines[lineIndex].first.y() + rect.top(); points[geomIndex+1].x = _lines[lineIndex].second.x() + rect.left(); points[geomIndex+1].y = _lines[lineIndex].second.y() + rect.top(); lineIndex++; } currentNode->setGeometry(geometry); currentNode = static_cast<QSGGeometryNode*>(currentNode->nextSibling()); } std::queue<QSGGeometryNode*> killThem; while(currentNode != NULL) //superfluous children! Lets kill em { killThem.push(currentNode); currentNode = static_cast<QSGGeometryNode*>(currentNode->nextSibling()); } while(killThem.size() > 0) { QSGGeometryNode * childToDie = killThem.front(); killThem.pop(); delete childToDie; } return oldNode; }
QSGNode *GraphConnection::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) { if (m_source == m_sink) return oldNode; QSGGeometryNode *node = 0; QSGGeometry *geometry = 0; QPointF p1, p2, p3, p4; p1.setX(m_source.x()); p1.setY(m_source.y()); p4.setX(m_sink.x()); p4.setY(m_sink.y()); p2.setX(p1.x()); p3.setX(p4.x()); if (p1.y() < p4.y()) { p2.setY(p1.y() * 0.75 + p4.y() * 0.25); p3.setY(p4.y() * 0.75 + p1.y() * 0.25); } else { p2.setY(p1.y() - (p4.y()-p1.y())*0.25); p3.setY(p4.y() + (p4.y()-p1.y())*0.25); } // quick 'n' dirty estimation of bezier length // http://steve.hollasch.net/cgindex/curves/cbezarclen.html qreal l1 = (QVector2D(p2)-QVector2D(p1)).length() + (QVector2D(p3)-QVector2D(p2)).length() + (QVector2D(p4)-QVector2D(p3)).length(); qreal l0 = (QVector2D(p4)-QVector2D(p1)).length(); qreal length = 0.5*l0 + 0.5*l1; int segmentCount = length; if (!oldNode) { node = new QSGGeometryNode; geometry = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), segmentCount); geometry->setLineWidth(2); geometry->setDrawingMode(GL_LINE_STRIP); node->setGeometry(geometry); node->setFlag(QSGNode::OwnsGeometry); QSGFlatColorMaterial *material = new QSGFlatColorMaterial; material->setColor(QColor(0, 0, 0)); node->setMaterial(material); node->setFlag(QSGNode::OwnsMaterial); } else { node = static_cast<QSGGeometryNode *>(oldNode); geometry = node->geometry(); geometry->allocate(segmentCount); } QRectF bounds = boundingRect(); QSGGeometry::Point2D *vertices = geometry->vertexDataAsPoint2D(); for (int i = 0; i < segmentCount; ++i) { qreal t = i / qreal(segmentCount - 1); qreal invt = 1 - t; // Bezier QPointF pos = invt * invt * invt * p1 + 3 * invt * invt * t * p2 + 3 * invt * t * t * p3 + t * t * t * p4; float x = pos.x(); float y = pos.y(); vertices[i].set(x, y); } return node; }
QSGNode* AudioBarSpectrumItem::updatePaintNode(QSGNode* oldNode, UpdatePaintNodeData*) { if (!m_analyzer) return oldNode; if (!isVisible()) return oldNode; const std::vector<double>& points = m_analyzer->getSimplifiedSpectrum(); const double gain = m_agcEnabled ? m_analyzer->getAgcValue() : m_manualGain; const int pointCount = points.size(); if (pointCount < 2) return oldNode; // -------------------- Prepare QSG Nodes: QSGNode* parentNode = nullptr; if (oldNode) { parentNode = static_cast<QSGNode*>(oldNode); } else { parentNode = new QSGNode; } // adapt child count: int childCount = parentNode->childCount(); if (childCount != 2) { parentNode->removeAllChildNodes(); QSGGeometryNode* node = new QSGGeometryNode; QSGGeometry* geometry = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), 3); geometry->setDrawingMode(GL_TRIANGLE_STRIP); node->setGeometry(geometry); node->setFlag(QSGNode::OwnsGeometry); QSGFlatColorMaterial* material = new QSGFlatColorMaterial; material->setColor("#fff"); node->setMaterial(material); node->setFlag(QSGNode::OwnsMaterial); parentNode->appendChildNode(node); // Attention: TODO: colors are swapped! node = new QSGGeometryNode; geometry = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), 3); geometry->setDrawingMode(GL_TRIANGLE_STRIP); node->setGeometry(geometry); node->setFlag(QSGNode::OwnsGeometry); material = new QSGFlatColorMaterial; material->setColor(m_color); node->setMaterial(material); node->setFlag(QSGNode::OwnsMaterial); parentNode->appendChildNode(node); } QSGGeometryNode* const qsgNode = static_cast<QSGGeometryNode*>(parentNode->childAtIndex(0)); QSGGeometryNode* const qsgNodeOutline = static_cast<QSGGeometryNode*>(parentNode->childAtIndex(1)); if (!qsgNode || !qsgNodeOutline) { qCritical() << "[SpectrumItem] Could not get QSG Node."; return nullptr; } QSGGeometry* const geometry = qsgNode->geometry(); QSGGeometry* const geometryOutline = qsgNodeOutline->geometry(); if (!geometry || !geometryOutline) { qCritical() << "[SpectrumItem] Could not get QSG Geometry."; return nullptr; } const int verticesCount = pointCount * 7; const int outlineVerticesCount = pointCount * 7; geometry->allocate(verticesCount); geometryOutline->allocate(outlineVerticesCount); QSGGeometry::Point2D* const vertices = geometry->vertexDataAsPoint2D(); QSGGeometry::Point2D* const verticesOutline = geometryOutline->vertexDataAsPoint2D(); if (! vertices || !verticesOutline) { qCritical() << "[SpectrumItem] Could not get QSG vertices."; return nullptr; } const double itemWidth = width(); const double itemHeight = height(); const double barWidth = (itemWidth / pointCount) * 0.4; const double spaceWidth = (itemWidth / pointCount) * 0.6; const double endLineHeight = itemHeight / 100.0; // draw spectrum: for (int i = 0; i < pointCount; ++i) { const float x = itemWidth * (i / float(pointCount)); const float y = itemHeight * (1 - points[i] * gain); vertices[i*7].set(x, itemHeight); vertices[i*7+1].set(x, y); vertices[i*7+2].set(x + barWidth, itemHeight); vertices[i*7+3].set(x + barWidth, y); vertices[i*7+4].set(x + barWidth, itemHeight); vertices[i*7+5].set(x + barWidth, itemHeight); vertices[i*7+6].set(x + barWidth + spaceWidth, itemHeight); const float y2 = qMin(itemHeight, itemHeight * (1 - points[i] * gain) + endLineHeight); verticesOutline[i*7].set(x, itemHeight); verticesOutline[i*7+1].set(x, y2); verticesOutline[i*7+2].set(x + barWidth, itemHeight); verticesOutline[i*7+3].set(x + barWidth, y2); verticesOutline[i*7+4].set(x + barWidth, itemHeight); verticesOutline[i*7+5].set(x + barWidth, itemHeight); verticesOutline[i*7+6].set(x + barWidth + spaceWidth, itemHeight); } // tell Scene Graph that this items needs to be drawn: qsgNode->markDirty(QSGNode::DirtyGeometry); qsgNodeOutline->markDirty(QSGNode::DirtyGeometry); return parentNode; }
QSGGeometryNode *createNode() { QSGGeometryNode *node = new QSGSimpleRectNode; node->setFlag(QSGNode::OwnedByParent, false); return node; }
TimelineRenderPass::State *TimelineNotesRenderPass::update(const TimelineAbstractRenderer *renderer, const TimelineRenderState *parentState, State *oldState, int firstIndex, int lastIndex, bool stateChanged, qreal spacing) const { Q_UNUSED(firstIndex); Q_UNUSED(lastIndex); Q_UNUSED(spacing); const TimelineNotesModel *notes = renderer->notes(); const TimelineModel *model = renderer->model(); if (!model || !notes) return oldState; TimelineNotesRenderPassState *state; if (oldState == 0) { state = new TimelineNotesRenderPassState(model->expandedRowCount()); } else { if (!stateChanged && !renderer->notesDirty()) return oldState; state = static_cast<TimelineNotesRenderPassState *>(oldState); } QVector<QVector<int> > expanded(model->expandedRowCount()); QVector<int> collapsed; for (int i = 0; i < qMin(notes->count(), NotesGeometry::maxNotes); ++i) { if (notes->timelineModel(i) != model->modelId()) continue; int timelineIndex = notes->timelineIndex(i); if (model->startTime(timelineIndex) > parentState->end() || model->endTime(timelineIndex) < parentState->start()) continue; expanded[model->expandedRow(timelineIndex)] << timelineIndex; collapsed << timelineIndex; } QSGGeometryNode *collapsedNode = static_cast<QSGGeometryNode *>(state->collapsedOverlay()); if (collapsed.count() > 0) { collapsedNode->setGeometry(NotesGeometry::createGeometry(collapsed, model, parentState, true)); collapsedNode->setFlag(QSGGeometryNode::OwnsGeometry, true); } else { collapsedNode->setGeometry(state->nullGeometry()); collapsedNode->setFlag(QSGGeometryNode::OwnsGeometry, false); } for (int row = 0; row < model->expandedRowCount(); ++row) { QSGGeometryNode *rowNode = static_cast<QSGGeometryNode *>(state->expandedRow(row)); if (expanded[row].isEmpty()) { rowNode->setGeometry(state->nullGeometry()); rowNode->setFlag(QSGGeometryNode::OwnsGeometry, false); } else { rowNode->setGeometry(NotesGeometry::createGeometry(expanded[row], model, parentState, false)); collapsedNode->setFlag(QSGGeometryNode::OwnsGeometry, true); } } return state; }
QSGNode* OMX_MediaProcessorElement::updatePaintNode(QSGNode*, UpdatePaintNodeData*) { if (!m_texProvider) { m_texProvider = new OMX_TextureProviderQQuickItem(this); m_mediaProc = new OMX_MediaProcessor(m_texProvider); connect(m_mediaProc, SIGNAL(playbackCompleted()), this, SIGNAL(playbackCompleted())); connect(m_mediaProc, SIGNAL(playbackStarted()), this, SIGNAL(playbackStarted())); // Open if filepath is set. // TODO: Handle errors. if (!m_source.isNull()) { //if (QFile(m_source).exists()) { if (openMedia(m_source)) m_mediaProc->play(); //} //else { LOG_WARNING(LOG_TAG, "File does not exist."); //} } } return NULL; #if 0 QSGGeometryNode* node = 0; QSGGeometry* geometry = 0; if (!oldNode) { // Create the node. node = new QSGGeometryNode; geometry = new QSGGeometry(QSGGeometry::defaultAttributes_TexturedPoint2D(), 4); geometry->setDrawingMode(GL_TRIANGLE_STRIP); node->setGeometry(geometry); node->setFlag(QSGNode::OwnsGeometry); // TODO: Who is freeing this? // TODO: I cannot know the texture size here. QSGOpaqueTextureMaterial* material = new QSGOpaqueTextureMaterial; m_sgtexture = new OMX_SGTexture(m_texture, QSize(1920, 1080)); material->setTexture(m_sgtexture); node->setMaterial(material); node->setFlag(QSGNode::OwnsMaterial); #ifdef ENABLE_VIDEO_PROCESSOR QPlatformNativeInterface* nativeInterface = QGuiApplicationPrivate::platformIntegration()->nativeInterface(); Q_ASSERT(nativeInterface); EGLDisplay eglDisplay = nativeInterface->nativeResourceForIntegration("egldisplay"); EGLContext eglContext = nativeInterface->nativeResourceForContext( "eglcontext", QOpenGLContext::currentContext() ); #endif // Provider MUST be built in this thread. m_provider = new OMX_TextureProviderQQuickItem(this); #ifdef ENABLE_VIDEO_PROCESSOR m_videoProc = new OMX_VideoProcessor(eglDisplay, eglContext, m_provider); connect(m_videoProc, SIGNAL(textureReady(uint)), this, SLOT(onTextureChanged(uint))); if (!m_source.isNull()) m_videoProc->setVideoPath(m_source); if (m_playScheduled) { m_timer->start(30); m_videoProc->play(); } #elif ENABLE_MEDIA_PROCESSOR LOG_VERBOSE(LOG_TAG, "Starting video using media processor..."); m_mediaProc = new OMX_MediaProcessor(m_provider); m_mediaProc->setFilename("/home/pi/usb/Cars2.mkv", m_texture); //if (m_playScheduled) { m_timer->start(40); m_mediaProc->play(); //} #else LOG_VERBOSE(LOG_TAG, "Starting video..."); QtConcurrent::run(&startVideo, m_provider, this); m_timer->start(30); #endif } else { node = static_cast<QSGGeometryNode*>(oldNode); geometry = node->geometry(); geometry->allocate(4); // Update texture in the node if needed. QSGOpaqueTextureMaterial* material = (QSGOpaqueTextureMaterial*)node->material(); if (m_texture != (GLuint)material->texture()->textureId()) { // TODO: Does setTextureId frees the prev texture? // TODO: I should the given the texture size. LOG_ERROR(LOG_TAG, "Updating texture to %u!", m_texture); material = new QSGOpaqueTextureMaterial; m_sgtexture->setTexture(m_texture, QSize(1920, 1080)); } } // Create the vertices and map to texture. QRectF bounds = boundingRect(); QSGGeometry::TexturedPoint2D* vertices = geometry->vertexDataAsTexturedPoint2D(); vertices[0].set(bounds.x(), bounds.y() + bounds.height(), 0.0f, 0.0f); vertices[1].set(bounds.x() + bounds.width(), bounds.y() + bounds.height(), 1.0f, 0.0f); vertices[2].set(bounds.x(), bounds.y(), 0.0f, 1.0f); vertices[3].set(bounds.x() + bounds.width(), bounds.y(), 1.0f, 1.0f); return node; #endif }
QSGNode* NodeConnectionLines::updatePaintNode(QSGNode* oldNode, UpdatePaintNodeData*) { if (!m_nodeObject) return nullptr; const QVector<QPointer<NodeBase>>& connectedNodes = m_nodeObject->getConnectedNodes(); int connectionCount = connectedNodes.size(); // -------------------- Prepare QSG Nodes: QSGNode* parentNode = oldNode; if (!oldNode) { parentNode = new QSGNode(); } else { // update color in case it changed: // FIXME: is there a more efficient way to do this? for (int i=0; i<parentNode->childCount(); ++i) { QSGGeometryNode* childNode = static_cast<QSGGeometryNode*>(parentNode->childAtIndex(i)); if (!childNode) continue; QSGFlatColorMaterial* material = static_cast<QSGFlatColorMaterial*>(childNode->material()); if (!material) continue; material->setColor(m_color); } } // adapt child count: int childCount = parentNode->childCount(); if (childCount < connectionCount) { for (int i=0; i<(connectionCount - childCount); ++i) { QSGGeometryNode* node = new QSGGeometryNode; QSGGeometry* geometry = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), 3); geometry->setDrawingMode(GL_TRIANGLE_STRIP); node->setGeometry(geometry); node->setFlag(QSGNode::OwnsGeometry); QSGFlatColorMaterial* material = new QSGFlatColorMaterial; material->setColor(m_color); node->setMaterial(material); node->setFlag(QSGNode::OwnsMaterial); parentNode->appendChildNode(node); } } else if (childCount > connectionCount) { for (int i=0; i<(childCount - connectionCount); ++i) { parentNode->removeChildNode(parentNode->childAtIndex(0)); } } Q_ASSERT(parentNode->childCount() == connectionCount); // calculate common start point: const QPointF p0(width(), height() / 2); double widthOffset = m_lineWidth / 2; //const QPointF posInScene = mapToScene(QPointF(0, 0)); for (int i=0; i<connectionCount; ++i) { NodeBase* otherNode = connectedNodes[i]; if (!otherNode) continue; QQuickItem* otherGuiItem = otherNode->getGuiItem(); if (!otherGuiItem) continue; const QPointF p3 = mapFromItem(otherGuiItem, QPointF(-otherGuiItem->width() / 2, otherGuiItem->height() / 2)); int handleLength = std::max(50, std::min(int(p3.x() - p0.x()), 80)); const QPointF p1(p0.x() + handleLength, p0.y()); const QPointF p2(p3.x() - handleLength, p3.y()); // calculate reasonable segment count: int segmentCount = qMax(16.0, qMin(qAbs(p3.y() - p0.y()) / 25, 50.0)); int verticesCount = segmentCount * 2; QSGGeometryNode* qsgNode = static_cast<QSGGeometryNode*>(parentNode->childAtIndex(i)); if (!qsgNode) continue; QSGGeometry* geometry = qsgNode->geometry(); if (!geometry) continue; geometry->allocate(verticesCount); QSGGeometry::Point2D* vertices = geometry->vertexDataAsPoint2D(); // triangulate cubic bezier curve: for (int i = 0; i < segmentCount; ++i) { // t is the position on the line: const qreal t = i / qreal(segmentCount - 1); // pos is the point on the curve at "t": const QPointF pos = calculateBezierPoint(t, p0, p1, p2, p3); // normal is the normal vector at that point const QPointF normal = normalFromTangent(calculateBezierTangent(t, p0, p1, p2, p3)); // first is a point offsetted in the normal direction by lineWidth / 2 from pos const QPointF first = pos - normal * widthOffset; // ssecond is a point offsetted in the negative normal direction by lineWidth / 2 from pos const QPointF second = pos + normal * widthOffset; // add first and second as vertices to this geometry: vertices[i*2].set(first.x(), first.y()); vertices[i*2+1].set(second.x(), second.y()); } // tell Scene Graph that this items needs to be drawn: qsgNode->markDirty(QSGNode::DirtyGeometry); } return parentNode; }