示例#1
0
void QQuickOpenGLShaderEffectCommon::updateParseLog(bool ignoreAttributes)
{
    parseLog.clear();
    if (!ignoreAttributes) {
        if (!attributes.contains(qtPositionAttributeName())) {
            parseLog += QLatin1String("Warning: Missing reference to \'")
                        + QLatin1String(qtPositionAttributeName())
                        + QLatin1String("\'.\n");
        }
        if (!attributes.contains(qtTexCoordAttributeName())) {
            parseLog += QLatin1String("Warning: Missing reference to \'")
                        + QLatin1String(qtTexCoordAttributeName())
                        + QLatin1String("\'.\n");
        }
    }
    bool respectsMatrix = false;
    bool respectsOpacity = false;
    for (int i = 0; i < uniformData[Key::VertexShader].size(); ++i)
        respectsMatrix |= uniformData[Key::VertexShader].at(i).specialType == UniformData::Matrix;
    for (int shaderType = 0; shaderType < Key::ShaderTypeCount; ++shaderType) {
        for (int i = 0; i < uniformData[shaderType].size(); ++i)
            respectsOpacity |= uniformData[shaderType].at(i).specialType == UniformData::Opacity;
    }
    if (!respectsMatrix)
        parseLog += QLatin1String("Warning: Vertex shader is missing reference to \'qt_Matrix\'.\n");
    if (!respectsOpacity)
        parseLog += QLatin1String("Warning: Shaders are missing reference to \'qt_Opacity\'.\n");
}
示例#2
0
QSGGeometry *QQuickGridMesh::updateGeometry(QSGGeometry *geometry, const QVector<QByteArray> &attributes, const QRectF &dstRect)
{
    int vmesh = m_resolution.height();
    int hmesh = m_resolution.width();
    int attrCount = attributes.count();

    int positionIndex = attributes.indexOf(qtPositionAttributeName());
    int texCoordIndex = attributes.indexOf(qtTexCoordAttributeName());

    if (!geometry) {
        switch (attrCount) {
        case 0:
            m_log = QLatin1String("Error: No attributes specified.");
            return 0;
        case 1:
            if (positionIndex != 0) {
                m_log = QLatin1String("Error: Missing \'");
                m_log += QLatin1String(qtPositionAttributeName());
                m_log += QLatin1String("\' attribute.\n");
                return 0;
            }
            break;
        case 2:
            if (positionIndex == -1 || texCoordIndex == -1) {
                m_log.clear();
                if (positionIndex == -1) {
                    m_log = QLatin1String("Error: Missing \'");
                    m_log += QLatin1String(qtPositionAttributeName());
                    m_log += QLatin1String("\' attribute.\n");
                }
                if (texCoordIndex == -1) {
                    m_log += QLatin1String("Error: Missing \'");
                    m_log += QLatin1String(qtTexCoordAttributeName());
                    m_log += QLatin1String("\' attribute.\n");
                }
                return 0;
            }
            break;
        default:
            m_log = QLatin1String("Error: Too many attributes specified.");
            return 0;
        }

        geometry = new QSGGeometry(attrCount == 1
                                   ? QSGGeometry::defaultAttributes_Point2D()
                                   : QSGGeometry::defaultAttributes_TexturedPoint2D(),
                                   (vmesh + 1) * (hmesh + 1), vmesh * 2 * (hmesh + 2),
                                   GL_UNSIGNED_SHORT);

    } else {
        geometry->allocate((vmesh + 1) * (hmesh + 1), vmesh * 2 * (hmesh + 2));
    }

    QSGGeometry::Point2D *vdata = static_cast<QSGGeometry::Point2D *>(geometry->vertexData());

    QRectF srcRect(0, 0, 1, 1);
    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);
            for (int ia = 0; ia < attrCount; ++ia) {
                if (ia == positionIndex) {
                    vdata->x = float(dstRect.left()) + fx * float(dstRect.width());
                    vdata->y = y;
                    ++vdata;
                } else {
                    vdata->x = float(srcRect.left()) + fx * float(srcRect.width());
                    vdata->y = ty;
                    ++vdata;
                }
            }
        }
    }

    quint16 *indices = (quint16 *)geometry->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;
    }

    return geometry;
}
示例#3
0
void QQuickOpenGLShaderEffectCommon::updateShader(QQuickItem *item,
                                                  const QMetaObject *itemMetaObject,
                                                  Key::ShaderType shaderType)
{
    disconnectPropertySignals(item, shaderType);
    uniformData[shaderType].clear();
    clearSignalMappers(shaderType);
    if (shaderType == Key::VertexShader)
        attributes.clear();

    // A qrc or file URL means the shader source is to be read from the specified file.
    QUrl srcUrl(QString::fromUtf8(source.sourceCode[shaderType]));
    if (!srcUrl.scheme().compare(QLatin1String("qrc"), Qt::CaseInsensitive) || srcUrl.isLocalFile()) {
        if (!fileSelector) {
            fileSelector = new QFileSelector(item);
            // There may not be an OpenGL context accessible here. So rely on
            // the window's requestedFormat().
            if (item->window()
                    && item->window()->requestedFormat().profile() == QSurfaceFormat::CoreProfile) {
                fileSelector->setExtraSelectors(QStringList() << QStringLiteral("glslcore"));
            }
        }
        const QString fn = fileSelector->select(QQmlFile::urlToLocalFileOrQrc(srcUrl));
        QFile f(fn);
        if (f.open(QIODevice::ReadOnly | QIODevice::Text)) {
            source.sourceCode[shaderType] = f.readAll();
            f.close();
        } else {
            qWarning("ShaderEffect: Failed to read %s", qPrintable(fn));
            source.sourceCode[shaderType] = QByteArray();
        }
    }

    const QByteArray &code = source.sourceCode[shaderType];
    if (code.isEmpty()) {
        // Optimize for default code.
        if (shaderType == Key::VertexShader) {
            attributes.append(QByteArray(qtPositionAttributeName()));
            attributes.append(QByteArray(qtTexCoordAttributeName()));
            UniformData d;
            d.name = "qt_Matrix";
            d.specialType = UniformData::Matrix;
            uniformData[Key::VertexShader].append(d);
            signalMappers[Key::VertexShader].append(0);
        } else if (shaderType == Key::FragmentShader) {
            UniformData d;
            d.name = "qt_Opacity";
            d.specialType = UniformData::Opacity;
            uniformData[Key::FragmentShader].append(d);
            signalMappers[Key::FragmentShader].append(0);
            const int mappedId = 1 | (Key::FragmentShader << 16);
            auto mapper = new QtPrivate::MappedSlotObject([this, mappedId](){mappedPropertyChanged(mappedId);});
            const char *sourceName = "source";
            d.name = sourceName;
            d.setValueFromProperty(item, itemMetaObject);
            d.specialType = UniformData::Sampler;
            uniformData[Key::FragmentShader].append(d);
            signalMappers[Key::FragmentShader].append(mapper);
        }
    } else {
        lookThroughShaderCode(item, itemMetaObject, shaderType, code);
    }

    connectPropertySignals(item, itemMetaObject, shaderType);
}