diff options
author | Sean Harmer <sean.harmer@kdab.com> | 2013-11-06 13:07:58 +0000 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-11-13 23:42:13 +0100 |
commit | 3afffa47feabc80e1bc20ffd2143a722a1c360a2 (patch) | |
tree | 1e8d5e367aefae0d25c67a1c5e82eeeb357203a6 /src/particles/shaders | |
parent | 376844cc6f312d2ab8cf3191ec3e5535bfa850e0 (diff) |
Adapt Qt Quick 2 renderer to work with OpenGL Core Profile
The basic approach is to have the batched renderer create and bind a
vertex array object if it detects we are using an OpenGL Core profile
context. The VAO is bound for the duration of the QQ2 renderer's
work cycle and unbound at the end so as to not interfere with any
other VAO's a user may wish to use.
All shaders have been copied and ported to be compliant with the
GLSL 150 core specification which is the minimum for a Core profile
context (OpenGL 3.2 Core). We are not using any newer features as
yet so this will work anywhere we can get a Core profile context.
The QSGShaderSourceBuilder class has been extended to resolve any
requests for shaders to the same basefilename with "_core"
appended prior to any file extension. This could be extended in
the future to allow version, or GPU or platform specific shaders.
The QSGShaderSourceBuilder has also been extended to allow it to
insert #define definitions in the prologue of a shader. Any such
definition is inserted:
* After the last #extension directive (if any are found)
* Otherwise after the #version directive (if found)
* Otherwise at the start of the shader source
This is required by the custom particle shaders which make
extensive use of such #defines.
In addition the mechanism used by the distance field glyph cache to
extend the cache with new glyphs has been modified to work (and
work more efficiently) when using a Core profile context.
Rather than using a shader program and a buffer filling quad to
blit the old texture into the new cache texture, we instead use
the technique of framebuffer blitting. The existing fallback
implementation using glTexSubImage2D() is still available if
needed.
The DECLARATIVE_EXAMPLE_MAIN macro has been extended to allow easy
testing of any of the QtDeclarative examples with a core profile
context. Just run the example with
QT_QUICK_CORE_PROFILE=1 ./text
for e.g. The only ones that may not work out of the box are those
that provide GLSL shader source e.g. the customparticles or
shader effect examples. These work fine if the shader source is
adapted to GLSL 150 core.
In the future it may be a good idea to expose some context property
to QML that the user can use to determine what shader source
variation to provide to Qt Quick. Along these lines it would also
be very nice to allow the provision of shader source to
ShaderEffect or CustomParticle from a separate source file just as
we now do within Qt Quick.
Task-number: QTBUG-32050
Change-Id: Ia6e9f06dbb8508af9ae03c6b60fb418b4cc9e41f
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
Diffstat (limited to 'src/particles/shaders')
-rw-r--r-- | src/particles/shaders/customparticle.frag | 2 | ||||
-rw-r--r-- | src/particles/shaders/customparticle_core.frag | 13 | ||||
-rw-r--r-- | src/particles/shaders/customparticle_core.vert | 4 | ||||
-rw-r--r-- | src/particles/shaders/customparticletemplate.vert | 2 | ||||
-rw-r--r-- | src/particles/shaders/customparticletemplate_core.vert | 28 | ||||
-rw-r--r-- | src/particles/shaders/imageparticle.frag | 2 | ||||
-rw-r--r-- | src/particles/shaders/imageparticle.vert | 2 | ||||
-rw-r--r-- | src/particles/shaders/imageparticle_core.frag | 44 | ||||
-rw-r--r-- | src/particles/shaders/imageparticle_core.vert | 145 |
9 files changed, 242 insertions, 0 deletions
diff --git a/src/particles/shaders/customparticle.frag b/src/particles/shaders/customparticle.frag index c1c15ecb0c..64007029f7 100644 --- a/src/particles/shaders/customparticle.frag +++ b/src/particles/shaders/customparticle.frag @@ -1,3 +1,5 @@ +#version 120 + varying highp vec2 qt_TexCoord0; uniform sampler2D source; diff --git a/src/particles/shaders/customparticle_core.frag b/src/particles/shaders/customparticle_core.frag new file mode 100644 index 0000000000..699c834605 --- /dev/null +++ b/src/particles/shaders/customparticle_core.frag @@ -0,0 +1,13 @@ +#version 150 + +in vec2 qt_TexCoord0; + +out vec4 fragColor; + +uniform sampler2D source; +uniform float qt_Opacity; + +void main() +{ + fragColor = texture(source, qt_TexCoord0) * qt_Opacity; +}
\ No newline at end of file diff --git a/src/particles/shaders/customparticle_core.vert b/src/particles/shaders/customparticle_core.vert new file mode 100644 index 0000000000..b99f73ea53 --- /dev/null +++ b/src/particles/shaders/customparticle_core.vert @@ -0,0 +1,4 @@ +void main() +{ + defaultMain(); +}
\ No newline at end of file diff --git a/src/particles/shaders/customparticletemplate.vert b/src/particles/shaders/customparticletemplate.vert index c482c4207b..eef8458a85 100644 --- a/src/particles/shaders/customparticletemplate.vert +++ b/src/particles/shaders/customparticletemplate.vert @@ -1,3 +1,5 @@ +#version 120 + attribute highp vec2 qt_ParticlePos; attribute highp vec2 qt_ParticleTex; attribute highp vec4 qt_ParticleData; // x = time, y = lifeSpan, z = size, w = endSize diff --git a/src/particles/shaders/customparticletemplate_core.vert b/src/particles/shaders/customparticletemplate_core.vert new file mode 100644 index 0000000000..15d38e797c --- /dev/null +++ b/src/particles/shaders/customparticletemplate_core.vert @@ -0,0 +1,28 @@ +#version 150 core + +in vec2 qt_ParticlePos; +in vec2 qt_ParticleTex; +in vec4 qt_ParticleData; // x = time, y = lifeSpan, z = size, w = endSize +in vec4 qt_ParticleVec; // x,y = constant velocity, z,w = acceleration +in float qt_ParticleR; + +out vec2 qt_TexCoord0; + +uniform mat4 qt_Matrix; +uniform float qt_Timestamp; + +void defaultMain() +{ + qt_TexCoord0 = qt_ParticleTex; + float size = qt_ParticleData.z; + float endSize = qt_ParticleData.w; + float t = (qt_Timestamp - qt_ParticleData.x) / qt_ParticleData.y; + float currentSize = mix(size, endSize, t * t); + if (t < 0. || t > 1.) + currentSize = 0.; + vec2 pos = qt_ParticlePos + - currentSize / 2. + currentSize * qt_ParticleTex // adjust size + + qt_ParticleVec.xy * t * qt_ParticleData.y // apply velocity vector.. + + 0.5 * qt_ParticleVec.zw * pow(t * qt_ParticleData.y, 2.); + gl_Position = qt_Matrix * vec4(pos.x, pos.y, 0, 1); +} diff --git a/src/particles/shaders/imageparticle.frag b/src/particles/shaders/imageparticle.frag index 699b90babf..92795a5381 100644 --- a/src/particles/shaders/imageparticle.frag +++ b/src/particles/shaders/imageparticle.frag @@ -1,3 +1,5 @@ +#version 120 + uniform sampler2D _qt_texture; uniform lowp float qt_Opacity; diff --git a/src/particles/shaders/imageparticle.vert b/src/particles/shaders/imageparticle.vert index 9e607a7477..377f831686 100644 --- a/src/particles/shaders/imageparticle.vert +++ b/src/particles/shaders/imageparticle.vert @@ -1,3 +1,5 @@ +#version 120 + #if defined(DEFORM) attribute highp vec4 vPosTex; #else diff --git a/src/particles/shaders/imageparticle_core.frag b/src/particles/shaders/imageparticle_core.frag new file mode 100644 index 0000000000..3ac8c8d34e --- /dev/null +++ b/src/particles/shaders/imageparticle_core.frag @@ -0,0 +1,44 @@ +#version 150 core + +#if defined(SPRITE) +in vec4 fTexS; +#elif defined(DEFORM) +in vec2 fTex; +#endif + +#if defined(COLOR) +in vec4 fColor; +#else +in float fFade; +#endif + +#if defined(TABLE) +in vec2 tt; +uniform sampler2D colortable; +#endif + +out vec4 fragColor; + +uniform sampler2D _qt_texture; +uniform float qt_Opacity; + +void main() +{ +#if defined(SPRITE) + fragColor = mix(texture(_qt_texture, fTexS.xy), texture(_qt_texture, fTexS.zw), tt.y) + * fColor + * texture(colortable, tt) + * qt_Opacity; +#elif defined(TABLE) + fragColor = texture(_qt_texture, fTex) + * fColor + * texture(colortable, tt) + * qt_Opacity; +#elif defined(DEFORM) + fragColor = texture(_qt_texture, fTex) * fColor * qt_Opacity; +#elif defined(COLOR) + fragColor = texture(_qt_texture, gl_PointCoord) * fColor * qt_Opacity; +#else + fragColor = texture(_qt_texture, gl_PointCoord) * fFade * qt_Opacity; +#endif +}
\ No newline at end of file diff --git a/src/particles/shaders/imageparticle_core.vert b/src/particles/shaders/imageparticle_core.vert new file mode 100644 index 0000000000..ed9a918eb3 --- /dev/null +++ b/src/particles/shaders/imageparticle_core.vert @@ -0,0 +1,145 @@ +#version 150 core + +#if defined(DEFORM) +in vec4 vPosTex; +#else +in vec2 vPos; +#endif + +in vec4 vData; // x = time, y = lifeSpan, z = size, w = endSize +in vec4 vVec; // x,y = constant velocity, z,w = acceleration +uniform float entry; + +#if defined(COLOR) +in vec4 vColor; +#endif + +#if defined(DEFORM) +in vec4 vDeformVec; // x,y x unit vector; z,w = y unit vector +in vec3 vRotation; // x = radians of rotation, y = rotation velocity, z = bool autoRotate +#endif + +#if defined(SPRITE) +in vec3 vAnimData; // w,h(premultiplied of anim), interpolation progress +in vec4 vAnimPos; // x,y, x,y (two frames for interpolation) +#endif + +uniform mat4 qt_Matrix; +uniform float timestamp; + +#if defined(TABLE) +out vec2 tt;//y is progress if Sprite mode +uniform float sizetable[64]; +uniform float opacitytable[64]; +#endif + +#if defined(SPRITE) +out vec4 fTexS; +#elif defined(DEFORM) +out vec2 fTex; +#endif + +#if defined(COLOR) +out vec4 fColor; +#else +out float fFade; +#endif + + +void main() +{ + float t = (timestamp - vData.x) / vData.y; + if (t < 0. || t > 1.) { +#if defined(DEFORM) + gl_Position = qt_Matrix * vec4(vPosTex.x, vPosTex.y, 0., 1.); +#else + gl_PointSize = 0.; +#endif + } else { +#if defined(SPRITE) + tt.y = vAnimData.z; + + // Calculate frame location in texture + fTexS.xy = vAnimPos.xy + vPosTex.zw * vAnimData.xy; + + // Next frame is also passed, for interpolation + fTexS.zw = vAnimPos.zw + vPosTex.zw * vAnimData.xy; + +#elif defined(DEFORM) + fTex = vPosTex.zw; +#endif + float currentSize = mix(vData.z, vData.w, t * t); +#if defined (Q_OS_BLACKBERRY) + float fade = 1.; +#else + float fade = 1.; +#endif + float fadeIn = min(t * 10., 1.); + float fadeOut = 1. - clamp((t - 0.75) * 4.,0., 1.); + +#if defined(TABLE) + currentSize = currentSize * sizetable[int(floor(t*64.))]; + fade = fade * opacitytable[int(floor(t*64.))]; +#endif + + if (entry == 1.) + fade = fade * fadeIn * fadeOut; + else if (entry == 2.) + currentSize = currentSize * fadeIn * fadeOut; + + if (currentSize <= 0.) { +#if defined(DEFORM) + gl_Position = qt_Matrix * vec4(vPosTex.x, vPosTex.y, 0., 1.); +#else + gl_PointSize = 0.; +#endif + } else { + if (currentSize < 3.) // Sizes too small look jittery as they move + currentSize = 3.; + + vec2 pos; +#if defined(DEFORM) + float rotation = vRotation.x + vRotation.y * t * vData.y; + if (vRotation.z == 1.0) { + vec2 curVel = vVec.zw * t * vData.y + vVec.xy; + if (length(curVel) > 0.) + rotation += atan(curVel.y, curVel.x); + } + vec2 trigCalcs = vec2(cos(rotation), sin(rotation)); + vec4 deform = vDeformVec * currentSize * (vPosTex.zzww - 0.5); + vec4 rotatedDeform = deform.xxzz * trigCalcs.xyxy; + rotatedDeform = rotatedDeform + (deform.yyww * trigCalcs.yxyx * vec4(-1.,1.,-1.,1.)); + /* The readable version: + vec2 xDeform = vDeformVec.xy * currentSize * (vTex.x-0.5); + vec2 yDeform = vDeformVec.zw * currentSize * (vTex.y-0.5); + vec2 xRotatedDeform; + xRotatedDeform.x = trigCalcs.x*xDeform.x - trigCalcs.y*xDeform.y; + xRotatedDeform.y = trigCalcs.y*xDeform.x + trigCalcs.x*xDeform.y; + vec2 yRotatedDeform; + yRotatedDeform.x = trigCalcs.x*yDeform.x - trigCalcs.y*yDeform.y; + yRotatedDeform.y = trigCalcs.y*yDeform.x + trigCalcs.x*yDeform.y; + */ + pos = vPosTex.xy + + rotatedDeform.xy + + rotatedDeform.zw + + vVec.xy * t * vData.y // apply velocity + + 0.5 * vVec.zw * pow(t * vData.y, 2.); // apply acceleration +#else + pos = vPos + + vVec.xy * t * vData.y // apply velocity vector.. + + 0.5 * vVec.zw * pow(t * vData.y, 2.); + gl_PointSize = currentSize; +#endif + gl_Position = qt_Matrix * vec4(pos.x, pos.y, 0, 1); + +#if defined(COLOR) + fColor = vColor * fade; +#else + fFade = fade; +#endif +#if defined(TABLE) + tt.x = t; +#endif + } + } +}
\ No newline at end of file |