diff options
Diffstat (limited to 'src/declarative/scenegraph/util')
22 files changed, 3600 insertions, 0 deletions
diff --git a/src/declarative/scenegraph/util/qsgareaallocator.cpp b/src/declarative/scenegraph/util/qsgareaallocator.cpp new file mode 100644 index 0000000000..a28575c982 --- /dev/null +++ b/src/declarative/scenegraph/util/qsgareaallocator.cpp @@ -0,0 +1,290 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qsgareaallocator_p.h" + +#include <QtCore/qglobal.h> +#include <QtCore/qrect.h> +#include <QtCore/qpoint.h> + +QT_BEGIN_NAMESPACE + +namespace +{ + enum SplitType + { + VerticalSplit, + HorizontalSplit + }; + + static const int maxMargin = 2; +} + +struct QSGAreaAllocatorNode +{ + QSGAreaAllocatorNode(QSGAreaAllocatorNode *parent); + ~QSGAreaAllocatorNode(); + inline bool isLeaf(); + + QSGAreaAllocatorNode *parent; + QSGAreaAllocatorNode *left; + QSGAreaAllocatorNode *right; + int split; // only valid for inner nodes. + SplitType splitType; + bool isOccupied; // only valid for leaf nodes. +}; + +QSGAreaAllocatorNode::QSGAreaAllocatorNode(QSGAreaAllocatorNode *parent) + : parent(parent) + , left(0) + , right(0) + , isOccupied(false) +{ +} + +QSGAreaAllocatorNode::~QSGAreaAllocatorNode() +{ + delete left; + delete right; +} + +bool QSGAreaAllocatorNode::isLeaf() +{ + Q_ASSERT((left != 0) == (right != 0)); + return !left; +} + + +QSGAreaAllocator::QSGAreaAllocator(const QSize &size) : m_size(size) +{ + m_root = new QSGAreaAllocatorNode(0); +} + +QSGAreaAllocator::~QSGAreaAllocator() +{ + delete m_root; +} + +QRect QSGAreaAllocator::allocate(const QSize &size) +{ + QPoint point; + bool result = allocateInNode(size, point, QRect(QPoint(0, 0), m_size), m_root); + return result ? QRect(point, size) : QRect(); +} + +bool QSGAreaAllocator::deallocate(const QRect &rect) +{ + return deallocateInNode(rect.topLeft(), m_root); +} + +bool QSGAreaAllocator::allocateInNode(const QSize &size, QPoint &result, const QRect ¤tRect, QSGAreaAllocatorNode *node) +{ + if (size.width() > currentRect.width() || size.height() > currentRect.height()) + return false; + + if (node->isLeaf()) { + if (node->isOccupied) + return false; + if (size.width() + maxMargin >= currentRect.width() && size.height() + maxMargin >= currentRect.height()) { + //Snug fit, occupy entire rectangle. + node->isOccupied = true; + result = currentRect.topLeft(); + return true; + } + // TODO: Reuse nodes. + // Split node. + node->left = new QSGAreaAllocatorNode(node); + node->right = new QSGAreaAllocatorNode(node); + QRect splitRect = currentRect; + if ((currentRect.width() - size.width()) * currentRect.height() < (currentRect.height() - size.height()) * currentRect.width()) { + node->splitType = HorizontalSplit; + node->split = currentRect.top() + size.height(); + splitRect.setHeight(size.height()); + } else { + node->splitType = VerticalSplit; + node->split = currentRect.left() + size.width(); + splitRect.setWidth(size.width()); + } + return allocateInNode(size, result, splitRect, node->left); + } else { + // TODO: avoid unnecessary recursion. + // has been split. + QRect leftRect = currentRect; + QRect rightRect = currentRect; + if (node->splitType == HorizontalSplit) { + leftRect.setHeight(node->split - leftRect.top()); + rightRect.setTop(node->split); + } else { + leftRect.setWidth(node->split - leftRect.left()); + rightRect.setLeft(node->split); + } + if (allocateInNode(size, result, leftRect, node->left)) + return true; + if (allocateInNode(size, result, rightRect, node->right)) + return true; + return false; + } +} + +bool QSGAreaAllocator::deallocateInNode(const QPoint &pos, QSGAreaAllocatorNode *node) +{ + while (!node->isLeaf()) { + // has been split. + int cmp = node->splitType == HorizontalSplit ? pos.y() : pos.x(); + node = cmp < node->split ? node->left : node->right; + } + if (!node->isOccupied) + return false; + node->isOccupied = false; + mergeNodeWithNeighbors(node); + return true; +} + +void QSGAreaAllocator::mergeNodeWithNeighbors(QSGAreaAllocatorNode *node) +{ + bool done = false; + QSGAreaAllocatorNode *parent = 0; + QSGAreaAllocatorNode *current = 0; + QSGAreaAllocatorNode *sibling; + while (!done) { + Q_ASSERT(node->isLeaf()); + Q_ASSERT(!node->isOccupied); + if (node->parent == 0) + return; // No neighbours. + + SplitType splitType = SplitType(node->parent->splitType); + done = true; + + /* Special case. Might be faster than going through the general code path. + // Merge with sibling. + parent = node->parent; + sibling = (node == parent->left ? parent->right : parent->left); + if (sibling->isLeaf() && !sibling->isOccupied) { + Q_ASSERT(!sibling->right); + node = parent; + parent->isOccupied = false; + delete parent->left; + delete parent->right; + parent->left = parent->right = 0; + done = false; + continue; + } + */ + + // Merge with left neighbour. + current = node; + parent = current->parent; + while (parent && current == parent->left && parent->splitType == splitType) { + current = parent; + parent = parent->parent; + } + + if (parent && parent->splitType == splitType) { + Q_ASSERT(current == parent->right); + Q_ASSERT(parent->left); + + QSGAreaAllocatorNode *neighbor = parent->left; + while (neighbor->right && neighbor->splitType == splitType) + neighbor = neighbor->right; + + if (neighbor->isLeaf() && neighbor->parent->splitType == splitType && !neighbor->isOccupied) { + // Left neighbour can be merged. + parent->split = neighbor->parent->split; + + parent = neighbor->parent; + sibling = neighbor == parent->left ? parent->right : parent->left; + QSGAreaAllocatorNode **nodeRef = &m_root; + if (parent->parent) { + if (parent == parent->parent->left) + nodeRef = &parent->parent->left; + else + nodeRef = &parent->parent->right; + } + sibling->parent = parent->parent; + *nodeRef = sibling; + parent->left = parent->right = 0; + delete parent; + delete neighbor; + done = false; + } + } + + // Merge with right neighbour. + current = node; + parent = current->parent; + while (parent && current == parent->right && parent->splitType == splitType) { + current = parent; + parent = parent->parent; + } + + if (parent && parent->splitType == splitType) { + Q_ASSERT(current == parent->left); + Q_ASSERT(parent->right); + + QSGAreaAllocatorNode *neighbor = parent->right; + while (neighbor->left && neighbor->splitType == splitType) + neighbor = neighbor->left; + + if (neighbor->isLeaf() && neighbor->parent->splitType == splitType && !neighbor->isOccupied) { + // Right neighbour can be merged. + parent->split = neighbor->parent->split; + + parent = neighbor->parent; + sibling = neighbor == parent->left ? parent->right : parent->left; + QSGAreaAllocatorNode **nodeRef = &m_root; + if (parent->parent) { + if (parent == parent->parent->left) + nodeRef = &parent->parent->left; + else + nodeRef = &parent->parent->right; + } + sibling->parent = parent->parent; + *nodeRef = sibling; + parent->left = parent->right = 0; + delete parent; + delete neighbor; + done = false; + } + } + } // end while(!done) +} + +QT_END_NAMESPACE diff --git a/src/declarative/scenegraph/util/qsgareaallocator_p.h b/src/declarative/scenegraph/util/qsgareaallocator_p.h new file mode 100644 index 0000000000..f84732fbdb --- /dev/null +++ b/src/declarative/scenegraph/util/qsgareaallocator_p.h @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef AREAALLOCATOR_H +#define AREAALLOCATOR_H + +#include <QtCore/qsize.h> + +QT_BEGIN_NAMESPACE + +class QRect; +class QPoint; +struct QSGAreaAllocatorNode; +class Q_DECLARATIVE_EXPORT QSGAreaAllocator +{ +public: + QSGAreaAllocator(const QSize &size); + ~QSGAreaAllocator(); + + QRect allocate(const QSize &size); + bool deallocate(const QRect &rect); + bool isEmpty() const { return m_root == 0; } + QSize size() const { return m_size; } +private: + bool allocateInNode(const QSize &size, QPoint &result, const QRect ¤tRect, QSGAreaAllocatorNode *node); + bool deallocateInNode(const QPoint &pos, QSGAreaAllocatorNode *node); + void mergeNodeWithNeighbors(QSGAreaAllocatorNode *node); + + QSGAreaAllocatorNode *m_root; + QSize m_size; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/declarative/scenegraph/util/qsgengine.cpp b/src/declarative/scenegraph/util/qsgengine.cpp new file mode 100644 index 0000000000..1b7f05809b --- /dev/null +++ b/src/declarative/scenegraph/util/qsgengine.cpp @@ -0,0 +1,244 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qsgengine.h" + +#include <private/qsgtexture_p.h> +#include <private/qsgrenderer_p.h> + +QT_BEGIN_NAMESPACE + +class QSGEnginePrivate : public QObjectPrivate +{ +public: + QSGEnginePrivate() + : context(0) + , clearBeforeRender(true) + { + } + + QSGContext *context; + + bool clearBeforeRender; +}; + + +/*! + \class QSGEngine + \brief The QSGEngine class serves as a generic entry point into scene graph specific APIs. + + The QSGEngine class provides factory functions for creating textures. Though the user + can implement any type of texture using the abstract QSGTexture class, the QSGEngine + class provides some convenience for the default usecases. This also allows the scene + graph to apply hardware specific optimzations. + + */ + + + +/*! + Constructs a new QSGengine + */ +QSGEngine::QSGEngine(QObject *parent) : + QObject(*(new QSGEnginePrivate), parent) +{ +} + + +QSGEngine::~QSGEngine() +{ +} + +/*! + \enum TextureOption + + The TextureOption enums are used to customize a texture is wrapped. + + \value TextureHasAlphaChannel The texture has an alpha channel and should + be drawn using blending. + + \value TextureHasMipmaps The texture has mipmaps and can be drawn with + mipmapping enabled. + + \value TextureOwnsGLTexture The texture object owns the texture id and + will delete the GL texture when the texture object is deleted. + + */ + +/*! + \fn void QSGEngine::beforeRendering() + + This signal is emitted before the scene starts rendering. + + Combined with the modes for clearing the background, this option + can be used to paint using raw GL under QML content. + + The GL context used for rendering the scene graph will be bound + at this point. +*/ + +/*! + \fn void QSGEngine::afterRendering() + + This signal is emitted after the scene has completed rendering, before swapbuffers is called. + + This signal can be used to paint using raw GL on top of QML content, + or to do screen scraping of the current frame buffer. + + The GL context used for rendering the scene graph will be bound at this point. + */ + + + +/*! + Sets weither the scene graph rendering of QML should clear the color buffer + before it starts rendering to \a enbled. + + By disabling clearing of the color buffer, it is possible to do GL painting + under the scene graph. + + The color buffer is cleared by default. + */ + +void QSGEngine::setClearBeforeRendering(bool enabled) +{ + Q_D(QSGEngine); + d->clearBeforeRender = enabled; + if (d->clearBeforeRender) { + d->context->renderer()->setClearMode(QSGRenderer::ClearDepthBuffer + | QSGRenderer::ClearColorBuffer); + } else { + d->context->renderer()->setClearMode(QSGRenderer::ClearDepthBuffer); + } +} + + + +/*! + Returns weither clearing of the color buffer is done before rendering or not. + */ + +bool QSGEngine::clearBeforeRendering() const +{ + Q_D(const QSGEngine); + return d->clearBeforeRender; +} + + + +/*! + Creates a new QSGTexture from the supplied \a image. If the image has an + alpha channel, the corresponding texture will have an alpha channel. + + The caller of the function is responsible for deleting the returned texture. + + The actual GL texture will be deleted when the texture object is deleted. + */ + +QSGTexture *QSGEngine::createTextureFromImage(const QImage &image) const +{ + Q_D(const QSGEngine); + return d->context->createTexture(image); +} + + + +/*! + Creates a new QSGTexture object from an existing GL texture \a id. + + The caller of the function is responsible for deleting the returned texture. + + Use \a options to customize the texture attributes. + */ +QSGTexture *QSGEngine::createTextureFromId(uint id, const QSize &size, TextureOptions options) const +{ + QSGPlainTexture *texture = new QSGPlainTexture(); + texture->setTextureId(id); + texture->setHasAlphaChannel(options & TextureHasAlphaChannel); + texture->setHasMipmaps(options & TextureHasMipmaps); + texture->setOwnsTexture(options & TextureOwnsGLTexture); + texture->setTextureSize(size); + return texture; +} + + + +/*! + \internal + + Sets the scene graph context of this engine to context. + + The context will be set by the QSGcontext::initialize() function, + as part of constructing the engine object. + */ + +void QSGEngine::setContext(QSGContext *context) +{ + Q_D(QSGEngine); + d->context = context; +} + + + +/*! + Sets the background color of the scene graph to \a color. + + Changing the clear color has no effect when clearing before rendering is + disabled. + */ + +void QSGEngine::setClearColor(const QColor &color) +{ + d_func()->context->renderer()->setClearColor(color); +} + + + +/*! + Returns the background color of the scene graph + */ + +QColor QSGEngine::clearColor() const +{ + return d_func()->context->renderer()->clearColor(); +} + +QT_END_NAMESPACE diff --git a/src/declarative/scenegraph/util/qsgengine.h b/src/declarative/scenegraph/util/qsgengine.h new file mode 100644 index 0000000000..1665d88ca3 --- /dev/null +++ b/src/declarative/scenegraph/util/qsgengine.h @@ -0,0 +1,100 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSGENGINE_H +#define QSGENGINE_H + +#include <QObject> + +#include <qsgtexture.h> + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Declarative) + +class QSGEnginePrivate; + +class QSGContext; +class Q_DECLARATIVE_EXPORT QSGEngine : public QObject +{ + Q_OBJECT + + Q_DECLARE_PRIVATE(QSGEngine) + +public: + + enum TextureOption { + TextureHasAlphaChannel = 0x0001, + TextureHasMipmaps = 0x0002, + TextureOwnsGLTexture = 0x0004 + }; + Q_DECLARE_FLAGS(TextureOptions, TextureOption) + + QSGTexture *createTextureFromImage(const QImage &image) const; + QSGTexture *createTextureFromId(uint id, const QSize &size, TextureOptions options = TextureOption(0)) const; + + void setClearBeforeRendering(bool enabled); + bool clearBeforeRendering() const; + + void setClearColor(const QColor &color); + QColor clearColor() const; + +Q_SIGNALS: + void beforeRendering(); + void afterRendering(); + +private: + QSGEngine(QObject *parent = 0); + ~QSGEngine(); + + friend class QSGContext; + friend class QSGContextPrivate; + void setContext(QSGContext *context); + +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QSGENGINE_H diff --git a/src/declarative/scenegraph/util/qsgflatcolormaterial.cpp b/src/declarative/scenegraph/util/qsgflatcolormaterial.cpp new file mode 100644 index 0000000000..74ff8acbe0 --- /dev/null +++ b/src/declarative/scenegraph/util/qsgflatcolormaterial.cpp @@ -0,0 +1,192 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qsgflatcolormaterial.h" + +#include <qglshaderprogram.h> + +QT_BEGIN_NAMESPACE + +class FlatColorMaterialShader : public QSGMaterialShader +{ +public: + virtual void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect); + virtual char const *const *attributeNames() const; + + static QSGMaterialType type; + +private: + virtual void initialize(); + virtual const char *vertexShader() const; + virtual const char *fragmentShader() const; + + int m_matrix_id; + int m_color_id; +}; + +QSGMaterialType FlatColorMaterialShader::type; + +void FlatColorMaterialShader::updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect) +{ + Q_ASSERT(oldEffect == 0 || newEffect->type() == oldEffect->type()); + + QSGFlatColorMaterial *oldMaterial = static_cast<QSGFlatColorMaterial *>(oldEffect); + QSGFlatColorMaterial *newMaterial = static_cast<QSGFlatColorMaterial *>(newEffect); + + const QColor &c = newMaterial->color(); + + if (oldMaterial == 0 || c != oldMaterial->color() || state.isOpacityDirty()) { + float opacity = state.opacity(); + QVector4D v(c.redF() * c.alphaF() * opacity, + c.greenF() * c.alphaF() * opacity, + c.blueF() * c.alphaF() * opacity, + c.alphaF() * opacity); + program()->setUniformValue(m_color_id, v); + } + + if (state.isMatrixDirty()) + program()->setUniformValue(m_matrix_id, state.combinedMatrix()); +} + +char const *const *FlatColorMaterialShader::attributeNames() const +{ + static char const *const attr[] = { "vCoord", 0 }; + return attr; +} + +void FlatColorMaterialShader::initialize() +{ + m_matrix_id = program()->uniformLocation("matrix"); + m_color_id = program()->uniformLocation("color"); +} + +const char *FlatColorMaterialShader::vertexShader() const { + return + "attribute highp vec4 vCoord; \n" + "uniform highp mat4 matrix; \n" + "void main() { \n" + " gl_Position = matrix * vCoord; \n" + "}"; +} + +const char *FlatColorMaterialShader::fragmentShader() const { + return + "uniform lowp vec4 color; \n" + "void main() { \n" + " gl_FragColor = color; \n" + "}"; +} + + + +/*! + \class QSGFlatColorMaterial + \brief The QSGFlatColorMaterial provides a convenient way of rendering + solid colored geometry in the scene graph. + + The flat color material will fill every pixel in a geometry using + a solid color. The color can contain transparency. + + The geometry to be rendered with a flat color material requires + vertices in attribute location 0 in the QSGGeometry object to render + correctly. The QSGGeometry::defaultAttributes_Point2D() returns an attribute + set compatible with this material. + + The flat color material respects both current opacity and current matrix + when updating it's rendering state. + */ + + +/*! + Constructs a new flat color material. + + The default color is white. + */ + +QSGFlatColorMaterial::QSGFlatColorMaterial() : m_color(QColor(255, 255, 255)) +{ +} + + + +/*! + \fn QColor QSGFlatColorMaterial::color() const + + Returns this flat color material's color. + + The default color is white. + */ + + + +/*! + Sets this flat color material's color to \a color. + */ + +void QSGFlatColorMaterial::setColor(const QColor &color) +{ + m_color = color; + setFlag(Blending, m_color.alpha() != 0xff); +} + + + +/*! + \internal + */ + +QSGMaterialType *QSGFlatColorMaterial::type() const +{ + return &FlatColorMaterialShader::type; +} + + + +/*! + \internal + */ + +QSGMaterialShader *QSGFlatColorMaterial::createShader() const +{ + return new FlatColorMaterialShader; +} + +QT_END_NAMESPACE diff --git a/src/declarative/scenegraph/util/qsgflatcolormaterial.h b/src/declarative/scenegraph/util/qsgflatcolormaterial.h new file mode 100644 index 0000000000..d9a8d5973c --- /dev/null +++ b/src/declarative/scenegraph/util/qsgflatcolormaterial.h @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef FLATCOLORMATERIAL_H +#define FLATCOLORMATERIAL_H + +#include <qsgmaterial.h> + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Declarative) + +class Q_AUTOTEST_EXPORT QSGFlatColorMaterial : public QSGMaterial +{ +public: + QSGFlatColorMaterial(); + virtual QSGMaterialType *type() const; + virtual QSGMaterialShader *createShader() const; + + void setColor(const QColor &color); + const QColor &color() const { return m_color; } + +private: + QColor m_color; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // FLATCOLORMATERIAL_H diff --git a/src/declarative/scenegraph/util/qsgpainternode.cpp b/src/declarative/scenegraph/util/qsgpainternode.cpp new file mode 100644 index 0000000000..b3f163c604 --- /dev/null +++ b/src/declarative/scenegraph/util/qsgpainternode.cpp @@ -0,0 +1,418 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qsgpainternode_p.h" + +#include "qsgpainteditem.h" +#include <private/qsgcontext_p.h> +#include <qglframebufferobject.h> +#include <qglfunctions.h> +#include <qmath.h> + +QT_BEGIN_NAMESPACE + +#define QT_MINIMUM_FBO_SIZE 64 + +static inline int qt_next_power_of_two(int v) +{ + v--; + v |= v >> 1; + v |= v >> 2; + v |= v >> 4; + v |= v >> 8; + v |= v >> 16; + ++v; + return v; +} + +QSGPainterTexture::QSGPainterTexture() + : QSGPlainTexture() +{ + +} + +void QSGPainterTexture::bind() +{ + if (m_dirty_rect.isNull() || m_texture_id == 0) { + QSGPlainTexture::bind(); + } else { + glBindTexture(GL_TEXTURE_2D, m_texture_id); + + QImage subImage = m_image.copy(m_dirty_rect); + + int w = m_dirty_rect.width(); + int h = m_dirty_rect.height(); + +#ifdef QT_OPENGL_ES + glTexSubImage2D(GL_TEXTURE_2D, 0, m_dirty_rect.x(), m_dirty_rect.y(), w, h, + GL_RGBA, GL_UNSIGNED_BYTE, subImage.constBits()); +#else + glTexSubImage2D(GL_TEXTURE_2D, 0, m_dirty_rect.x(), m_dirty_rect.y(), w, h, + GL_BGRA, GL_UNSIGNED_BYTE, subImage.constBits()); +#endif + + if (m_has_mipmaps && !m_mipmaps_generated) { + const QGLContext *ctx = QGLContext::currentContext(); + ctx->functions()->glGenerateMipmap(GL_TEXTURE_2D); + m_mipmaps_generated = true; + } + + m_dirty_texture = false; + m_dirty_bind_options = false; + } + m_dirty_rect = QRect(); +} + +QSGPainterNode::QSGPainterNode(QSGPaintedItem *item) + : QSGGeometryNode() + , m_preferredRenderTarget(QSGPaintedItem::Image) + , m_actualRenderTarget(QSGPaintedItem::Image) + , m_item(item) + , m_fbo(0) + , m_multisampledFbo(0) + , m_geometry(QSGGeometry::defaultAttributes_TexturedPoint2D(), 4) + , m_texture(0) + , m_size(1, 1) + , m_dirtyContents(false) + , m_opaquePainting(false) + , m_linear_filtering(false) + , m_mipmapping(false) + , m_smoothPainting(false) + , m_extensionsChecked(false) + , m_multisamplingSupported(false) + , m_fillColor(Qt::transparent) + , m_contentsScale(1.0) + , m_dirtyGeometry(false) + , m_dirtyRenderTarget(false) + , m_dirtyTexture(false) +{ + setMaterial(&m_materialO); + setOpaqueMaterial(&m_material); + setGeometry(&m_geometry); +} + +QSGPainterNode::~QSGPainterNode() +{ + delete m_texture; + delete m_fbo; + delete m_multisampledFbo; +} + +void QSGPainterNode::paint() +{ + QRect dirtyRect = m_dirtyRect.isNull() ? QRect(0, 0, m_size.width(), m_size.height()) : m_dirtyRect; + + QPainter painter; + if (m_actualRenderTarget == QSGPaintedItem::Image) + painter.begin(&m_image); + else if (m_multisampledFbo) + painter.begin(m_multisampledFbo); + else + painter.begin(m_fbo); + + if (m_smoothPainting) { + painter.setRenderHints(QPainter::Antialiasing | QPainter::HighQualityAntialiasing + | QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform); + } + + painter.scale(m_contentsScale, m_contentsScale); + + QRect sclip(qFloor(dirtyRect.x()/m_contentsScale), + qFloor(dirtyRect.y()/m_contentsScale), + qCeil(dirtyRect.width()/m_contentsScale+dirtyRect.x()/m_contentsScale-qFloor(dirtyRect.x()/m_contentsScale)), + qCeil(dirtyRect.height()/m_contentsScale+dirtyRect.y()/m_contentsScale-qFloor(dirtyRect.y()/m_contentsScale))); + + if (!m_dirtyRect.isNull()) + painter.setClipRect(sclip); + + painter.setCompositionMode(QPainter::CompositionMode_Source); + painter.fillRect(sclip, m_fillColor); + painter.setCompositionMode(QPainter::CompositionMode_SourceOver); + + m_item->paint(&painter); + painter.end(); + + if (m_actualRenderTarget == QSGPaintedItem::Image) { + m_texture->setImage(m_image); + m_texture->setDirtyRect(dirtyRect); + } else if (m_multisampledFbo) { + QGLFramebufferObject::blitFramebuffer(m_fbo, dirtyRect, m_multisampledFbo, dirtyRect); + } + + m_dirtyRect = QRect(); +} + +void QSGPainterNode::update() +{ + if (m_dirtyRenderTarget) + updateRenderTarget(); + if (m_dirtyGeometry) + updateGeometry(); + if (m_dirtyTexture) + updateTexture(); + + if (m_dirtyContents) + paint(); + + m_dirtyGeometry = false; + m_dirtyRenderTarget = false; + m_dirtyTexture = false; + m_dirtyContents = false; +} + +void QSGPainterNode::updateTexture() +{ + m_texture->setHasMipmaps(m_mipmapping); + m_texture->setHasAlphaChannel(!m_opaquePainting); + m_material.setTexture(m_texture); + m_materialO.setTexture(m_texture); + + markDirty(DirtyMaterial); +} + +void QSGPainterNode::updateGeometry() +{ + QRectF source; + if (m_actualRenderTarget == QSGPaintedItem::Image) + source = QRectF(0, 0, 1, 1); + else + source = QRectF(0, 1, qreal(m_size.width()) / m_fboSize.width(), qreal(-m_size.height()) / m_fboSize.height()); + QSGGeometry::updateTexturedRectGeometry(&m_geometry, + QRectF(0, 0, m_size.width(), m_size.height()), + source); + markDirty(DirtyGeometry); +} + +void QSGPainterNode::updateRenderTarget() +{ + if (!m_extensionsChecked) { + QList<QByteArray> extensions = QByteArray((const char *)glGetString(GL_EXTENSIONS)).split(' '); + m_multisamplingSupported = extensions.contains("GL_EXT_framebuffer_multisample") + && extensions.contains("GL_EXT_framebuffer_blit"); + m_extensionsChecked = true; + } + + m_dirtyContents = true; + + QSGPaintedItem::RenderTarget oldTarget = m_actualRenderTarget; + if (m_preferredRenderTarget == QSGPaintedItem::Image) { + m_actualRenderTarget = QSGPaintedItem::Image; + } else { + if (!m_multisamplingSupported && m_smoothPainting) + m_actualRenderTarget = QSGPaintedItem::Image; + else + m_actualRenderTarget = QSGPaintedItem::FramebufferObject; + } + if (oldTarget != m_actualRenderTarget) { + m_image = QImage(); + delete m_fbo; + delete m_multisampledFbo; + m_fbo = m_multisampledFbo = 0; + } + + if (m_actualRenderTarget == QSGPaintedItem::FramebufferObject) { + const QGLContext *ctx = QGLContext::currentContext(); + if (m_fbo && !m_dirtyGeometry && (!ctx->format().sampleBuffers() || !m_multisamplingSupported)) + return; + + if (m_fboSize.isEmpty()) + updateFBOSize(); + + delete m_fbo; + delete m_multisampledFbo; + m_fbo = m_multisampledFbo = 0; + + if (m_smoothPainting && ctx->format().sampleBuffers() && m_multisamplingSupported) { + { + QGLFramebufferObjectFormat format; + format.setAttachment(QGLFramebufferObject::CombinedDepthStencil); + format.setSamples(ctx->format().samples()); + m_multisampledFbo = new QGLFramebufferObject(m_fboSize, format); + } + { + QGLFramebufferObjectFormat format; + format.setAttachment(QGLFramebufferObject::NoAttachment); + m_fbo = new QGLFramebufferObject(m_fboSize, format); + } + } else { + QGLFramebufferObjectFormat format; + format.setAttachment(QGLFramebufferObject::CombinedDepthStencil); + m_fbo = new QGLFramebufferObject(m_fboSize, format); + } + } else { + if (!m_image.isNull() && !m_dirtyGeometry) + return; + + m_image = QImage(m_size, QImage::Format_ARGB32_Premultiplied); + m_image.fill(Qt::transparent); + } + + QSGPainterTexture *texture = new QSGPainterTexture; + if (m_actualRenderTarget == QSGPaintedItem::Image) { + texture->setOwnsTexture(true); + texture->setTextureSize(m_size); + } else { + texture->setTextureId(m_fbo->texture()); + texture->setOwnsTexture(false); + texture->setTextureSize(m_fboSize); + } + + if (m_texture) + delete m_texture; + + texture->setTextureSize(m_size); + m_texture = texture; +} + +void QSGPainterNode::updateFBOSize() +{ + int fboWidth = qMax(QT_MINIMUM_FBO_SIZE, qt_next_power_of_two(m_size.width())); + int fboHeight = qMax(QT_MINIMUM_FBO_SIZE, qt_next_power_of_two(m_size.height())); + m_fboSize = QSize(fboWidth, fboHeight); +} + +void QSGPainterNode::setPreferredRenderTarget(QSGPaintedItem::RenderTarget target) +{ + if (m_preferredRenderTarget == target) + return; + + m_preferredRenderTarget = target; + + m_dirtyRenderTarget = true; + m_dirtyGeometry = true; + m_dirtyTexture = true; +} + +void QSGPainterNode::setSize(const QSize &size) +{ + if (size == m_size) + return; + + m_size = size; + updateFBOSize(); + + if (m_fbo) + m_dirtyRenderTarget = m_fbo->size() != m_fboSize || m_dirtyRenderTarget; + else + m_dirtyRenderTarget = true; + m_dirtyGeometry = true; + m_dirtyTexture = true; +} + +void QSGPainterNode::setDirty(bool d, const QRect &dirtyRect) +{ + m_dirtyContents = d; + m_dirtyRect = dirtyRect; + + if (m_mipmapping) + m_dirtyTexture = true; + + markDirty(DirtyMaterial); +} + +void QSGPainterNode::setOpaquePainting(bool opaque) +{ + if (opaque == m_opaquePainting) + return; + + m_opaquePainting = opaque; + m_dirtyTexture = true; +} + +void QSGPainterNode::setLinearFiltering(bool linearFiltering) +{ + if (linearFiltering == m_linear_filtering) + return; + + m_linear_filtering = linearFiltering; + + m_material.setFiltering(linearFiltering ? QSGTexture::Linear : QSGTexture::Nearest); + m_materialO.setFiltering(linearFiltering ? QSGTexture::Linear : QSGTexture::Nearest); + markDirty(DirtyMaterial); +} + +void QSGPainterNode::setMipmapping(bool mipmapping) +{ + if (mipmapping == m_mipmapping) + return; + + m_mipmapping = mipmapping; + m_material.setMipmapFiltering(mipmapping ? QSGTexture::Linear : QSGTexture::None); + m_materialO.setMipmapFiltering(mipmapping ? QSGTexture::Linear : QSGTexture::None); + m_dirtyTexture = true; +} + +void QSGPainterNode::setSmoothPainting(bool s) +{ + if (s == m_smoothPainting) + return; + + m_smoothPainting = s; + m_dirtyRenderTarget = true; +} + +void QSGPainterNode::setFillColor(const QColor &c) +{ + if (c == m_fillColor) + return; + + m_fillColor = c; + markDirty(DirtyMaterial); +} + +void QSGPainterNode::setContentsScale(qreal s) +{ + if (s == m_contentsScale) + return; + + m_contentsScale = s; + markDirty(DirtyMaterial); +} + +QImage QSGPainterNode::toImage() const +{ + if (m_actualRenderTarget == QSGPaintedItem::Image) + return m_image; + else + return m_fbo->toImage(); +} + +QT_END_NAMESPACE diff --git a/src/declarative/scenegraph/util/qsgpainternode_p.h b/src/declarative/scenegraph/util/qsgpainternode_p.h new file mode 100644 index 0000000000..625a0cbcb6 --- /dev/null +++ b/src/declarative/scenegraph/util/qsgpainternode_p.h @@ -0,0 +1,149 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSGPAINTERNODE_P_H +#define QSGPAINTERNODE_P_H + +#include "qsgnode.h" +#include "qsgtexturematerial.h" +#include "qsgtexture_p.h" +#include "qsgpainteditem.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Declarative) + +class QGLFramebufferObject; + +class Q_DECLARATIVE_EXPORT QSGPainterTexture : public QSGPlainTexture +{ +public: + QSGPainterTexture(); + + void setDirtyRect(const QRect &rect) { m_dirty_rect = rect; } + + void bind(); + +private: + QRect m_dirty_rect; +}; + +class Q_DECLARATIVE_EXPORT QSGPainterNode : public QSGGeometryNode +{ +public: + QSGPainterNode(QSGPaintedItem *item); + virtual ~QSGPainterNode(); + + void setPreferredRenderTarget(QSGPaintedItem::RenderTarget target); + + void setSize(const QSize &size); + QSize size() const { return m_size; } + + void setDirty(bool d, const QRect &dirtyRect = QRect()); + + void setOpaquePainting(bool opaque); + bool opaquePainting() const { return m_opaquePainting; } + + void setLinearFiltering(bool linearFiltering); + bool linearFiltering() const { return m_linear_filtering; } + + void setMipmapping(bool mipmapping); + bool mipmapping() const { return m_mipmapping; } + + void setSmoothPainting(bool s); + bool smoothPainting() const { return m_smoothPainting; } + + void setFillColor(const QColor &c); + QColor fillColor() const { return m_fillColor; } + + void setContentsScale(qreal s); + qreal contentsScale() const { return m_contentsScale; } + + QImage toImage() const; + void update(); + + void paint(); + +private: + void updateTexture(); + void updateGeometry(); + void updateRenderTarget(); + void updateFBOSize(); + + QSGPaintedItem::RenderTarget m_preferredRenderTarget; + QSGPaintedItem::RenderTarget m_actualRenderTarget; + + QSGPaintedItem *m_item; + + QGLFramebufferObject *m_fbo; + QGLFramebufferObject *m_multisampledFbo; + QImage m_image; + + QSGOpaqueTextureMaterial m_material; + QSGTextureMaterial m_materialO; + QSGGeometry m_geometry; + QSGPainterTexture *m_texture; + + QSize m_size; + QSize m_fboSize; + bool m_dirtyContents; + QRect m_dirtyRect; + bool m_opaquePainting; + bool m_linear_filtering; + bool m_mipmapping; + bool m_smoothPainting; + bool m_extensionsChecked; + bool m_multisamplingSupported; + QColor m_fillColor; + qreal m_contentsScale; + + bool m_dirtyGeometry; + bool m_dirtyRenderTarget; + bool m_dirtyTexture; +}; + +QT_END_HEADER + +QT_END_NAMESPACE + +#endif // QSGPAINTERNODE_P_H diff --git a/src/declarative/scenegraph/util/qsgsimplerectnode.cpp b/src/declarative/scenegraph/util/qsgsimplerectnode.cpp new file mode 100644 index 0000000000..604222dad5 --- /dev/null +++ b/src/declarative/scenegraph/util/qsgsimplerectnode.cpp @@ -0,0 +1,132 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qsgsimplerectnode.h" +#include "qsgflatcolormaterial.h" + +QT_BEGIN_NAMESPACE + +/*! + \class QSGSimpleRectNode + + \brief The QSGSimpleRectNode class is a convenience class for drawing + solid filled rectangles using scenegraph. + + */ + + + +/*! + Constructs a QSGSimpleRectNode instance which is spanning \a rect with + the color \a color. + */ +QSGSimpleRectNode::QSGSimpleRectNode(const QRectF &rect, const QColor &color) + : m_geometry(QSGGeometry::defaultAttributes_Point2D(), 4) +{ + QSGGeometry::updateRectGeometry(&m_geometry, rect); + m_material.setColor(color); + setMaterial(&m_material); + setGeometry(&m_geometry); +} + + + +/*! + Constructs a QSGSimpleRectNode instance with an empty rectangle and + white color. + */ +QSGSimpleRectNode::QSGSimpleRectNode() + : m_geometry(QSGGeometry::defaultAttributes_Point2D(), 4) +{ + QSGGeometry::updateRectGeometry(&m_geometry, QRectF()); + setMaterial(&m_material); + setGeometry(&m_geometry); +} + + + +/*! + Sets the rectangle of this rect node to \a rect. + */ +void QSGSimpleRectNode::setRect(const QRectF &rect) +{ + QSGGeometry::updateRectGeometry(&m_geometry, rect); + markDirty(QSGNode::DirtyGeometry); +} + + + +/*! + Returns the rectangle that this rect node covers. + */ +QRectF QSGSimpleRectNode::rect() const +{ + const QSGGeometry::Point2D *pts = m_geometry.vertexDataAsPoint2D(); + return QRectF(pts[0].x, + pts[0].y, + pts[3].x - pts[0].x, + pts[3].y - pts[0].y); +} + + +/*! + Sets the color of this rectangle to \a color. The default + color will be white. + */ +void QSGSimpleRectNode::setColor(const QColor &color) +{ + if (color != m_material.color()) { + m_material.setColor(color); + markDirty(QSGNode::DirtyMaterial); + } +} + + + +/*! + Returns the color of this rectangle. + */ +QColor QSGSimpleRectNode::color() const +{ + return m_material.color(); +} + +QT_END_NAMESPACE diff --git a/src/declarative/scenegraph/util/qsgsimplerectnode.h b/src/declarative/scenegraph/util/qsgsimplerectnode.h new file mode 100644 index 0000000000..ac001ab4eb --- /dev/null +++ b/src/declarative/scenegraph/util/qsgsimplerectnode.h @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef SOLIDRECTNODE_H +#define SOLIDRECTNODE_H + +#include "qsgnode.h" +#include "qsgflatcolormaterial.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Declarative) + +class Q_DECLARATIVE_EXPORT QSGSimpleRectNode : public QSGGeometryNode +{ +public: + QSGSimpleRectNode(const QRectF &rect, const QColor &color); + QSGSimpleRectNode(); + + void setRect(const QRectF &rect); + inline void setRect(qreal x, qreal y, qreal w, qreal h) { setRect(QRectF(x, y, w, h)); } + QRectF rect() const; + + void setColor(const QColor &color); + QColor color() const; + +private: + QSGFlatColorMaterial m_material; + QSGGeometry m_geometry; + void *reserved; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // SOLIDRECTNODE_H diff --git a/src/declarative/scenegraph/util/qsgsimpletexturenode.cpp b/src/declarative/scenegraph/util/qsgsimpletexturenode.cpp new file mode 100644 index 0000000000..a3c96dcd2b --- /dev/null +++ b/src/declarative/scenegraph/util/qsgsimpletexturenode.cpp @@ -0,0 +1,152 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include "qsgsimpletexturenode.h" + +QT_BEGIN_NAMESPACE + +static void qsgsimpletexturenode_update(QSGGeometry *g, + QSGTexture *texture, + const QRectF &rect) +{ + if (!texture) + return; + + QSize ts = texture->textureSize(); + QRectF sourceRect(0, 0, ts.width(), ts.height()); + QSGGeometry::updateTexturedRectGeometry(g, rect, texture->convertToNormalizedSourceRect(sourceRect)); +} + +/*! + \class QSGSimpleTextureNode + \brief The QSGSimpleTextureNode provided for convenience to easily draw + textured content using the QML scene graph. + + \warning The simple texture node class must have texture before being + added to the scene graph to be rendered. +*/ + +/*! + Constructs a new simple texture node + */ +QSGSimpleTextureNode::QSGSimpleTextureNode() + : m_geometry(QSGGeometry::defaultAttributes_TexturedPoint2D(), 4) +{ + setGeometry(&m_geometry); + setMaterial(&m_material); + setOpaqueMaterial(&m_opaque_material); +} + +/*! + Sets the filtering to be used for this texture node to \a filtering. + + For smooth scaling, use QSGTexture::Linear; for normal scaling, use + QSGTexture::Nearest. + */ +void QSGSimpleTextureNode::setFiltering(QSGTexture::Filtering filtering) +{ + if (m_material.filtering() == filtering) + return; + + m_material.setFiltering(filtering); + m_opaque_material.setFiltering(filtering); + markDirty(DirtyMaterial); +} + + +/*! + Returns the filtering currently set on this texture node + */ +QSGTexture::Filtering QSGSimpleTextureNode::filtering() const +{ + return m_material.filtering(); +} + + +/*! + Sets the target rect of this texture node to \a r + */ +void QSGSimpleTextureNode::setRect(const QRectF &r) +{ + if (m_rect == r) + return; + m_rect = r; + qsgsimpletexturenode_update(&m_geometry, texture(), m_rect); + markDirty(DirtyGeometry); +} + + +/*! + Returns the target rect of this texture node. + */ +QRectF QSGSimpleTextureNode::rect() const +{ + return m_rect; +} + +/*! + Sets the texture of this texture node to \a texture. + + \warning A texture node must have a texture before being added + to the scenegraph to be rendered. + */ +void QSGSimpleTextureNode::setTexture(QSGTexture *texture) +{ + if (m_material.texture() == texture) + return; + m_material.setTexture(texture); + m_opaque_material.setTexture(texture); + qsgsimpletexturenode_update(&m_geometry, texture, m_rect); + markDirty(DirtyMaterial); +} + + + +/*! + Returns the texture for this texture node + */ +QSGTexture *QSGSimpleTextureNode::texture() const +{ + return m_material.texture(); +} + +QT_END_NAMESPACE diff --git a/src/declarative/scenegraph/util/qsgsimpletexturenode.h b/src/declarative/scenegraph/util/qsgsimpletexturenode.h new file mode 100644 index 0000000000..44925be881 --- /dev/null +++ b/src/declarative/scenegraph/util/qsgsimpletexturenode.h @@ -0,0 +1,82 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSGSIMPLETEXTURENODE_H +#define QSGSIMPLETEXTURENODE_H + +#include "qsgnode.h" +#include "qsggeometry.h" +#include "qsgtexturematerial.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Declarative) + +class Q_DECLARATIVE_EXPORT QSGSimpleTextureNode : public QSGGeometryNode +{ +public: + QSGSimpleTextureNode(); + + void setRect(const QRectF &rect); + inline void setRect(qreal x, qreal y, qreal w, qreal h) { setRect(QRectF(x, y, w, h)); } + QRectF rect() const; + + void setTexture(QSGTexture *texture); + QSGTexture *texture() const; + + void setFiltering(QSGTexture::Filtering filtering); + QSGTexture::Filtering filtering() const; + +private: + QSGGeometry m_geometry; + QSGOpaqueTextureMaterial m_opaque_material; + QSGTextureMaterial m_material; + + QRectF m_rect; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QSGSIMPLETEXTURENODE_H diff --git a/src/declarative/scenegraph/util/qsgtexture.cpp b/src/declarative/scenegraph/util/qsgtexture.cpp new file mode 100644 index 0000000000..c82f214cc8 --- /dev/null +++ b/src/declarative/scenegraph/util/qsgtexture.cpp @@ -0,0 +1,415 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#define GL_GLEXT_PROTOTYPES + +#include <private/qsgtexture_p.h> +#include <qglfunctions.h> +#include <private/qsgcontext_p.h> +#include <qthread.h> + +QT_BEGIN_NAMESPACE + +inline static bool isPowerOfTwo(int x) +{ + // Assumption: x >= 1 + return x == (x & -x); +} + +QSGTexturePrivate::QSGTexturePrivate() + : wrapChanged(false) + , filteringChanged(false) + , horizontalWrap(QSGTexture::ClampToEdge) + , verticalWrap(QSGTexture::ClampToEdge) + , mipmapMode(QSGTexture::None) + , filterMode(QSGTexture::Nearest) +{ +} + +#ifndef QT_NO_DEBUG +static int qt_texture_count = 0; + +static void qt_print_texture_count() +{ + qDebug("Number of leaked textures: %i", qt_texture_count); + qt_texture_count = -1; +} +#endif + + + +QSGTexture::QSGTexture() + : QObject(*(new QSGTexturePrivate)) +{ +#ifndef QT_NO_DEBUG + ++qt_texture_count; + static bool atexit_registered = false; + if (!atexit_registered) { + atexit(qt_print_texture_count); + atexit_registered = true; + } +#endif +} + +QSGTexture::~QSGTexture() +{ +#ifndef QT_NO_DEBUG + --qt_texture_count; + if (qt_texture_count < 0) + qDebug("Material destroyed after qt_print_texture_count() was called."); +#endif +} + + +/*! + \fn void QSGTexture::setImage(const QImage &image) + + This function may be calld from arbitrary an arbitrary thread and may not + use GL calls. + */ + + +/*! + \fn void QSGTexture::bind() + + Call this function to bind this texture to the current texture + target. + + Binding a texture may also include uploading the texture data from + a previously set QImage. + */ + +void QSGTexture::removeFromAtlas() +{ + // default textures are not in atlasses, so do nothing... +} + +/*! + Returns weither this texture is part of an atlas or not. + + The default implementation returns false. + */ +bool QSGTexture::isAtlasTexture() const +{ + return false; +} + + +/*! + Returns the rectangle inside textureSize() that this texture + represents in normalized coordinates. + + The default implementation returns a rect at position (0, 0) with + width and height of 1. + */ +QRectF QSGTexture::textureSubRect() const +{ + return QRectF(0, 0, 1, 1); +} + +/*! + \fn bool QSGTexture::hasMipmaps() const + + Returns true if the texture data contains mipmap levels. + */ + + +/*! + Sets the mipmap sampling mode to be used for the upcoming bind() call to \a filter. + + Setting the mipmap filtering has no effect it the texture does not have mipmaps. + + \sa hasMipmaps() + */ +void QSGTexture::setMipmapFiltering(Filtering filter) +{ + Q_D(QSGTexture); + if (d->mipmapMode != (uint) filter) { + d->mipmapMode = filter; + d->filteringChanged = true; + } +} + +/*! + Returns whether mipmapping should be used when sampling from this texture. + */ +QSGTexture::Filtering QSGTexture::mipmapFiltering() const +{ + return (QSGTexture::Filtering) d_func()->mipmapMode; +} + + +/*! + Sets the sampling mode to be used for the upcoming bind() call to \a filter. + */ +void QSGTexture::setFiltering(QSGTexture::Filtering filter) +{ + Q_D(QSGTexture); + if (d->filterMode != (uint) filter) { + d->filterMode = filter; + d->filteringChanged = true; + } +} + +QSGTexture::Filtering QSGTexture::filtering() const +{ + return (QSGTexture::Filtering) d_func()->filterMode; +} + + + +/*! + Sets the horizontal wrap mode to be used for the upcoming bind() call to \a hwrap + */ + +void QSGTexture::setHorizontalWrapMode(WrapMode hwrap) +{ + Q_D(QSGTexture); + if ((uint) hwrap != d->horizontalWrap) { + d->horizontalWrap = hwrap; + d->wrapChanged = true; + } +} + +QSGTexture::WrapMode QSGTexture::horizontalWrapMode() const +{ + return (QSGTexture::WrapMode) d_func()->horizontalWrap; +} + + + +void QSGTexture::setVerticalWrapMode(WrapMode vwrap) +{ + Q_D(QSGTexture); + if ((uint) vwrap != d->verticalWrap) { + d->verticalWrap = vwrap; + d->wrapChanged = true; + } +} + +QSGTexture::WrapMode QSGTexture::verticalWrapMode() const +{ + return (QSGTexture::WrapMode) d_func()->verticalWrap; +} + + +/*! + Update the texture state to match the filtering, mipmap and wrap options + currently set. + + If \a force is true, all properties will be updated regardless of weither + they have changed or not. + */ +void QSGTexture::updateBindOptions(bool force) +{ + Q_D(QSGTexture); + if (force || d->filteringChanged) { + bool linear = d->filterMode == Linear; + GLint minFilter = linear ? GL_LINEAR : GL_NEAREST; + GLint magFilter = linear ? GL_LINEAR : GL_NEAREST; + + if (hasMipmaps()) { + if (d->mipmapMode == Nearest) + minFilter = linear ? GL_LINEAR_MIPMAP_NEAREST : GL_NEAREST_MIPMAP_NEAREST; + else if (d->mipmapMode == Linear) + minFilter = linear ? GL_LINEAR_MIPMAP_LINEAR : GL_NEAREST_MIPMAP_LINEAR; + } + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minFilter); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magFilter); + d->filteringChanged = false; + } + + if (force || d->wrapChanged) { +#if !defined(QT_NO_DEBUG) && defined(QT_OPENGL_ES_2) + if (d->horizontalWrap == Repeat || d->verticalWrap == Repeat) { + bool npotSupported = QGLContext::currentContext()->functions()->hasOpenGLFeature(QGLFunctions::NPOTTextures); + QSize size = textureSize(); + bool isNpot = !isPowerOfTwo(size.width()) || !isPowerOfTwo(size.height()); + if (!npotSupported && isNpot) + qWarning("Scene Graph: This system does not support the REPEAT wrap mode for non-power-of-two textures."); + } +#endif + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, d->horizontalWrap == Repeat ? GL_REPEAT : GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, d->verticalWrap == Repeat ? GL_REPEAT : GL_CLAMP_TO_EDGE); + d->wrapChanged = false; + } +} + +QSGPlainTexture::QSGPlainTexture() + : QSGTexture() + , m_texture_id(0) + , m_has_alpha(false) + , m_has_mipmaps(false) + , m_dirty_bind_options(false) + , m_owns_texture(true) + , m_mipmaps_generated(false) +{ +} + + +QSGPlainTexture::~QSGPlainTexture() +{ + if (m_texture_id && m_owns_texture) + glDeleteTextures(1, &m_texture_id); +} + +#ifdef QT_OPENGL_ES +static void swizzleBGRAToRGBA(QImage *image) +{ + const int width = image->width(); + const int height = image->height(); + for (int i = 0; i < height; ++i) { + uint *p = (uint *) image->scanLine(i); + for (int x = 0; x < width; ++x) + p[x] = ((p[x] << 16) & 0xff0000) | ((p[x] >> 16) & 0xff) | (p[x] & 0xff00ff00); + } +} +#endif + +void QSGPlainTexture::setImage(const QImage &image) +{ + m_image = image.convertToFormat(QImage::Format_ARGB32_Premultiplied); +#ifdef QT_OPENGL_ES + swizzleBGRAToRGBA(&m_image); +#endif + + m_texture_size = image.size(); + m_has_alpha = image.hasAlphaChannel(); + m_dirty_texture = true; + m_dirty_bind_options = true; + } + +void QSGPlainTexture::setTextureId(int id) +{ + if (m_texture_id && m_owns_texture) + glDeleteTextures(1, &m_texture_id); + + m_texture_id = id; + m_dirty_texture = false; + m_dirty_bind_options = true; + m_image = QImage(); + m_mipmaps_generated = false; +} + +void QSGPlainTexture::setHasMipmaps(bool mm) +{ + m_has_mipmaps = mm; + m_mipmaps_generated = false; +} + + +void QSGPlainTexture::bind() +{ + if (!m_dirty_texture) { + glBindTexture(GL_TEXTURE_2D, m_texture_id); + if (m_has_mipmaps && !m_mipmaps_generated) { + const QGLContext *ctx = QGLContext::currentContext(); + ctx->functions()->glGenerateMipmap(GL_TEXTURE_2D); + m_mipmaps_generated = true; + } + updateBindOptions(m_dirty_bind_options); + m_dirty_bind_options = false; + return; + } + + m_dirty_texture = false; + + if (m_texture_id && m_owns_texture) + glDeleteTextures(1, &m_texture_id); + + if (m_image.isNull()) { + m_texture_id = 0; + m_texture_size = QSize(); + m_has_mipmaps = false; + m_has_alpha = false; + return; + } + + glGenTextures(1, &m_texture_id); + glBindTexture(GL_TEXTURE_2D, m_texture_id); + + // ### TODO: check for out-of-memory situations... + int w = m_image.width(); + int h = m_image.height(); + +#ifdef QT_OPENGL_ES + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, m_image.constBits()); +#else + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_BGRA, GL_UNSIGNED_BYTE, m_image.constBits()); +#endif + + if (m_has_mipmaps) { + const QGLContext *ctx = QGLContext::currentContext(); + ctx->functions()->glGenerateMipmap(GL_TEXTURE_2D); + m_mipmaps_generated = true; + } + + m_texture_size = QSize(w, h); + m_texture_rect = QRectF(0, 0, 1, 1); + + updateBindOptions(m_dirty_bind_options); + m_dirty_bind_options = false; +} + + +/*! + \class QSGDynamicTexture + \brief The QSGDynamicTexture class serves as a baseclass for dynamically changing textures, + such as content that is rendered to FBO's. + + To update the content of the texture, call updateTexture() explicitly. Simply calling bind() + will not update the texture. + */ + + +/*! + \fn bool QSGDynamicTexture::updateTexture() + + Call this function to explicitely update the dynamic texture. Calling bind() will bind + the content that was previously updated. + + The function returns true if the texture was changed as a resul of the update; otherwise + returns false. + */ + + + +QT_END_NAMESPACE diff --git a/src/declarative/scenegraph/util/qsgtexture.h b/src/declarative/scenegraph/util/qsgtexture.h new file mode 100644 index 0000000000..9b95ef36ad --- /dev/null +++ b/src/declarative/scenegraph/util/qsgtexture.h @@ -0,0 +1,132 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSGTEXTURE_H +#define QSGTEXTURE_H + +#include <QObject> +#include <QImage> + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Declarative) + +class QSGTexturePrivate; +class Q_DECLARATIVE_EXPORT QSGTexture : public QObject +{ + Q_OBJECT + Q_DECLARE_PRIVATE(QSGTexture) + +public: + QSGTexture(); + ~QSGTexture(); + + enum WrapMode { + Repeat, + ClampToEdge + }; + + enum Filtering { + None, + Nearest, + Linear + }; + + virtual int textureId() const = 0; + virtual QSize textureSize() const = 0; + virtual bool hasAlphaChannel() const = 0; + virtual bool hasMipmaps() const = 0; + + virtual QRectF textureSubRect() const; + + virtual bool isAtlasTexture() const; + virtual void removeFromAtlas(); + + virtual void bind() = 0; + void updateBindOptions(bool force = false); + + void setMipmapFiltering(Filtering filter); + QSGTexture::Filtering mipmapFiltering() const; + + void setFiltering(Filtering filter); + QSGTexture::Filtering filtering() const; + + void setHorizontalWrapMode(WrapMode hwrap); + QSGTexture::WrapMode horizontalWrapMode() const; + + void setVerticalWrapMode(WrapMode vwrap); + QSGTexture::WrapMode verticalWrapMode() const; + + inline QRectF convertToNormalizedSourceRect(const QRectF &rect) const; + +protected: + QSGTexture(QSGTexturePrivate &dd); +}; + +QRectF QSGTexture::convertToNormalizedSourceRect(const QRectF &rect) const +{ + QSize s = textureSize(); + QRectF r = textureSubRect(); + + qreal sx = r.width() / s.width(); + qreal sy = r.height() / s.height(); + + return QRectF(r.x() + rect.x() * sx, + r.y() + rect.y() * sy, + rect.width() * sx, + rect.height() * sy); +} + + +class QSGDynamicTexture : public QSGTexture +{ + Q_OBJECT +public: + virtual bool updateTexture() = 0; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/declarative/scenegraph/util/qsgtexture_p.h b/src/declarative/scenegraph/util/qsgtexture_p.h new file mode 100644 index 0000000000..d504732f35 --- /dev/null +++ b/src/declarative/scenegraph/util/qsgtexture_p.h @@ -0,0 +1,113 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSGTEXTURE_P_H +#define QSGTEXTURE_P_H + +#include <private/qobject_p.h> + +#include <QtOpenGL/qgl.h> + +#include "qsgtexture.h" +#include <private/qsgcontext_p.h> + +QT_BEGIN_NAMESPACE + +class QSGTexturePrivate : public QObjectPrivate +{ + Q_DECLARE_PUBLIC(QSGTexture); +public: + QSGTexturePrivate(); + + uint wrapChanged : 1; + uint filteringChanged : 1; + + uint horizontalWrap : 1; + uint verticalWrap : 1; + uint mipmapMode : 2; + uint filterMode : 2; +}; + +class Q_DECLARATIVE_EXPORT QSGPlainTexture : public QSGTexture +{ + Q_OBJECT +public: + QSGPlainTexture(); + virtual ~QSGPlainTexture(); + + void setOwnsTexture(bool owns) { m_owns_texture = owns; } + bool ownsTexture() const { return m_owns_texture; } + + void setTextureId(int id); + int textureId() const { return m_texture_id; } + + void setTextureSize(const QSize &size) { m_texture_size = size; } + QSize textureSize() const { return m_texture_size; } + + void setHasAlphaChannel(bool alpha) { m_has_alpha = alpha; } + bool hasAlphaChannel() const { return m_has_alpha; } + + void setHasMipmaps(bool mm); + bool hasMipmaps() const { return m_has_mipmaps; } + + void setImage(const QImage &image); + const QImage &image() { return m_image; } + + virtual void bind(); + +protected: + QImage m_image; + + GLuint m_texture_id; + QSize m_texture_size; + QRectF m_texture_rect; + + uint m_has_alpha : 1; + uint m_has_mipmaps : 1; + uint m_dirty_texture : 1; + uint m_dirty_bind_options : 1; + uint m_owns_texture : 1; + uint m_mipmaps_generated : 1; +}; + +QT_END_NAMESPACE + +#endif // QSGTEXTURE_P_H diff --git a/src/declarative/scenegraph/util/qsgtexturematerial.cpp b/src/declarative/scenegraph/util/qsgtexturematerial.cpp new file mode 100644 index 0000000000..cdca59963c --- /dev/null +++ b/src/declarative/scenegraph/util/qsgtexturematerial.cpp @@ -0,0 +1,410 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qsgtexturematerial_p.h" + +#include <QtOpenGL/qglshaderprogram.h> +#include <QtOpenGL/qglfunctions.h> + +QT_BEGIN_NAMESPACE + +inline static bool isPowerOfTwo(int x) +{ + // Assumption: x >= 1 + return x == (x & -x); +} + +const char qt_scenegraph_texture_material_vertex_code[] = + "uniform highp mat4 qt_Matrix; \n" + "attribute highp vec4 qt_VertexPosition; \n" + "attribute highp vec2 qt_VertexTexCoord; \n" + "varying highp vec2 qt_TexCoord; \n" + "void main() { \n" + " qt_TexCoord = qt_VertexTexCoord; \n" + " gl_Position = qt_Matrix * qt_VertexPosition; \n" + "}"; + +const char qt_scenegraph_texture_material_fragment[] = + "varying highp vec2 qt_TexCoord; \n" + "uniform sampler2D qt_Texture; \n" + "void main() { \n" + " gl_FragColor = texture2D(qt_Texture, qt_TexCoord);\n" + "}"; + + +const char *QSGOpaqueTextureMaterialShader::vertexShader() const +{ + return qt_scenegraph_texture_material_vertex_code; +} + +const char *QSGOpaqueTextureMaterialShader::fragmentShader() const +{ + return qt_scenegraph_texture_material_fragment; +} + +QSGMaterialType QSGOpaqueTextureMaterialShader::type; + +char const *const *QSGOpaqueTextureMaterialShader::attributeNames() const +{ + static char const *const attr[] = { "qt_VertexPosition", "qt_VertexTexCoord", 0 }; + return attr; +} + +void QSGOpaqueTextureMaterialShader::initialize() +{ + m_matrix_id = program()->uniformLocation("qt_Matrix"); +} + +void QSGOpaqueTextureMaterialShader::updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect) +{ + Q_ASSERT(oldEffect == 0 || newEffect->type() == oldEffect->type()); + QSGOpaqueTextureMaterial *tx = static_cast<QSGOpaqueTextureMaterial *>(newEffect); + QSGOpaqueTextureMaterial *oldTx = static_cast<QSGOpaqueTextureMaterial *>(oldEffect); + + QSGTexture *t = tx->texture(); + + t->setFiltering(tx->filtering()); +#ifdef QT_OPENGL_ES_2 + bool npotSupported = state.context()->functions()->hasOpenGLFeature(QGLFunctions::NPOTTextures); + QSize size = t->textureSize(); + bool isNpot = !isPowerOfTwo(size.width()) || !isPowerOfTwo(size.height()); + if (!npotSupported && isNpot) { + t->setHorizontalWrapMode(QSGTexture::ClampToEdge); + t->setVerticalWrapMode(QSGTexture::ClampToEdge); + } else +#endif + { + t->setHorizontalWrapMode(tx->horizontalWrapMode()); + t->setVerticalWrapMode(tx->verticalWrapMode()); + } + t->setMipmapFiltering(tx->mipmapFiltering()); + + if (oldTx == 0 || oldTx->texture()->textureId() != t->textureId()) + t->bind(); + else + t->updateBindOptions(); + + if (state.isMatrixDirty()) + program()->setUniformValue(m_matrix_id, state.combinedMatrix()); +} + + +/*! + \class QSGOpaqueTextureMaterial + \brief The QSGOpaqueTextureMaterial class provides a convenient way of + rendering textured geometry in the scene graph. + + The opaque textured material will fill every pixel in a geometry with + the supplied texture. The material does not respect the opacity of the + QSGMaterialShader::RenderState, so opacity nodes in the parent chain + of nodes using this material, have no effect. + + The geometry to be rendered with an opaque texture material requires + vertices in attribute location 0 and texture coordinates in attribute + location 1. The texture coordinate is a 2-dimensional floating-point + tuple. The QSGGeometry::defaultAttributes_TexturedPoint2D returns an + attribute set compatible with this material. + + The texture to be rendered is can be set using setTexture(). How the + texure should be rendered can be specified using setMipmapFiltering(), + setFiltering(), setHorizontalWrapMode() and setVerticalWrapMode(). + The rendering state is set on the texture instance just before it + is bound. + + The opaque textured material respects the current matrix and the alpha + channel of the texture. It will disregard the accumulated opacity in + the scenegraph. + + A texture material must have a texture set before it is used as + a material in the scene graph. + */ + + + +/*! + Creates a new QSGOpaqueTextureMaterial. + + The default mipmap filtering and filtering mode is set to + QSGTexture::Nearest. The default wrap modes is set to + QSGTexture::ClampToEdge. + + */ +QSGOpaqueTextureMaterial::QSGOpaqueTextureMaterial() + : m_texture(0) + , m_filtering(QSGTexture::Nearest) + , m_mipmap_filtering(QSGTexture::Nearest) + , m_horizontal_wrap(QSGTexture::ClampToEdge) + , m_vertical_wrap(QSGTexture::ClampToEdge) +{ +} + + +/*! + \internal + */ +QSGMaterialType *QSGOpaqueTextureMaterial::type() const +{ + return &QSGOpaqueTextureMaterialShader::type; +} + +/*! + \internal + */ +QSGMaterialShader *QSGOpaqueTextureMaterial::createShader() const +{ + return new QSGOpaqueTextureMaterialShader; +} + + + +/*! + \fn QSGTexture *QSGOpaqueTextureMaterial::texture() const + + Returns this texture material's texture. + */ + + + +/*! + Sets the texture of this material to \a texture. + + The material does not take ownership over the texture. + */ + +void QSGOpaqueTextureMaterial::setTexture(QSGTexture *texture) +{ + m_texture = texture; + setFlag(Blending, m_texture ? m_texture->hasAlphaChannel() : false); +} + + + +/*! + \fn void QSGOpaqueTextureMaterial::setMipmapFiltering(QSGTexture::Filtering filtering) + + Sets the mipmap mode to \a filtering. + + The mipmap filtering mode is set on the texture instance just before the + texture is bound for rendering. + + If the texture does not have mipmapping support, enabling mipmapping has no + effect. + */ + + + +/*! + \fn QSGTexture::Filtering QSGOpaqueTextureMaterial::mipmapFiltering() const + + Returns this material's mipmap filtering mode. + + The default mipmap mode is QSGTexture::Nearest. + */ + + + +/*! + \fn void QSGOpaqueTextureMaterial::setFiltering(QSGTexture::Filtering filtering) + + Sets the filtering to \a filtering. + + The filtering mode is set on the texture instance just before the texture + is bound for rendering. + */ + + + +/*! + \fn QSGTexture::Filtering filtering() const + + Returns this material's filtering mode. + + The default filtering is QSGTexture::Nearest. + */ + + + +/*! + \fn void setHorizontalWrapMode(QSGTexture::WrapMode mode) + + Sets the horizontal wrap mode to \a mode. + + The horizontal wrap mode is set on the texture instance just before the texture + is bound for rendering. + */ + + + + /*! + \fn QSGTexture::WrapMode horizontalWrapMode() const + + Returns this material's horizontal wrap mode. + + The default horizontal wrap mode is QSGTexutre::ClampToEdge + */ + + + +/*! + \fn void setVerticalWrapMode(QSGTexture::WrapMode mode) + + Sets the vertical wrap mode to \a mode. + + The vertical wrap mode is set on the texture instance just before the texture + is bound for rendering. + */ + + + + /*! + \fn QSGTexture::WrapMode verticalWrapMode() const + + Returns this material's vertical wrap mode. + + The default vertical wrap mode is QSGTexutre::ClampToEdge + */ + + + +/*! + \internal + */ + +int QSGOpaqueTextureMaterial::compare(const QSGMaterial *o) const +{ + Q_ASSERT(o && type() == o->type()); + const QSGOpaqueTextureMaterial *other = static_cast<const QSGOpaqueTextureMaterial *>(o); + if (int diff = m_texture->textureId() - other->texture()->textureId()) + return diff; + return int(m_filtering) - int(other->m_filtering); +} + + + +/*! + \class QSGTextureMaterial + \brief The QSGTextureMaterial class provides a convenient way of + rendering textured geometry in the scene graph. + + The textured material will fill every pixel in a geometry with + the supplied texture. + + The geometry to be rendered with an opaque texture material requires + vertices in attribute location 0 and texture coordinates in attribute + location 1. The texture coordinate is a 2-dimensional floating-point + tuple. The QSGGeometry::defaultAttributes_TexturedPoint2D returns an + attribute set compatible with this material. + + The texture to be rendered is set using setTexture(). How the + texure should be rendered can be specified using setMipmapFiltering(), + setFiltering(), setHorizontalWrapMode() and setVerticalWrapMode(). + The rendering state is set on the texture instance just before it + is bound. + + The opaque textured material respects the current matrix and the alpha + channel of the texture. It will disregard the accumulated opacity in + the scenegraph. + + A texture material must have a texture set before it is used as + a material in the scene graph. + */ + +static const char qt_scenegraph_texture_material_opacity_fragment[] = + "varying highp vec2 qt_TexCoord; \n" + "uniform sampler2D qt_Texture; \n" + "uniform lowp float opacity; \n" + "void main() { \n" + " gl_FragColor = texture2D(qt_Texture, qt_TexCoord) * opacity; \n" + "}"; + +class QSGTextureMaterialShader : public QSGOpaqueTextureMaterialShader +{ +public: + virtual void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect); + virtual void initialize(); + + static QSGMaterialType type; + +protected: + virtual const char *fragmentShader() const { return qt_scenegraph_texture_material_opacity_fragment; } + + int m_opacity_id; +}; +QSGMaterialType QSGTextureMaterialShader::type; + + + +/*! + \internal + */ + +QSGMaterialType *QSGTextureMaterial::type() const +{ + return &QSGTextureMaterialShader::type; +} + + + +/*! + \internal + */ + +QSGMaterialShader *QSGTextureMaterial::createShader() const +{ + return new QSGTextureMaterialShader; +} + +void QSGTextureMaterialShader::updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect) +{ + Q_ASSERT(oldEffect == 0 || newEffect->type() == oldEffect->type()); + if (state.isOpacityDirty()) + program()->setUniformValue(m_opacity_id, state.opacity()); + + QSGOpaqueTextureMaterialShader::updateState(state, newEffect, oldEffect); +} + +void QSGTextureMaterialShader::initialize() +{ + QSGOpaqueTextureMaterialShader::initialize(); + m_opacity_id = program()->uniformLocation("opacity"); +} + +QT_END_NAMESPACE diff --git a/src/declarative/scenegraph/util/qsgtexturematerial.h b/src/declarative/scenegraph/util/qsgtexturematerial.h new file mode 100644 index 0000000000..375d4849cf --- /dev/null +++ b/src/declarative/scenegraph/util/qsgtexturematerial.h @@ -0,0 +1,102 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef TEXTUREMATERIAL_H +#define TEXTUREMATERIAL_H + +#include "qsgmaterial.h" +#include <qsgtexture.h> + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Declarative) + + +class Q_DECLARATIVE_EXPORT QSGOpaqueTextureMaterial : public QSGMaterial +{ +public: + QSGOpaqueTextureMaterial(); + + virtual QSGMaterialType *type() const; + virtual QSGMaterialShader *createShader() const; + virtual int compare(const QSGMaterial *other) const; + + void setTexture(QSGTexture *texture); + QSGTexture *texture() const { return m_texture; } + + void setMipmapFiltering(QSGTexture::Filtering filtering) { m_mipmap_filtering = filtering; } + QSGTexture::Filtering mipmapFiltering() const { return (QSGTexture::Filtering) m_mipmap_filtering; } + + void setFiltering(QSGTexture::Filtering filtering) { m_filtering = filtering; } + QSGTexture::Filtering filtering() const { return (QSGTexture::Filtering) m_filtering; } + + void setHorizontalWrapMode(QSGTexture::WrapMode mode) { m_horizontal_wrap = mode; } + QSGTexture::WrapMode horizontalWrapMode() const { return (QSGTexture::WrapMode) m_horizontal_wrap; } + + void setVerticalWrapMode(QSGTexture::WrapMode mode) { m_vertical_wrap = mode; } + QSGTexture::WrapMode verticalWrapMode() const { return (QSGTexture::WrapMode) m_vertical_wrap; } + +protected: + QSGTexture *m_texture; + + uint m_filtering: 2; + uint m_mipmap_filtering: 2; + uint m_horizontal_wrap : 1; + uint m_vertical_wrap: 1; + + uint m_reserved : 26; +}; + + +class Q_DECLARATIVE_EXPORT QSGTextureMaterial : public QSGOpaqueTextureMaterial +{ +public: + virtual QSGMaterialType *type() const; + virtual QSGMaterialShader *createShader() const; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // TEXTUREMATERIAL_H diff --git a/src/declarative/scenegraph/util/qsgtexturematerial_p.h b/src/declarative/scenegraph/util/qsgtexturematerial_p.h new file mode 100644 index 0000000000..3e14da525a --- /dev/null +++ b/src/declarative/scenegraph/util/qsgtexturematerial_p.h @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef TEXTUREMATERIAL_P_H +#define TEXTUREMATERIAL_P_H + +#include "qsgtexturematerial.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Declarative) + +class Q_DECLARATIVE_EXPORT QSGOpaqueTextureMaterialShader : public QSGMaterialShader +{ +public: + virtual void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect); + virtual char const *const *attributeNames() const; + + static QSGMaterialType type; + +protected: + virtual void initialize(); + virtual const char *vertexShader() const; + virtual const char *fragmentShader() const; + + int m_matrix_id; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QSGTEXTUREMATERIAL_P_H diff --git a/src/declarative/scenegraph/util/qsgtextureprovider.cpp b/src/declarative/scenegraph/util/qsgtextureprovider.cpp new file mode 100644 index 0000000000..2cae0f8f92 --- /dev/null +++ b/src/declarative/scenegraph/util/qsgtextureprovider.cpp @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qsgtextureprovider_p.h" + +#ifndef GL_CLAMP_TO_EDGE +#define GL_CLAMP_TO_EDGE 0x812F +#endif + +QT_BEGIN_NAMESPACE + +/*! + \class QSGTextureProvider + \brief The QSGTextureProvider class encapsulates texture based entities in QML. + */ + + +/*! + Convenience function for casting a QObject to a QSGTextureProvider + */ +QSGTextureProvider *QSGTextureProvider::from(QObject *object) +{ + return object ? static_cast<QSGTextureProvider *>(object->qt_metacast("QSGTextureProvider")) : 0; +} + + +QT_END_NAMESPACE diff --git a/src/declarative/scenegraph/util/qsgtextureprovider_p.h b/src/declarative/scenegraph/util/qsgtextureprovider_p.h new file mode 100644 index 0000000000..486e7d5882 --- /dev/null +++ b/src/declarative/scenegraph/util/qsgtextureprovider_p.h @@ -0,0 +1,70 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSGTEXTUREPROVIDER_H +#define QSGTEXTUREPROVIDER_H + +#include <qgl.h> + +#include "qsgtexture.h" +#include "qobject.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Declarative) + +class QSGTextureProvider +{ +public: + virtual QSGTexture *texture() const = 0; + virtual const char *textureChangedSignal() const { return 0; } + + static QSGTextureProvider *from(QObject *object); +}; +Q_DECLARE_INTERFACE(QSGTextureProvider, "QSGTextureProvider") + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/declarative/scenegraph/util/qsgvertexcolormaterial.cpp b/src/declarative/scenegraph/util/qsgvertexcolormaterial.cpp new file mode 100644 index 0000000000..033de1f73e --- /dev/null +++ b/src/declarative/scenegraph/util/qsgvertexcolormaterial.cpp @@ -0,0 +1,171 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qsgvertexcolormaterial_p.h" + +#include <qglshaderprogram.h> + +QT_BEGIN_NAMESPACE + +class QSGVertexColorMaterialShader : public QSGMaterialShader +{ +public: + virtual void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect); + virtual char const *const *attributeNames() const; + + static QSGMaterialType type; + +private: + virtual void initialize(); + virtual const char *vertexShader() const; + virtual const char *fragmentShader() const; + + int m_matrix_id; + int m_opacity_id; +}; + +QSGMaterialType QSGVertexColorMaterialShader::type; + +void QSGVertexColorMaterialShader::updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *) +{ + if (!(newEffect->flags() & QSGMaterial::Blending) || state.isOpacityDirty()) + program()->setUniformValue(m_opacity_id, state.opacity()); + + if (state.isMatrixDirty()) + program()->setUniformValue(m_matrix_id, state.combinedMatrix()); +} + +char const *const *QSGVertexColorMaterialShader::attributeNames() const +{ + static const char *const attr[] = { "vertexCoord", "vertexColor", 0 }; + return attr; +} + +void QSGVertexColorMaterialShader::initialize() +{ + m_matrix_id = program()->uniformLocation("matrix"); + m_opacity_id = program()->uniformLocation("opacity"); +} + +const char *QSGVertexColorMaterialShader::vertexShader() const { + return + "attribute highp vec4 vertexCoord; \n" + "attribute highp vec4 vertexColor; \n" + "uniform highp mat4 matrix; \n" + "uniform highp float opacity; \n" + "varying lowp vec4 color; \n" + "void main() { \n" + " gl_Position = matrix * vertexCoord; \n" + " color = vertexColor * opacity; \n" + "}"; +} + +const char *QSGVertexColorMaterialShader::fragmentShader() const { + return + "varying lowp vec4 color; \n" + "void main() { \n" + " gl_FragColor = color; \n" + "}"; +} + + + +/*! + \class QSGVertexColorMaterial + \brief The QSGVertexColorMaterial provides a convenient way of rendering per-vertex + colored geometry in the scene graph. + + The vertex color material will give each vertex in a geometry a color. Pixels between + vertices will be linearly interpolated. The colors can contain transparency. + + The geometry to be rendered with vertex color must have the following layout. Attribute + position 0 must contain vertices. Attribute position 1 must contain colors, a tuple of + 4 values with RGBA layout. Both floats in the range of 0 to 1 and unsigned bytes in + the range 0 to 255 are valid for the color values. The + QSGGeometry::defaultAttributes_ColoredPoint2D() constructs an attribute set + compatible with this material. + + The vertex color material respets both current opacity and current matrix when + updating it's rendering state. + */ + + +QSGVertexColorMaterial::QSGVertexColorMaterial() +{ + setFlag(Blending, true); +} + + + +/*! + Sets if the renderer should treat colors as opaque. + + Setting this flag can in some cases improve performance. + */ + +void QSGVertexColorMaterial::setColorsAreOpaque(bool opaqueHint) +{ + setFlag(Blending, !opaqueHint); +} + + + +/*! + \internal + */ + +QSGMaterialType *QSGVertexColorMaterial::type() const +{ + return &QSGVertexColorMaterialShader::type; +} + + + +/*! + \internal + */ + +QSGMaterialShader *QSGVertexColorMaterial::createShader() const +{ + return new QSGVertexColorMaterialShader; +} + +QT_END_NAMESPACE diff --git a/src/declarative/scenegraph/util/qsgvertexcolormaterial_p.h b/src/declarative/scenegraph/util/qsgvertexcolormaterial_p.h new file mode 100644 index 0000000000..7f05537986 --- /dev/null +++ b/src/declarative/scenegraph/util/qsgvertexcolormaterial_p.h @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef VERTEXCOLORMATERIAL_H +#define VERTEXCOLORMATERIAL_H + +#include <qsgmaterial.h> + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Declarative) + +class QSGVertexColorMaterial : public QSGMaterial +{ +public: + QSGVertexColorMaterial(); + + void setColorsAreOpaque(bool opaqueHint); + +protected: + virtual QSGMaterialType *type() const; + virtual QSGMaterialShader *createShader() const; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // VERTEXCOLORMATERIAL_H |