Пример #1
0
void FullscreenQuad::setShader(const char* name)
{
	shader.loadShaderPairByName(name);
	shader.compile();

	bindGeometry();
}
Пример #2
0
void ShaderEffectItem::renderEffect(QPainter *painter, const QMatrix4x4 &matrix)
{
    if (!painter || !painter->device())
        return;

    if (!m_program.isLinked() || m_program_dirty)
        updateShaderProgram();

    m_program.bind();

    QMatrix4x4 combinedMatrix;
    combinedMatrix.scale(2.0 / painter->device()->width(), -2.0 / painter->device()->height(), 1.0);
    combinedMatrix.translate(-painter->device()->width() / 2.0, -painter->device()->height() / 2.0 );
    combinedMatrix *= matrix;
    updateEffectState(combinedMatrix);

    for (int i = 0; i < m_attributeNames.size(); ++i) {
        m_program.enableAttributeArray(m_geometry.attributes()[i].position);
    }

    bindGeometry();

    // Optimization, disable depth test when we know we don't need it.
    if (m_defaultVertexShader) {
        glDepthMask(false);
        glDisable(GL_DEPTH_TEST);
    } else {
        glEnable(GL_DEPTH_TEST);
        glDepthFunc(GL_GREATER);
        glDepthMask(true);
#if defined(QT_OPENGL_ES)
        glClearDepthf(0);
#else
        glClearDepth(0);
#endif
        glClearColor(0, 0, 0, 0);
        glClear(GL_DEPTH_BUFFER_BIT);
    }

    if (m_blending){
        glEnable(GL_BLEND);
        glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
    } else {
        glDisable(GL_BLEND);
    }

    if (m_geometry.indexCount())
        glDrawElements(m_geometry.drawingMode(), m_geometry.indexCount(), m_geometry.indexType(), m_geometry.indexData());
    else
        glDrawArrays(m_geometry.drawingMode(), 0, m_geometry.vertexCount());

    glDepthMask(false);
    glDisable(GL_DEPTH_TEST);

   for (int i = 0; i < m_attributeNames.size(); ++i)
        m_program.disableAttributeArray(m_geometry.attributes()[i].position);
}
void QSGDefaultRenderer::buildLists(QSGNode *node)
{
    if (node->isSubtreeBlocked())
        return;

    if (node->type() == QSGNode::GeometryNodeType) {
        QSGGeometryNode *geomNode = static_cast<QSGGeometryNode *>(node);
        qreal opacity = geomNode->inheritedOpacity();
        QSGMaterial *m = geomNode->activeMaterial();

#ifdef FORCE_NO_REORDER
        if (true) {
#else
        if ((m->flags() & QSGMaterial::Blending) || opacity < 1) {
#endif
            geomNode->setRenderOrder(m_currentRenderOrder - 1);
            m_transparentNodes.add(geomNode);
        } else {
            geomNode->setRenderOrder(m_currentRenderOrder);
            m_opaqueNodes.add(geomNode);
            m_currentRenderOrder += 2;
        }
    }

    if (!node->firstChild())
        return;

#ifdef FORCE_NO_REORDER
    static bool reorder = false;
#else
    static bool reorder = !qApp->arguments().contains(QLatin1String("--no-reorder"));
#endif

    if (reorder && node->firstChild() != node->lastChild() && (node->flags() & QSGNode::ChildrenDoNotOverlap)) {
        QVarLengthArray<int, 16> beginIndices;
        QVarLengthArray<int, 16> endIndices;
        int baseCount = m_transparentNodes.size();
        int count = 0;
        for (QSGNode *c = node->firstChild(); c; c = c->nextSibling()) {
            beginIndices.append(m_transparentNodes.size());
            buildLists(c);
            endIndices.append(m_transparentNodes.size());
            ++count;
        }

        int childNodeCount = m_transparentNodes.size() - baseCount;
        if (childNodeCount) {
            m_tempNodes.reset();
            m_tempNodes.reserve(childNodeCount);
            while (childNodeCount) {
                for (int i = 0; i < count; ++i) {
                    if (beginIndices[i] != endIndices[i])
                        m_heap.insert(IndexGeometryNodePair(i, m_transparentNodes.at(beginIndices[i]++)));
                }
                while (!m_heap.isEmpty()) {
                    IndexGeometryNodePair pair = m_heap.pop();
                    m_tempNodes.add(pair.second);
                    --childNodeCount;
                    int i = pair.first;
                    if (beginIndices[i] != endIndices[i] && !nodeLessThan(m_transparentNodes.at(beginIndices[i]), pair.second))
                        m_heap.insert(IndexGeometryNodePair(i, m_transparentNodes.at(beginIndices[i]++)));
                }
            }
            Q_ASSERT(m_tempNodes.size() == m_transparentNodes.size() - baseCount);

            qMemCopy(&m_transparentNodes.at(baseCount), &m_tempNodes.at(0), m_tempNodes.size() * sizeof(QSGGeometryNode *));
        }
    } else {
        for (QSGNode *c = node->firstChild(); c; c = c->nextSibling())
            buildLists(c);
    }
}

void QSGDefaultRenderer::renderNodes(const QDataBuffer<QSGGeometryNode *> &list)
{
    const float scale = 1.0f / m_currentRenderOrder;
    int count = list.size();
    int currentRenderOrder = 0x80000000;
    m_current_projection_matrix.setColumn(2, scale * projectionMatrix().column(2));

    //int clipChangeCount = 0;
    //int programChangeCount = 0;
    //int materialChangeCount = 0;

    for (int i = 0; i < count; ++i) {
        QSGGeometryNode *geomNode = list.at(i);

        QSGMaterialShader::RenderState::DirtyStates updates;

#if defined (QML_RUNTIME_TESTING)
        static bool dumpTree = qApp->arguments().contains(QLatin1String("--dump-tree"));
        if (dumpTree)
            qDebug() << geomNode;
#endif

        bool changeMatrix = m_currentMatrix != geomNode->matrix();

        if (changeMatrix) {
            m_currentMatrix = geomNode->matrix();
            if (m_currentMatrix)
                m_current_model_view_matrix = *m_currentMatrix;
            else
                m_current_model_view_matrix.setToIdentity();
            updates |= QSGMaterialShader::RenderState::DirtyMatrix;
        }

        bool changeOpacity = m_current_opacity != geomNode->inheritedOpacity();
        if (changeOpacity) {
            updates |= QSGMaterialShader::RenderState::DirtyOpacity;
            m_current_opacity = geomNode->inheritedOpacity();
        }

        Q_ASSERT(geomNode->activeMaterial());

        QSGMaterial *material = geomNode->activeMaterial();
        QSGMaterialShader *program = m_context->prepareMaterial(material);
        Q_ASSERT(program->program()->isLinked());

        bool changeClip = geomNode->clipList() != m_currentClip;
        QSGRenderer::ClipType clipType = QSGRenderer::NoClip;
        if (changeClip) {
            clipType = updateStencilClip(geomNode->clipList());
            m_currentClip = geomNode->clipList();
#ifdef FORCE_NO_REORDER
            glDepthMask(false);
#else
            glDepthMask((material->flags() & QSGMaterial::Blending) == 0 && m_current_opacity == 1);
#endif
            //++clipChangeCount;
        }

        bool changeProgram = (changeClip && clipType == QSGRenderer::StencilClip) || m_currentProgram != program;
        if (changeProgram) {
            if (m_currentProgram)
                m_currentProgram->deactivate();
            m_currentProgram = program;
            m_currentProgram->activate();
            //++programChangeCount;
            updates |= (QSGMaterialShader::RenderState::DirtyMatrix | QSGMaterialShader::RenderState::DirtyOpacity);

#ifdef RENDERER_DEBUG
            materialChanges++;
#endif
        }

        bool changeRenderOrder = currentRenderOrder != geomNode->renderOrder();
        if (changeRenderOrder) {
            currentRenderOrder = geomNode->renderOrder();
            m_current_projection_matrix.setColumn(3, projectionMatrix().column(3)
                                                  + currentRenderOrder
                                                  * m_current_projection_matrix.column(2));
            updates |= QSGMaterialShader::RenderState::DirtyMatrix;
        }

        if (changeProgram || m_currentMaterial != material) {
            program->updateState(state(updates), material, changeProgram ? 0 : m_currentMaterial);
            m_currentMaterial = material;
            //++materialChangeCount;
        }

        //glDepthRange((geomNode->renderOrder() + 0.1) * scale, (geomNode->renderOrder() + 0.9) * scale);

        const QSGGeometry *g = geomNode->geometry();
        bindGeometry(program, g);
        draw(geomNode);

#ifdef RENDERER_DEBUG
        geometryNodesDrawn++;
#endif
    }
    //qDebug("Clip: %i, shader program: %i, material: %i times changed while drawing %s items",
    //    clipChangeCount, programChangeCount, materialChangeCount,
    //    &list == &m_transparentNodes ? "transparent" : "opaque");
}

QT_END_NAMESPACE
Пример #4
0
void ShaderEffectItem::renderEffect(QPainter *painter, const QMatrix4x4 &matrix)
{
    if (!painter || !painter->device())
        return;

    if (!m_program || !m_program->programId()) {
        // Deleted due to deactivation, to save GPU memory,
        // or invalidated due to GL context change.
        delete m_program;
        if (QGLContext::currentContext())
            m_program = new QGLShaderProgram(this);
        if (!m_program)
            qWarning() << "ShaderEffectItem::renderEffect - Creating QGLShaderProgram failed!";
    }

    if (!m_program)
        return;

    if (!m_program->isLinked() || m_program_dirty)
        updateShaderProgram();

    m_program->bind();

    QMatrix4x4 combinedMatrix;
    combinedMatrix.scale(2.0 / painter->device()->width(), -2.0 / painter->device()->height(), 1.0);
    combinedMatrix.translate(-painter->device()->width() / 2.0, -painter->device()->height() / 2.0 );
    combinedMatrix *= matrix;
    updateEffectState(combinedMatrix);

    for (int i = 0; i < m_attributeNames.size(); ++i) {
        m_program->enableAttributeArray(m_geometry.attributes()[i].position);
    }

    bindGeometry();

    // Optimization, disable depth test when we know we don't need it.
    if (m_defaultVertexShader) {
        glDepthMask(false);
        glDisable(GL_DEPTH_TEST);
    } else {
        glEnable(GL_DEPTH_TEST);
        glDepthFunc(GL_GREATER);
        glDepthMask(true);
#if defined(QT_OPENGL_ES)
        glClearDepthf(0);
#else
        glClearDepth(0);
#endif
        glClearColor(0, 0, 0, 0);
        glClear(GL_DEPTH_BUFFER_BIT);
    }

    if (m_blending) {
        glEnable(GL_BLEND);
        glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
    } else {
        glDisable(GL_BLEND);
    }

    if (m_geometry.indexCount())
        glDrawElements(m_geometry.drawingMode(), m_geometry.indexCount(), m_geometry.indexType(), m_geometry.indexData());
    else
        glDrawArrays(m_geometry.drawingMode(), 0, m_geometry.vertexCount());

    glDepthMask(false);
    glDisable(GL_DEPTH_TEST);

    for (int i = 0; i < m_attributeNames.size(); ++i)
        m_program->disableAttributeArray(m_geometry.attributes()[i].position);
}