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); }
/* * The function hardcodes a fixed set of grid lines and scales * those to the bounding rect. */ void GridNode::setRect(const QRectF &rect) { int vCount = int((rect.width() - 1) / GRID_SIZE); int hCount = int((rect.height() - 1) / GRID_SIZE); int lineCount = vCount + hCount; QSGGeometry *g = geometry(); g->allocate(lineCount * 2); float x = rect.x(); float y = rect.y(); float w = rect.width(); float h = rect.height(); QSGGeometry::Point2D *v = g->vertexDataAsPoint2D(); // Then write the vertical lines for (int i=0; i<vCount; ++i) { float dx = (i + 1) * GRID_SIZE; v[i*2].set(dx, y); v[i*2+1].set(dx, y + h); } v += vCount * 2; // Then write the horizontal lines for (int i=0; i<hCount; ++i) { float dy = (i + 1) * GRID_SIZE; v[i*2].set(x, dy); v[i*2+1].set(x + w, dy); } // Tell the scenegraph we updated the geometry.. markDirty(QSGNode::DirtyGeometry); }
void compareSelectionNode(QSGNode *node, const QRectF &rect, int selectionId) { QSGGeometryNode *geometryNode = static_cast<QSGGeometryNode *>(node); QSGGeometry *geometry = geometryNode->geometry(); QCOMPARE(geometry->vertexCount(), 4); QCOMPARE(geometry->drawingMode(), (GLenum)GL_TRIANGLE_STRIP); OpaqueColoredPoint2DWithSize *data = static_cast<OpaqueColoredPoint2DWithSize *>(geometry->vertexData()); float *lowerLeft = reinterpret_cast<float *>(data); float *lowerRight = reinterpret_cast<float *>(++data); float *upperLeft = reinterpret_cast<float *>(++data); float *upperRight = reinterpret_cast<float *>(++data); QCOMPARE(QRectF(QPointF(upperLeft[0], upperLeft[1]), QPointF(lowerRight[0], lowerRight[1])), rect); QCOMPARE(lowerRight[0], upperRight[0]); QCOMPARE(lowerRight[1], lowerLeft[1]); QCOMPARE(upperLeft[0], lowerLeft[0]); QCOMPARE(upperLeft[1], upperRight[1]); QCOMPARE(int(lowerLeft[4]), selectionId); QCOMPARE(int(lowerRight[4]), selectionId); QCOMPARE(int(upperLeft[4]), selectionId); QCOMPARE(int(upperRight[4]), selectionId); TimelineItemsMaterial *material = static_cast<TimelineItemsMaterial *>( geometryNode->material()); QVERIFY(!(material->flags() & QSGMaterial::Blending)); }
QcLocationCircleNode::QcLocationCircleNode(const QcViewport * viewport) : QSGOpacityNode(), m_viewport(viewport), m_geometry_node(new QSGGeometryNode()) { setOpacity(.25); // 1. black QSGGeometry * geometry = new QSGGeometry(LocationCirclePoint2D_AttributeSet, 0); // Fixme: geometry->setDrawingMode(GL_TRIANGLE_STRIP); m_geometry_node->setGeometry(geometry); m_geometry_node->setFlag(QSGNode::OwnsGeometry); QSGSimpleMaterial<QcLocationCircleMaterialShaderState> * material = QcLocationCircleMaterialShader::createMaterial(); material->state()->cone_r = 0; // Fixme: QColor material->state()->cone_g = 0; material->state()->cone_b = 1; material->state()->cone_a = 1.; material->state()->accuracy_r = 1; material->state()->accuracy_g = 0; material->state()->accuracy_b = 0; material->state()->accuracy_a = 1.; // QSGFlatColorMaterial * material = new QSGFlatColorMaterial(); // material->setColor(QColor("black")); material->setFlag(QSGMaterial::Blending); m_geometry_node->setMaterial(material); m_geometry_node->setFlag(QSGNode::OwnsMaterial); appendChildNode(m_geometry_node); }
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); }
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); }
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; }
//! [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; }
bool SGGeometryExtension::setObject(void* object, const QString& typeName) { if (typeName == "QSGGeometryNode") { m_node = static_cast<QSGGeometryNode*>(object); m_model->setNode(m_node); QSGGeometry *geometry = m_node->geometry(); emit geometryChanged(geometry->drawingMode(), QByteArray::fromRawData(reinterpret_cast<char*>(geometry->indexData()), geometry->indexCount()*geometry->sizeOfIndex()), geometry->indexType()); return true; } return false; }
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; }
Point2DWithOffset *BindlingLoopsGeometry::vertexData() { QSGGeometry *geometry = node->geometry(); Q_ASSERT(geometry->attributeCount() == 2); Q_ASSERT(geometry->sizeOfVertex() == sizeof(Point2DWithOffset)); const QSGGeometry::Attribute *attributes = geometry->attributes(); Q_ASSERT(attributes[0].position == 0); Q_ASSERT(attributes[0].tupleSize == 2); Q_ASSERT(attributes[0].type == GL_FLOAT); Q_ASSERT(attributes[1].position == 1); Q_ASSERT(attributes[1].tupleSize == 2); Q_ASSERT(attributes[1].type == GL_FLOAT); Q_UNUSED(attributes); return static_cast<Point2DWithOffset *>(geometry->vertexData()); }
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 QQuickAndroid9PatchNode::initialize(QSGTexture *texture, const QRectF &bounds, const QSize &sourceSize, const QQuickAndroid9PatchDivs &xDivs, const QQuickAndroid9PatchDivs &yDivs) { delete m_material.texture(); m_material.setTexture(texture); const int xlen = xDivs.data.size(); const int ylen = yDivs.data.size(); if (xlen > 0 && ylen > 0) { const int quads = (xlen - 1) * (ylen - 1); static const int verticesPerQuad = 6; m_geometry.allocate(xlen * ylen, verticesPerQuad * quads); QSGGeometry::TexturedPoint2D *vertices = m_geometry.vertexDataAsTexturedPoint2D(); QVector<qreal> xCoords = xDivs.coordsForSize(bounds.width()); QVector<qreal> yCoords = yDivs.coordsForSize(bounds.height()); for (int y = 0; y < ylen; ++y) { for (int x = 0; x < xlen; ++x, ++vertices) vertices->set(xCoords[x], yCoords[y], xDivs.data[x] / sourceSize.width(), yDivs.data[y] / sourceSize.height()); } quint16 *indices = m_geometry.indexDataAsUShort(); int n = quads; for (int q = 0; n--; ++q) { if ((q + 1) % xlen == 0) // next row ++q; // Bottom-left half quad triangle indices[0] = q; indices[1] = q + xlen; indices[2] = q + xlen + 1; // Top-right half quad triangle indices[3] = q; indices[4] = q + xlen + 1; indices[5] = q + 1; indices += verticesPerQuad; } } markDirty(QSGNode::DirtyGeometry | QSGNode::DirtyMaterial); }
void QQuickDefaultClipNode::updateGeometry() { QSGGeometry *g = geometry(); if (qFuzzyIsNull(m_radius)) { g->allocate(4); QSGGeometry::updateRectGeometry(g, m_rect); } else { int vertexCount = 0; // Radius should never exceeds half of the width or half of the height qreal radius = qMin(qMin(m_rect.width() / 2, m_rect.height() / 2), m_radius); QRectF rect = m_rect; rect.adjust(radius, radius, -radius, -radius); int segments = qMin(30, qCeil(radius)); // Number of segments per corner. g->allocate((segments + 1) * 2); QVector2D *vertices = (QVector2D *)g->vertexData(); for (int part = 0; part < 2; ++part) { for (int i = 0; i <= segments; ++i) { //### Should change to calculate sin/cos only once. qreal angle = qreal(0.5 * M_PI) * (part + i / qreal(segments)); qreal s = qFastSin(angle); qreal c = qFastCos(angle); qreal y = (part ? rect.bottom() : rect.top()) - radius * c; // current inner y-coordinate. qreal lx = rect.left() - radius * s; // current inner left x-coordinate. qreal rx = rect.right() + radius * s; // current inner right x-coordinate. vertices[vertexCount++] = QVector2D(rx, y); vertices[vertexCount++] = QVector2D(lx, y); } } } markDirty(DirtyGeometry); setClipRect(m_rect); }
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); }
void VideoNode::updateGeometry(const PaintAreas & areas) { QSGGeometry *g = geometry(); if (m_materialType == MaterialTypeVideo) { if (!m_validGeometry) g = new QSGGeometry(QSGGeometry::defaultAttributes_TexturedPoint2D(), 4); QSGGeometry::TexturedPoint2D *v = g->vertexDataAsTexturedPoint2D(); // Set geometry first setGeom(v + 0, areas.videoArea.topLeft()); setGeom(v + 1, areas.videoArea.bottomLeft()); setGeom(v + 2, areas.videoArea.topRight()); setGeom(v + 3, areas.videoArea.bottomRight()); // and then texture coordinates setTex(v + 0, areas.sourceRect.topLeft()); setTex(v + 1, areas.sourceRect.bottomLeft()); setTex(v + 2, areas.sourceRect.topRight()); setTex(v + 3, areas.sourceRect.bottomRight()); } else { if (!m_validGeometry) g = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), 4); QSGGeometry::Point2D *v = g->vertexDataAsPoint2D(); setGeom(v + 0, areas.videoArea.topLeft()); setGeom(v + 1, areas.videoArea.bottomLeft()); setGeom(v + 2, areas.videoArea.topRight()); setGeom(v + 3, areas.videoArea.bottomRight()); } if (!m_validGeometry) { setGeometry(g); m_validGeometry = true; } markDirty(DirtyGeometry); }
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; }
QSGGeometry *NotesGeometry::createGeometry(QVector<int> &ids, const TimelineModel *model, const TimelineRenderState *parentState, bool collapsed) { float rowHeight = TimelineModel::defaultRowHeight(); QSGGeometry *geometry = new QSGGeometry(point2DWithDistanceFromTop(), ids.count() * 2); geometry->setDrawingMode(GL_LINES); geometry->setLineWidth(3); Point2DWithDistanceFromTop *v = static_cast<Point2DWithDistanceFromTop *>(geometry->vertexData()); for (int i = 0; i < ids.count(); ++i) { int timelineIndex = ids[i]; float horizontalCenter = ((model->startTime(timelineIndex) + model->endTime(timelineIndex)) / (qint64)2 - parentState->start()) * parentState->scale(); float verticalStart = (collapsed ? (model->collapsedRow(timelineIndex) + 0.1) : 0.1) * rowHeight; float verticalEnd = verticalStart + 0.8 * rowHeight; v[i * 2].set(horizontalCenter, verticalStart, 0); v[i * 2 + 1].set(horizontalCenter, verticalEnd, 1); } return geometry; }
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 Renderer::buildRenderList(QSGNode *node, QSGClipNode *clip) { if (node->isSubtreeBlocked()) return; if (node->type() == QSGNode::GeometryNodeType || node->type() == QSGNode::ClipNodeType) { QSGBasicGeometryNode *gn = static_cast<QSGBasicGeometryNode *>(node); QSGGeometry *g = gn->geometry(); Element e; e.node = gn; if (g->vertexCount() > 0) { e.vboOffset = m_vboSize; int vertexSize = g->sizeOfVertex() * g->vertexCount(); m_vboSize += vertexSize; m_vboData.resize(m_vboSize); memcpy(m_vboData.data() + e.vboOffset, g->vertexData(), vertexSize); } else { e.vboOffset = -1; } if (g->indexCount() > 0) { e.iboOffset = m_iboSize; int indexSize = g->sizeOfIndex() * g->indexCount(); m_iboSize += indexSize; m_iboData.resize(m_iboSize); memcpy(m_iboData.data() + e.iboOffset, g->indexData(), indexSize); } else { e.iboOffset = -1; } m_renderList.add(e); static_cast<BasicGeometryNode_Accessor *>(node)->m_clip_list = clip; if (node->type() == QSGNode::ClipNodeType) clip = static_cast<QSGClipNode *>(node); } QSGNODE_TRAVERSE(node) buildRenderList(child, clip); }
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); }
void QcLocationCircleNode::update(const QcLocationCircleData & location_circle_data) { // QSGGeometry * location_circle_geometry = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), 1); // location_circle_geometry->setLineWidth(100); // point size, max is 255 // location_circle_geometry->setDrawingMode(GL_POINTS); QSGGeometry * geometry = new QSGGeometry(LocationCirclePoint2D_AttributeSet, 4); geometry->setDrawingMode(GL_TRIANGLE_STRIP); m_geometry_node->setGeometry(geometry); m_geometry_node->setFlag(QSGNode::OwnsGeometry); LocationCirclePoint2D * vertices = static_cast<LocationCirclePoint2D *>(geometry->vertexData()); float x, y; if (location_circle_data.visible()) { QcVectorDouble screen_coordinate = m_viewport->coordinate_to_screen(location_circle_data.coordinate()); x = screen_coordinate.x(); y = screen_coordinate.y(); qInfo() << screen_coordinate; } else { x = .5 * m_viewport->width(); // Fixme: vector y = .5 * m_viewport->height(); } float accuracy_radius = m_viewport->to_px(location_circle_data.horizontal_precision()); constexpr float dot_radius_minimum = 10.; constexpr float cone_scale_factor = 5.; float dot_radius = qMax(accuracy_radius, dot_radius_minimum); float radius = cone_scale_factor * dot_radius_minimum; float margin = 10; float size = radius + margin; float angle = location_circle_data.bearing() + 90.; // North point to y vertices[0].set(QcVectorDouble(x - size, y - size), QcVectorDouble(-size, -size), radius, dot_radius, accuracy_radius, angle); vertices[1].set(QcVectorDouble(x - size, y + size), QcVectorDouble(-size, size), radius, dot_radius, accuracy_radius, angle); vertices[2].set(QcVectorDouble(x + size, y - size), QcVectorDouble( size, -size), radius, dot_radius, accuracy_radius, angle); vertices[3].set(QcVectorDouble(x + size, y + size), QcVectorDouble( size, size), radius, dot_radius, accuracy_radius, angle); }
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 ShaderEffectItem::updateGeometry() { QRectF srcRect(0, 1, 1, -1); if (m_mirrored) srcRect = QRectF(0, 0, 1, 1); QRectF dstRect = QRectF(0,0, width(), height()); int vmesh = m_meshResolution.height(); int hmesh = m_meshResolution.width(); QSGGeometry *g = &m_geometry; if (vmesh == 1 && hmesh == 1) { if (g->vertexCount() != 4) g->allocate(4); QSGGeometry::updateTexturedRectGeometry(g, dstRect, srcRect); return; } g->allocate((vmesh + 1) * (hmesh + 1), vmesh * 2 * (hmesh + 2)); QSGGeometry::TexturedPoint2D *vdata = g->vertexDataAsTexturedPoint2D(); for (int iy = 0; iy <= vmesh; ++iy) { float fy = iy / float(vmesh); float y = float(dstRect.top()) + fy * float(dstRect.height()); float ty = float(srcRect.top()) + fy * float(srcRect.height()); for (int ix = 0; ix <= hmesh; ++ix) { float fx = ix / float(hmesh); vdata->x = float(dstRect.left()) + fx * float(dstRect.width()); vdata->y = y; vdata->tx = float(srcRect.left()) + fx * float(srcRect.width()); vdata->ty = ty; ++vdata; } } quint16 *indices = (quint16 *)g->indexDataAsUShort(); int i = 0; for (int iy = 0; iy < vmesh; ++iy) { *(indices++) = i + hmesh + 1; for (int ix = 0; ix <= hmesh; ++ix, ++i) { *(indices++) = i + hmesh + 1; *(indices++) = i; } *(indices++) = i - 1; } }
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 }