Provide determinant accessor in render state structure.
authorGlenn Watson <glenn.watson@nokia.com>
Tue, 7 Feb 2012 23:36:18 +0000 (09:36 +1000)
committerQt by Nokia <qt-info@nokia.com>
Wed, 8 Feb 2012 13:37:04 +0000 (14:37 +0100)
This allows custom renderers to set the determinant to a value
different than the actual model view transform matrix. This is
useful when parts of the scene node transformation are done on
the CPU rather than in the vertex shader.

Change-Id: Icf26a5922b0933275a61af4656cf842bf61e70d5
Reviewed-by: Michael Brasser <michael.brasser@nokia.com>
Reviewed-by: Gunnar Sletta <gunnar.sletta@nokia.com>
src/quick/scenegraph/coreapi/qsgdefaultrenderer.cpp
src/quick/scenegraph/coreapi/qsgmaterial.cpp
src/quick/scenegraph/coreapi/qsgmaterial.h
src/quick/scenegraph/coreapi/qsgrenderer.cpp
src/quick/scenegraph/coreapi/qsgrenderer_p.h
src/quick/scenegraph/qsgdistancefieldglyphnode_p.cpp

index 63edb33..404fe06 100644 (file)
@@ -450,6 +450,7 @@ void QSGDefaultRenderer::renderNodes(const QDataBuffer<QSGGeometryNode *> &list)
                 m_current_model_view_matrix = *m_currentMatrix;
             else
                 m_current_model_view_matrix.setToIdentity();
+            m_current_determinant = m_current_model_view_matrix.determinant();
             updates |= QSGMaterialShader::RenderState::DirtyMatrix;
         }
 
index 3c7a401..308a1fa 100644 (file)
@@ -334,7 +334,15 @@ float QSGMaterialShader::RenderState::opacity() const
     return static_cast<const QSGRenderer *>(m_data)->currentOpacity();
 }
 
+/*!
+    Returns the modelview determinant to be used for rendering
+ */
 
+float QSGMaterialShader::RenderState::determinant() const
+{
+    Q_ASSERT(m_data);
+    return static_cast<const QSGRenderer *>(m_data)->determinant();
+}
 
 /*!
     Returns the matrix combined of modelview matrix and project matrix.
@@ -350,6 +358,20 @@ QMatrix4x4 QSGMaterialShader::RenderState::combinedMatrix() const
 
 /*!
     Returns the model view matrix.
+
+    If the material has the RequiresFullMatrix flag
+    set, this is guaranteed to be the complete transform
+    matrix calculated from the scenegraph.
+
+    However, if this flag is not set, the renderer may
+    choose to alter this matrix. For example, it may
+    pre-transform vertices on the CPU and set this matrix
+    to identity.
+
+    In a situation such as the above, it is still possible
+    to retrieve the actual matrix determinant by setting
+    the RequiresDeterminant flag in the material and
+    calling the determinant() accessor.
  */
 
 QMatrix4x4 QSGMaterialShader::RenderState::modelViewMatrix() const
index 65c8df2..0673aca 100644 (file)
@@ -73,6 +73,7 @@ public:
         QMatrix4x4 modelViewMatrix() const;
         QRect viewportRect() const;
         QRect deviceRect() const;
+        float determinant() const;
 
         QOpenGLContext *context() const;
 
index 6a894ee..eb7cab5 100644 (file)
@@ -137,6 +137,7 @@ QSGRenderer::QSGRenderer(QSGContext *context)
     , m_clear_color(Qt::transparent)
     , m_clear_mode(ClearColorBuffer | ClearDepthBuffer)
     , m_current_opacity(1)
+    , m_current_determinant(1)
     , m_context(context)
     , m_root_node(0)
     , m_node_updater(0)
index ff4196c..ec09ed4 100644 (file)
@@ -104,6 +104,7 @@ public:
     QMatrix4x4 currentModelViewMatrix() const { return m_current_model_view_matrix; }
     QMatrix4x4 currentCombinedMatrix() const { return m_current_projection_matrix * m_current_model_view_matrix; }
     qreal currentOpacity() const { return m_current_opacity; }
+    qreal determinant() const { return m_current_determinant; }
 
     void setProjectionMatrixToDeviceRect();
     void setProjectionMatrixToRect(const QRectF &rect);
@@ -153,6 +154,7 @@ protected:
     QMatrix4x4 m_current_projection_matrix;
     QMatrix4x4 m_current_model_view_matrix;
     qreal m_current_opacity;
+    qreal m_current_determinant;
 
     QSGContext *m_context;
 
index f17958c..e525d2a 100644 (file)
@@ -157,7 +157,7 @@ void QSGDistanceFieldTextMaterialShader::updateState(const RenderState &state, Q
     }
     if (state.isMatrixDirty()) {
         program()->setUniformValue(m_matrix_id, state.combinedMatrix());
-        m_matrixScale = qSqrt(qAbs(state.modelViewMatrix().determinant()));
+        m_matrixScale = qSqrt(qAbs(state.determinant()));
         updateRange = true;
     }
     if (updateRange) {