diff options
Diffstat (limited to 'src/datavis3d/utils/texturehelper.cpp')
-rw-r--r-- | src/datavis3d/utils/texturehelper.cpp | 208 |
1 files changed, 208 insertions, 0 deletions
diff --git a/src/datavis3d/utils/texturehelper.cpp b/src/datavis3d/utils/texturehelper.cpp new file mode 100644 index 00000000..395ed1f3 --- /dev/null +++ b/src/datavis3d/utils/texturehelper.cpp @@ -0,0 +1,208 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtDataVis3D module. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia 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. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "texturehelper_p.h" + +#include <QImage> + +//#include <QDebug> + +QTCOMMERCIALDATAVIS3D_BEGIN_NAMESPACE + +GLuint TextureHelper::create2DTexture(const QImage &image, bool useTrilinearFiltering) +{ + GLuint textureId; + glGenTextures(1, &textureId); + glBindTexture(GL_TEXTURE_2D, textureId); + QImage glTexture = TextureHelper::convertToGLFormat(image); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, glTexture.width(), glTexture.height() + , 0, GL_RGBA, GL_UNSIGNED_BYTE, glTexture.bits()); + if (useTrilinearFiltering) { +// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); +// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); +// glGenerateMipmap(GL_TEXTURE_2D); + } else { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + } + glBindTexture(GL_TEXTURE_2D, 0); + return textureId; +} + +GLuint TextureHelper::createCubeMapTexture(const QImage &image, bool useTrilinearFiltering) +{ + GLuint textureId; + glGenTextures(1, &textureId); +// glBindTexture(GL_TEXTURE_CUBE_MAP, textureId); +// QImage glTexture = convertToGLFormat(image); +// glTexImage2D(GL_TEXTURE_CUBE_MAP, 0, GL_RGB, glTexture.width(), glTexture.height() +// , 0, GL_RGB, GL_UNSIGNED_BYTE, glTexture.bits()); +// if (useTrilinearFiltering) { +// glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); +// glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); +// glGenerateMipmap(GL_TEXTURE_CUBE_MAP); +// } else { +// glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST); +// glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); +// } +// glBindTexture(GL_TEXTURE_2D, 0); + return textureId; +} + +QImage TextureHelper::convertToGLFormat(const QImage &srcImage) +{ + QImage res(srcImage.size(), QImage::Format_ARGB32); + convertToGLFormatHelper(res, srcImage.convertToFormat(QImage::Format_ARGB32), GL_RGBA); + return res; +} + +void TextureHelper::convertToGLFormatHelper(QImage &dstImage, const QImage &srcImage + , GLenum texture_format) +{ + Q_ASSERT(dstImage.depth() == 32); + Q_ASSERT(srcImage.depth() == 32); + + if (dstImage.size() != srcImage.size()) { + int target_width = dstImage.width(); + int target_height = dstImage.height(); + qreal sx = target_width / qreal(srcImage.width()); + qreal sy = target_height / qreal(srcImage.height()); + + quint32 *dest = (quint32 *) dstImage.scanLine(0); // NB! avoid detach here + uchar *srcPixels = (uchar *) srcImage.scanLine(srcImage.height() - 1); + int sbpl = srcImage.bytesPerLine(); + int dbpl = dstImage.bytesPerLine(); + + int ix = int(0x00010000 / sx); + int iy = int(0x00010000 / sy); + + quint32 basex = int(0.5 * ix); + quint32 srcy = int(0.5 * iy); + + // scale, swizzle and mirror in one loop + while (target_height--) { + const uint *src = (const quint32 *) (srcPixels - (srcy >> 16) * sbpl); + int srcx = basex; + for (int x=0; x<target_width; ++x) { + dest[x] = qt_gl_convertToGLFormatHelper(src[srcx >> 16], texture_format); + srcx += ix; + } + dest = (quint32 *)(((uchar *) dest) + dbpl); + srcy += iy; + } + } else { + const int width = srcImage.width(); + const int height = srcImage.height(); + const uint *p = (const uint*) srcImage.scanLine(srcImage.height() - 1); + uint *q = (uint*) dstImage.scanLine(0); + + if (texture_format == GL_BGRA) { + if (QSysInfo::ByteOrder == QSysInfo::BigEndian) { + // mirror + swizzle + for (int i=0; i < height; ++i) { + const uint *end = p + width; + while (p < end) { + *q = ((*p << 24) & 0xff000000) + | ((*p >> 24) & 0x000000ff) + | ((*p << 8) & 0x00ff0000) + | ((*p >> 8) & 0x0000ff00); + p++; + q++; + } + p -= 2 * width; + } + } else { + const uint bytesPerLine = srcImage.bytesPerLine(); + for (int i=0; i < height; ++i) { + memcpy(q, p, bytesPerLine); + q += width; + p -= width; + } + } + } else { + if (QSysInfo::ByteOrder == QSysInfo::BigEndian) { + for (int i=0; i < height; ++i) { + const uint *end = p + width; + while (p < end) { + *q = (*p << 8) | ((*p >> 24) & 0xff); + p++; + q++; + } + p -= 2 * width; + } + } else { + for (int i=0; i < height; ++i) { + const uint *end = p + width; + while (p < end) { + *q = ((*p << 16) & 0xff0000) | ((*p >> 16) & 0xff) | (*p & 0xff00ff00); + p++; + q++; + } + p -= 2 * width; + } + } + } + } +} + +QRgb TextureHelper::qt_gl_convertToGLFormatHelper(QRgb src_pixel, GLenum texture_format) +{ + if (texture_format == GL_BGRA) { + if (QSysInfo::ByteOrder == QSysInfo::BigEndian) { + return ((src_pixel << 24) & 0xff000000) + | ((src_pixel >> 24) & 0x000000ff) + | ((src_pixel << 8) & 0x00ff0000) + | ((src_pixel >> 8) & 0x0000ff00); + } else { + return src_pixel; + } + } else { // GL_RGBA + if (QSysInfo::ByteOrder == QSysInfo::BigEndian) { + return (src_pixel << 8) | ((src_pixel >> 24) & 0xff); + } else { + return ((src_pixel << 16) & 0xff0000) + | ((src_pixel >> 16) & 0xff) + | (src_pixel & 0xff00ff00); + } + } +} + +QTCOMMERCIALDATAVIS3D_END_NAMESPACE |