void MultiTrackPlotter::updateTransform() { qreal y_scaling = 1.0; y_scaling *= m_height * 0.5; if (!m_overlay && m_channel_count > 1) y_scaling /= m_channel_count; qreal x_scaling = m_width; if (m_frame_count > 1) x_scaling /= (m_frame_count - 1); for (int idx = 0; idx < m_channel_count; ++idx) { qreal y_translation = 1.0; if (!m_overlay) y_translation += idx * 2.0; QMatrix4x4 matrix; matrix.scale(x_scaling, y_scaling); matrix.translate(0.0, y_translation); matrix.scale(1.0, -m_scaling); // flip y axis! QSGTransformNode *transformNode = static_cast<QSGTransformNode*>( childAtIndex(idx) );; transformNode->setMatrix(matrix); } }
void TimelineRenderState::assembleNodeTree(const TimelineModel *model, int defaultRowHeight, int defaultRowOffset) { Q_D(TimelineRenderState); QTC_ASSERT(isEmpty(), return); for (int pass = 0; pass < d->passes.length(); ++pass) { const TimelineRenderPass::State *passState = d->passes[pass]; if (!passState) continue; if (passState->expandedOverlay()) d->expandedOverlayRoot->appendChildNode(passState->expandedOverlay()); if (passState->collapsedOverlay()) d->collapsedOverlayRoot->appendChildNode(passState->collapsedOverlay()); } int row = 0; for (int i = 0; i < model->expandedRowCount(); ++i) { QSGTransformNode *rowNode = new QSGTransformNode; for (int pass = 0; pass < d->passes.length(); ++pass) { const TimelineRenderPass::State *passState = d->passes[pass]; if (!passState) continue; const QVector<QSGNode *> &rows = passState->expandedRows(); if (rows.length() > row) { QSGNode *rowChildNode = rows[row]; if (rowChildNode) rowNode->appendChildNode(rowChildNode); } } d->expandedRowRoot->appendChildNode(rowNode); ++row; } for (int row = 0; row < model->collapsedRowCount(); ++row) { QSGTransformNode *rowNode = new QSGTransformNode; QMatrix4x4 matrix; matrix.translate(0, row * defaultRowOffset, 0); matrix.scale(1.0, static_cast<float>(defaultRowHeight) / static_cast<float>(TimelineModel::defaultRowHeight()), 1.0); rowNode->setMatrix(matrix); for (int pass = 0; pass < d->passes.length(); ++pass) { const TimelineRenderPass::State *passState = d->passes[pass]; if (!passState) continue; const QVector<QSGNode *> &rows = passState->collapsedRows(); if (rows.length() > row) { QSGNode *rowChildNode = rows[row]; if (rowChildNode) rowNode->appendChildNode(rowChildNode); } } d->collapsedRowRoot->appendChildNode(rowNode); } updateExpandedRowHeights(model, defaultRowHeight, defaultRowOffset); }
void tst_TimelineRenderState::assembleNodeTree() { TimelineModel model(3); TimelineRenderState state1(1, 2, 0.5, 3); state1.assembleNodeTree(&model, 30, 30); QSGTransformNode *node = state1.finalize(0, true, QMatrix4x4()); QVERIFY(node != static_cast<QSGTransformNode *>(0)); QVERIFY(node->childCount() == 2); TimelineRenderState state2(3, 4, 0.5, 3); state2.setPassState(0, new TimelineRenderPass::State); state2.assembleNodeTree(&model, 30, 30); QCOMPARE(state2.finalize(node, true, QMatrix4x4()), node); QVERIFY(node->childCount() == 2); TimelineRenderState state3(4, 5, 0.5, 3); DummyPassState *dummyState = new DummyPassState; state3.setPassState(0, new TimelineRenderPass::State); state3.setPassState(1, dummyState); state3.assembleNodeTree(&model, 30, 30); node = state3.finalize(node, true, QMatrix4x4()); QCOMPARE(node->firstChild()->firstChild()->firstChild(), dummyState->expandedRows()[0]); QCOMPARE(node->lastChild()->firstChild(), dummyState->expandedOverlay()); node = state3.finalize(node, false, QMatrix4x4()); QCOMPARE(node->firstChild()->firstChild()->firstChild(), dummyState->collapsedRows()[0]); QCOMPARE(node->lastChild()->firstChild(), dummyState->collapsedOverlay()); delete node; }
void Renderer::updateMatrices(QSGNode *node, QSGTransformNode *xform) { if (node->isSubtreeBlocked()) return; if (node->type() == QSGNode::TransformNodeType) { QSGTransformNode *tn = static_cast<QSGTransformNode *>(node); if (xform) tn->setCombinedMatrix(xform->combinedMatrix() * tn->matrix()); else tn->setCombinedMatrix(tn->matrix()); QSGNODE_TRAVERSE(node) updateMatrices(child, tn); } else { if (node->type() == QSGNode::GeometryNodeType || node->type() == QSGNode::ClipNodeType) { static_cast<BasicGeometryNode_Accessor *>(node)->m_matrix = xform ? &xform->combinedMatrix() : 0; } QSGNODE_TRAVERSE(node) updateMatrices(child, xform); } }
void MultiTrackPlotter::setDataFormat( int channels, int frames ) { if (channels == m_channel_count && frames == m_frame_count) return; m_frame_count = frames; if (channels != m_channel_count) { m_channel_count = channels; removeAllChildNodes(); for (int idx = 0; idx < m_channel_count; ++idx) { PlotNode1D *plotNode = new PlotNode1D; QSGTransformNode *transformNode = new QSGTransformNode; transformNode->appendChildNode(plotNode); this->appendChildNode(transformNode); } } updateTransform(); }
QSGTransformNode *TimelineRenderState::finalize(QSGNode *oldNode, bool expanded, const QMatrix4x4 &transform) { Q_D(TimelineRenderState); QSGNode *rowNode = expanded ? d->expandedRowRoot : d->collapsedRowRoot; QSGNode *overlayNode = expanded ?d->expandedOverlayRoot : d->collapsedOverlayRoot; QSGTransformNode *node = oldNode ? static_cast<QSGTransformNode *>(oldNode) : new QSGTransformNode; node->setMatrix(transform); if (node->firstChild() != rowNode || node->lastChild() != overlayNode) { node->removeAllChildNodes(); node->appendChildNode(rowNode); node->appendChildNode(overlayNode); } return node; }
void HsQMLCanvasBackEnd::doRendering() { if (!mGL) { mGL = mWindow->openglContext(); QObject::connect( mGL, SIGNAL(aboutToBeDestroyed()), this, SLOT(doCleanup())); HsQMLGLCanvasType ctype; QSurfaceFormat format = mGL->format(); switch (format.renderableType()) { case QSurfaceFormat::OpenGL: ctype = HSQML_GL_DESKTOP; break; case QSurfaceFormat::OpenGLES: ctype = HSQML_GL_ES; break; default: setStatus(HsQMLCanvas::BadConfig); return; } mGLViewportFn = reinterpret_cast<GLViewportFn>( mGL->getProcAddress("glViewport")); mGLClearColorFn = reinterpret_cast<GLClearColorFn>( mGL->getProcAddress("glClearColor")); mGLClearFn = reinterpret_cast<GLClearFn>( mGL->getProcAddress("glClear")); if (!mGLViewportFn || !mGLClearColorFn || !mGLClearFn) { setStatus(HsQMLCanvas::BadProcs); return; } mGLCallbacks->mSetupCb( ctype, format.majorVersion(), format.minorVersion()); } // Reset OpenGL state before rendering #if QT_VERSION >= 0x050200 mWindow->resetOpenGLState(); #else #warning Resetting OpenGL state requires Qt 5.2 or later #endif // Clear window if painting below the scenegraph if (mWinInfo.needsBelowClear()) { QColor bg = mWindow->color(); mGLClearColorFn(bg.redF(), bg.greenF(), bg.blueF(), bg.alphaF()); mGLClearFn(GL_COLOR_BUFFER_BIT); } // Setup prior to paint callback QMatrix4x4 matrix; bool inlineMode = HsQMLCanvas::Inline == mDisplayMode; if (inlineMode) { if (!mFBO->bind()) { setStatus(HsQMLCanvas::BadBind); return; } mGLViewportFn(0, 0, qCeil(mCanvasWidth), qCeil(mCanvasHeight)); // Clear FBO to transparent mGLClearColorFn(0, 0, 0, 0); mGLClearFn(GL_COLOR_BUFFER_BIT); } else { // Calculate matrix for non-inline display modes QMatrix4x4 smatrix; QSGNode* node = mTransformNode; while (node) { if (QSGNode::TransformNodeType == node->type()) { QSGTransformNode* tnode = static_cast<QSGTransformNode*>(node); smatrix = tnode->matrix() * smatrix; } node = node->parent(); } matrix.translate(-1, 1); matrix.scale(2.0f/mWindow->width(), -2.0f/mWindow->height()); matrix *= smatrix; matrix.scale(mItemWidth/2.0f, mItemHeight/2.0f); matrix.translate(1, 1); mGLViewportFn(0, 0, mWindow->width(), mWindow->height()); } setStatus(HsQMLCanvas::Okay); mGLCallbacks->mPaintCb(matrix.data(), mItemWidth, mItemHeight); if (inlineMode) { mFBO->release(); } }