diff options
Diffstat (limited to 'src/declarative/opengl')
-rw-r--r-- | src/declarative/opengl/glbasicshaders.cpp | 707 | ||||
-rw-r--r-- | src/declarative/opengl/glbasicshaders.h | 244 | ||||
-rw-r--r-- | src/declarative/opengl/glheaders.h | 49 | ||||
-rw-r--r-- | src/declarative/opengl/glsave.cpp | 1 | ||||
-rw-r--r-- | src/declarative/opengl/glsave.h | 111 | ||||
-rw-r--r-- | src/declarative/opengl/gltexture.cpp | 321 | ||||
-rw-r--r-- | src/declarative/opengl/gltexture.h | 116 | ||||
-rw-r--r-- | src/declarative/opengl/opengl.pri | 20 |
8 files changed, 1569 insertions, 0 deletions
diff --git a/src/declarative/opengl/glbasicshaders.cpp b/src/declarative/opengl/glbasicshaders.cpp new file mode 100644 index 0000000..e95e53f --- /dev/null +++ b/src/declarative/opengl/glbasicshaders.cpp @@ -0,0 +1,707 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtDeclarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "glbasicshaders.h" +#include <QDebug> +#include <QColor> + + +QT_BEGIN_NAMESPACE +SingleTextureVertexOpacityShader::SingleTextureVertexOpacityShader() +{ + QGLShader vert(QGLShader::VertexShader); + QGLShader frag(QGLShader::FragmentShader); + + vert.setSourceCode("\ + attribute highp vec4 myVertex;\ + attribute lowp float myOpacity;\ + attribute mediump vec4 myUV;\ + uniform mediump mat4 myPMVMatrix;\ + varying mediump vec2 myTexCoord;\ + varying lowp float myFragOpacity;\ + void main(void)\ + {\ + gl_Position = myPMVMatrix * myVertex;\ + myTexCoord = myUV.st;\ + myFragOpacity = myOpacity;\ + }" + ); + + frag.setSourceCode("\ + uniform sampler2D sampler2d;\ + varying mediump vec2 myTexCoord;\ + varying lowp float myFragOpacity;\ + void main(void)\ + {\ + mediump vec4 frag = texture2D(sampler2d,myTexCoord);\ + gl_FragColor = vec4(frag.rgb, frag.a * myFragOpacity);\ + }" + ); + + addShader(&vert); + addShader(&frag); + + bindAttributeLocation("myVertex", Vertices); + bindAttributeLocation("myUV", TextureCoords); + bindAttributeLocation("myOpacity", OpacityCoords); +} + +bool SingleTextureVertexOpacityShader::link() +{ + if (!QGLShaderProgram::link()) + return false; + transform = uniformLocation("myPMVMatrix"); + enable(); + setUniformValue("sampler2d", 0); + disable(); + return true; +} + +void SingleTextureVertexOpacityShader::setTransform(const QMatrix4x4 &matrix) +{ + setUniformValue(transform, matrix); +} + +BlurTextureShader::BlurTextureShader() +{ + QGLShader vert(QGLShader::VertexShader); + QGLShader frag(QGLShader::FragmentShader); + + vert.setSourceCode("\ + attribute highp vec4 myVertex;\ + attribute mediump vec4 myUV;\ + uniform mediump mat4 myPMVMatrix;\ + varying mediump vec2 myTexCoord;\ + void main(void)\ + {\ + gl_Position = myPMVMatrix * myVertex;\ + myTexCoord = myUV.st;\ + }" + ); + +#if 0 + frag.setSourceCode("\ + uniform sampler2D sampler2d;\ + uniform bool horizontal; \ + uniform mediump float blurStep; \ + varying mediump vec2 myTexCoord;\ + void main(void)\ + {\ + mediump vec4 accum = vec4(0, 0, 0, 0); \ + mediump vec2 offset; \ + if(horizontal) \ + offset = vec2(blurStep, 0); \ + else \ + offset = vec2(0, blurStep); \ + accum += texture2D(sampler2d, myTexCoord + 2.0 * offset); \ + accum += 2.0 * texture2D(sampler2d, myTexCoord + 1.0 * offset); \ + accum += 4.0 * texture2D(sampler2d, myTexCoord + 0.0 * offset); \ + accum += 2.0 * texture2D(sampler2d, myTexCoord - 1.0 * offset); \ + accum += texture2D(sampler2d, myTexCoord - 2.0 * offset); \ + gl_FragColor = accum / 10.0; \ + }" + ); +#else + frag.setSourceCode("\ + uniform sampler2D sampler2d;\ + uniform bool horizontal; \ + uniform mediump float blurStep; \ + uniform int blurSteps; \ + varying mediump vec2 myTexCoord;\ + void main(void)\ + {\ + mediump vec4 accum = vec4(0, 0, 0, 0); \ + mediump vec2 offset; \ + if(horizontal) \ + offset = vec2(blurStep, 0); \ + else \ + offset = vec2(0, blurStep); \ + mediump float sum = 0.0; \ + for(int ii = 0; ii < blurSteps; ++ii) { \ + mediump float frac = float(blurSteps - ii) / float(blurSteps); \ + mediump vec2 coord = myTexCoord + -float(ii) * offset; \ + if(coord.x >= 0.0 && coord.y >= 0.0 && coord.y <= 1.0 && coord.x <=1.0) \ + accum += texture2D(sampler2d, coord) * frac; \ + sum += frac; \ + } \ + for(int ii = 1; ii < blurSteps; ++ii) { \ + mediump float frac = float(blurSteps - ii) / float(blurSteps); \ + mediump vec2 coord = myTexCoord + float(ii) * offset; \ + if(coord.x <= 1.0 && coord.y <= 1.0 && coord.x >= 0.0 && coord.y >= 0.0) \ + accum += texture2D(sampler2d, coord) * frac; \ + sum += frac; \ + } \ + gl_FragColor = accum / sum; \ + }" + ); +#endif + + addShader(&vert); + addShader(&frag); + + bindAttributeLocation("myVertex", Vertices); + bindAttributeLocation("myUV", TextureCoords); +} + +bool BlurTextureShader::link() +{ + if (!QGLShaderProgram::link()) + return false; + transform = uniformLocation("myPMVMatrix"); + mode = uniformLocation("horizontal"); + step = uniformLocation("blurStep"); + steps = uniformLocation("blurSteps"); + enable(); + setUniformValue("sampler2d", 0); + disable(); + return true; +} + +void BlurTextureShader::setStep(float f) +{ + setUniformValue(step, f); +} + +void BlurTextureShader::setSteps(int s) +{ + setUniformValue(steps, s); +} + +void BlurTextureShader::setMode(Mode m) +{ + if(m == Horizontal) + setUniformValue(mode, 1); + else + setUniformValue(mode, 0); +} + +void BlurTextureShader::setTransform(const QMatrix4x4 &matrix) +{ + setUniformValue(transform, matrix); +} + +DualTextureBlendShader::DualTextureBlendShader() +{ + QGLShader vert(QGLShader::VertexShader); + QGLShader frag(QGLShader::FragmentShader); + + vert.setSourceCode("\ + attribute highp vec4 myVertex;\ + attribute mediump vec4 myUV;\ + attribute mediump vec4 myBlendUV;\ + uniform mediump mat4 myPMVMatrix;\ + varying mediump vec2 myTexCoord;\ + varying mediump vec2 myBlendTexCoord;\ + void main(void)\ + {\ + gl_Position = myPMVMatrix * myVertex;\ + myTexCoord = myUV.st;\ + myBlendTexCoord = myBlendUV.st;\ + }" + ); + + frag.setSourceCode("\ + uniform sampler2D sampler2d;\ + uniform sampler2D sampler2dBlend;\ + uniform lowp float myOpacity;\ + uniform lowp float myBlend; \ + varying mediump vec2 myTexCoord;\ + varying mediump vec2 myBlendTexCoord;\ + void main(void)\ + {\ + mediump vec4 tex = texture2D(sampler2d,myTexCoord);\ + mediump vec4 blendtex = texture2D(sampler2dBlend, myBlendTexCoord);\ + gl_FragColor = mix(tex, blendtex, myBlend) * myOpacity; \ + }" + ); + + addShader(&vert); + addShader(&frag); + + bindAttributeLocation("myVertex", Vertices); + bindAttributeLocation("myUV", TextureCoords); + bindAttributeLocation("myBlendUV", BlendTextureCoords); +} + +bool DualTextureBlendShader::link() +{ + if (!QGLShaderProgram::link()) + return false; + transform = uniformLocation("myPMVMatrix"); + opacity = uniformLocation("myOpacity"); + blend = uniformLocation("myBlend"); + enable(); + setUniformValue("sampler2d", 0); + setUniformValue("sampler2dBlend", 1); + disable(); + return true; +} + +void DualTextureBlendShader::setOpacity(GLfloat o) +{ + setUniformValue(opacity, o); +} + +void DualTextureBlendShader::setBlend(GLfloat b) +{ + setUniformValue(blend, b); +} + +void DualTextureBlendShader::setTransform(const QMatrix4x4 &matrix) +{ + setUniformValue(transform, matrix); +} + +DualTextureAddShader::DualTextureAddShader() +{ + QGLShader vert(QGLShader::VertexShader); + QGLShader frag(QGLShader::FragmentShader); + + vert.setSourceCode("\ + attribute highp vec4 myVertex;\ + attribute mediump vec4 myUV;\ + attribute mediump vec4 myAddUV;\ + uniform mediump mat4 myPMVMatrix;\ + varying mediump vec2 myTexCoord;\ + varying mediump vec2 myAddTexCoord;\ + void main(void)\ + {\ + gl_Position = myPMVMatrix * myVertex;\ + myTexCoord = myUV.st;\ + myAddTexCoord = myAddUV.st;\ + }" + ); + + frag.setSourceCode("\ + uniform sampler2D sampler2d;\ + uniform sampler2D sampler2dAdd;\ + uniform lowp float myOpacity;\ + varying mediump vec2 myTexCoord;\ + varying mediump vec2 myAddTexCoord;\ + void main(void)\ + {\ + mediump vec4 tex = texture2D(sampler2d,myTexCoord);\ + mediump vec4 addtex = texture2D(sampler2dAdd, myAddTexCoord);\ + tex = tex + vec4(addtex.rgb * addtex.a * tex.a, 0); \ + tex = min(tex, vec4(1, 1, 1, 1)); \ + gl_FragColor = vec4(tex.rgb, tex.a) * myOpacity;\ + }" + ); + + addShader(&vert); + addShader(&frag); + + bindAttributeLocation("myVertex", Vertices); + bindAttributeLocation("myUV", TextureCoords); + bindAttributeLocation("myAddUV", AddTextureCoords); +} + +void DualTextureAddShader::setOpacity(GLfloat f) +{ + setUniformValue(opacity, f); +} + +void DualTextureAddShader::setTransform(const QMatrix4x4 &matrix) +{ + setUniformValue(transform, matrix); +} + +bool DualTextureAddShader::link() +{ + if (!QGLShaderProgram::link()) + return false; + transform = uniformLocation("myPMVMatrix"); + opacity = uniformLocation("myOpacity"); + enable(); + setUniformValue("sampler2d", 0); + setUniformValue("sampler2dAdd", 1); + disable(); + return true; +} + +SingleTextureShader::SingleTextureShader() +{ + QGLShader vert(QGLShader::VertexShader); + QGLShader frag(QGLShader::FragmentShader); + + vert.setSourceCode("\ + attribute highp vec4 myVertex;\ + attribute mediump vec4 myUV;\ + uniform mediump mat4 myPMVMatrix;\ + varying mediump vec2 myTexCoord;\ + void main(void)\ + {\ + gl_Position = myPMVMatrix * myVertex;\ + myTexCoord = myUV.st;\ + }" + ); + + frag.setSourceCode("\ + uniform sampler2D sampler2d;\ + varying mediump vec2 myTexCoord;\ + void main(void)\ + {\ + gl_FragColor = texture2D(sampler2d,myTexCoord);\ + }" + ); + + addShader(&vert); + addShader(&frag); + + bindAttributeLocation("myVertex", Vertices); + bindAttributeLocation("myUV", TextureCoords); +} + +bool SingleTextureShader::link() +{ + if (!QGLShaderProgram::link()) + return false; + transform = uniformLocation("myPMVMatrix"); + enable(); + setUniformValue("sampler2d", 0); + disable(); + return true; +} + +void SingleTextureShader::setTransform(const QMatrix4x4 &matrix) +{ + setUniformValue(transform, matrix); +} + +ConstantColorShader::ConstantColorShader() +{ + QGLShader vert(QGLShader::VertexShader); + QGLShader frag(QGLShader::FragmentShader); + + vert.setSourceCode("\ + uniform mediump mat4 myPMVMatrix;\ + attribute highp vec4 myVertex;\ + void main(void)\ + {\ + gl_Position = myPMVMatrix * myVertex; \ + }" + ); + + frag.setSourceCode("\ + uniform lowp vec4 myColor;\ + void main(void)\ + {\ + gl_FragColor = myColor;\ + }" + ); + + addShader(&vert); + addShader(&frag); + + bindAttributeLocation("myVertex", Vertices); +} + +void ConstantColorShader::setColor(const QColor &c) +{ + setUniformValue(color, c); +} + +void ConstantColorShader::setTransform(const QMatrix4x4 &matrix) +{ + setUniformValue(transform, matrix); +} + +bool ConstantColorShader::link() +{ + if (!QGLShaderProgram::link()) + return false; + transform = uniformLocation("myPMVMatrix"); + color = uniformLocation("myColor"); + return true; +} + +ColorShader::ColorShader() +{ + QGLShader vert(QGLShader::VertexShader); + QGLShader frag(QGLShader::FragmentShader); + + vert.setSourceCode("\ + uniform mediump mat4 myPMVMatrix;\ + attribute highp vec4 myVertex;\ + attribute lowp vec4 myColors;\ + varying lowp vec4 myColor;\ + void main(void)\ + {\ + gl_Position = myPMVMatrix * myVertex; \ + myColor = myColors; \ + }" + ); + + frag.setSourceCode("\ + varying lowp vec4 myColor;\ + void main(void)\ + {\ + gl_FragColor = myColor;\ + }" + ); + + addShader(&vert); + addShader(&frag); + + bindAttributeLocation("myVertex", Vertices); + bindAttributeLocation("myColors", Colors); +} + +void ColorShader::setTransform(const QMatrix4x4 &matrix) +{ + setUniformValue(transform, matrix); +} + +bool ColorShader::link() +{ + if (!QGLShaderProgram::link()) + return false; + transform = uniformLocation("myPMVMatrix"); + return true; +} + +class GLBasicShadersPrivate +{ +public: + GLBasicShadersPrivate(); + ~GLBasicShadersPrivate(); + + BlurTextureShader *blurTexture; + SingleTextureShader *singleTexture; + SingleTextureOpacityShader *singleTextureOpacity; + DualTextureAddShader *dualTextureAdd; + SingleTextureShadowShader *singleTextureShadow; + SingleTextureVertexOpacityShader *singleTextureVertexOpacity; + ConstantColorShader *constantColor; + ColorShader *color; +}; + +GLBasicShadersPrivate::GLBasicShadersPrivate() +: blurTexture(0), singleTexture(0), singleTextureOpacity(0), + dualTextureAdd(0), singleTextureShadow(0), singleTextureVertexOpacity(0), + constantColor(0), color(0) +{ +} + +GLBasicShadersPrivate::~GLBasicShadersPrivate() +{ + delete blurTexture; + delete singleTexture; + delete singleTextureOpacity; + delete dualTextureAdd; + delete singleTextureVertexOpacity; + delete singleTextureShadow; + delete constantColor; + delete color; +} + +GLBasicShaders::GLBasicShaders() +: d(new GLBasicShadersPrivate) +{ +} + +GLBasicShaders::~GLBasicShaders() +{ + delete d; +} + +BlurTextureShader *GLBasicShaders::blurTexture() +{ + if(!d->blurTexture) d->blurTexture = new BlurTextureShader(); + return d->blurTexture; +} + +SingleTextureShader *GLBasicShaders::singleTexture() +{ + if(!d->singleTexture) d->singleTexture = new SingleTextureShader(); + return d->singleTexture; +} + +SingleTextureOpacityShader *GLBasicShaders::singleTextureOpacity() +{ + if(!d->singleTextureOpacity) d->singleTextureOpacity = new SingleTextureOpacityShader(); + return d->singleTextureOpacity; +} + +DualTextureAddShader *GLBasicShaders::dualTextureAdd() +{ + if(!d->dualTextureAdd) d->dualTextureAdd = new DualTextureAddShader(); + return d->dualTextureAdd; +} + +SingleTextureVertexOpacityShader *GLBasicShaders::singleTextureVertexOpacity() +{ + if(!d->singleTextureVertexOpacity) d->singleTextureVertexOpacity = new SingleTextureVertexOpacityShader(); + return d->singleTextureVertexOpacity; +} + +SingleTextureShadowShader *GLBasicShaders::singleTextureShadow() +{ + if(!d->singleTextureShadow) d->singleTextureShadow = new SingleTextureShadowShader(); + return d->singleTextureShadow; +} + +ConstantColorShader *GLBasicShaders::constantColor() +{ + if(!d->constantColor) d->constantColor = new ConstantColorShader(); + return d->constantColor; +} + +ColorShader *GLBasicShaders::color() +{ + if(!d->color) d->color = new ColorShader(); + return d->color; +} + +SingleTextureOpacityShader::SingleTextureOpacityShader() +{ + QGLShader vert(QGLShader::VertexShader); + QGLShader frag(QGLShader::FragmentShader); + + vert.setSourceCode("\ + attribute highp vec4 myVertex;\ + attribute mediump vec4 myUV;\ + uniform mediump mat4 myPMVMatrix;\ + varying mediump vec2 myTexCoord;\ + void main(void)\ + {\ + gl_Position = myPMVMatrix * myVertex;\ + myTexCoord = myUV.st;\ + }" + ); + + frag.setSourceCode("\ + uniform sampler2D sampler2d;\ + uniform lowp float myOpacity;\ + varying mediump vec2 myTexCoord;\ + void main(void)\ + {\ + mediump vec4 tex = texture2D(sampler2d,myTexCoord);\ + gl_FragColor = vec4(tex.rgb, myOpacity * tex.a);\ + }" + ); + + addShader(&vert); + addShader(&frag); + + bindAttributeLocation("myVertex", Vertices); + bindAttributeLocation("myUV", TextureCoords); +} + +bool SingleTextureOpacityShader::link() +{ + if (!QGLShaderProgram::link()) + return false; + transform = uniformLocation("myPMVMatrix"); + opacity = uniformLocation("myOpacity"); + enable(); + setUniformValue("sampler2d", 0); + disable(); + return true; +} + +void SingleTextureOpacityShader::setTransform(const QMatrix4x4 &matrix) +{ + setUniformValue(transform, matrix); +} + +void SingleTextureOpacityShader::setOpacity(GLfloat f) +{ + setUniformValue(opacity, f); +} + +SingleTextureShadowShader::SingleTextureShadowShader() +{ + QGLShader vert(QGLShader::VertexShader); + QGLShader frag(QGLShader::FragmentShader); + + vert.setSourceCode("\ + attribute highp vec4 myVertex;\ + attribute mediump vec4 myUV;\ + uniform mediump mat4 myPMVMatrix;\ + varying mediump vec2 myTexCoord;\ + void main(void)\ + {\ + gl_Position = myPMVMatrix * myVertex;\ + myTexCoord = myUV.st;\ + }" + ); + + frag.setSourceCode("\ + uniform sampler2D sampler2d;\ + uniform lowp float myOpacity;\ + varying mediump vec2 myTexCoord;\ + void main(void)\ + {\ + mediump vec4 tex = texture2D(sampler2d,myTexCoord);\ + gl_FragColor = vec4(0, 0, 0, myOpacity * tex.a * .75);\ + }" + ); + + addShader(&vert); + addShader(&frag); + + bindAttributeLocation("myVertex", Vertices); + bindAttributeLocation("myUV", TextureCoords); +} + +bool SingleTextureShadowShader::link() +{ + if (!QGLShaderProgram::link()) + return false; + transform = uniformLocation("myPMVMatrix"); + opacity = uniformLocation("myOpacity"); + enable(); + setUniformValue("sampler2d", 0); + disable(); + return true; +} + +void SingleTextureShadowShader::setTransform(const QMatrix4x4 &matrix) +{ + setUniformValue(transform, matrix); +} + +void SingleTextureShadowShader::setOpacity(GLfloat f) +{ + setUniformValue(opacity, f); +} +QT_END_NAMESPACE diff --git a/src/declarative/opengl/glbasicshaders.h b/src/declarative/opengl/glbasicshaders.h new file mode 100644 index 0000000..7d358d8 --- /dev/null +++ b/src/declarative/opengl/glbasicshaders.h @@ -0,0 +1,244 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtDeclarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef _GLBASICSHADERS_H_ +#define _GLBASICSHADERS_H_ + +#include <QtOpenGL/qglshaderprogram.h> +#include <QtGui/qmatrix4x4.h> + + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Declarative) +class BlurTextureShader : public QGLShaderProgram +{ + Q_OBJECT +public: + BlurTextureShader(); + + enum { Vertices = 0, + TextureCoords = 1 }; + + enum Mode { Horizontal, Vertical }; + void setMode(Mode); + void setStep(float); + void setSteps(int); + void setTransform(const QMatrix4x4 &); + virtual bool link(); + +private: + GLint mode; + GLint step; + GLint steps; + GLint transform; +}; + +class SingleTextureShader : public QGLShaderProgram +{ + Q_OBJECT +public: + SingleTextureShader(); + + enum { Vertices = 0, + TextureCoords = 1 }; + + void setTransform(const QMatrix4x4 &); + virtual bool link(); + +private: + GLint transform; +}; + +class DualTextureBlendShader : public QGLShaderProgram +{ + Q_OBJECT +public: + DualTextureBlendShader(); + enum { Vertices = 0, + TextureCoords = 1, + BlendTextureCoords = 2 }; + + void setOpacity(GLfloat); + void setBlend(GLfloat); + void setTransform(const QMatrix4x4 &); + virtual bool link(); + +private: + GLint transform; + GLint opacity; + GLint blend; +}; + +class DualTextureAddShader : public QGLShaderProgram +{ + Q_OBJECT +public: + DualTextureAddShader(); + enum { Vertices = 0, + TextureCoords = 1, + AddTextureCoords = 2 }; + + void setOpacity(GLfloat); + void setTransform(const QMatrix4x4 &); + virtual bool link(); + +private: + GLint transform; + GLint opacity; +}; + +class SingleTextureOpacityShader : public QGLShaderProgram +{ + Q_OBJECT +public: + SingleTextureOpacityShader(); + + enum { Vertices = 0, + TextureCoords = 1 }; + + void setOpacity(GLfloat); + void setTransform(const QMatrix4x4 &); + virtual bool link(); + +private: + GLint transform; + GLint opacity; +}; + +class SingleTextureVertexOpacityShader : public QGLShaderProgram +{ + Q_OBJECT +public: + SingleTextureVertexOpacityShader(); + + enum { Vertices = 0, + TextureCoords = 1, + OpacityCoords = 2 }; + + void setTransform(const QMatrix4x4 &); + virtual bool link(); + +private: + GLint transform; +}; + + +class SingleTextureShadowShader : public QGLShaderProgram +{ + Q_OBJECT +public: + SingleTextureShadowShader(); + + enum { Vertices = 0, + TextureCoords = 1 }; + + void setOpacity(GLfloat); + void setTransform(const QMatrix4x4 &); + virtual bool link(); + +private: + GLint transform; + GLint opacity; +}; + + +class QColor; +class ConstantColorShader : public QGLShaderProgram +{ + Q_OBJECT +public: + ConstantColorShader(); + + enum { Vertices = 0 }; + + void setColor(const QColor &); + void setTransform(const QMatrix4x4 &); + virtual bool link(); + +private: + GLint transform; + GLint color; +}; + +class ColorShader : public QGLShaderProgram +{ + Q_OBJECT +public: + ColorShader(); + + enum { Vertices = 0, Colors = 1 }; + + void setTransform(const QMatrix4x4 &); + virtual bool link(); + +private: + GLint transform; +}; + +class GLBasicShadersPrivate; +class GLBasicShaders +{ +public: + GLBasicShaders(); + virtual ~GLBasicShaders(); + + BlurTextureShader *blurTexture(); + SingleTextureShader *singleTexture(); + SingleTextureOpacityShader *singleTextureOpacity(); + DualTextureAddShader *dualTextureAdd(); + SingleTextureVertexOpacityShader *singleTextureVertexOpacity(); + SingleTextureShadowShader *singleTextureShadow(); + ConstantColorShader *constantColor(); + ColorShader *color(); + +private: + GLBasicShadersPrivate *d; +}; + +#endif // _GLBASICSHADERS_H_ + + +QT_END_NAMESPACE + +QT_END_HEADER diff --git a/src/declarative/opengl/glheaders.h b/src/declarative/opengl/glheaders.h new file mode 100644 index 0000000..f0f6a55 --- /dev/null +++ b/src/declarative/opengl/glheaders.h @@ -0,0 +1,49 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtDeclarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef _GLHEADERS_H_ +#define _GLHEADERS_H_ + +#include <qfxglobal.h> +#define GL_GLEXT_PROTOTYPES 1 +#include <QtOpenGL/qgl.h> + +#endif // _GLHEADERS_H_ diff --git a/src/declarative/opengl/glsave.cpp b/src/declarative/opengl/glsave.cpp new file mode 100644 index 0000000..125e81b --- /dev/null +++ b/src/declarative/opengl/glsave.cpp @@ -0,0 +1 @@ +#include "glsave.h" diff --git a/src/declarative/opengl/glsave.h b/src/declarative/opengl/glsave.h new file mode 100644 index 0000000..3a67fb0 --- /dev/null +++ b/src/declarative/opengl/glsave.h @@ -0,0 +1,111 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtDeclarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef _GLSAVE_H_ +#define _GLSAVE_H_ + +#include <qglobal.h> +#include <qfxglobal.h> +#include <QRect> +#include "glheaders.h" + + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Declarative) +class GLSaveViewport +{ +public: + GLSaveViewport() + { + glGetIntegerv(GL_VIEWPORT, viewport); + } + + ~GLSaveViewport() + { + glViewport(viewport[0], viewport[1], viewport[2], viewport[3]); + } + +private: + Q_DISABLE_COPY(GLSaveViewport); + GLint viewport[4]; +}; + +class GLSaveScissor +{ +public: + GLSaveScissor() + { + enabled = glIsEnabled(GL_SCISSOR_TEST); + glGetIntegerv(GL_SCISSOR_BOX, box); + } + + ~GLSaveScissor() + { + if(enabled) + glEnable(GL_SCISSOR_TEST); + else + glDisable(GL_SCISSOR_TEST); + glScissor(box[0], box[1], box[2], box[3]); + } + + bool wasEnabled() const + { + return enabled == GL_TRUE; + } + + QRect rect() const + { + return QRect(box[0], box[1], box[2], box[3]); + } + +private: + Q_DISABLE_COPY(GLSaveScissor); + GLint box[4]; + GLboolean enabled; +}; + +QT_END_NAMESPACE + +QT_END_HEADER +#endif // _GLSAVE_H_ diff --git a/src/declarative/opengl/gltexture.cpp b/src/declarative/opengl/gltexture.cpp new file mode 100644 index 0000000..73deece --- /dev/null +++ b/src/declarative/opengl/gltexture.cpp @@ -0,0 +1,321 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtDeclarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "gltexture.h" +#include <QImage> + + +QT_BEGIN_NAMESPACE +/*! + \class GLTexture + \brief The GLTexture class simplifies the use of OpenGL textures. +*/ + +// Copied from QGLWidget::convertToGLFormat +static QImage QGLWidget_convertToGLFormat(const QImage& img) +{ + QImage res = img.convertToFormat(QImage::Format_ARGB32); + res = res.mirrored(); + + if (QSysInfo::ByteOrder == QSysInfo::BigEndian) { + // Qt has ARGB; OpenGL wants RGBA + for (int i=0; i < res.height(); i++) { + uint *p = (uint*)res.scanLine(i); + uint *end = p + res.width(); + while (p < end) { + *p = (*p << 8) | ((*p >> 24) & 0xFF); + p++; + } + } + } + else { + // Qt has ARGB; OpenGL wants ABGR (i.e. RGBA backwards) + res = res.rgbSwapped(); + } + return res; +} +class GLTexturePrivate +{ +public: + GLTexturePrivate(GLTexture *_q) + : q(_q), texture(0), width(0), height(0), + horizWrap(GLTexture::Repeat), vertWrap(GLTexture::Repeat), + minFilter(GLTexture::Linear), magFilter(GLTexture::Linear) + { + } + + GLTexture *q; + GLuint texture; + int width; + int height; + GLTexture::WrapMode horizWrap; + GLTexture::WrapMode vertWrap; + GLTexture::FilterMode minFilter; + GLTexture::FilterMode magFilter; + + void genTexture(); +}; + +void GLTexturePrivate::genTexture() +{ + if(texture) + return; + + glGenTextures(1, &texture); + glBindTexture(GL_TEXTURE_2D, texture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minFilter); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magFilter); + q->setHorizontalWrap(horizWrap); + q->setVerticalWrap(vertWrap); +} + +GLTexture::GLTexture() +: d(new GLTexturePrivate(this)) +{ +} + +GLTexture::GLTexture(const QString &file) +: d(new GLTexturePrivate(this)) +{ + QImage img(file); + if(!img.isNull()) + setImage(img); +} + +GLTexture::GLTexture(const QImage &img) +: d(new GLTexturePrivate(this)) +{ + setImage(img); +} + +GLTexture::~GLTexture() +{ + if(d->texture) + glDeleteTextures(1, &d->texture); + delete d; + d = 0; +} + +bool GLTexture::isNull() const +{ + return d->texture == 0; +} + +void GLTexture::clear() +{ + if(d->texture) { + glDeleteTextures(1, &d->texture); + d->texture = 0; + d->width = 0; + d->height = 0; + } +} + +static inline int npot(int size) +{ + size--; + size |= size >> 1; + size |= size >> 2; + size |= size >> 4; + size |= size >> 8; + size |= size >> 16; + size++; + return size; +} + +/*! + Set the texture to \a img. If the texture has already been created (either + by explicitly setting the size, or by previously setting an image), it will + be destroyed and a new texture created with \a img's contents and size. + */ +void GLTexture::setImage(const QImage &img) +{ + if(img.isNull()) + return; + + d->genTexture(); + + //QImage dataImage = img.scaled(npot(img.width()), npot(img.height()), Qt::IgnoreAspectRatio, Qt::SmoothTransformation); + QImage dataImage = QGLWidget_convertToGLFormat(img); + + glBindTexture(GL_TEXTURE_2D, d->texture); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, dataImage.width(), + dataImage.height(), 0, + (dataImage.format() == QImage::Format_ARGB32)?GL_RGBA:GL_RGB, + GL_UNSIGNED_BYTE, dataImage.bits()); + d->width = dataImage.width(); + d->height = dataImage.height(); + +#if 0 + glGenerateMipmap(GL_TEXTURE_2D); + int e = glGetError(); + if(d->magFilter == Linear) + setMagFilter(MipmapLinear); + if(d->minFilter == Linear) + setMinFilter((GLTexture::FilterMode)GL_LINEAR_MIPMAP_LINEAR); +#endif +} + +void GLTexture::copyImage(const QImage &img, const QPoint &point, + const QRect &srcRect) +{ + qFatal("Not implemented"); + Q_UNUSED(img); + Q_UNUSED(point); + Q_UNUSED(srcRect); +} + +QSize GLTexture::size() const +{ + return QSize(d->width, d->height); +} + +int GLTexture::width() const +{ + return d->width; +} + +int GLTexture::height() const +{ + return d->height; +} + +/*! + Sets the \a size of the texture. This will destroy the current contents of + the texture. If an image has been assigned, it will need to be reassigned + using either setImage() or copyImage(). + + If size is invalid (width or height is less than or equal to 0) the texture + will be destroyed. This is equivalent to calling clear(). +*/ +void GLTexture::setSize(const QSize &size) +{ + if(size.width() <= 0 || size.height() <= 0) { + clear(); + return; + } + + d->genTexture(); + glBindTexture(GL_TEXTURE_2D, d->texture); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size.width(), size.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); + d->width = size.width(); + d->height = size.height(); +} + +GLTexture::WrapMode GLTexture::horizontalWrap() const +{ + return d->horizWrap; +} + +GLTexture::WrapMode GLTexture::verticalWrap() const +{ + return d->vertWrap; +} + +void GLTexture::setHorizontalWrap(WrapMode mode) +{ + d->horizWrap = mode; + if(d->texture) { + GLint last; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last); + if(GLuint(last) != d->texture) + glBindTexture(GL_TEXTURE_2D, d->texture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, mode); + if(GLuint(last) != d->texture) + glBindTexture(GL_TEXTURE_2D, last); + } +} + +/*! + Set the veritcal wrap mode to \a mode. + */ +void GLTexture::setVerticalWrap(WrapMode mode) +{ + d->vertWrap = mode; + if(d->texture) { + GLint last; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last); + if(GLuint(last) != d->texture) + glBindTexture(GL_TEXTURE_2D, d->texture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, mode); + if(GLuint(last) != d->texture) + glBindTexture(GL_TEXTURE_2D, last); + } +} + +GLTexture::FilterMode GLTexture::minFilter() const +{ + return d->minFilter; +} + +GLTexture::FilterMode GLTexture::magFilter() const +{ + return d->magFilter; +} + +void GLTexture::setMinFilter(FilterMode f) +{ + if(d->minFilter == f) + return; + d->minFilter = f; + if(d->texture) { + glBindTexture(GL_TEXTURE_2D, d->texture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, d->minFilter); + } +} + +void GLTexture::setMagFilter(FilterMode f) +{ + if(d->magFilter == f) + return; + d->magFilter = f; + if(d->texture) { + glBindTexture(GL_TEXTURE_2D, d->texture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, d->magFilter); + } +} + +GLuint GLTexture::texture() const +{ + return d->texture; +} + +QT_END_NAMESPACE diff --git a/src/declarative/opengl/gltexture.h b/src/declarative/opengl/gltexture.h new file mode 100644 index 0000000..f920b60 --- /dev/null +++ b/src/declarative/opengl/gltexture.h @@ -0,0 +1,116 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtDeclarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef _GLTEXTURE_H_ +#define _GLTEXTURE_H_ + +#include <qfxglobal.h> + +#include <QRect> +#include <QPoint> +#include "glheaders.h" + + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Declarative) + +class QString; +class QImage; +class GLTexturePrivate; +class Q_DECLARATIVE_EXPORT GLTexture +{ +public: + GLTexture(); + GLTexture(const QString &file); + GLTexture(const QImage &img); + virtual ~GLTexture(); + + bool isNull() const; + void clear(); + + void setImage(const QImage &); + void copyImage(const QImage &, const QPoint & = QPoint(0, 0), const QRect & = QRect()); + + int width() const; + int height() const; + QSize size() const; + void setSize(const QSize &); + + enum WrapMode { + Repeat = GL_REPEAT, + ClampToEdge = GL_CLAMP_TO_EDGE, +#if defined(QFX_RENDER_OPENGL2) + MirroredRepeat = GL_MIRRORED_REPEAT, +#else + MirroredRepeat = Repeat +#endif + }; + + WrapMode horizontalWrap() const; + WrapMode verticalWrap() const; + void setHorizontalWrap(WrapMode); + void setVerticalWrap(WrapMode); + + enum FilterMode { + Nearest = GL_NEAREST, + Linear = GL_LINEAR, + MipmapLinear = GL_LINEAR_MIPMAP_LINEAR + }; + + FilterMode minFilter() const; + FilterMode magFilter() const; + void setMinFilter(FilterMode); + void setMagFilter(FilterMode); + + GLuint texture() const; +private: + Q_DISABLE_COPY(GLTexture); + GLTexturePrivate *d; +}; + + +QT_END_NAMESPACE + +QT_END_HEADER +#endif // _GLTEXTURE_H_ diff --git a/src/declarative/opengl/opengl.pri b/src/declarative/opengl/opengl.pri new file mode 100644 index 0000000..c9ccefb --- /dev/null +++ b/src/declarative/opengl/opengl.pri @@ -0,0 +1,20 @@ +DEPENDPATH += opengl +INCLUDEPATH += opengl +INCLUDEPATH += $$QMAKE_INCDIR_OPENGL +QT += opengl + +contains(QT_CONFIG, opengles1) { + SOURCES += gltexture.cpp \ + glsave.cpp + + HEADERS += gltexture.h \ + glsave.h +} else:contains(QT_CONFIG, opengles2) { + SOURCES += gltexture.cpp \ + glbasicshaders.cpp \ + glsave.cpp + + HEADERS += gltexture.h \ + glbasicshaders.h \ + glsave.h +} |