diff options
Diffstat (limited to 'src/threed/textures')
-rw-r--r-- | src/threed/textures/qareaallocator.cpp | 877 | ||||
-rw-r--r-- | src/threed/textures/qareaallocator.h | 169 | ||||
-rw-r--r-- | src/threed/textures/qglsharedresource.cpp | 236 | ||||
-rw-r--r-- | src/threed/textures/qglsharedresource_p.h | 96 | ||||
-rw-r--r-- | src/threed/textures/qgltexture2d.cpp | 805 | ||||
-rw-r--r-- | src/threed/textures/qgltexture2d.h | 115 | ||||
-rw-r--r-- | src/threed/textures/qgltexture2d_p.h | 126 | ||||
-rw-r--r-- | src/threed/textures/qgltexturecube.cpp | 549 | ||||
-rw-r--r-- | src/threed/textures/qgltexturecube.h | 112 | ||||
-rw-r--r-- | src/threed/textures/qgltextureutils.cpp | 785 | ||||
-rw-r--r-- | src/threed/textures/qgltextureutils_p.h | 164 | ||||
-rw-r--r-- | src/threed/textures/textures.pri | 15 |
12 files changed, 0 insertions, 4049 deletions
diff --git a/src/threed/textures/qareaallocator.cpp b/src/threed/textures/qareaallocator.cpp deleted file mode 100644 index 79340c1a..00000000 --- a/src/threed/textures/qareaallocator.cpp +++ /dev/null @@ -1,877 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtQuick3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qareaallocator.h" -#include "qglnamespace.h" - -QT_BEGIN_NAMESPACE - -/*! - \class QAreaAllocator - \brief The QAreaAllocator class provides facilities for allocating sub-regions from a rectangular image. - \since 4.8 - \ingroup qt3d - \ingroup qt3d::textures - \internal - - Performance on a system can sometimes be improved by storing - multiple small images in a single large image. This reduces - memory allocation overhead and GPU state switching costs. - - QAreaAllocator and its subclasses implement standard strategies - for sub-region allocation in images without tying those strategies - to specific technologies such as raster, OpenGL, etc. - - Allocations are managed in a virtual two-dimensional space. - The caller performs the actual texture upload based on the sub-region - that allocate() returns. - - The caller can return a sub-region to the allocation pool with - release(). Note that not all strategies support release(). - - \sa QSimpleAreaAllocator, QGeneralAreaAllocator, QUniformAreaAllocator -*/ - -/*! - \class QSimpleAreaAllocator - \brief The QSimpleAreaAllocator class provides a simple allocation policy for simple-sized sub-allocations. - \since 4.8 - \ingroup qt3d - \ingroup qt3d::textures - \internal - - QSimpleAreaAllocator uses a trivial allocation strategy whereby - sub-regions are allocated in rows, with a new row started each - time the previous row fills up. Space is never reclaimed by - release(). - - This allocator is suitable for use when the allocations will all - be of a similar size and all regions will be discarded at - the same time when the allocator is destroyed. An example would - be a font glyph manager. - - \sa QAreaAllocator, QGeneralAreaAllocator -*/ - -/*! - \class QGeneralAreaAllocator - \brief The QGeneralAreaAllocator class provides a general allocation policy for sub-regions in an image. - \since 4.8 - \ingroup qt3d - \ingroup qt3d::textures - \internal - - QGeneralAreaAllocator can handle arbitrary-sized allocations up to - size(), in any order, and can release() previously allocated regions. - It uses a binary subdivision algorithm on the image, which may result - in fragmentation under heavy load. - - While technically any size sub-region up to size() can be allocated, - once subdivision begins, the sizes that can be allocated will reduce - substantially. It is recommended that incoming requests be size() / 4 - or less for best performance. - - If the sub-region sizes to be allocated are very similar, and release() - is not necessary, then QSimpleAreaAllocator may work better than - QGeneralAreaAllocator. If the sizes are very similar, and - release() is necessary, then QUniformAreaAllocator may work better - than QGeneralAreaAllocator. - - \sa QAreaAllocator, QSimpleAreaAllocator, QUniformAreaAllocator -*/ - -/*! - \class QUniformAreaAllocator - \brief The QUniformAreaAllocator class provides an allocation policy for uniform-sized areas. - \since 4.8 - \ingroup qt3d - \ingroup qt3d::textures - \internal - - QUniformAreaAllocator allocates any size up to uniformSize() - by dividing size() up into a grid of uniformSize() areas. - Areas can be deallocated with release() and returned to the pool. - - This allocator is suitable for use when the allocations will all - be of a similar size. Unlike QSimpleAreaAllocator, this class - can release allocations. - - \sa QAreaAllocator, QSimpleAreaAllocator, QGeneralAreaAllocator -*/ - -/*! - \internal - - Constructs a new area allocator that is initially \a size pixels - in size. - - \sa expand() -*/ -QAreaAllocator::QAreaAllocator(const QSize &size) - : m_size(size) - , m_minAlloc(1, 1) - , m_margin(0, 0) -{ -} - -/*! - \internal - - Destroys this area allocator. -*/ -QAreaAllocator::~QAreaAllocator() -{ -} - -/*! - \fn QSize QAreaAllocator::size() const - \internal - - Returns the current size of the area being used by this allocator. -*/ - -/*! - \fn QSize QAreaAllocator::minimumAllocation() const - \internal - - Returns the minimum allocation size in the x and y directions - for areas returned by allocate(). The default is (1, 1). - - \sa setMinimumAllocation() -*/ - -/*! - \fn void QAreaAllocator::setMinimumAllocation(const QSize &size) - \internal - - Sets the minimum allocation \a size in the x and y directions - for areas returned by allocate(). - - For example, setting the minimum allocation to (8, 8) will force - all allocations to be aligned on an 8-pixel boundary. - - \sa minimumAllocation() -*/ - -/*! - \fn QSize QAreaAllocator::margin() const - \internal - - Returns the margin that should be left between allocated items - in the x and y directions. The default is (0, 0). - - This may be needed when using OpenGL textures because of - rounding errors in the floating-point representation of - texture co-ordinates. Leaving a small margin between allocations - can help avoid adjacent images from bleeding into each other. - - \sa setMargin() -*/ - -/*! - \fn void QAreaAllocator::setMargin(const QSize &margin) - \internal - - Sets the \a margin that should be left between allocated items - in the x and y directions. - - \sa margin() -*/ - -/*! - \internal - - Expands this allocator to encompass the width and height of \a size. - If the area is already larger, this function does nothing. - - The rectangles that were returned for previous allocations will - remain valid. - - \sa expandBy() -*/ -void QAreaAllocator::expand(const QSize &size) -{ - int newWidth = qMax(m_size.width(), size.width()); - int newHeight = qMax(m_size.height(), size.height()); - m_size = QSize(newWidth, newHeight); -} - -/*! - \internal - - Expands this allocator by \a size pixels in the x and y directions. - - For example, expanding by (0, 128) will add 128 additional pixels - of height but will leave the width unchanged. - - \sa expand() -*/ -void QAreaAllocator::expandBy(const QSize &size) -{ - expand(m_size + size); -} - -/*! - \fn QRect QAreaAllocator::allocate(const QSize &size) - \internal - - Allocates \a size pixels from this allocator and returns the rectangle - that should be used by the caller. Returns a null rectangle if - this allocator does not have sufficient space to accommodate \a size. - - \sa release() -*/ - -/*! - \internal - - Allocates and returns a list of rectangles corresponding to the - elements of \a sizes. The returned list will have less elements - than \a sizes if there is insufficient space to accommodate - all of the allocation requests. The values that are in the returned - list will be allocated and need to be passed to release() to - deallocate them. - - The default implementation will call the subclass allocate() once - for each size until all \a sizes have been allocated or an - allocation fails. Subclasses may override this method to - reorder the allocations for best-fit. - - \sa release() -*/ -QList<QRect> QAreaAllocator::allocate(const QList<QSize> &sizes) -{ - QList<QRect> rects; - QRect rect; - for (int index = 0; index < sizes.count(); ++index) { - rect = allocate(sizes[index]); - if (rect.isNull()) - break; - rects.append(rect); - } - return rects; -} - -/*! - \internal - - Releases the space occupied by \a rect back to the allocator. - The default implementation does nothing. - - The \a rect must have been returned by a previous call to allocate(). - Otherwise the behaviour is undefined. - - \sa allocate() -*/ -void QAreaAllocator::release(const QRect &rect) -{ - Q_UNUSED(rect); -} - -/*! - \internal - - Releases the space occupied by the members of \a rects back to - the allocator. The default implementation calls release() for - each rectangle in the list. - - The members of \a rects must have been returned by previous calls - to allocate(). Otherwise the behaviour is undefined. - - \sa allocate() -*/ -void QAreaAllocator::release(const QList<QRect> &rects) -{ - for (int index = 0; index < rects.count(); ++index) - release(rects[index]); -} - -/*! - \internal - - Returns a rough estimate of the number of bytes of overhead that - are currently in use to store the house-keeping data structures - for this area allocator. The default implementation returns zero. -*/ -int QAreaAllocator::overhead() const -{ - return 0; -} - -/*! - \internal - - Returns \a size, after rounding it up to account for - minimumAllocation() and margin(). - - This is a convenience function, provided for subclass overrides - of allocate(). - - \sa allocate() -*/ -QSize QAreaAllocator::roundAllocation(const QSize &size) const -{ - int width = size.width() + m_margin.width(); - int height = size.height() + m_margin.height(); - int extra = width % m_minAlloc.width(); - if (extra) - width += m_minAlloc.width() - extra; - extra = height % m_minAlloc.height(); - if (extra) - height += m_minAlloc.height() - extra; - return QSize(width, height); -} - -/*! - \internal - - Constructs a simple area allocator that is initially \a size pixels - in size. -*/ -QSimpleAreaAllocator::QSimpleAreaAllocator(const QSize &size) - : QAreaAllocator(size) - , m_row(0) - , m_column(0) - , m_rowHeight(0) -{ -} - -/*! - \internal - - Destroys this simple area allocator. -*/ -QSimpleAreaAllocator::~QSimpleAreaAllocator() -{ -} - -/*! - \internal -*/ -QRect QSimpleAreaAllocator::allocate(const QSize &size) -{ - // Round up the allocation size to account for the margin and - // minimum allocation parameters. - QSize rounded = roundAllocation(size); - int width = rounded.width(); - int height = rounded.height(); - - // Bail out if the size is obviously too small or too big. - if (width <= 0 || width > m_size.width()) - return QRect(); - if (height <= 0 || height > (m_size.height() - m_row)) - return QRect(); - - // Do we need to place this allocation on a new row? - int row = m_row; - int column = m_column; - int rowHeight = m_rowHeight; - if ((column + width) > m_size.width()) { - row += m_rowHeight; - column = 0; - rowHeight = 0; - if (height > (m_size.height() - row)) - return QRect(); - } - - // Update the current allocation position. - m_row = row; - m_column = column + width; - m_rowHeight = qMax(rowHeight, height); - - // Return the allocation, using the original size without rounding. - return QRect(column, row, size.width(), size.height()); -} - -/*! - \internal - - Constructs a general area allocator that is initially \a size pixels - in size. The \a size will be rounded up to the next power of two, - to simplify the internal allocation policy. - - This constructor sets minimumAllocation() to (8, 8) to reduce the - housekeeping overhead of the internal data structures. -*/ -QGeneralAreaAllocator::QGeneralAreaAllocator(const QSize &size) - : QAreaAllocator(QGL::nextPowerOfTwo(size)) -{ - m_root = new Node(); - m_root->rect = QRect(0, 0, m_size.width(), m_size.height()); - m_root->largestFree = m_size; - m_root->parent = 0; - m_root->left = 0; - m_root->right = 0; - m_nodeCount = 1; - setMinimumAllocation(QSize(8, 8)); -} - -/*! - \internal - - Destroys this general area allocator. -*/ -QGeneralAreaAllocator::~QGeneralAreaAllocator() -{ - freeNode(m_root); -} - -/*! - \internal -*/ -void QGeneralAreaAllocator::freeNode(Node *node) -{ - if (node) { - freeNode(node->left); - freeNode(node->right); - } - delete node; -} - -/*! - \internal - - The \a size will be rounded up to the next power of two. - Use size() to determine the actual size after expansion. -*/ -void QGeneralAreaAllocator::expand(const QSize &size) -{ - QAreaAllocator::expand(QGL::nextPowerOfTwo(size)); - - if (m_root->rect.size() == m_size) - return; // No change. - if (!m_root->left && m_root->largestFree.width() > 0) { - // No allocations have occurred, so just adjust the root size. - m_root->rect = QRect(0, 0, m_size.width(), m_size.height()); - m_root->largestFree = m_size; - return; - } - - // Add extra nodes above the current root to expand the tree. - Node *oldRoot = m_root; - Split split; - if (m_size.width() >= m_size.height()) - split = SplitOnX; - else - split = SplitOnY; - while (m_root->rect.size() != m_size) { - if (m_root->rect.width() == m_size.width()) - split = SplitOnY; - else if (m_root->rect.height() == m_size.height()) - split = SplitOnX; - Node *parent = new Node(); - Node *right = new Node(); - m_nodeCount += 2; - m_root->parent = parent; - parent->parent = 0; - parent->left = m_root; - parent->right = right; - parent->largestFree = m_root->rect.size(); - right->parent = parent; - right->left = 0; - right->right = 0; - right->largestFree = m_root->rect.size(); - if (split == SplitOnX) { - parent->rect = QRect(m_root->rect.x(), m_root->rect.y(), - m_root->rect.width() * 2, - m_root->rect.height()); - right->rect = QRect(m_root->rect.x() + m_root->rect.width(), - m_root->rect.y(), - m_root->rect.width(), m_root->rect.height()); - } else { - parent->rect = QRect(m_root->rect.x(), m_root->rect.y(), - m_root->rect.width(), - m_root->rect.height() * 2); - right->rect = QRect(m_root->rect.x(), - m_root->rect.y() + m_root->rect.width(), - m_root->rect.width(), m_root->rect.height()); - } - split = (split == SplitOnX ? SplitOnY : SplitOnX); - m_root = parent; - } - updateLargestFree(oldRoot); -} - -static inline bool fitsWithin(const QSize &size1, const QSize &size2) -{ - return size1.width() <= size2.width() && size1.height() <= size2.height(); -} - -/*! - \internal -*/ -QRect QGeneralAreaAllocator::allocate(const QSize &size) -{ - QSize rounded = roundAllocation(size); - rounded = QGL::nextPowerOfTwo(rounded); - if (rounded.width() <= 0 || rounded.width() > m_size.width() || - rounded.height() <= 0 || rounded.height() > m_size.height()) - return QRect(); - QPoint point = allocateFromNode(rounded, m_root); - if (point.x() >= 0) - return QRect(point, size); - else - return QRect(); -} - -/*! - \internal -*/ -QPoint QGeneralAreaAllocator::allocateFromNode(const QSize &size, Node *node) -{ - // Find the best node to insert into, which should be - // a node with the least amount of unused space that is - // big enough to contain the requested size. - while (node != 0) { - // Go down a level and determine if the left or right - // sub-tree contains the best chance of allocation. - Node *left = node->left; - Node *right = node->right; - if (left && fitsWithin(size, left->largestFree)) { - if (right && fitsWithin(size, right->largestFree)) { - if (left->largestFree.width() < right->largestFree.width() || - left->largestFree.height() < right->largestFree.height()) { - // The largestFree values may be a little oversized, - // so try the left sub-tree and then the right sub-tree. - QPoint point = allocateFromNode(size, left); - if (point.x() >= 0) - return point; - else - return allocateFromNode(size, right); - } else { - node = right; - } - } else { - node = left; - } - } else if (right && fitsWithin(size, right->largestFree)) { - node = right; - } else if (left || right) { - // Neither sub-node has enough space to allocate from. - return QPoint(-1, -1); - } else if (fitsWithin(size, node->largestFree)) { - // Do we need to split this node into smaller pieces? - Split split; - if (fitsWithin(QSize(size.width() * 2, size.height() * 2), - node->largestFree)) { - // Split in either direction: choose the inverse of - // the parent node's split direction to try to balance - // out the wasted space as further subdivisions happen. - if (node->parent && - node->parent->left->rect.x() == - node->parent->right->rect.x()) - split = SplitOnX; - else if (node->parent) - split = SplitOnY; - else if (node->rect.width() >= node->rect.height()) - split = SplitOnX; - else - split = SplitOnY; - } else if (fitsWithin(QSize(size.width() * 2, size.height()), - node->largestFree)) { - // Split along the X direction. - split = SplitOnX; - } else if (fitsWithin(QSize(size.width(), size.height() * 2), - node->largestFree)) { - // Split along the Y direction. - split = SplitOnY; - } else { - // Cannot split further - allocate this node. - node->largestFree = QSize(0, 0); - updateLargestFree(node); - return node->rect.topLeft(); - } - - // Split the node, then go around again using the left sub-tree. - node = splitNode(node, split); - } else { - // Cannot possibly fit into this node. - break; - } - } - return QPoint(-1, -1); -} - -/*! - \internal -*/ -QGeneralAreaAllocator::Node *QGeneralAreaAllocator::splitNode - (Node *node, Split split) -{ - Node *left = new Node(); - Node *right = new Node(); - m_nodeCount += 2; - left->parent = node; - left->left = 0; - left->right = 0; - right->parent = node; - right->left = 0; - right->right = 0; - node->left = left; - node->right = right; - if (split == SplitOnX) { - left->rect = QRect(node->rect.x(), node->rect.y(), - node->rect.width() / 2, - node->rect.height()); - right->rect = QRect(left->rect.right() + 1, node->rect.y(), - node->rect.width() / 2, - node->rect.height()); - } else { - left->rect = QRect(node->rect.x(), node->rect.y(), - node->rect.width(), - node->rect.height() / 2); - right->rect = QRect(node->rect.x(), left->rect.bottom() + 1, - node->rect.width(), - node->rect.height() / 2); - } - left->largestFree = left->rect.size(); - right->largestFree = right->rect.size(); - node->largestFree = right->largestFree; - return left; -} - -/*! - \internal -*/ -void QGeneralAreaAllocator::updateLargestFree(Node *node) -{ - while ((node = node->parent) != 0) { - node->largestFree = - QSize(qMax(node->left->largestFree.width(), - node->right->largestFree.width()), - qMax(node->left->largestFree.height(), - node->right->largestFree.height())); - } -} - -/*! - \internal -*/ -void QGeneralAreaAllocator::release(const QRect &rect) -{ - // Locate the node that contains the allocated region. - Node *node = m_root; - QPoint point = rect.topLeft(); - while (node != 0) { - if (node->left && node->left->rect.contains(point)) - node = node->left; - else if (node->right && node->right->rect.contains(point)) - node = node->right; - else if (node->rect.contains(point)) - break; - else - return; // Point is completely outside the tree. - } - if (!node) - return; - - // Mark the node as free and then work upwards through the tree - // recombining and deleting nodes until we reach a sibling - // that is still allocated. - node->largestFree = node->rect.size(); - while (node->parent) { - if (node->parent->left == node) { - if (node->parent->right->largestFree != - node->parent->right->rect.size()) - break; - } else { - if (node->parent->left->largestFree != - node->parent->left->rect.size()) - break; - } - node = node->parent; - freeNode(node->left); - freeNode(node->right); - m_nodeCount -= 2; - node->left = 0; - node->right = 0; - node->largestFree = node->rect.size(); - } - - // Make the rest of our ancestors have the correct "largest free size". - updateLargestFree(node); -} - -/*! - \internal -*/ -int QGeneralAreaAllocator::overhead() const -{ - return m_nodeCount * sizeof(Node); -} - -/*! - \internal - - Constructs a uniform area allocator that is initially \a size pixels - in size. The \a uniformSize specifies the single allocation size - that is supported. All allocate() requests must be \a uniformSize - or less. -*/ -QUniformAreaAllocator::QUniformAreaAllocator - (const QSize &size, const QSize &uniformSize) - : QAreaAllocator(size), m_uniformSize(uniformSize), m_firstFree(0) -{ - Q_ASSERT(uniformSize.width() > 0 && uniformSize.height() > 0); - Q_ASSERT(size.width() >= uniformSize.width() && - size.height() >= uniformSize.height()); - m_gridSize = QSize(size.width() / uniformSize.width(), - size.height() / uniformSize.height()); - int count = m_gridSize.width() * m_gridSize.height(); - m_grid = new int [count]; - for (int index = 0; index < (count - 1); ++index) - m_grid[index] = index + 1; - m_grid[count - 1] = -1; -} - -/*! - \internal - - Destroys this uniform area allocator. -*/ -QUniformAreaAllocator::~QUniformAreaAllocator() -{ - delete [] m_grid; -} - -/*! - \fn QSize QUniformAreaAllocator::uniformSize() const - \internal - - Returns the uniform size of all allocations. - - \sa allocate() -*/ - -/*! - \internal -*/ -void QUniformAreaAllocator::expand(const QSize &size) -{ - QAreaAllocator::expand(size); - - QSize newGridSize = QSize(m_size.width() / m_uniformSize.width(), - m_size.height() / m_uniformSize.height()); - if (m_gridSize == newGridSize) - return; - - // Create a new grid. - int newCount = newGridSize.width() * newGridSize.height(); - int *newGrid = new int [newCount]; - - // Copy across the free blocks from the old grid. - int posn = m_firstFree; - int newFirstFree = -1; - while (posn != -1) { - int x = posn % m_gridSize.width(); - int y = posn / m_gridSize.width(); - int newPosn = x + y * newGridSize.width(); - newGrid[newPosn] = newFirstFree; - newFirstFree = newPosn; - posn = m_grid[posn]; - } - - // Add free blocks within the expanded area of the new grid. - for (int y = 0; y < m_gridSize.height(); ++y) { - int newPosn = y * newGridSize.width() + m_gridSize.width(); - for (int x = m_gridSize.width(); x < newGridSize.width(); ++x) { - newGrid[newPosn] = newFirstFree; - newFirstFree = newPosn; - ++newPosn; - } - } - for (int y = m_gridSize.height(); y < newGridSize.height(); ++y) { - int newPosn = y * newGridSize.width(); - for (int x = 0; x < newGridSize.width(); ++x) { - newGrid[newPosn] = newFirstFree; - newFirstFree = newPosn; - ++newPosn; - } - } - - // Replace the old grid. - delete [] m_grid; - m_grid = newGrid; - m_gridSize = newGridSize; - m_firstFree = newFirstFree; -} - -/*! - \internal -*/ -QRect QUniformAreaAllocator::allocate(const QSize &size) -{ - QSize rounded = roundAllocation(size); - if (rounded.width() > m_uniformSize.width() || - rounded.height() > m_uniformSize.height()) - return QRect(); - int posn = m_firstFree; - if (posn == -1) - return QRect(); - m_firstFree = m_grid[posn]; - int x = posn % m_gridSize.width(); - int y = posn / m_gridSize.width(); - return QRect(x * m_uniformSize.width(), y * m_uniformSize.height(), - size.width(), size.height()); -} - -/*! - \internal -*/ -void QUniformAreaAllocator::release(const QRect &rect) -{ - int x = rect.x() / m_uniformSize.width(); - int y = rect.y() / m_uniformSize.height(); - int posn = x + y * m_gridSize.width(); - Q_ASSERT(posn >= 0 && posn < m_gridSize.width() * m_gridSize.height()); - m_grid[posn] = m_firstFree; - m_firstFree = posn; -} - -/*! - \internal -*/ -int QUniformAreaAllocator::overhead() const -{ - return sizeof(int) * m_gridSize.width() * m_gridSize.height(); -} - -QT_END_NAMESPACE diff --git a/src/threed/textures/qareaallocator.h b/src/threed/textures/qareaallocator.h deleted file mode 100644 index f861b500..00000000 --- a/src/threed/textures/qareaallocator.h +++ /dev/null @@ -1,169 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtQuick3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QAREAALLOCATOR_P_H -#define QAREAALLOCATOR_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include "qt3dglobal.h" -#include <QtCore/qsize.h> -#include <QtCore/qrect.h> -#include <QtCore/qlist.h> - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Qt3D) - -class Q_QT3D_EXPORT QAreaAllocator -{ -public: - QAreaAllocator(const QSize &size); - virtual ~QAreaAllocator(); - - QSize size() const { return m_size; } - - QSize minimumAllocation() const { return m_minAlloc; } - void setMinimumAllocation(const QSize &size) { m_minAlloc = size; } - - QSize margin() const { return m_margin; } - void setMargin(const QSize &margin) { m_margin = margin; } - - virtual void expand(const QSize &size); - void expandBy(const QSize &size); - - virtual QRect allocate(const QSize &size) = 0; - virtual QList<QRect> allocate(const QList<QSize> &sizes); - virtual void release(const QRect &rect); - virtual void release(const QList<QRect> &rects); - - virtual int overhead() const; - -protected: - QSize m_size; - QSize m_minAlloc; - QSize m_margin; - - QSize roundAllocation(const QSize &size) const; -}; - -class Q_QT3D_EXPORT QSimpleAreaAllocator : public QAreaAllocator -{ -public: - QSimpleAreaAllocator(const QSize &size); - virtual ~QSimpleAreaAllocator(); - - QRect allocate(const QSize &size); - -private: - int m_row; - int m_column; - int m_rowHeight; -}; - -class Q_QT3D_EXPORT QGeneralAreaAllocator : public QAreaAllocator -{ -public: - QGeneralAreaAllocator(const QSize &size); - virtual ~QGeneralAreaAllocator(); - - void expand(const QSize &size); - QRect allocate(const QSize &size); - void release(const QRect &rect); - int overhead() const; - -private: - enum Split { SplitOnX, SplitOnY }; - - struct Node - { - QRect rect; - QSize largestFree; - Node *parent; - Node *left; - Node *right; - }; - - Node *m_root; - int m_nodeCount; - - static void freeNode(Node *node); - QPoint allocateFromNode(const QSize &size, Node *node); - Node *splitNode(Node *node, Split split); - static void updateLargestFree(Node *node); -}; - -class Q_QT3D_EXPORT QUniformAreaAllocator : public QAreaAllocator -{ -public: - QUniformAreaAllocator(const QSize &size, const QSize &uniformSize); - virtual ~QUniformAreaAllocator(); - - QSize uniformSize() const { return m_uniformSize; } - - void expand(const QSize &size); - QRect allocate(const QSize &size); - void release(const QRect &rect); - int overhead() const; - -private: - QSize m_uniformSize; - QSize m_gridSize; - int *m_grid; - int m_firstFree; -}; - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif diff --git a/src/threed/textures/qglsharedresource.cpp b/src/threed/textures/qglsharedresource.cpp deleted file mode 100644 index ab6d0101..00000000 --- a/src/threed/textures/qglsharedresource.cpp +++ /dev/null @@ -1,236 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtQuick3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qglsharedresource_p.h" -#include <QtCore/qmutex.h> -#include <QtCore/qcoreapplication.h> - -QT_BEGIN_NAMESPACE - -#if !defined(Q_MOC_RUN) - -class Q_OPENGL_EXPORT QGLSignalProxy : public QObject -{ - Q_OBJECT -public: - QGLSignalProxy() : QObject() {} - void emitAboutToDestroyContext(const QGLContext *context) { - emit aboutToDestroyContext(context); - } - static QGLSignalProxy *instance(); -Q_SIGNALS: - void aboutToDestroyContext(const QGLContext *context); -}; - -#endif - -class QGLContextInfo -{ -public: - QGLContextInfo(const QGLContext *ctx) : m_context(ctx), m_resources(0) {} - ~QGLContextInfo(); - - const QGLContext *m_context; - QGLSharedResource *m_resources; -}; - -QGLContextInfo::~QGLContextInfo() -{ - // Detach this information block from all of the shared resources - // that used to be owned by it. - QGLSharedResource *resource = m_resources; - while (resource != 0) { - resource->m_contextInfo = 0; - resource->m_id = 0; - resource = resource->m_next; - } -} - -class QGLContextManager : public QObject -{ - Q_OBJECT -public: - QGLContextManager(QObject *parent = 0); - ~QGLContextManager(); - - QMutex managerLock; - - QGLContextInfo *contextInfo(const QGLContext *ctx); - -private Q_SLOTS: - void aboutToDestroyContext(const QGLContext *ctx); - -private: - QList<QGLContextInfo *> m_contexts; -}; - -Q_GLOBAL_STATIC(QGLContextManager, qt_gl_context_manager) - -QGLContextManager::QGLContextManager(QObject *parent) - : QObject(parent) -{ - QGLSignalProxy *proxy = QGLSignalProxy::instance(); - QThread *mainThread = qApp->thread(); - if (thread() != mainThread) { - // The manager and signal proxy have been created for the first - // time in a background thread. For safety, move both objects - // to the main thread. - moveToThread(mainThread); - proxy->moveToThread(mainThread); - } - connect(proxy, SIGNAL(aboutToDestroyContext(const QGLContext *)), - this, SLOT(aboutToDestroyContext(const QGLContext *))); -} - -QGLContextManager::~QGLContextManager() -{ - QMutexLocker locker(&managerLock); - qDeleteAll(m_contexts); -} - -QGLContextInfo *QGLContextManager::contextInfo(const QGLContext *ctx) -{ - QGLContextInfo *info; - for (int index = 0; index < m_contexts.size(); ++index) { - info = m_contexts[index]; - if (info->m_context == ctx) - return info; - } - info = new QGLContextInfo(ctx); - m_contexts.append(info); - return info; -} - -Q_OPENGL_EXPORT const QGLContext *qt_gl_transfer_context(const QGLContext *); - -void QGLContextManager::aboutToDestroyContext(const QGLContext *ctx) -{ - QMutexLocker locker(&managerLock); - int index = 0; - while (index < m_contexts.size()) { - QGLContextInfo *info = m_contexts[index]; - if (info->m_context == ctx) { - const QGLContext *transfer = qt_gl_transfer_context(ctx); - if (transfer) { - // Transfer ownership to another context in the same sharing - // group. This may result in multiple QGLContextInfo objects - // for the same context, which is ok. - info->m_context = transfer; - } else { - // All contexts in the sharing group have been deleted, - // so detach all of the shared resources. - m_contexts.removeAt(index); - delete info; - continue; - } - } - ++index; - } -} - -const QGLContext *QGLSharedResource::context() const -{ - // Hope that the context will not be destroyed in another thread - // while we are doing this so we don't have to acquire the lock. - return m_contextInfo ? m_contextInfo->m_context : 0; -} - -void QGLSharedResource::attach(const QGLContext *context, GLuint id) -{ - Q_ASSERT(!m_contextInfo); - QGLContextManager *manager = qt_gl_context_manager(); - QMutexLocker locker(&(manager->managerLock)); - m_contextInfo = manager->contextInfo(context); - m_id = id; - m_next = m_contextInfo->m_resources; - m_prev = 0; - if (m_contextInfo->m_resources) - m_contextInfo->m_resources->m_prev = this; - m_contextInfo->m_resources = this; -} - -void QGLSharedResource::destroy() -{ - // Detach this resource from the context information block. - QGLContextManager *manager = qt_gl_context_manager(); - const QGLContext *owner = 0; - GLuint id = 0; - manager->managerLock.lock(); - if (m_contextInfo) { - if (m_next) - m_next->m_prev = m_prev; - if (m_prev) - m_prev->m_next = m_next; - else - m_contextInfo->m_resources = m_next; - owner = m_contextInfo->m_context; - id = m_id; - } - m_contextInfo = 0; - m_id = 0; - m_next = 0; - m_prev = 0; - manager->managerLock.unlock(); - - // Switch back to the owning context temporarily and delete the id. - if (owner && id) { - QGLContext *currentContext = const_cast<QGLContext *>(QGLContext::currentContext()); - QGLContext *oldContext; - QGLContext *doneContext; - if (currentContext != owner && !QGLContext::areSharing(owner, currentContext)) { - oldContext = currentContext; - doneContext = const_cast<QGLContext *>(owner); - doneContext->makeCurrent(); - } else { - oldContext = 0; - doneContext = 0; - } - m_destroyFunc(id); - if (oldContext) - oldContext->makeCurrent(); - else if (!currentContext && doneContext) - doneContext->doneCurrent(); - } -} - -QT_END_NAMESPACE - -#include "qglsharedresource.moc" diff --git a/src/threed/textures/qglsharedresource_p.h b/src/threed/textures/qglsharedresource_p.h deleted file mode 100644 index 2e03c9fa..00000000 --- a/src/threed/textures/qglsharedresource_p.h +++ /dev/null @@ -1,96 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtQuick3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QGLSHAREDRESOURCE_P_H -#define QGLSHAREDRESOURCE_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QtOpenGL/qgl.h> - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -class QGLContextManager; -class QGLContextInfo; - -class QGLSharedResource -{ -public: - typedef void (*DestroyResourceFunc)(GLuint id); - QGLSharedResource(DestroyResourceFunc destroyFunc) - : m_destroyFunc(destroyFunc), m_contextInfo(0), m_id(0) - , m_next(0), m_prev(0) {} - ~QGLSharedResource() { destroy(); } - - const QGLContext *context() const; - GLuint id() const { return m_id; } - void clearId() { m_id = 0; } - - void attach(const QGLContext *context, GLuint id); - void destroy(); - -private: - DestroyResourceFunc m_destroyFunc; - QGLContextInfo *m_contextInfo; - GLuint m_id; - QGLSharedResource *m_next; - QGLSharedResource *m_prev; - - friend class QGLContextManager; - friend class QGLContextInfo; -}; - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif diff --git a/src/threed/textures/qgltexture2d.cpp b/src/threed/textures/qgltexture2d.cpp deleted file mode 100644 index 07fe9891..00000000 --- a/src/threed/textures/qgltexture2d.cpp +++ /dev/null @@ -1,805 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtQuick3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qgltexture2d.h" -#include "qgltexture2d_p.h" -#include "qgltextureutils_p.h" -#include "qglpainter_p.h" -#include "qglext_p.h" -#include "qabstractdownloadmanager.h" -#include "qdownloadmanager.h" -#include "qthreadeddownloadmanager.h" -#include "qopenglfunctions.h" - -#include <QtCore/qfile.h> -#include <QtCore/qfileinfo.h> -#include <QImageReader> - -QT_BEGIN_NAMESPACE - -/*! - \class QGLTexture2D - \brief The QGLTexture2D class represents a 2D texture object for GL painting operations. - \since 4.8 - \ingroup qt3d - \ingroup qt3d::textures - - QGLTexture2D contains a QImage and settings for texture filters, - wrap modes, and mipmap generation. When bind() is called, this - information is uploaded to the GL server if it has changed since - the last time bind() was called. - - Once a QGLTexture2D object is created, it can be bound to multiple - GL contexts. Internally, a separate texture identifier is created - for each context. This makes QGLTexture2D easier to use than - raw GL texture identifiers because the application does not need - to be as concerned with whether the texture identifier is valid - in the current context. The application merely calls bind() and - QGLTexture2D will create a new texture identifier for the context - if necessary. - - QGLTexture2D internally points to a reference-counted object that - represents the current texture state. If the QGLTexture2D is copied, - the internal pointer is the same. Modifications to one QGLTexture2D - copy will affect all of the other copies in the system. - - The texture identifiers will be destroyed when the last QGLTexture2D - reference is destroyed, or when a context is destroyed that contained a - texture identifier that was created by QGLTexture2D. - - QGLTexture2D can also be used for uploading 1D textures into the - GL server by specifying an image() with a height of 1. - - \sa QGLTextureCube -*/ - -Q_GLOBAL_STATIC(QSize, getMaxImageSize) - -QGLTexture2DPrivate::ForcePowerOfTwo QGLTexture2DPrivate::forcePowerOfTwo = QGLTexture2DPrivate::ForcePowerOfTwoUndefined; - -QGLTexture2DPrivate::QGLTexture2DPrivate() -{ - horizontalWrap = QGL::Repeat; - verticalWrap = QGL::Repeat; - bindOptions = QGLContext::DefaultBindOption; -#if !defined(QT_OPENGL_ES) - mipmapSupported = false; - mipmapSupportedKnown = false; -#endif - imageGeneration = 0; - parameterGeneration = 0; - infos = 0; - downloadManager = 0; - - if (forcePowerOfTwo == ForcePowerOfTwoUndefined) { - if (qgetenv("NPOT_MIPMAP_UNSUPPORTED").toInt() == 1) - forcePowerOfTwo = ForcePowerOfTwoTrue; - else - forcePowerOfTwo = ForcePowerOfTwoFalse; - } -} - -QGLTexture2DPrivate::~QGLTexture2DPrivate() -{ - // Destroy the texture id's in the GL server in their original contexts. - QGLTexture2DTextureInfo *current = infos; - QGLTexture2DTextureInfo *next; - const QGLContext *currentContext = - const_cast<QGLContext *>(QGLContext::currentContext()); - const QGLContext *firstContext = currentContext; - while (current != 0) { - next = current->next; - if (current->isLiteral) - current->tex.clearId(); // Don't delete literal id's. - delete current; - current = next; - } - if (firstContext != currentContext) { - if (firstContext) - const_cast<QGLContext *>(firstContext)->makeCurrent(); - else if (currentContext) - const_cast<QGLContext *>(currentContext)->doneCurrent(); - } -} - -/*! - Constructs a null texture object and attaches it to \a parent. - - \sa isNull() -*/ -QGLTexture2D::QGLTexture2D(QObject *parent) - : QObject(parent), d_ptr(new QGLTexture2DPrivate()) -{ -} - -/*! - Destroys this texture object. If this object is the last - reference to the underlying GL texture, then the underlying - GL texture will also be deleted. -*/ -QGLTexture2D::~QGLTexture2D() -{ -} - -/*! - Returns true if this texture object is null; that is, image() - is null and textureId() is zero. -*/ -bool QGLTexture2D::isNull() const -{ - Q_D(const QGLTexture2D); - return d->image.isNull() && !d->infos; -} - -/*! - Returns true if this texture has an alpha channel; false if the - texture is fully opaque. -*/ -bool QGLTexture2D::hasAlphaChannel() const -{ - Q_D(const QGLTexture2D); - if (!d->image.isNull()) - return d->image.hasAlphaChannel(); - QGLTexture2DTextureInfo *info = d->infos; - if (info) - return info->tex.hasAlpha(); - return false; -} - -/*! - Returns the size of this texture. If the underlying OpenGL - implementation requires texture sizes to be a power of two, - then this function will return the next power of two equal - to or greater than requestedSize() - - \sa setSize(), requestedSize() -*/ -QSize QGLTexture2D::size() const -{ - Q_D(const QGLTexture2D); - return d->size; -} - -/*! - Sets the size of this texture to \a value. If the underlying - OpenGL implementation requires texture sizes to be a power of - two, then requestedSize() will be set to \a value, and the - actual size will be set to the next power of two equal - to or greater than \a value. Otherwise both size() and - requestedSize() will be set to \a value. - - \sa size(), requestedSize() -*/ -void QGLTexture2D::setSize(const QSize& value) -{ - Q_D(QGLTexture2D); - if (d->requestedSize == value) - return; - if (!(QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_2_0) - && !(QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_ES_Version_2_0)) - d->size = QGL::nextPowerOfTwo(value); - else - d->size = value; - d->requestedSize = value; - ++(d->imageGeneration); -} - -/*! - Returns the size that was previously set with setSize() before - it was rounded to a power of two. - - \sa size(), setSize() -*/ -QSize QGLTexture2D::requestedSize() const -{ - Q_D(const QGLTexture2D); - return d->requestedSize; -} - -/*! - Returns the image that is currently associated with this texture. - The image may not have been uploaded into the GL server yet. - Uploads occur upon the next call to bind(). - - \sa setImage() -*/ -QImage QGLTexture2D::image() const -{ - Q_D(const QGLTexture2D); - return d->image; -} - -/*! - Sets the \a image that is associated with this texture. The image - will be uploaded into the GL server the next time bind() is called. - - If setSize() or setImage() has been called previously, then \a image - will be scaled to size() when it is uploaded. - - If \a image is null, then this function is equivalent to clearImage(). - - \sa image(), setSize(), copyImage(), setPixmap() -*/ -void QGLTexture2D::setImage(const QImage& image) -{ - Q_D(QGLTexture2D); - d->compressedData = QByteArray(); // Clear compressed file data. - if (image.isNull()) { - // Don't change the imageGeneration, because we aren't actually - // changing the image in the GL server, only the client copy. - d->image = image; - } else { - if (image.size().isValid()) - setSize(image.size()); - d->image = image; - ++(d->imageGeneration); - } -} - -/*! - Sets the image that is associated with this texture to \a pixmap. - - This is a convenience that calls setImage() after converting - \a pixmap into a QImage. It may be more efficient on some - platforms than the application calling QPixmap::toImage(). - - \sa setImage() -*/ -void QGLTexture2D::setPixmap(const QPixmap& pixmap) -{ - QImage image = pixmap.toImage(); - if (pixmap.depth() == 16 && !image.hasAlphaChannel()) { - // If the system depth is 16 and the pixmap doesn't have an alpha channel - // then we convert it to RGB16 in the hope that it gets uploaded as a 16 - // bit texture which is much faster to access than a 32-bit one. - image = image.convertToFormat(QImage::Format_RGB16); - } - setImage(image); -} - -/*! - Clears the image() that is associated with this texture, but the - GL texture will retain its current value. This can be used to - release client-side memory that is no longer required once the - image has been uploaded into the GL server. - - The following code will queue \c image to be uploaded, immediately - force it to be uploaded into the current GL context, and then - clear the client copy: - - \code - texture.setImage(image); - texture.bind(); - texture.clearImage() - \endcode - - \sa image(), setImage() -*/ -void QGLTexture2D::clearImage() -{ - Q_D(QGLTexture2D); - d->image = QImage(); -} - -#ifndef GL_GENERATE_MIPMAP_SGIS -#define GL_GENERATE_MIPMAP_SGIS 0x8191 -#define GL_GENERATE_MIPMAP_HINT_SGIS 0x8192 -#endif - -/*! - Sets this texture to the contents of a compressed image file - at \a path. Returns true if the file exists and has a supported - compressed format; false otherwise. - - The DDS, ETC1, PVRTC2, and PVRTC4 compression formats are - supported, assuming that the GL implementation has the - appropriate extension. - - \sa setImage(), setSize() -*/ -bool QGLTexture2D::setCompressedFile(const QString &path) -{ - Q_D(QGLTexture2D); - d->image = QImage(); - QFile f(path); - if (!f.open(QIODevice::ReadOnly)) - { - qWarning("QGLTexture2D::setCompressedFile(%s): File could not be read", - qPrintable(path)); - return false; - } - QByteArray data = f.readAll(); - f.close(); - - bool hasAlpha, isFlipped; - if (!QGLBoundTexture::canBindCompressedTexture - (data.constData(), data.size(), 0, &hasAlpha, &isFlipped)) { - qWarning("QGLTexture2D::setCompressedFile(%s): Format is not supported", - path.toLocal8Bit().constData()); - return false; - } - - QFileInfo fi(path); - d->url = QUrl::fromLocalFile(fi.absoluteFilePath()); - - // The 3DS loader expects the flip state to be set before bind(). - if (isFlipped) - d->bindOptions &= ~QGLContext::InvertedYBindOption; - else - d->bindOptions |= QGLContext::InvertedYBindOption; - - d->compressedData = data; - ++(d->imageGeneration); - return true; -} - -/*! - Returns the url that was last set with setUrl. -*/ -QUrl QGLTexture2D::url() const -{ - Q_D(const QGLTexture2D); - return d->url; -} - -/*! - Sets this texture to have the contents of the image stored at \a url. - - If the environment variable QT3D_MULTITHREAD is defined, network urls - (http, etc) are downloaded in a separate download thread, otherwise they are - downloaded asynchronously in the current thread. -*/ -void QGLTexture2D::setUrl(const QUrl &url) -{ - Q_D(QGLTexture2D); - if (d->url == url) - return; - d->url = url; - - if (url.isEmpty()) - { - d->image = QImage(); - } - else - { - if (url.scheme() == QLatin1String("file") || url.scheme().toLower() == QLatin1String("qrc")) - { - QString fileName = url.toLocalFile(); - - // slight hack since there doesn't appear to be a QUrl::toResourcePath() function - // to convert qrc:///foo into :/foo - if (url.scheme().toLower() == QLatin1String("qrc")) { - // strips off any qrc: prefix and any excess slashes and replaces it with :/ - QUrl tempUrl(url); - tempUrl.setScheme(""); - fileName = QLatin1String(":")+tempUrl.toString(); - } - - if (fileName.endsWith(QLatin1String(".dds"), Qt::CaseInsensitive)) - { - setCompressedFile(fileName); - } - else - { - QImageReader imgReader; - imgReader.setFileName(fileName); - - if (!getMaxImageSize()->isValid()) { - imgReader.setScaledSize(imgReader.size().boundedTo(*getMaxImageSize())); - } - - QImage im = imgReader.read(); - if (im.isNull()) - qWarning("Could not load texture: %s", qPrintable(fileName)); - setImage(im); - } - } - else - { - if (!d->downloadManager) { - if (getenv(QT3D_MULTITHREAD)) { - //Download in a multithreaded environment - d->downloadManager = new QThreadedDownloadManager(); - } else { - //Download in a single threaded environment - d->downloadManager = new QDownloadManager(); - } - connect (d->downloadManager,SIGNAL(downloadComplete(QByteArray)),this, SLOT(textureRequestFinished(QByteArray))); - } - - //Create a temporary image that will be used until the Url is loaded. - static QImage tempImg(128,128, QImage::Format_RGB32); - QColor fillcolor(Qt::gray); - tempImg.fill(fillcolor.rgba()); - setImage(tempImg); - - if (!d->downloadManager->beginDownload(QUrl(url.toString()))) { - qWarning("Unable to issue texture download request."); - } - } - } -} - -/*! - Copies the contents of \a image to \a offset in this texture - within the current GL context. - - Unlike setImage(), this function copies the image data to the - GL server immediately using \c{glTexSubImage2D()}. This is typically - used to update the contents of a texture after it has been created. - - It is assumed that the application has already called bind() on - this texture to bind it to the current GL context. - - If the texture has been created in multiple contexts, only the - texture identifier for the current context will be updated. - - \sa setImage(), bind() -*/ -void QGLTexture2D::copyImage(const QImage& image, const QPoint& offset) -{ - QImage img = QGLWidget::convertToGLFormat(image); - glTexSubImage2D(GL_TEXTURE_2D, 0, offset.x(), offset.y(), - img.width(), img.height(), GL_RGBA, - GL_UNSIGNED_BYTE, img.bits()); -#if defined(QT_OPENGL_ES_2) - Q_D(QGLTexture2D); - if (d->bindOptions & QGLContext::MipmapBindOption) - glGenerateMipmap(GL_TEXTURE_2D); -#endif -} - -/*! - Returns the options to use when binding the image() to an OpenGL - context for the first time. The default options are - QGLContext::LinearFilteringBindOption | - QGLContext::InvertedYBindOption | QGLContext::MipmapBindOption. - - \sa setBindOptions() -*/ -QGLContext::BindOptions QGLTexture2D::bindOptions() const -{ - Q_D(const QGLTexture2D); - return d->bindOptions; -} - -/*! - Sets the \a options to use when binding the image() to an - OpenGL context. If the image() has already been bound, - then changing the options will cause it to be recreated - from image() the next time bind() is called. - - \sa bindOptions(), bind() -*/ -void QGLTexture2D::setBindOptions(QGLContext::BindOptions options) -{ - Q_D(QGLTexture2D); - if (d->bindOptions != options) { - d->bindOptions = options; - ++(d->imageGeneration); - } -} - -/*! - Returns the wrapping mode for horizontal texture co-ordinates. - The default value is QGL::Repeat. - - \sa setHorizontalWrap(), verticalWrap() -*/ -QGL::TextureWrap QGLTexture2D::horizontalWrap() const -{ - Q_D(const QGLTexture2D); - return d->horizontalWrap; -} - -/*! - Sets the wrapping mode for horizontal texture co-ordinates to \a value. - - If \a value is not supported by the OpenGL implementation, it will be - replaced with a value that is supported. If the application desires a - very specific \a value, it can call horizontalWrap() to check that - the specific value was actually set. - - The \a value will not be applied to the texture in the GL - server until the next call to bind(). - - \sa horizontalWrap(), setVerticalWrap() -*/ -void QGLTexture2D::setHorizontalWrap(QGL::TextureWrap value) -{ - Q_D(QGLTexture2D); - value = qt_gl_modify_texture_wrap(value); - if (d->horizontalWrap != value) { - d->horizontalWrap = value; - ++(d->parameterGeneration); - } -} - -/*! - Returns the wrapping mode for vertical texture co-ordinates. - The default value is QGL::Repeat. - - \sa setVerticalWrap(), horizontalWrap() -*/ -QGL::TextureWrap QGLTexture2D::verticalWrap() const -{ - Q_D(const QGLTexture2D); - return d->verticalWrap; -} - -/*! - Sets the wrapping mode for vertical texture co-ordinates to \a value. - - If \a value is not supported by the OpenGL implementation, it will be - replaced with a value that is supported. If the application desires a - very specific \a value, it can call verticalWrap() to check that - the specific value was actually set. - - The \a value will not be applied to the texture in the GL - server until the next call to bind(). - - \sa verticalWrap(), setHorizontalWrap() -*/ -void QGLTexture2D::setVerticalWrap(QGL::TextureWrap value) -{ - Q_D(QGLTexture2D); - value = qt_gl_modify_texture_wrap(value); - if (d->verticalWrap != value) { - d->verticalWrap = value; - ++(d->parameterGeneration); - } -} - -/*! - Binds this texture to the 2D texture target. - - If this texture object is not associated with an identifier in - the current context, then a new identifier will be created, - and image() uploaded into the GL server. - - If setImage() or setSize() was called since the last upload, - then image() will be re-uploaded to the GL server. - - Returns false if the texture could not be bound for some reason. - - \sa release(), textureId(), setImage() -*/ -bool QGLTexture2D::bind() const -{ - Q_D(const QGLTexture2D); - return const_cast<QGLTexture2DPrivate *>(d)->bind(GL_TEXTURE_2D); -} - -bool QGLTexture2DPrivate::bind(GLenum target) -{ - // Get the current context. If we don't have one, then we - // cannot bind the texture. - const QGLContext *ctx = QGLContext::currentContext(); - if (!ctx) - return false; - - QOpenGLFunctions glFuncs(ctx); - if (!glFuncs.hasOpenGLFeature(QOpenGLFunctions::NPOTTextures)) - { - QSize oldSize = size; - size = QGL::nextPowerOfTwo(size); - if (size != oldSize) - ++imageGeneration; - } - - // Find the information block for the context, or create one. - QGLTexture2DTextureInfo *info = infos; - QGLTexture2DTextureInfo *prev = 0; - while (info != 0 && !QGLContext::areSharing(info->tex.context(), ctx)) { - if (info->isLiteral) - return false; // Cannot create extra texture id's for literals. - prev = info; - info = info->next; - } - if (!info) { - info = new QGLTexture2DTextureInfo - (ctx, 0, imageGeneration - 1, parameterGeneration - 1); - if (prev) - prev->next = info; - else - infos = info; - } - - if (!info->tex.textureId() || imageGeneration != info->imageGeneration) { - // Create the texture contents and upload a new image. - info->tex.setOptions(bindOptions); - if (!compressedData.isEmpty()) { - info->tex.bindCompressedTexture - (compressedData.constData(), compressedData.size()); - } else { - info->tex.startUpload(ctx, target, image.size()); - bindImages(info); - info->tex.finishUpload(target); - } - info->imageGeneration = imageGeneration; - } else { - // Bind the existing texture to the texture target. - glBindTexture(target, info->tex.textureId()); - } - - // If the parameter generation has changed, then alter the parameters. - if (parameterGeneration != info->parameterGeneration) { - info->parameterGeneration = parameterGeneration; - q_glTexParameteri(target, GL_TEXTURE_WRAP_S, horizontalWrap); - q_glTexParameteri(target, GL_TEXTURE_WRAP_T, verticalWrap); - } - - // Texture is ready to be used. - return true; -} - -void QGLTexture2DPrivate::bindImages(QGLTexture2DTextureInfo *info) -{ - QSize scaledSize(size); -#if defined(QT_OPENGL_ES_2) - if ((bindOptions & QGLContext::MipmapBindOption) || - horizontalWrap != QGL::ClampToEdge || - verticalWrap != QGL::ClampToEdge) { - // ES 2.0 does not support NPOT textures when mipmaps are in use, - // or if the wrap mode isn't ClampToEdge. - scaledSize = QGL::nextPowerOfTwo(scaledSize); - } -#endif - - if (forcePowerOfTwo == ForcePowerOfTwoTrue) - scaledSize = QGL::nextPowerOfTwo(scaledSize); - - if (!image.isNull()) - info->tex.uploadFace(GL_TEXTURE_2D, image, scaledSize); - else if (size.isValid()) - info->tex.createFace(GL_TEXTURE_2D, scaledSize); -} - -/*! - Releases the texture associated with the 2D texture target. - This is equivalent to \c{glBindTexture(GL_TEXTURE_2D, 0)}. - - \sa bind() -*/ -void QGLTexture2D::release() const -{ - glBindTexture(GL_TEXTURE_2D, 0); -} - -/*! - Returns the identifier associated with this texture object in - the current context. - - Returns zero if the texture has not previously been bound to - the 2D texture target in the current context with bind(). - - \sa bind() -*/ -GLuint QGLTexture2D::textureId() const -{ - Q_D(const QGLTexture2D); - const QGLContext *ctx = QGLContext::currentContext(); - if (!ctx) - return 0; - QGLTexture2DTextureInfo *info = d->infos; - while (info != 0 && !QGLContext::areSharing(info->tex.context(), ctx)) - info = info->next; - return info ? info->tex.textureId() : 0; -} - -/*! - Constructs a QGLTexture2D object that wraps the supplied literal - texture identifier \a id, with the dimensions specified by \a size. - - The \a id is assumed to have been created by the application in - the current GL context, and it will be destroyed by the application - after the returned QGLTexture2D object is destroyed. - - This function is intended for interfacing to existing code that - uses raw GL texture identifiers. The returned QGLTexture2D can - only be used with the current GL context. - - \sa textureId() -*/ -QGLTexture2D *QGLTexture2D::fromTextureId(GLuint id, const QSize& size) -{ - const QGLContext *ctx = QGLContext::currentContext(); - if (!id || !ctx) - return 0; - - QGLTexture2D *texture = new QGLTexture2D(); - if (!size.isNull()) - texture->setSize(size); - QGLTexture2DTextureInfo *info = new QGLTexture2DTextureInfo - (ctx, id, texture->d_ptr->imageGeneration, - texture->d_ptr->parameterGeneration, true); - texture->d_ptr->infos = info; - return texture; -} - -/*! - This slot is used to recieve signals from the QDownloadManager class - which provides Url download capability across the network. - - A successful download will have a valid QByteArray stored in \a assetData, - while a failed download (due to network error, etc), will result in - a NULL value. - - Successful downloads use the image data downloaded into \a assetData, - which is converted to an image/texture, and emit a textureUpdated() - signal. - - \sa QDownloadManager -*/ -void QGLTexture2D::textureRequestFinished(QByteArray assetData) -{ - //Ensure valid asset data exists. - if (assetData.isEmpty()) { - qWarning("Network request failed. Texture not loaded."); - } else { - //Convert asset data to an image. - QImage texImage; - texImage.loadFromData(assetData); - setImage(texImage.mirrored()); - - emit textureUpdated(); - } -} - -/*! - Sets the maximum size of an image file loaded in a texture as being - of \a width x \a height in size. - - \sa setUrl() -*/ -void QGLTexture2D::setMaxImageSize(int width, int height) -{ - Q_ASSERT(width>0 && height>0); - (*getMaxImageSize()) = QSize(width, height); -} - -/*! - \fn QGLTexture2D::textureUpdated() - Signals that some property of this texture has changed in a manner - that may require that the parent material class be updated. -*/ - -QT_END_NAMESPACE diff --git a/src/threed/textures/qgltexture2d.h b/src/threed/textures/qgltexture2d.h deleted file mode 100644 index 0513848a..00000000 --- a/src/threed/textures/qgltexture2d.h +++ /dev/null @@ -1,115 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtQuick3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QGLTEXTURE2D_H -#define QGLTEXTURE2D_H - -#include "qglnamespace.h" -#include <QtOpenGL/qgl.h> -#include <QtCore/qscopedpointer.h> - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Qt3D) - -class QGLTexture2DPrivate; - -class Q_QT3D_EXPORT QGLTexture2D : public QObject -{ - Q_OBJECT -public: - QGLTexture2D(QObject *parent = 0); - ~QGLTexture2D(); - - bool isNull() const; - bool hasAlphaChannel() const; - - QSize size() const; - void setSize(const QSize& value); - QSize requestedSize() const; - - QImage image() const; - void setImage(const QImage& image); - bool setCompressedFile(const QString &path); - QUrl url() const; - void setUrl(const QUrl &url); - - void setPixmap(const QPixmap& pixmap); - - void clearImage(); - - void copyImage(const QImage& image, const QPoint& offset = QPoint(0, 0)); - - QGLContext::BindOptions bindOptions() const; - void setBindOptions(QGLContext::BindOptions options); - - QGL::TextureWrap horizontalWrap() const; - void setHorizontalWrap(QGL::TextureWrap value); - - QGL::TextureWrap verticalWrap() const; - void setVerticalWrap(QGL::TextureWrap value); - - bool bind() const; - void release() const; - - GLuint textureId() const; - - static void setMaxImageSize(int width, int height); - - static QGLTexture2D *fromTextureId(GLuint id, const QSize& size); -signals: - void textureUpdated(); -public slots: - void textureRequestFinished(QByteArray); -private: - QScopedPointer<QGLTexture2DPrivate> d_ptr; - - Q_DISABLE_COPY(QGLTexture2D) - Q_DECLARE_PRIVATE(QGLTexture2D) -}; - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif diff --git a/src/threed/textures/qgltexture2d_p.h b/src/threed/textures/qgltexture2d_p.h deleted file mode 100644 index 0e9ac634..00000000 --- a/src/threed/textures/qgltexture2d_p.h +++ /dev/null @@ -1,126 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtQuick3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QGLTEXTURE2D_P_H -#define QGLTEXTURE2D_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include "qgltexture2d.h" -#include "qgltextureutils_p.h" -#include "qurl.h" -#include <QtCore/qatomic.h> - -QT_BEGIN_NAMESPACE - -class QAbstractDownloadManager; - -class QGLTexture2DTextureInfo -{ -public: - QGLTexture2DTextureInfo - (const QGLContext *context, GLuint textureId, uint imageGeneration, - uint parameterGeneration, bool isLiteral = false) - { - if (textureId) - tex.setTextureId(context, textureId); - this->imageGeneration = imageGeneration; - this->parameterGeneration = parameterGeneration; - this->isLiteral = isLiteral; - this->next = 0; - } - - QGLBoundTexture tex; - uint imageGeneration; - uint parameterGeneration; - bool isLiteral; - QGLTexture2DTextureInfo *next; -}; - -class DDSFormat; - -class QGLTexture2DPrivate -{ -public: - QGLTexture2DPrivate(); - ~QGLTexture2DPrivate(); - - QSize size; - QSize requestedSize; - QImage image; - QUrl url; - QByteArray compressedData; - QGLContext::BindOptions bindOptions; - QGL::TextureWrap horizontalWrap; - QGL::TextureWrap verticalWrap; -#if !defined(QT_OPENGL_ES) - bool mipmapSupported; - bool mipmapSupportedKnown; -#endif - uint imageGeneration; - uint parameterGeneration; - QGLTexture2DTextureInfo *infos; - QAbstractDownloadManager *downloadManager; - - enum ForcePowerOfTwo { - ForcePowerOfTwoUndefined = -1, - ForcePowerOfTwoFalse = 0, - ForcePowerOfTwoTrue = 1 - }; - - static ForcePowerOfTwo forcePowerOfTwo; - - bool bind(GLenum target); - virtual void bindImages(QGLTexture2DTextureInfo *info); -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/threed/textures/qgltexturecube.cpp b/src/threed/textures/qgltexturecube.cpp deleted file mode 100644 index f9587462..00000000 --- a/src/threed/textures/qgltexturecube.cpp +++ /dev/null @@ -1,549 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtQuick3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qgltexturecube.h" -#include "qgltexture2d_p.h" -#include "qgltextureutils_p.h" -#include "qglpainter_p.h" - -QT_BEGIN_NAMESPACE - -/*! - \class QGLTextureCube - \brief The QGLTextureCube class represents a cube map texture object for GL painting operations. - \since 4.8 - \ingroup qt3d - \ingroup qt3d::textures - - QGLTextureCube contains six QImage objects for each of the cube - map faces and settings for texture filters, wrap modes, and mipmap - generation. When bind() is called, this information is uploaded to - the GL server if it has changed since the last time bind() was called. - - Once a QGLTextureCube object is created, it can be bound to multiple - GL contexts. Internally, a separate texture identifier is created - for each context. This makes QGLTextureCube easier to use than - raw GL texture identifiers because the application does not need - to be as concerned with whether the texture identifier is valid - in the current context. The application merely calls bind() and - QGLTextureCube will create a new texture identifier for the context - if necessary. - - QGLTextureCube internally points to a reference-counted object that - represents the current texture state. If the QGLTextureCube is copied, - the internal pointer is the same. Modifications to one QGLTextureCube - copy will affect all of the other copies in the system. - - The texture identifiers will be destroyed when the last QGLTextureCube - reference is destroyed, or when a context is destroyed that contained a - texture identifier that was created by QGLTextureCube. - - \sa QGLTexture2D -*/ - -/*! - \enum QGLTextureCube::Face - This enum defines the face of a cube map texture that is affected - by a texture operation on QGLTextureCube instances. - - \value PositiveX The positive X face of the cube map. - \value NegativeX The negative X face of the cube map. - \value PositiveY The positive Y face of the cube map. - \value NegativeY The negative Y face of the cube map. - \value PositiveZ The positive Z face of the cube map. - \value NegativeZ The negative Z face of the cube map. -*/ - -class QGLTextureCubePrivate : public QGLTexture2DPrivate -{ -public: - QGLTextureCubePrivate(); - ~QGLTextureCubePrivate(); - - void bindImages(QGLTexture2DTextureInfo *info); - - QImage otherImages[5]; - uint changedFaces; -}; - -QGLTextureCubePrivate::QGLTextureCubePrivate() -{ - changedFaces = 0; -} - -QGLTextureCubePrivate::~QGLTextureCubePrivate() -{ -} - -void QGLTextureCubePrivate::bindImages(QGLTexture2DTextureInfo *info) -{ - QSize scaledSize(size); -#if defined(QT_OPENGL_ES_2) - if ((bindOptions & QGLContext::MipmapBindOption) || - horizontalWrap != QGL::ClampToEdge || - verticalWrap != QGL::ClampToEdge) { - // ES 2.0 does not support NPOT textures when mipmaps are in use, - // or if the wrap mode isn't ClampToEdge. - scaledSize = QGL::nextPowerOfTwo(scaledSize); - } -#endif - - // Handle the first face. - if (!image.isNull()) - info->tex.uploadFace(GL_TEXTURE_CUBE_MAP_POSITIVE_X, image, scaledSize); - else if (size.isValid()) - info->tex.createFace(GL_TEXTURE_CUBE_MAP_POSITIVE_X, scaledSize); - - // Handle the other faces. - for (int face = 1; face < 6; ++face) { - if (!otherImages[face - 1].isNull()) { - info->tex.uploadFace(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, - otherImages[face - 1], scaledSize); - } else { - info->tex.createFace(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, scaledSize); - } - } -} - -/*! - Constructs a null texture object. - - \sa isNull() -*/ -QGLTextureCube::QGLTextureCube() - : d_ptr(new QGLTextureCubePrivate()) -{ -} - -/*! - Destroys this texture object. If this object is the last - reference to the underlying GL texture, then the underlying - GL texture will also be deleted. -*/ -QGLTextureCube::~QGLTextureCube() -{ -} - -/*! - Returns true if this texture object is null; that is, all image() - values are null and textureId() is zero. -*/ -bool QGLTextureCube::isNull() const -{ - // TODO - Q_D(const QGLTextureCube); - return !d->infos; -} - -/*! - Returns true if this texture has an alpha channel; false if the - texture is fully opaque. -*/ -bool QGLTextureCube::hasAlphaChannel() const -{ - Q_D(const QGLTextureCube); - if (!d->image.isNull() && d->image.hasAlphaChannel()) - return true; - for (int face = 0; face < 5; ++face) { - if (!d->otherImages[face].isNull()) { - if (d->otherImages[face].hasAlphaChannel()) - return true; - } - } - QGLTexture2DTextureInfo *info = d->infos; - if (info) - return info->tex.hasAlpha(); - return false; -} - -/*! - Returns the size of this texture. If the underlying OpenGL - implementation requires texture sizes to be a power of two, - then this function will return the next power of two equal - to or greater than requestedSize() - - \sa setSize(), requestedSize() -*/ -QSize QGLTextureCube::size() const -{ - Q_D(const QGLTextureCube); - return d->size; -} - -/*! - Sets the size of this texture to \a value. If the underlying - OpenGL implementation requires texture sizes to be a power of - two, then requestedSize() will be set to \a value, and the - actual size will be set to the next power of two equal - to or greater than \a value. Otherwise both size() and - requestedSize() will be set to \a value. - - \sa size(), requestedSize() -*/ -void QGLTextureCube::setSize(const QSize& value) -{ - Q_D(QGLTextureCube); - if (d->requestedSize == value) - return; - if (!(QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_2_0) && - !(QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_ES_Version_2_0)) - d->size = QGL::nextPowerOfTwo(value); - else - d->size = value; - d->requestedSize = value; - ++(d->imageGeneration); -} - -/*! - Returns the size that was previously set with setSize() before - it was rounded to a power of two. - - \sa size(), setSize() -*/ -QSize QGLTextureCube::requestedSize() const -{ - Q_D(const QGLTextureCube); - return d->requestedSize; -} - -/*! - Returns the image that is currently associated with the specified - \a face of this cube map texture. The image may not have been - uploaded into the GL server yet. Uploads occur upon the next - call to bind(). - - \sa setImage() -*/ -QImage QGLTextureCube::image(QGLTextureCube::Face face) const -{ - Q_D(const QGLTextureCube); - if (uint(face) >= 6) - return QImage(); - if (face == 0) - return d->image; - else - return d->otherImages[face - 1]; -} - -/*! - Sets the \a image that is associated with this texture on the - specified \a face of the cube map. The image will be uploaded - into the GL server the next time bind() is called. - - If setSize() or setImage() has been called previously, then \a image - will be scaled to size() when it is uploaded. - - If \a image is null, then this function is equivalent to clearImage(). - - \sa image(), setSize(), copyImage() -*/ -void QGLTextureCube::setImage - (QGLTextureCube::Face face, const QImage& image) -{ - Q_D(QGLTextureCube); - if (uint(face) >= 6) - return; - if (image.isNull()) { - // Don't change the imageGeneration, because we aren't actually - // changing the image in the GL server, only the client copy. - if (face == 0) - d->image = image; - else - d->otherImages[face - 1] = image; - } else { - if (!d->size.isValid()) - setSize(image.size()); - if (face == 0) - d->image = image; - else - d->otherImages[face - 1] = image; - ++(d->imageGeneration); - d->changedFaces |= (1 << face); - } -} - -/*! - Clears the image() that is associated with this texture on the - specified \a face of the cube map. The GL texture will retain - its current value. This can be used to release client-side memory - that is no longer required once the image has been uploaded into - the GL server. - - The following code will queue \c image to be uploaded as the - positive X face of the cube map, immediately force it to - be uploaded into the current GL context, and then clear the - client copy: - - \code - texture.setImage(QGLTextureCube::PositiveX, image); - texture.bind(); - texture.clearImage(QGLTextureCube::PositiveX); - \endcode - - \sa image(), setImage() -*/ -void QGLTextureCube::clearImage(QGLTextureCube::Face face) -{ - Q_D(QGLTextureCube); - if (face == 0) - d->image = QImage(); - else - d->otherImages[face - 1] = QImage(); -} - -/*! - Copies the contents of \a image to \a offset in this texture - within the current GL context. The \a face parameter indicates - which face of the cube map should be altered. - - Unlike setImage(), this function copies the image data to the - GL server immediately using \c{glTexSubImage2D()}. This is typically - used to update the contents of a texture after it has been created. - - It is assumed that the application has already called bind() on - this texture to bind it to the current GL context. - - If the texture has been created in multiple contexts, only the - texture identifier for the current context will be updated. - - \sa setImage(), bind() -*/ -void QGLTextureCube::copyImage - (QGLTextureCube::Face face, const QImage& image, const QPoint& offset) -{ - if (uint(face) >= 6) - return; // Invalid face number. - QImage img = QGLWidget::convertToGLFormat(image); - glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + int(face), - 0, offset.x(), offset.y(), - img.width(), img.height(), GL_RGBA, - GL_UNSIGNED_BYTE, img.bits()); -#if defined(QT_OPENGL_ES_2) - Q_D(QGLTextureCube); - if (d->bindOptions & QGLContext::MipmapBindOption) - glGenerateMipmap(GL_TEXTURE_CUBE_MAP); -#endif -} - -/*! - Returns the options to use when binding the image() to an OpenGL - context for the first time. The default options are - QGLContext::LinearFilteringBindOption | - QGLContext::InvertedYBindOption | QGLContext::MipmapBindOption. - - \sa setBindOptions() -*/ -QGLContext::BindOptions QGLTextureCube::bindOptions() const -{ - Q_D(const QGLTextureCube); - return d->bindOptions; -} - -/*! - Sets the \a options to use when binding the image() to an - OpenGL context. If the image() has already been bound, - then changing the options will cause it to be recreated - from image() the next time bind() is called. - - \sa bindOptions(), bind() -*/ -void QGLTextureCube::setBindOptions(QGLContext::BindOptions options) -{ - Q_D(QGLTextureCube); - if (d->bindOptions != options) { - d->bindOptions = options; - ++(d->imageGeneration); - } -} - -/*! - Returns the wrapping mode for horizontal texture co-ordinates. - The default value is QGL::Repeat. - - \sa setHorizontalWrap(), verticalWrap() -*/ -QGL::TextureWrap QGLTextureCube::horizontalWrap() const -{ - Q_D(const QGLTextureCube); - return d->horizontalWrap; -} - -/*! - Sets the wrapping mode for horizontal texture co-ordinates to \a value. - - If \a value is not supported by the OpenGL implementation, it will be - replaced with a value that is supported. If the application desires a - very specific \a value, it can call horizontalWrap() to check that - the specific value was actually set. - - The \a value will not be applied to the texture in the GL - server until the next call to bind(). - - \sa horizontalWrap(), setVerticalWrap() -*/ -void QGLTextureCube::setHorizontalWrap(QGL::TextureWrap value) -{ - Q_D(QGLTextureCube); - value = qt_gl_modify_texture_wrap(value); - if (d->horizontalWrap != value) { - d->horizontalWrap = value; - ++(d->parameterGeneration); - } -} - -/*! - Returns the wrapping mode for vertical texture co-ordinates. - The default value is QGL::Repeat. - - \sa setVerticalWrap(), horizontalWrap() -*/ -QGL::TextureWrap QGLTextureCube::verticalWrap() const -{ - Q_D(const QGLTextureCube); - return d->verticalWrap; -} - -/*! - Sets the wrapping mode for vertical texture co-ordinates to \a value. - - If \a value is not supported by the OpenGL implementation, it will be - replaced with a value that is supported. If the application desires a - very specific \a value, it can call verticalWrap() to check that - the specific value was actually set. - - The \a value will not be applied to the texture in the GL - server until the next call to bind(). - - \sa verticalWrap(), setHorizontalWrap() -*/ -void QGLTextureCube::setVerticalWrap(QGL::TextureWrap value) -{ - Q_D(QGLTextureCube); - value = qt_gl_modify_texture_wrap(value); - if (d->verticalWrap != value) { - d->verticalWrap = value; - ++(d->parameterGeneration); - } -} - -/*! - Binds this texture to the cube map texture target. - - If this texture object is not associated with an identifier in - the current context, then a new identifier will be created, - and the face images will be uploaded into the GL server. - - If setImage() or setSize() was called since the last upload, - then the face images will be re-uploaded to the GL server. - - Returns false if the texture could not be bound for some reason. - - \sa release(), textureId(), setImage() -*/ -bool QGLTextureCube::bind() const -{ - Q_D(const QGLTextureCube); - return const_cast<QGLTextureCubePrivate *>(d)->bind(GL_TEXTURE_CUBE_MAP); -} - -/*! - Releases the texture associated with the cube map texture target. - This is equivalent to \c{glBindTexture(GL_TEXTURE_CUBE_MAP, 0)}. - - \sa bind() -*/ -void QGLTextureCube::release() -{ - glBindTexture(GL_TEXTURE_CUBE_MAP, 0); -} - -/*! - Returns the identifier associated with this texture object in - the current context. - - Returns zero if the texture has not previously been bound to - the 2D texture target in the current context with bind(). - - \sa bind() -*/ -GLuint QGLTextureCube::textureId() const -{ - Q_D(const QGLTextureCube); - const QGLContext *ctx = QGLContext::currentContext(); - if (!ctx) - return 0; - QGLTexture2DTextureInfo *info = d->infos; - while (info != 0 && info->tex.context() != ctx) - info = info->next; - return info ? info->tex.textureId() : 0; -} - -/*! - Constructs a QGLTextureCube object that wraps the supplied literal - texture identifier \a id, with the dimensions specified by \a size. - - The \a id is assumed to have been created by the application in - the current GL context, and it will be destroyed by the application - after the returned QGLTextureCube object is destroyed. - - This function is intended for interfacing to existing code that - uses raw GL texture identifiers. The returned QGLTextureCube can - only be used with the current GL context. - - \sa textureId() -*/ -QGLTextureCube *QGLTextureCube::fromTextureId(GLuint id, const QSize& size) -{ - const QGLContext *ctx = QGLContext::currentContext(); - if (!id || !ctx) - return 0; - - QGLTextureCube *texture = new QGLTextureCube(); - if (!size.isNull()) - texture->setSize(size); - QGLTexture2DTextureInfo *info = new QGLTexture2DTextureInfo - (ctx, id, texture->d_ptr->imageGeneration, - texture->d_ptr->parameterGeneration, true); - texture->d_ptr->infos = info; - return texture; -} - -QT_END_NAMESPACE diff --git a/src/threed/textures/qgltexturecube.h b/src/threed/textures/qgltexturecube.h deleted file mode 100644 index 24f397b4..00000000 --- a/src/threed/textures/qgltexturecube.h +++ /dev/null @@ -1,112 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtQuick3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QGLTEXTURECUBEMAP_H -#define QGLTEXTURECUBEMAP_H - -#include "qglnamespace.h" -#include <QtOpenGL/qgl.h> - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Qt3D) - -class QGLTextureCubePrivate; - -class Q_QT3D_EXPORT QGLTextureCube -{ -public: - QGLTextureCube(); - ~QGLTextureCube(); - - enum Face - { - PositiveX, - NegativeX, - PositiveY, - NegativeY, - PositiveZ, - NegativeZ - }; - - bool isNull() const; - bool hasAlphaChannel() const; - - QSize size() const; - void setSize(const QSize& value); - QSize requestedSize() const; - - QImage image(QGLTextureCube::Face face) const; - void setImage(QGLTextureCube::Face face, const QImage& image); - void clearImage(QGLTextureCube::Face face); - - void copyImage(QGLTextureCube::Face face, const QImage& image, const QPoint& offset = QPoint(0, 0)); - - QGLContext::BindOptions bindOptions() const; - void setBindOptions(QGLContext::BindOptions options); - - QGL::TextureWrap horizontalWrap() const; - void setHorizontalWrap(QGL::TextureWrap value); - - QGL::TextureWrap verticalWrap() const; - void setVerticalWrap(QGL::TextureWrap value); - - bool bind() const; - static void release(); - - GLuint textureId() const; - - static QGLTextureCube *fromTextureId(GLuint id, const QSize& size); - -private: - QScopedPointer<QGLTextureCubePrivate> d_ptr; - - Q_DISABLE_COPY(QGLTextureCube) - Q_DECLARE_PRIVATE(QGLTextureCube) -}; - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif diff --git a/src/threed/textures/qgltextureutils.cpp b/src/threed/textures/qgltextureutils.cpp deleted file mode 100644 index acdf7a9d..00000000 --- a/src/threed/textures/qgltextureutils.cpp +++ /dev/null @@ -1,785 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtQuick3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qgltextureutils_p.h" -#include "qglext_p.h" -#include <QtCore/qfile.h> - -QT_BEGIN_NAMESPACE - -QGL::TextureWrap qt_gl_modify_texture_wrap(QGL::TextureWrap value) -{ - switch (value) { -#if defined(QT_OPENGL_ES) - case QGL::Clamp: - value = QGL::ClampToEdge; - break; -#endif -#if !defined(QT_OPENGL_ES) - case QGL::ClampToBorder: - if ((QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_1_3) - == 0) - value = QGL::Clamp; - break; -#else - case QGL::ClampToBorder: - value = QGL::ClampToEdge; - break; -#endif -#if !defined(QT_OPENGL_ES) - case QGL::ClampToEdge: - if ((QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_1_2) - == 0) - value = QGL::Clamp; - break; -#endif -#if !defined(QT_OPENGL_ES) - case QGL::MirroredRepeat: - if ((QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_1_4) - == 0) - value = QGL::Repeat; - break; -#elif !defined(QT_OPENGL_ES_2) - case QGL::MirroredRepeat: - value = QGL::Repeat; - break; -#endif - default: break; - } - return value; -} - -QGLTextureExtensions::QGLTextureExtensions(const QGLContext *ctx) - : npotTextures(false) - , generateMipmap(false) - , bgraTextureFormat(false) - , ddsTextureCompression(false) - , etc1TextureCompression(false) - , pvrtcTextureCompression(false) - , compressedTexImage2D(0) -{ - Q_UNUSED(ctx); - QGLExtensionChecker extensions(reinterpret_cast<const char *>(glGetString(GL_EXTENSIONS))); - if (extensions.match("GL_ARB_texture_non_power_of_two")) - npotTextures = true; - if (extensions.match("GL_SGIS_generate_mipmap")) - generateMipmap = true; - if (extensions.match("GL_EXT_bgra")) - bgraTextureFormat = true; - if (extensions.match("GL_EXT_texture_compression_s3tc")) - ddsTextureCompression = true; - if (extensions.match("GL_OES_compressed_ETC1_RGB8_texture")) - etc1TextureCompression = true; - if (extensions.match("GL_IMG_texture_compression_pvrtc")) - pvrtcTextureCompression = true; -#if defined(QT_OPENGL_ES_2) - npotTextures = true; - generateMipmap = true; -#endif -#if !defined(QT_OPENGL_ES) - if (extensions.match("GL_ARB_texture_compression")) { - compressedTexImage2D = (q_glCompressedTexImage2DARB) - ctx->getProcAddress(QLatin1String("glCompressedTexImage2DARB")); - } -#else - compressedTexImage2D = glCompressedTexImage2D; -#endif -} - -QGLTextureExtensions::~QGLTextureExtensions() -{ -} - -Q_GLOBAL_STATIC(QGLResource<QGLTextureExtensions>, qt_gl_texture_extensions) - -QGLTextureExtensions *QGLTextureExtensions::extensions() -{ - const QGLContext *ctx = QGLContext::currentContext(); - if (!ctx) - return 0; - return qt_gl_texture_extensions()->value(ctx); -} - -static void qt_gl_destroyTextureId(GLuint id) -{ - glDeleteTextures(1, &id); -} - -QGLBoundTexture::QGLBoundTexture() - : m_resource(qt_gl_destroyTextureId) - , m_options(QGLContext::DefaultBindOption) - , m_hasAlpha(false) -{ -} - -QGLBoundTexture::~QGLBoundTexture() -{ -} - -// #define QGL_BIND_TEXTURE_DEBUG - -void QGLBoundTexture::startUpload(const QGLContext *ctx, GLenum target, const QSize &imageSize) -{ - Q_UNUSED(imageSize); - - QGLTextureExtensions *extensions = QGLTextureExtensions::extensions(); - if (!extensions) - return; - -#ifdef QGL_BIND_TEXTURE_DEBUG - printf("QGLBoundTexture::startUpload(), imageSize=(%d,%d), options=%x\n", - imageSize.width(), imageSize.height(), int(m_options)); - time.start(); -#endif - -#ifndef QT_NO_DEBUG - // Reset the gl error stack... - while (glGetError() != GL_NO_ERROR) ; -#endif - - // Create the texture id for the target, which should be one of - // GL_TEXTURE_2D or GL_TEXTURE_CUBE_MAP. - GLuint id = m_resource.id(); - if (id) { - glBindTexture(target, 0); // Just in case texture is bound. - m_resource.destroy(); - } - id = 0; - glGenTextures(1, &id); - glBindTexture(target, id); - m_resource.attach(ctx, id); - - GLuint filtering = m_options & QGLContext::LinearFilteringBindOption ? GL_LINEAR : GL_NEAREST; - -#ifdef QGL_BIND_TEXTURE_DEBUG - printf(" - setting options (%d ms)\n", time.elapsed()); -#endif - q_glTexParameteri(target, GL_TEXTURE_MAG_FILTER, filtering); - - if (QGLContext::currentContext()->format().directRendering() - && extensions->generateMipmap - && (m_options & QGLContext::MipmapBindOption)) - { -#if !defined(QT_OPENGL_ES_2) - glHint(GL_GENERATE_MIPMAP_HINT_SGIS, GL_NICEST); - q_glTexParameteri(target, GL_GENERATE_MIPMAP_SGIS, GL_TRUE); -#else - glHint(GL_GENERATE_MIPMAP_HINT, GL_NICEST); -#endif - q_glTexParameteri(target, GL_TEXTURE_MIN_FILTER, - m_options & QGLContext::LinearFilteringBindOption - ? GL_LINEAR_MIPMAP_LINEAR : GL_NEAREST_MIPMAP_NEAREST); - } else { - q_glTexParameteri(target, GL_TEXTURE_MIN_FILTER, filtering); - m_options &= ~QGLContext::MipmapBindOption; - } -} - -// map from Qt's ARGB endianness-dependent format to GL's big-endian RGBA layout -static inline void qt_gl_byteSwapImage(QImage &img, GLenum pixel_type) -{ - const int width = img.width(); - const int height = img.height(); - - if (pixel_type == GL_UNSIGNED_INT_8_8_8_8_REV - || (pixel_type == GL_UNSIGNED_BYTE && QSysInfo::ByteOrder == QSysInfo::LittleEndian)) - { - for (int i = 0; i < height; ++i) { - uint *p = (uint *) img.scanLine(i); - for (int x = 0; x < width; ++x) - p[x] = ((p[x] << 16) & 0xff0000) | ((p[x] >> 16) & 0xff) | (p[x] & 0xff00ff00); - } - } else { - for (int i = 0; i < height; ++i) { - uint *p = (uint *) img.scanLine(i); - for (int x = 0; x < width; ++x) - p[x] = (p[x] << 8) | ((p[x] >> 24) & 0xff); - } - } -} - -// #define QGL_BIND_TEXTURE_DEBUG - -void QGLBoundTexture::uploadFace - (GLenum target, const QImage &image, const QSize &scaleSize, GLenum format) -{ - GLenum internalFormat(format); - - // Resolve the texture-related extensions for the current context. - QGLTextureExtensions *extensions = QGLTextureExtensions::extensions(); - if (!extensions) - return; - - // Adjust the image size for scaling and power of two. - QSize size = (!scaleSize.isEmpty() ? scaleSize : image.size()); - if (!extensions->npotTextures) - size = QGL::nextPowerOfTwo(size); - QImage img(image); - if (size != image.size()) { -#ifdef QGL_BIND_TEXTURE_DEBUG - printf(" - scaling up to %dx%d (%d ms) \n", size.width(), size.height(), time.elapsed()); -#endif - img = img.scaled(size); - } - m_size = size; - - QImage::Format target_format = img.format(); - bool premul = m_options & QGLContext::PremultipliedAlphaBindOption; - GLenum externalFormat; - GLuint pixel_type; - if (extensions->bgraTextureFormat) { - externalFormat = GL_BGRA; - if (QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_1_2) - pixel_type = GL_UNSIGNED_INT_8_8_8_8_REV; - else - pixel_type = GL_UNSIGNED_BYTE; - } else { - externalFormat = GL_RGBA; - pixel_type = GL_UNSIGNED_BYTE; - } - - switch (target_format) { - case QImage::Format_ARGB32: - if (premul) { - img = img.convertToFormat(target_format = QImage::Format_ARGB32_Premultiplied); -#ifdef QGL_BIND_TEXTURE_DEBUG - printf(" - converting ARGB32 -> ARGB32_Premultiplied (%d ms) \n", time.elapsed()); -#endif - } - break; - case QImage::Format_ARGB32_Premultiplied: - if (!premul) { - img = img.convertToFormat(target_format = QImage::Format_ARGB32); -#ifdef QGL_BIND_TEXTURE_DEBUG - printf(" - converting ARGB32_Premultiplied -> ARGB32 (%d ms)\n", time.elapsed()); -#endif - } - break; - case QImage::Format_RGB16: - pixel_type = GL_UNSIGNED_SHORT_5_6_5; - externalFormat = GL_RGB; - internalFormat = GL_RGB; - break; - case QImage::Format_RGB32: - break; - default: - if (img.hasAlphaChannel()) { - img = img.convertToFormat(premul - ? QImage::Format_ARGB32_Premultiplied - : QImage::Format_ARGB32); -#ifdef QGL_BIND_TEXTURE_DEBUG - printf(" - converting to 32-bit alpha format (%d ms)\n", time.elapsed()); -#endif - } else { - img = img.convertToFormat(QImage::Format_RGB32); -#ifdef QGL_BIND_TEXTURE_DEBUG - printf(" - converting to 32-bit (%d ms)\n", time.elapsed()); -#endif - } - } - - if (m_options & QGLContext::InvertedYBindOption) { -#ifdef QGL_BIND_TEXTURE_DEBUG - printf(" - flipping bits over y (%d ms)\n", time.elapsed()); -#endif - if (img.isDetached()) { - int ipl = img.bytesPerLine() / 4; - int h = img.height(); - for (int y=0; y<h/2; ++y) { - int *a = (int *) img.scanLine(y); - int *b = (int *) img.scanLine(h - y - 1); - for (int x=0; x<ipl; ++x) - qSwap(a[x], b[x]); - } - } else { - // Create a new image and copy across. If we use the - // above in-place code then a full copy of the image is - // made before the lines are swapped, which processes the - // data twice. This version should only do it once. - img = img.mirrored(); - } - } - - if (externalFormat == GL_RGBA) { -#ifdef QGL_BIND_TEXTURE_DEBUG - printf(" - doing byte swapping (%d ms)\n", time.elapsed()); -#endif - // The only case where we end up with a depth different from - // 32 in the switch above is for the RGB16 case, where we set - // the format to GL_RGB - Q_ASSERT(img.depth() == 32); - qt_gl_byteSwapImage(img, pixel_type); - } -#ifdef QT_OPENGL_ES - // OpenGL/ES requires that the internal and external formats be - // identical. - internalFormat = externalFormat; -#endif -#ifdef QGL_BIND_TEXTURE_DEBUG - printf(" - uploading, image.format=%d, externalFormat=0x%x, internalFormat=0x%x, pixel_type=0x%x\n", - img.format(), externalFormat, internalFormat, pixel_type); -#endif - - const QImage &constRef = img; // to avoid detach in bits()... - glTexImage2D(target, 0, internalFormat, img.width(), img.height(), 0, externalFormat, - pixel_type, constRef.bits()); - - m_hasAlpha = (internalFormat != GL_RGB); -} - -void QGLBoundTexture::createFace - (GLenum target, const QSize &size, GLenum format) -{ - glTexImage2D(target, 0, format, size.width(), - size.height(), 0, format, GL_UNSIGNED_BYTE, 0); - m_hasAlpha = (format != GL_RGB); -} - -void QGLBoundTexture::finishUpload(GLenum target) -{ - Q_UNUSED(target); - -#if defined(QT_OPENGL_ES_2) - // OpenGL/ES 2.0 needs to generate mipmaps after all cubemap faces - // have been uploaded. - if (m_options & QGLContext::MipmapBindOption) { -#ifdef QGL_BIND_TEXTURE_DEBUG - printf(" - generating mipmaps (%d ms)\n", time.elapsed()); -#endif - glGenerateMipmap(target); - } -#endif - -#ifndef QT_NO_DEBUG - GLenum error = glGetError(); - if (error != GL_NO_ERROR) { - qWarning(" - texture upload failed, error code 0x%x, enum: %d (%x)\n", error, target, target); - } -#endif - -#ifdef QGL_BIND_TEXTURE_DEBUG - static int totalUploadTime = 0; - totalUploadTime += time.elapsed(); - printf(" - upload done in (%d ms) time=%d\n", time.elapsed(), totalUploadTime); -#endif -} - -// DDS format structure -struct DDSFormat { - quint32 dwSize; - quint32 dwFlags; - quint32 dwHeight; - quint32 dwWidth; - quint32 dwLinearSize; - quint32 dummy1; - quint32 dwMipMapCount; - quint32 dummy2[11]; - struct { - quint32 dummy3[2]; - quint32 dwFourCC; - quint32 dummy4[5]; - } ddsPixelFormat; -}; - -// compressed texture pixel formats -#define FOURCC_DXT1 0x31545844 -#define FOURCC_DXT2 0x32545844 -#define FOURCC_DXT3 0x33545844 -#define FOURCC_DXT4 0x34545844 -#define FOURCC_DXT5 0x35545844 - -#ifndef GL_COMPRESSED_RGB_S3TC_DXT1_EXT -#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0 -#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1 -#define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2 -#define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3 -#endif - -// PVR header format for container files that store textures compressed -// with the ETC1, PVRTC2, and PVRTC4 encodings. Format information from the -// PowerVR SDK at http://www.imgtec.com/powervr/insider/powervr-sdk.asp -// "PVRTexTool Reference Manual, version 1.11f". -struct PvrHeader -{ - quint32 headerSize; - quint32 height; - quint32 width; - quint32 mipMapCount; - quint32 flags; - quint32 dataSize; - quint32 bitsPerPixel; - quint32 redMask; - quint32 greenMask; - quint32 blueMask; - quint32 alphaMask; - quint32 magic; - quint32 surfaceCount; -}; - -#define PVR_MAGIC 0x21525650 // "PVR!" in little-endian - -#define PVR_FORMAT_MASK 0x000000FF -#define PVR_FORMAT_PVRTC2 0x00000018 -#define PVR_FORMAT_PVRTC4 0x00000019 -#define PVR_FORMAT_ETC1 0x00000036 - -#define PVR_HAS_MIPMAPS 0x00000100 -#define PVR_TWIDDLED 0x00000200 -#define PVR_NORMAL_MAP 0x00000400 -#define PVR_BORDER_ADDED 0x00000800 -#define PVR_CUBE_MAP 0x00001000 -#define PVR_FALSE_COLOR_MIPMAPS 0x00002000 -#define PVR_VOLUME_TEXTURE 0x00004000 -#define PVR_ALPHA_IN_TEXTURE 0x00008000 -#define PVR_VERTICAL_FLIP 0x00010000 - -#ifndef GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG -#define GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG 0x8C00 -#define GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG 0x8C01 -#define GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG 0x8C02 -#define GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG 0x8C03 -#endif - -#ifndef GL_ETC1_RGB8_OES -#define GL_ETC1_RGB8_OES 0x8D64 -#endif - -bool QGLBoundTexture::canBindCompressedTexture - (const char *buf, int len, const char *format, bool *hasAlpha, - bool *isFlipped) -{ - if (QSysInfo::ByteOrder != QSysInfo::LittleEndian) { - // Compressed texture loading only supported on little-endian - // systems such as x86 and ARM at the moment. - return false; - } - if (!format) { - // Auto-detect the format from the header. - if (len >= 4 && !qstrncmp(buf, "DDS ", 4)) { - *hasAlpha = true; - *isFlipped = true; - return true; - } else if (len >= 52 && !qstrncmp(buf + 44, "PVR!", 4)) { - const PvrHeader *pvrHeader = - reinterpret_cast<const PvrHeader *>(buf); - *hasAlpha = (pvrHeader->alphaMask != 0); - *isFlipped = ((pvrHeader->flags & PVR_VERTICAL_FLIP) != 0); - return true; - } - } else { - // Validate the format against the header. - if (!qstricmp(format, "DDS")) { - if (len >= 4 && !qstrncmp(buf, "DDS ", 4)) { - *hasAlpha = true; - *isFlipped = true; - return true; - } - } else if (!qstricmp(format, "PVR") || !qstricmp(format, "ETC1")) { - if (len >= 52 && !qstrncmp(buf + 44, "PVR!", 4)) { - const PvrHeader *pvrHeader = - reinterpret_cast<const PvrHeader *>(buf); - *hasAlpha = (pvrHeader->alphaMask != 0); - *isFlipped = ((pvrHeader->flags & PVR_VERTICAL_FLIP) != 0); - return true; - } - } - } - return false; -} - -bool QGLBoundTexture::bindCompressedTexture - (const char *buf, int len, const char *format) -{ - if (QSysInfo::ByteOrder != QSysInfo::LittleEndian) { - // Compressed texture loading only supported on little-endian - // systems such as x86 and ARM at the moment. - return false; - } -#if !defined(QT_OPENGL_ES) - QGLTextureExtensions *extensions = QGLTextureExtensions::extensions(); - if (!extensions) - return false; - if (!extensions->compressedTexImage2D) { - qWarning("QGLContext::bindTexture(): The GL implementation does " - "not support texture compression extensions."); - return false; - } -#endif - if (!format) { - // Auto-detect the format from the header. - if (len >= 4 && !qstrncmp(buf, "DDS ", 4)) - return bindCompressedTextureDDS(buf, len); - else if (len >= 52 && !qstrncmp(buf + 44, "PVR!", 4)) - return bindCompressedTexturePVR(buf, len); - } else { - // Validate the format against the header. - if (!qstricmp(format, "DDS")) { - if (len >= 4 && !qstrncmp(buf, "DDS ", 4)) - return bindCompressedTextureDDS(buf, len); - } else if (!qstricmp(format, "PVR") || !qstricmp(format, "ETC1")) { - if (len >= 52 && !qstrncmp(buf + 44, "PVR!", 4)) - return bindCompressedTexturePVR(buf, len); - } - } - return false; -} - -bool QGLBoundTexture::bindCompressedTexture - (const QString& fileName, const char *format) -{ - QFile file(fileName); - if (!file.open(QIODevice::ReadOnly)) - return false; - QByteArray contents = file.readAll(); - file.close(); - return bindCompressedTexture - (contents.constData(), contents.size(), format); -} - -bool QGLBoundTexture::bindCompressedTextureDDS(const char *buf, int len) -{ - QGLTextureExtensions *extensions = QGLTextureExtensions::extensions(); - if (!extensions) - return false; - - // Bail out if the necessary extension is not present. - if (!extensions->ddsTextureCompression) { - qWarning("QGLBoundTexture::bindCompressedTextureDDS(): DDS texture compression is not supported."); - return false; - } - - const DDSFormat *ddsHeader = reinterpret_cast<const DDSFormat *>(buf + 4); - if (!ddsHeader->dwLinearSize) { - qWarning("QGLBoundTexture::bindCompressedTextureDDS(): DDS image size is not valid."); - return false; - } - - int blockSize = 16; - GLenum format; - - switch(ddsHeader->ddsPixelFormat.dwFourCC) { - case FOURCC_DXT1: - format = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; - blockSize = 8; - break; - case FOURCC_DXT3: - format = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; - break; - case FOURCC_DXT5: - format = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; - break; - default: - qWarning("QGLBoundTexture::bindCompressedTextureDDS(): DDS image format not supported."); - return false; - } - - const GLubyte *pixels = - reinterpret_cast<const GLubyte *>(buf + ddsHeader->dwSize + 4); - - GLuint id = m_resource.id(); - if (id) { - glBindTexture(GL_TEXTURE_2D, 0); // Just in case it is bound. - m_resource.destroy(); - } - id = 0; - glGenTextures(1, &id); - glBindTexture(GL_TEXTURE_2D, id); - q_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - q_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - m_resource.attach(QGLContext::currentContext(), id); - - int size; - int offset = 0; - int available = len - int(ddsHeader->dwSize + 4); - int w = ddsHeader->dwWidth; - int h = ddsHeader->dwHeight; - - // load mip-maps - for (int i = 0; i < (int) ddsHeader->dwMipMapCount; ++i) { - if (w == 0) w = 1; - if (h == 0) h = 1; - - size = ((w+3)/4) * ((h+3)/4) * blockSize; - if (size > available) - break; - extensions->compressedTexImage2D - (GL_TEXTURE_2D, i, format, w, h, 0, size, pixels + offset); - offset += size; - available -= size; - - // half size for each mip-map level - w = w/2; - h = h/2; - } - - // DDS images are not inverted. - m_options &= ~QGLContext::InvertedYBindOption; - - m_size = QSize(ddsHeader->dwWidth, ddsHeader->dwHeight); - m_hasAlpha = false; - return true; -} - -bool QGLBoundTexture::bindCompressedTexturePVR(const char *buf, int len) -{ - QGLTextureExtensions *extensions = QGLTextureExtensions::extensions(); - if (!extensions) - return false; - - // Determine which texture format we will be loading. - const PvrHeader *pvrHeader = reinterpret_cast<const PvrHeader *>(buf); - GLenum textureFormat; - quint32 minWidth, minHeight; - switch (pvrHeader->flags & PVR_FORMAT_MASK) { - case PVR_FORMAT_PVRTC2: - if (pvrHeader->alphaMask) - textureFormat = GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG; - else - textureFormat = GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG; - minWidth = 16; - minHeight = 8; - break; - - case PVR_FORMAT_PVRTC4: - if (pvrHeader->alphaMask) - textureFormat = GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG; - else - textureFormat = GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG; - minWidth = 8; - minHeight = 8; - break; - - case PVR_FORMAT_ETC1: - textureFormat = GL_ETC1_RGB8_OES; - minWidth = 4; - minHeight = 4; - break; - - default: - qWarning("QGLBoundTexture::bindCompressedTexturePVR(): PVR image format 0x%x not supported.", int(pvrHeader->flags & PVR_FORMAT_MASK)); - return false; - } - - // Bail out if the necessary extension is not present. - if (textureFormat == GL_ETC1_RGB8_OES) { - if (!extensions->etc1TextureCompression) { - qWarning("QGLBoundTexture::bindCompressedTexturePVR(): ETC1 texture compression is not supported."); - return false; - } - } else { - if (!extensions->pvrtcTextureCompression) { - qWarning("QGLBoundTexture::bindCompressedTexturePVR(): PVRTC texture compression is not supported."); - return false; - } - } - - // Boundary check on the buffer size. - quint32 bufferSize = pvrHeader->headerSize + pvrHeader->dataSize; - if (bufferSize > quint32(len)) { - qWarning("QGLBoundTexture::bindCompressedTexturePVR(): PVR image size is not valid."); - return false; - } - - // Create the texture. - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - GLuint id = m_resource.id(); - if (id) { - glBindTexture(GL_TEXTURE_2D, 0); // Just in case it is bound. - m_resource.destroy(); - } - id = 0; - glGenTextures(1, &id); - glBindTexture(GL_TEXTURE_2D, id); - m_resource.attach(QGLContext::currentContext(), id); - if (pvrHeader->mipMapCount) { - if ((m_options & QGLContext::LinearFilteringBindOption) != 0) { - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); - } else { - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST); - } - } else if ((m_options & QGLContext::LinearFilteringBindOption) != 0) { - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - } else { - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - } - - // Load the compressed mipmap levels. - const GLubyte *buffer = - reinterpret_cast<const GLubyte *>(buf + pvrHeader->headerSize); - bufferSize = pvrHeader->dataSize; - quint32 level = 0; - quint32 width = pvrHeader->width; - quint32 height = pvrHeader->height; - while (bufferSize > 0 && level <= pvrHeader->mipMapCount) { - quint32 size = - (qMax(width, minWidth) * qMax(height, minHeight) * - pvrHeader->bitsPerPixel) / 8; - if (size > bufferSize) - break; - extensions->compressedTexImage2D - (GL_TEXTURE_2D, GLint(level), textureFormat, - GLsizei(width), GLsizei(height), 0, GLsizei(size), buffer); - width /= 2; - height /= 2; - buffer += size; - ++level; - } - - // Restore the default pixel alignment for later texture uploads. - glPixelStorei(GL_UNPACK_ALIGNMENT, 4); - - // Set the invert flag for the texture. The "vertical flip" - // flag in PVR is the opposite sense to our sense of inversion. - if ((pvrHeader->flags & PVR_VERTICAL_FLIP) != 0) - m_options &= ~QGLContext::InvertedYBindOption; - else - m_options |= QGLContext::InvertedYBindOption; - - m_size = QSize(pvrHeader->width, pvrHeader->height); - m_hasAlpha = (pvrHeader->alphaMask != 0); - return true; -} - -QT_END_NAMESPACE diff --git a/src/threed/textures/qgltextureutils_p.h b/src/threed/textures/qgltextureutils_p.h deleted file mode 100644 index 2cff59d3..00000000 --- a/src/threed/textures/qgltextureutils_p.h +++ /dev/null @@ -1,164 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtQuick3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QGLTEXTUREUTILS_P_H -#define QGLTEXTUREUTILS_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QtOpenGL/qgl.h> -#include <QtCore/qdatetime.h> -#include "qglnamespace.h" -#include "qopenglfunctions.h" -#include "qglsharedresource_p.h" - -QT_BEGIN_NAMESPACE - -#ifndef GL_BGRA -#define GL_BGRA 0x80E1 -#endif -#ifndef GL_UNSIGNED_SHORT_5_6_5 -#define GL_UNSIGNED_SHORT_5_6_5 0x8363 -#endif -#ifndef GL_UNSIGNED_INT_8_8_8_8_REV -#define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367 -#endif -#ifndef GL_TEXTURE_CUBE_MAP -#define GL_TEXTURE_CUBE_MAP 0x8513 -#endif -#ifndef GL_TEXTURE_CUBE_MAP_POSITIVE_X -#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515 -#endif -#ifndef GL_TEXTURE_CUBE_MAP_NEGATIVE_Z -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A -#endif - -#ifndef GL_GENERATE_MIPMAP_SGIS -#define GL_GENERATE_MIPMAP_SGIS 0x8191 -#define GL_GENERATE_MIPMAP_HINT_SGIS 0x8192 -#endif - -#if !defined(QT_OPENGL_ES) -#define q_glTexParameteri(target,name,value) \ - glTexParameteri((target), (name), int(value)) -#else -#define q_glTexParameteri(target,name,value) \ - glTexParameterf((target), (name), GLfloat(int(value))) -#endif - -// Modify a wrapping mode to account for platform differences. -QGL::TextureWrap qt_gl_modify_texture_wrap(QGL::TextureWrap value); - -typedef void (QT3D_GLF_APIENTRYP q_glCompressedTexImage2DARB) - (GLenum, GLint, GLenum, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *); - -class QGLTextureExtensions -{ -public: - QGLTextureExtensions(const QGLContext *ctx); - ~QGLTextureExtensions(); - - int npotTextures : 1; - int generateMipmap : 1; - int bgraTextureFormat : 1; - int ddsTextureCompression : 1; - int etc1TextureCompression : 1; - int pvrtcTextureCompression : 1; - q_glCompressedTexImage2DARB compressedTexImage2D; - - static QGLTextureExtensions *extensions(); -}; - -class QGLBoundTexture -{ -public: - QGLBoundTexture(); - ~QGLBoundTexture(); - - const QGLContext *context() const { return m_resource.context(); } - - GLuint textureId() const { return m_resource.id(); } - void setTextureId(const QGLContext *ctx, GLuint id) - { m_resource.attach(ctx, id); } - void clearId() { m_resource.clearId(); } - - QGLContext::BindOptions options() const { return m_options; } - void setOptions(QGLContext::BindOptions options) { m_options = options; } - - QSize size() const { return m_size; } - bool hasAlpha() const { return m_hasAlpha; } - - void startUpload(const QGLContext *ctx, GLenum target, const QSize &imageSize); - void uploadFace(GLenum target, const QImage &image, const QSize &scaleSize, - GLenum format = GL_RGBA); - void createFace(GLenum target, const QSize &size, GLenum format = GL_RGBA); - void finishUpload(GLenum target); - - static bool canBindCompressedTexture - (const char *buf, int len, const char *format, bool *hasAlpha, - bool *isFlipped); - bool bindCompressedTexture - (const QString& fileName, const char *format = 0); - bool bindCompressedTexture - (const char *buf, int len, const char *format = 0); - bool bindCompressedTextureDDS(const char *buf, int len); - bool bindCompressedTexturePVR(const char *buf, int len); - -private: - QGLSharedResource m_resource; - QGLContext::BindOptions m_options; - QSize m_size; - bool m_hasAlpha; - QTime time; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/threed/textures/textures.pri b/src/threed/textures/textures.pri deleted file mode 100644 index ce60c58e..00000000 --- a/src/threed/textures/textures.pri +++ /dev/null @@ -1,15 +0,0 @@ -INCLUDEPATH += $$PWD -VPATH += $$PWD -HEADERS += \ - textures/qgltexture2d.h \ - textures/qgltexturecube.h \ - textures/qareaallocator.h -SOURCES += \ - qareaallocator.cpp \ - qglsharedresource.cpp \ - qgltexture2d.cpp \ - qgltexturecube.cpp \ - qgltextureutils.cpp -PRIVATE_HEADERS += \ - qglsharedresource_p.h \ - qgltexture2d_p.h |