From 645e55729f5b1eb40699b426e0828e2fc448b5a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomi=20Korpip=C3=A4=C3=A4?= Date: Thu, 11 Apr 2013 10:20:33 +0300 Subject: Texture stuff added (lots of test hacks still included, to be removed) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Ib6a68df778970a3339ed16cd579f0bd9fa411e0b Reviewed-by: Tomi Korpipää --- src/datavis3d/datavis3d.pro | 2 +- src/datavis3d/engine/engine.qrc | 3 + src/datavis3d/engine/q3dbars.cpp | 36 ++-- src/datavis3d/engine/shaders/fragmentShaderTexture | 39 ++-- src/datavis3d/engine/textures/cube.png | Bin 0 -> 30341 bytes src/datavis3d/utils/texturehelper.cpp | 208 +++++++++++++++++++++ src/datavis3d/utils/texturehelper_p.h | 66 +++++++ src/datavis3d/utils/utils.pri | 2 + 8 files changed, 323 insertions(+), 33 deletions(-) create mode 100644 src/datavis3d/engine/textures/cube.png create mode 100644 src/datavis3d/utils/texturehelper.cpp create mode 100644 src/datavis3d/utils/texturehelper_p.h (limited to 'src/datavis3d') diff --git a/src/datavis3d/datavis3d.pro b/src/datavis3d/datavis3d.pro index 43b4642f..b4169c4e 100644 --- a/src/datavis3d/datavis3d.pro +++ b/src/datavis3d/datavis3d.pro @@ -1,5 +1,5 @@ TARGET = QtDataVis3D -QT = core gui #qml +QT = core gui opengl #qml DEFINES += QTCOMMERCIALDATAVIS3D_LIBRARY diff --git a/src/datavis3d/engine/engine.qrc b/src/datavis3d/engine/engine.qrc index 8e781f05..6803d1b7 100644 --- a/src/datavis3d/engine/engine.qrc +++ b/src/datavis3d/engine/engine.qrc @@ -22,4 +22,7 @@ shaders/fragmentShaderTexture shaders/vertexShaderTexture + + textures/cube.png + diff --git a/src/datavis3d/engine/q3dbars.cpp b/src/datavis3d/engine/q3dbars.cpp index 5965cc37..9a72bd1a 100644 --- a/src/datavis3d/engine/q3dbars.cpp +++ b/src/datavis3d/engine/q3dbars.cpp @@ -47,6 +47,7 @@ #include "qdataset_p.h" #include "shaderhelper_p.h" #include "objecthelper_p.h" +#include "texturehelper_p.h" #include "utils_p.h" #include @@ -85,8 +86,11 @@ void Q3DBars::initialize() d_ptr->initShaders(QStringLiteral(":/shaders/vertex") , QStringLiteral(":/shaders/fragment")); } - d_ptr->initBackgroundShaders(QStringLiteral(":/shaders/vertex") - , QStringLiteral(":/shaders/fragment")); + // TODO: Texture test + d_ptr->initBackgroundShaders(QStringLiteral(":/shaders/vertexTexture") + , QStringLiteral(":/shaders/fragmentTexture")); +// d_ptr->initBackgroundShaders(QStringLiteral(":/shaders/vertexTexture") +// , QStringLiteral(":/shaders/fragmentTexture")); d_ptr->initSelectionShader(); #ifndef USE_HAX0R_SELECTION @@ -623,11 +627,9 @@ void Q3DBars::drawScene() // Bind background shader d_ptr->m_backgroundShader->bind(); - // Texture test - //glEnable(GL_TEXTURE_2D); - //GLuint bgrTexture = QGLContext::bindTexture(QImage(":/cube.png")); - //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + // TODO: Texture test + glEnable(GL_TEXTURE_2D); + GLuint bgrTexture = TextureHelper::create2DTexture(QImage(QStringLiteral(":/textures/cubetex"))); // Draw background if (d_ptr->m_backgroundObj) { @@ -660,11 +662,11 @@ void Q3DBars::drawScene() , d_ptr->m_lightStrength); d_ptr->m_backgroundShader->setUniformValue(d_ptr->m_backgroundShader->ambientS() , d_ptr->m_ambientStrength); - - // Bind the texture in texture unit 0 -// glActiveTexture(GL_TEXTURE0); -// glBindTexture(GL_TEXTURE_2D, bgrTexture); -// glUniform1i(d_ptr->m_backgroundShader->texture(), 0); + // TODO: Texture test + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, bgrTexture); + d_ptr->m_backgroundShader->setUniformValue(d_ptr->m_backgroundShader->texture() + , 0); // 1st attribute buffer : vertices glEnableVertexAttribArray(d_ptr->m_backgroundShader->posAtt()); @@ -678,6 +680,7 @@ void Q3DBars::drawScene() glVertexAttribPointer(d_ptr->m_backgroundShader->normalAtt() , 3, GL_FLOAT, GL_FALSE, 0, (void*)0); + // TODO: Texture test // 3rd attribute buffer : UVs glEnableVertexAttribArray(d_ptr->m_backgroundShader->uvAtt()); glBindBuffer(GL_ARRAY_BUFFER, d_ptr->m_backgroundObj->uvBuf()); @@ -695,11 +698,18 @@ void Q3DBars::drawScene() glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - //glDisableVertexAttribArray(d_ptr->m_backgroundShader->uvAtt()); + // TODO: Texture test + glDisableVertexAttribArray(d_ptr->m_backgroundShader->uvAtt()); + glDisableVertexAttribArray(d_ptr->m_backgroundShader->normalAtt()); glDisableVertexAttribArray(d_ptr->m_backgroundShader->posAtt()); } + // TODO: Texture test + glBindTexture(GL_TEXTURE_2D, 0); + glDeleteTextures(1, &bgrTexture); + glDisable(GL_TEXTURE_2D); + // Release background shader d_ptr->m_backgroundShader->release(); diff --git a/src/datavis3d/engine/shaders/fragmentShaderTexture b/src/datavis3d/engine/shaders/fragmentShaderTexture index f1b11908..9f2692f2 100644 --- a/src/datavis3d/engine/shaders/fragmentShaderTexture +++ b/src/datavis3d/engine/shaders/fragmentShaderTexture @@ -10,24 +10,25 @@ uniform highp float lightStrength; uniform highp float ambientStrength; uniform sampler2D textureSampler; void main() { - highp vec3 materialDiffuseColor = texture2D(textureSampler, UV); - highp vec3 materialAmbientColor = vec3(ambientStrength, ambientStrength, ambientStrength) * materialDiffuseColor; - highp vec3 materialSpecularColor = vec3(1.0, 1.0, 1.0); - highp float distance = length(lightPosition_wrld - position_wrld); - highp vec3 n = normalize(normal_cmr); - highp vec3 l = normalize(lightDirection_cmr); - highp float cosTheta = dot(n, l); - if (cosTheta < 0.0) { cosTheta = 0.0; } - if (cosTheta > 1.0) { cosTheta = 1.0; } - highp vec3 E = normalize(eyeDirection_cmr); - highp vec3 R = reflect(-l, n); - highp float cosAlpha = dot(E, R); - if (cosAlpha < 0.0) { cosAlpha = 0.0; } - if (cosAlpha > 1.0) { cosAlpha = 1.0; } - gl_FragColor.rgb = //color_mdl + color_mdl * vec3(cosTheta * cosTheta) / (distance * distance) + vec3(cosAlpha * cosAlpha * cosAlpha * cosAlpha * cosAlpha * cosAlpha * cosAlpha * cosAlpha) / (distance * distance); - materialAmbientColor + - materialDiffuseColor * lightStrength * (cosTheta * cosTheta) / distance + - materialSpecularColor * lightStrength * (cosAlpha * cosAlpha * cosAlpha * cosAlpha * cosAlpha * cosAlpha * cosAlpha * cosAlpha * cosAlpha * cosAlpha) / distance;//(distance * distance); - gl_FragColor.a = 1.0; + //highp vec3 materialDiffuseColor = texture2D(textureSampler, UV).rgb; + //highp vec3 materialAmbientColor = vec3(ambientStrength, ambientStrength, ambientStrength) * materialDiffuseColor; + //highp vec3 materialSpecularColor = vec3(1.0, 1.0, 1.0); + //highp float distance = length(lightPosition_wrld - position_wrld); + //highp vec3 n = normalize(normal_cmr); + //highp vec3 l = normalize(lightDirection_cmr); + //highp float cosTheta = dot(n, l); + //if (cosTheta < 0.0) { cosTheta = 0.0; } + //if (cosTheta > 1.0) { cosTheta = 1.0; } + //highp vec3 E = normalize(eyeDirection_cmr); + //highp vec3 R = reflect(-l, n); + //highp float cosAlpha = dot(E, R); + //if (cosAlpha < 0.0) { cosAlpha = 0.0; } + //if (cosAlpha > 1.0) { cosAlpha = 1.0; } + //gl_FragColor.rgb = //color_mdl + color_mdl * vec3(cosTheta * cosTheta) / (distance * distance) + vec3(cosAlpha * cosAlpha * cosAlpha * cosAlpha * cosAlpha * cosAlpha * cosAlpha * cosAlpha) / (distance * distance); + // materialAmbientColor + + // materialDiffuseColor * lightStrength * (cosTheta * cosTheta) / distance + + // materialSpecularColor * lightStrength * (cosAlpha * cosAlpha * cosAlpha * cosAlpha * cosAlpha * cosAlpha * cosAlpha * cosAlpha * cosAlpha * cosAlpha) / distance;//(distance * distance); + //gl_FragColor.a = 1.0; + gl_FragColor = texture2D(textureSampler, UV); } diff --git a/src/datavis3d/engine/textures/cube.png b/src/datavis3d/engine/textures/cube.png new file mode 100644 index 00000000..42c8c51b Binary files /dev/null and b/src/datavis3d/engine/textures/cube.png differ 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 + +//#include + +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> 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 diff --git a/src/datavis3d/utils/texturehelper_p.h b/src/datavis3d/utils/texturehelper_p.h new file mode 100644 index 00000000..ac86bccf --- /dev/null +++ b/src/datavis3d/utils/texturehelper_p.h @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ + +#ifndef TEXTUREHELPER_P_H +#define TEXTUREHELPER_P_H + +#include "qdatavis3dglobal.h" +#include +#include + +QTCOMMERCIALDATAVIS3D_BEGIN_NAMESPACE + +class TextureHelper +{ +public: + // Ownership of created texture is transferred to caller + static GLuint create2DTexture(const QImage &image, bool useTrilinearFiltering = false); + static GLuint createCubeMapTexture(const QImage &image, bool useTrilinearFiltering = false); + +private: + static QImage convertToGLFormat(const QImage &srcImage); + static void convertToGLFormatHelper(QImage &dstImage, const QImage &srcImage, GLenum texture_format); + static QRgb qt_gl_convertToGLFormatHelper(QRgb src_pixel, GLenum texture_format); +}; + +QTCOMMERCIALDATAVIS3D_END_NAMESPACE + +#endif diff --git a/src/datavis3d/utils/utils.pri b/src/datavis3d/utils/utils.pri index 62134c71..566af55f 100644 --- a/src/datavis3d/utils/utils.pri +++ b/src/datavis3d/utils/utils.pri @@ -3,6 +3,7 @@ HEADERS += $$PWD/meshloader_p.h \ $$PWD/camerahelper_p.h \ $$PWD/shaderhelper_p.h \ $$PWD/objecthelper_p.h \ + $$PWD/texturehelper_p.h \ $$PWD/utils_p.h SOURCES += $$PWD/meshloader.cpp \ @@ -10,4 +11,5 @@ SOURCES += $$PWD/meshloader.cpp \ $$PWD/camerahelper.cpp \ $$PWD/shaderhelper.cpp \ $$PWD/objecthelper.cpp \ + $$PWD/texturehelper.cpp \ $$PWD/utils.cpp -- cgit v1.2.3