summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrederic Plourde <frederic.plourde@collabora.co.uk>2011-10-24 11:55:32 -0400
committerFrederic Plourde <frederic.plourde@collabora.co.uk>2011-10-24 11:55:32 -0400
commit630b5db8ca894a898c41b53c7b2f7b76ed2c66c3 (patch)
treeb4e8641560b8d231336f37b3149e3d91bfc31823
parentef087a7d5374088d10190cb9bc13f6348fa0c2e2 (diff)
downloadcore-630b5db8ca894a898c41b53c7b2f7b76ed2c66c3.tar.gz
core-630b5db8ca894a898c41b53c7b2f7b76ed2c66c3.tar.bz2
Port water plugin to GLES
-rw-r--r--plugins/water/src/shaders.h201
-rw-r--r--plugins/water/src/water.cpp770
-rw-r--r--plugins/water/src/water.h95
-rw-r--r--plugins/water/water.xml.in24
4 files changed, 562 insertions, 528 deletions
diff --git a/plugins/water/src/shaders.h b/plugins/water/src/shaders.h
new file mode 100644
index 0000000..ca49fe6
--- /dev/null
+++ b/plugins/water/src/shaders.h
@@ -0,0 +1,201 @@
+/*
+ * Copyright © 2011 Collabora Ltd.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Collabora Ltd. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior permission.
+ * Collabora Ltd. makes no representations about the suitability of this
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
+ *
+ * COLLABORA LTD. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
+ * NO EVENT SHALL LINARO LTD. BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
+ * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: Frederic Plourde <frederic.plourde@collabora.co.uk>
+ */
+
+#ifndef _COMPIZ_WATERSHADERS_H
+#define _COMPIZ_WATERSHADERS_H
+
+
+// This vertex shader is used to set water vertices ...
+static std::string set_water_vertices_vertex_shader = " \n\
+#ifdef GL_ES \n\
+precision mediump float; \n\
+#endif \n\
+ \n\
+attribute vec3 position; \n\
+ \n\
+void main () \n\
+{ \n\
+ gl_PointSize = 3.0; \n\
+ gl_Position = vec4(position, 1.0); \n\
+ \n\
+}";
+
+// This fragment shader is used to draw water primitives ...
+// we're only setting the height here, so we only care about the .w coord.
+static std::string set_water_vertices_fragment_shader = " \n\
+#ifdef GL_ES \n\
+precision mediump float; \n\
+#endif \n\
+ \n\
+uniform float color; \n\
+ \n\
+void main () \n\
+{ \n\
+ gl_FragColor = vec4(0.0, 0.0, 0.0, color); \n\
+}";
+
+
+
+
+// This vertex shader is used to update water vertices...
+static std::string update_water_vertices_vertex_shader = " \n\
+#ifdef GL_ES \n\
+precision mediump float; \n\
+#endif \n\
+ \n\
+attribute vec3 position; \n\
+attribute vec2 texCoord0; \n\
+ \n\
+varying vec2 vTexCoord0; \n\
+ \n\
+void main () \n\
+{ \n\
+ vTexCoord0 = texCoord0; \n\
+ gl_Position = vec4(position, 1.0); \n\
+ \n\
+}";
+
+// This fragment shader is used to compute new normal + height of water vertices.
+// here we're using two input textures, previous and current.
+static std::string update_water_vertices_fragment_shader = " \n\
+#ifdef GL_ES \n\
+precision mediump float; \n\
+#endif \n\
+ \n\
+uniform sampler2D prevTex; \n\
+uniform sampler2D currTex; \n\
+ \n\
+varying vec2 vTexCoord0; \n\
+ \n\
+uniform float timeLapse; \n\
+uniform float fade; \n\
+ \n\
+void main () \n\
+{ \n\
+ vec2 t01, t21, t10, t12; \n\
+ vec4 c01, c21, c10, c12; \n\
+ vec4 curr, prev, v; \n\
+ float accel; \n\
+ \n\
+ // fetch current and previous normals \n\
+ prev = texture%s (prevTex, vTexCoord0); \n\
+ curr = texture%s (currTex, vTexCoord0); \n\
+ \n\
+ // sample offsets \n\
+ t01 = vTexCoord0 + vec2 (- %f, 0.0); \n\
+ t21 = vTexCoord0 + vec2 ( %f, 0.0); \n\
+ t10 = vTexCoord0 + vec2 ( 0.0,- %f); \n\
+ t12 = vTexCoord0 + vec2 ( 0.0, %f); \n\
+ \n\
+ // fetch necessary samples \n\
+ c01 = texture%s (currTex, t01); \n\
+ c21 = texture%s (currTex, t21); \n\
+ c10 = texture%s (currTex, t10); \n\
+ c12 = texture%s (currTex, t12); \n\
+ \n\
+ // x/y normals from height \n\
+ v = vec4 (0.0, 0.0, 0.75, 0.0); \n\
+ v.x = c01.w - c21.w; \n\
+ v.y = c12.w - c10.w; \n\
+ \n\
+ // bumpiness \n\
+ v = normalize (v); \n\
+ \n\
+ // add scale and bias \n\
+ v = (v * 0.5) + 0.5; \n\
+ \n\
+ // done with computing the normal, continue with computing \n\
+ // the next height value \n\
+ accel = (curr.w * -4.0) + (c10.w + c12.w + c01.w + c21.w); \n\
+ \n\
+ // store new height in alpha component \n\
+ v.w = (accel * timeLapse) + ((curr.w * 2.0) - prev.w); \n\
+ \n\
+ // fade out height \n\
+ v.w *= fade; \n\
+ \n\
+ gl_FragColor = v; \n\
+}";
+
+
+
+
+// This vertex shader is used when painting our bump map FX over
+// final composited screen FBO
+static std::string paint_water_vertices_vertex_shader = " \n\
+#ifdef GL_ES \n\
+precision mediump float; \n\
+#endif \n\
+ \n\
+attribute vec3 position; \n\
+attribute vec2 texCoord0; \n\
+ \n\
+varying vec2 vTexCoord0; \n\
+ \n\
+void main () \n\
+{ \n\
+ vTexCoord0 = texCoord0; \n\
+ gl_Position = vec4(position, 1.0); \n\
+ \n\
+}";
+
+// This fragment shader is used to produce our dot3 bump mapping output,
+// blended over final composited glScreen FBO.
+// here we're using two input textures :
+// 1) The final composited FBO color attachment over which we're
+// applying our bump map FX (baseTex)
+// 2) The updated bump map (waveTex)
+static std::string paint_water_vertices_fragment_shader = " \n\
+#ifdef GL_ES \n\
+precision mediump float; \n\
+#endif \n\
+ \n\
+uniform sampler2D baseTex; \n\
+uniform sampler2D waveTex; \n\
+ \n\
+varying vec2 vTexCoord0; \n\
+ \n\
+uniform vec3 lightVec; \n\
+uniform float offsetScale; \n\
+ \n\
+void main () \n\
+{ \n\
+ vec4 normal = texture2D (waveTex, vTexCoord0); \n\
+ float height = normal.w; \n\
+ float diffuse = 0.75; \n\
+ vec4 offset; \n\
+ \n\
+ normal = normalize ((normal * 2.0) - 1.0); \n\
+ \n\
+ offset.x = normal.x * height * offsetScale/%d.0; \n\
+ offset.y = normal.y * height * offsetScale/%d.0; \n\
+ vec4 baseColor = texture2D (baseTex, vTexCoord0 + offset.xy); \n\
+ \n\
+ float diffFact = dot (normal.xyz, vec3(lightVec.xy, 0.0)) * diffuse; \n\
+ gl_FragColor = vec4 (vec3 (baseColor) + diffFact, 1.0); \n\
+}";
+
+#endif // _COMPIZ_WATERSHADERS_H
+
diff --git a/plugins/water/src/water.cpp b/plugins/water/src/water.cpp
index b3a0c78..6da7bcc 100644
--- a/plugins/water/src/water.cpp
+++ b/plugins/water/src/water.cpp
@@ -21,6 +21,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Author: David Reveman <davidr@novell.com>
+ * Frederic Plourde <frederic.plourde@collabora.co.uk>
*/
#include "water.h"
@@ -30,202 +31,25 @@ COMPIZ_PLUGIN_20090315 (water, WaterPluginVTable)
static int waterLastPointerX = 0;
static int waterLastPointerY = 0;
-static const char *waterFpString =
- "!!ARBfp1.0"
-
- "PARAM param = program.local[0];"
- "ATTRIB t11 = fragment.texcoord[0];"
-
- "TEMP t01, t21, t10, t12;"
- "TEMP c11, c01, c21, c10, c12;"
- "TEMP prev, v, temp, accel;"
-
- "TEX prev, t11, texture[0], %s;"
- "TEX c11, t11, texture[1], %s;"
-
- /* sample offsets */
- "ADD t01, t11, { - %f, 0.0, 0.0, 0.0 };"
- "ADD t21, t11, { %f, 0.0, 0.0, 0.0 };"
- "ADD t10, t11, { 0.0, - %f, 0.0, 0.0 };"
- "ADD t12, t11, { 0.0, %f, 0.0, 0.0 };"
-
- /* fetch nesseccary samples */
- "TEX c01, t01, texture[1], %s;"
- "TEX c21, t21, texture[1], %s;"
- "TEX c10, t10, texture[1], %s;"
- "TEX c12, t12, texture[1], %s;"
-
- /* x/y normals from height */
- "MOV v, { 0.0, 0.0, 0.75, 0.0 };"
- "SUB v.x, c12.w, c10.w;"
- "SUB v.y, c01.w, c21.w;"
-
- /* bumpiness */
- "MUL v, v, 1.5;"
-
- /* normalize */
- "MAD temp, v.x, v.x, 1.0;"
- "MAD temp, v.y, v.y, temp;"
- "RSQ temp, temp.x;"
- "MUL v, v, temp;"
-
- /* add scale and bias to normal */
- "MAD v, v, 0.5, 0.5;"
-
- /* done with computing the normal, continue with computing the next
- height value */
- "ADD accel, c10, c12;"
- "ADD accel, c01, accel;"
- "ADD accel, c21, accel;"
- "MAD accel, -4.0, c11, accel;"
-
- /* store new height in alpha component */
- "MAD v.w, 2.0, c11, -prev.w;"
- "MAD v.w, accel, param.x, v.w;"
-
- /* fade out height */
- "MUL v.w, v.w, param.y;"
-
- "MOV result.color, v;"
-
- "END";
-
-static bool
-loadFragmentProgram (GLuint *program,
- const char *string)
-{
- GLint errorPos;
-
- /* clear errors */
- glGetError ();
-
- if (!*program)
- GL::genPrograms (1, program);
-
- GL::bindProgram (GL_FRAGMENT_PROGRAM_ARB, *program);
- GL::programString (GL_FRAGMENT_PROGRAM_ARB,
- GL_PROGRAM_FORMAT_ASCII_ARB,
- strlen (string), string);
-
- glGetIntegerv (GL_PROGRAM_ERROR_POSITION_ARB, &errorPos);
- if (glGetError () != GL_NO_ERROR || errorPos != -1)
- {
- compLogMessage ("water", CompLogLevelError,
- "failed to load bump map program");
-
- GL::deletePrograms (1, program);
- *program = 0;
-
- return false;
- }
-
- return true;
-}
-
-static int
-loadWaterProgram ()
-{
- char buffer[1024];
-
- WATER_SCREEN (screen);
-
- if (ws->target == GL_TEXTURE_2D)
- sprintf (buffer, waterFpString,
- "2D", "2D",
- 1.0f / ws->width, 1.0f / ws->width,
- 1.0f / ws->height, 1.0f / ws->height,
- "2D", "2D", "2D", "2D");
- else
- sprintf (buffer, waterFpString,
- "RECT", "RECT",
- 1.0f, 1.0f, 1.0f, 1.0f,
- "RECT", "RECT", "RECT", "RECT");
-
- return loadFragmentProgram (&ws->program, buffer);
-}
-
-GLFragment::FunctionId
-WaterScreen::getBumpMapFragmentFunction (GLTexture *texture,
- int unit,
- int param)
-{
- GLFragment::FunctionData data;
- int target;
- WaterFunction function;
-
- if (texture->target () == GL_TEXTURE_2D)
- target = COMP_FETCH_TARGET_2D;
- else
- target = COMP_FETCH_TARGET_RECT;
-
- foreach (WaterFunction &f, bumpMapFunctions)
- {
- if (f.param == param &&
- f.unit == unit &&
- f.target == target)
- return f.id;
- }
-
- static const char *temp[] = { "normal", "temp", "total", "bump", "offset" };
-
- for (unsigned int i = 0; i < sizeof (temp) / sizeof (temp[0]); i++)
- data.addTempHeaderOp (temp[i]);
-
- data.addDataOp (
- /* get normal from normal map */
- "TEX normal, fragment.texcoord[%d], texture[%d], %s;"
-
- /* save height */
- "MOV offset, normal;"
-
- /* remove scale and bias from normal */
- "MAD normal, normal, 2.0, -1.0;"
-
- /* normalize the normal map */
- "DP3 temp, normal, normal;"
- "RSQ temp, temp.x;"
- "MUL normal, normal, temp;"
-
- /* scale down normal by height and constant and use as
- offset in texture */
- "MUL offset, normal, offset.w;"
- "MUL offset, offset, program.env[%d];",
-
- unit, unit,
- (this->target == GL_TEXTURE_2D) ? "2D" : "RECT",
- param);
-
- data.addFetchOp ("output", "offset.yxzz", target);
-
- data.addDataOp (
- /* normal dot lightdir, this should eventually be
- changed to a real light vector */
- "DP3 bump, normal, { 0.707, 0.707, 0.0, 0.0 };"
- "MUL bump, bump, state.light[0].diffuse;");
-
-
- data.addColorOp ("output", "output");
-
- data.addDataOp (
- /* diffuse per-vertex lighting, opacity and brightness
- and add lightsource bump color */
- "ADD output, output, bump;");
-
- if (!data.status ())
- return 0;
-
-
- function.id = data.createFragmentFunction ("water");
-
- function.target = target;
- function.param = param;
- function.unit = unit;
-
- bumpMapFunctions.push_back (function);
-
- return function.id;
-}
-
+GLfloat WaterScreen::vertexData [18] = {
+ -1.0f, -1.0f, 0.0f,
+ 1.0f, -1.0f, 0.0f,
+ -1.0f, 1.0f, 0.0f,
+ -1.0f, 1.0f, 0.0f,
+ 1.0f, -1.0f, 0.0f,
+ 1.0f, 1.0f, 0.0f,
+};
+
+GLfloat WaterScreen::textureData [12] = {
+ 0.0f, 0.0f,
+ 1.0f, 0.0f,
+ 0.0f, 1.0f,
+ 0.0f, 1.0f,
+ 1.0f, 0.0f,
+ 1.0f, 1.0f,
+};
+
+#ifndef USE_GLES
void
WaterScreen::allocTexture (int index)
{
@@ -237,7 +61,7 @@ WaterScreen::allocTexture (int index)
glTexParameteri (target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri (target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- glTexImage2D (target, 0, GL_RGBA, width, height, 0, GL_BGRA,
+ glTexImage2D (target, 0, GL_RGBA, texWidth, texHeight, 0, GL_BGRA,
#if IMAGE_BYTE_ORDER == MSBFirst
GL_UNSIGNED_INT_8_8_8_8_REV,
#else
@@ -247,46 +71,19 @@ WaterScreen::allocTexture (int index)
glBindTexture (target, 0);
}
+#endif
bool
-WaterScreen::fboPrologue (int tIndex)
+WaterScreen::fboPrologue (int fIndex)
{
- if (!fbo)
+ if (!useFbo)
return false;
- if (!texture[tIndex])
- allocTexture (tIndex);
-
- GL::bindFramebuffer (GL_FRAMEBUFFER_EXT, fbo);
-
- GL::framebufferTexture2D (GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
- target, texture[tIndex], 0);
-
- glDrawBuffer (GL_COLOR_ATTACHMENT0_EXT);
- glReadBuffer (GL_COLOR_ATTACHMENT0_EXT);
-
- /* check status the first time */
- if (!fboStatus)
- {
- fboStatus = GL::checkFramebufferStatus (GL_FRAMEBUFFER_EXT);
- if (fboStatus != GL_FRAMEBUFFER_COMPLETE_EXT)
- {
- compLogMessage ("water", CompLogLevelError,
- "framebuffer incomplete");
-
- GL::bindFramebuffer (GL_FRAMEBUFFER_EXT, 0);
- GL::deleteFramebuffers (1, &fbo);
-
- glDrawBuffer (GL_BACK);
- glReadBuffer (GL_BACK);
-
- fbo = 0;
-
- return false;
- }
- }
+ oldFbo = waterFbo[fIndex]->bind ();
+ glGetIntegerv(GL_VIEWPORT, &oldViewport[0]);
+ glViewport (0, 0, texWidth, texHeight);
- glViewport (0, 0, width, height);
+#ifndef USE_GLES
glMatrixMode (GL_PROJECTION);
glPushMatrix ();
glLoadIdentity ();
@@ -294,6 +91,7 @@ WaterScreen::fboPrologue (int tIndex)
glMatrixMode (GL_MODELVIEW);
glPushMatrix ();
glLoadIdentity ();
+#endif
return true;
}
@@ -301,58 +99,53 @@ WaterScreen::fboPrologue (int tIndex)
void
WaterScreen::fboEpilogue ()
{
- GL::bindFramebuffer (GL_FRAMEBUFFER_EXT, 0);
+ GLFramebufferObject::rebind (oldFbo);
+ glViewport (oldViewport[0], oldViewport[1], oldViewport[2], oldViewport[3]);
+#ifndef USE_GLES
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
glMatrixMode (GL_MODELVIEW);
glLoadIdentity ();
- glDepthRange (0, 1);
- glViewport (-1, -1, 2, 2);
-
- gScreen->resetRasterPos ();
-
- gScreen->setDefaultViewport ();
-
- glMatrixMode (GL_PROJECTION);
- glPopMatrix ();
- glMatrixMode (GL_MODELVIEW);
- glPopMatrix ();
-
- glDrawBuffer (GL_BACK);
- glReadBuffer (GL_BACK);
+#endif
}
bool
WaterScreen::fboUpdate (float dt, float fade)
{
- if (!fboPrologue (TINDEX (this, 1)))
+ if (!fboPrologue (INDEX (this, 1)))
return false;
- if (!texture[TINDEX (this, 2)])
- allocTexture (TINDEX (this, 2));
-
- if (!texture[TINDEX (this, 0)])
- allocTexture (TINDEX (this, 0));
-
- glEnable (target);
-
- GL::activeTexture (GL_TEXTURE0_ARB);
- glBindTexture (target, texture[TINDEX (this, 2)]);
-
- glTexParameteri (target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri (target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- GL::activeTexture (GL_TEXTURE1_ARB);
- glBindTexture (target, texture[TINDEX (this, 0)]);
- glTexParameteri (target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri (target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-
- glEnable (GL_FRAGMENT_PROGRAM_ARB);
- GL::bindProgram (GL_FRAGMENT_PROGRAM_ARB, program);
-
- GL::programLocalParameter4f (GL_FRAGMENT_PROGRAM_ARB, 0,
- dt * K, fade, 1.0f, 1.0f);
-
+ glEnable (GL_TEXTURE_2D);
+
+ vertexBuffer[UPDATE]->begin ();
+ vertexBuffer[UPDATE]->addVertices (6, &vertexData[0]);
+ vertexBuffer[UPDATE]->addTexCoords (0, 6, &textureData[0]);
+ vertexBuffer[UPDATE]->end ();
+
+ // TODO: use GLTexture facilities here, instead of manually setting active
+ // texture, especially when there will be texture unit support
+ glActiveTexture (GL_TEXTURE0);
+ waterFbo[INDEX (this, 2)]->tex ()->setFilter (GL_NEAREST);
+ glBindTexture (GL_TEXTURE_2D, waterFbo[INDEX (this, 2)]->tex ()->name ());
+
+ glActiveTexture (GL_TEXTURE1);
+ waterFbo[INDEX (this, 0)]->tex ()->setFilter (GL_NEAREST);
+ glBindTexture (GL_TEXTURE_2D, waterFbo[INDEX (this, 0)]->tex ()->name ());
+
+ vertexBuffer[UPDATE]->addUniform ("prevTex", 0);
+ vertexBuffer[UPDATE]->addUniform ("currTex", 1);
+ vertexBuffer[UPDATE]->addUniform ("timeLapse", dt * K);
+ vertexBuffer[UPDATE]->addUniform ("fade", fade);
+
+#ifdef USE_GLES
+ GLboolean isBlendingEnabled;
+ glGetBooleanv (GL_BLEND, &isBlendingEnabled);
+ glDisable (GL_BLEND);
+ vertexBuffer[UPDATE]->render ();
+ if (isBlendingEnabled)
+ glEnable (GL_BLEND);
+#else
glBegin (GL_QUADS);
glTexCoord2f (0.0f, 0.0f);
@@ -365,24 +158,20 @@ WaterScreen::fboUpdate (float dt, float fade)
glVertex2f (0.0f, 1.0f);
glEnd ();
+#endif
- glDisable (GL_FRAGMENT_PROGRAM_ARB);
+ glActiveTexture (GL_TEXTURE0);
+ glBindTexture (GL_TEXTURE_2D, 0);
- glTexParameteri (target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri (target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glBindTexture (target, 0);
- GL::activeTexture (GL_TEXTURE0_ARB);
- glTexParameteri (target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri (target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glBindTexture (target, 0);
+ glActiveTexture (GL_TEXTURE1);
+ glBindTexture (GL_TEXTURE_2D, 0);
- glDisable (target);
+ glDisable (GL_TEXTURE_2D);
fboEpilogue ();
/* increment texture index */
- tIndex = TINDEX (this, 1);
-
+ fboIndex = INDEX (this, 1);
return true;
}
@@ -392,36 +181,63 @@ WaterScreen::fboVertices (GLenum type,
int n,
float v)
{
- if (!fboPrologue (TINDEX (this, 0)))
+ if (!fboPrologue (INDEX (this, 0)))
return false;
glColorMask (GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE);
- glColor4f (0.0f, 0.0f, 0.0f, v);
-
- glPointSize (3.0f);
glLineWidth (1.0f);
- glScalef (1.0f / width, 1.0f / height, 1.0);
- glTranslatef (0.5f, 0.5f, 0.0f);
+#ifndef USE_GLES
+ if (!GL::vbo || !GL::shaders)
+ {
+ glColor4f (0.0f, 0.0f, 0.0f, v);
+ glPointSize (3.0f);
- glBegin (type);
+ glScalef (1.0f / texWidth, 1.0f / texHeight, 1.0);
+ glTranslatef (0.5f, 0.5f, 0.0f);
- while (n--)
+ glBegin (type);
+ while (n--)
+ {
+ glVertex2i (p->x, p->y);
+ p++;
+ }
+ glEnd ();
+
+ glColor4usv (defaultColor);
+ }
+ else
+#endif
{
- glVertex2i (p->x, p->y);
- p++;
+ vertexBuffer[SET]->begin (type);
+ float data[3];
+ for (int i = 0; i < n; i++)
+ {
+ data[0] = (((float) p->x / (float) screen->width ()) * 2.0f) - 1.0f;
+ data[1] = ((((float) screen->height () - (float) p->y)/
+ (float) screen->height ()) * 2.0f) - 1.0f;
+ data[2] = 0.0f;
+ p++;
+ vertexBuffer[SET]->addVertices (1, &data[0]);
+ }
+ vertexBuffer[SET]->end();
+
+ vertexBuffer[SET]->addUniform ("color", v);
+ GLboolean isBlendingEnabled;
+ glGetBooleanv (GL_BLEND, &isBlendingEnabled);
+ glDisable (GL_BLEND);
+ vertexBuffer[SET]->render ();
+ if (isBlendingEnabled)
+ glEnable (GL_BLEND);
}
- glEnd ();
-
- glColor4usv (defaultColor);
glColorMask (GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
fboEpilogue ();
-
return true;
}
+#ifndef USE_GLES
void
WaterScreen::softwareUpdate (float dt, float fade)
{
@@ -433,14 +249,14 @@ WaterScreen::softwareUpdate (float dt, float fade)
int dWidth, dHeight;
float *d01, *d10, *d11, *d12;
- if (!texture[TINDEX (this, 0)])
- allocTexture (TINDEX (this, 0));
+ if (!texture[INDEX (this, 0)])
+ allocTexture (INDEX (this, 0));
dt *= K * 2.0f;
fade *= 0.99f;
- dWidth = width + 2;
- dHeight = height + 2;
+ dWidth = texWidth + 2;
+ dHeight = texHeight + 2;
#define D(d, j) (*((d) + (j)))
@@ -494,9 +310,9 @@ WaterScreen::softwareUpdate (float dt, float fade)
t0 = this->t0;
/* update texture */
- for (i = 0; i < height; i++)
+ for (i = 0; i < texHeight; i++)
{
- for (j = 0; j < width; j++)
+ for (j = 0; j < texWidth; j++)
{
v0 = (D (d12, j) - D (d10, j)) * 1.5f;
v1 = (D (d11, j - 1) - D (d11, j + 1)) * 1.5f;
@@ -522,7 +338,7 @@ WaterScreen::softwareUpdate (float dt, float fade)
d11 += dWidth;
d12 += dWidth;
- t0 += width * 4;
+ t0 += texWidth * 4;
}
#undef D
@@ -532,10 +348,11 @@ WaterScreen::softwareUpdate (float dt, float fade)
d0 = d1;
d1 = dTmp;
- if (texture[TINDEX (this, 0)])
+ if (texture[INDEX (this
+ , 0)])
{
- glBindTexture (target, texture[TINDEX (this, 0)]);
- glTexImage2D (target, 0, GL_RGBA, width, height, 0, GL_BGRA,
+ glBindTexture (target, texture[INDEX (this, 0)]);
+ glTexImage2D (target, 0, GL_RGBA, texWidth, texHeight, 0, GL_BGRA,
#if IMAGE_BYTE_ORDER == MSBFirst
GL_UNSIGNED_INT_8_8_8_8_REV,
#else
@@ -546,7 +363,7 @@ WaterScreen::softwareUpdate (float dt, float fade)
}
-#define SET(x, y, v) *((d1) + (width + 2) * (y + 1) + (x + 1)) = (v)
+#define SET(x, y, v) *((d1) + (texWidth + 2) * (y + 1) + (x + 1)) = (v)
void
WaterScreen::softwarePoints (XPoint *p,
@@ -666,6 +483,7 @@ WaterScreen::softwareVertices (GLenum type,
break;
}
}
+#endif
void
WaterScreen::waterUpdate (float dt)
@@ -675,23 +493,17 @@ WaterScreen::waterUpdate (float dt)
if (count < 1000)
{
if (count > 1)
- fade = 0.90f + count / 10000.0f;
+ fade = 0.90f + (float) count / 10000.0f;
else
fade = 0.0f;
}
- if (!fboUpdate (dt, fade))
- softwareUpdate (dt, fade);
-}
-
-void
-WaterScreen::scaleVertices (XPoint *p, int n)
-{
- while (n--)
- {
- p[n].x = (width * p[n].x) / screen->width ();
- p[n].y = (height * p[n].y) / screen->height ();
- }
+ if (!fboUpdate (dt, fade))
+ {
+#ifndef USE_GLES
+ softwareUpdate (dt, fade);
+#endif
+ }
}
void
@@ -700,25 +512,19 @@ WaterScreen::waterVertices (GLenum type,
int n,
float v)
{
- if (!GL::fragmentProgram)
- return;
-
- scaleVertices (p, n);
-
if (!fboVertices (type, p, n, v))
- softwareVertices (type, p, n, v);
+ {
+#ifndef USE_GLES
+ softwareVertices (type, p, n, v);
+#endif
+ }
if (count <= 0)
{
- WaterWindow *ww;
-
cScreen->preparePaintSetEnabled (this, true);
+ gScreen->glPaintOutputSetEnabled (this, true);
+ gScreen->glPaintCompositedOutputSetEnabled (this, true);
cScreen->donePaintSetEnabled (this, true);
- foreach (CompWindow *w, screen->windows ())
- {
- ww = WaterWindow::get (w);
- ww->gWindow->glDrawTextureSetEnabled (ww, true);
- }
}
if (count < 3000)
@@ -755,15 +561,21 @@ WaterScreen::wiperTimeout ()
}
void
-WaterScreen::waterReset ()
+WaterScreen::waterSetup ()
{
- int size, i, j;
+ int size;
+ char buf[8192];
+ std::string buffer;
- height = TEXTURE_SIZE;
- width = (height * screen->width ()) / screen->height ();
+ texHeight = TEXTURE_SIZE;
+ texWidth = (texHeight * screen->width ()) / screen->height ();
+#ifdef USE_GLES
+ target = GL_TEXTURE_2D;
+ tx = ty = 1.0f;
+#else
if (GL::textureNonPowerOfTwo ||
- (POWER_OF_TWO (width) && POWER_OF_TWO (height)))
+ (POWER_OF_TWO (texWidth) && POWER_OF_TWO (texHeight)))
{
target = GL_TEXTURE_2D;
tx = ty = 1.0f;
@@ -771,38 +583,15 @@ WaterScreen::waterReset ()
else
{
target = GL_TEXTURE_RECTANGLE_NV;
- tx = width;
- ty = height;
- }
-
- if (!GL::fragmentProgram)
- return;
-
- if (GL::fbo)
- {
- loadWaterProgram ();
- if (!fbo)
- GL::genFramebuffers (1, &fbo);
- }
-
- fboStatus = 0;
-
- for (i = 0; i < TEXTURE_NUM; i++)
- {
- if (texture[i])
- {
- glDeleteTextures (1, &texture[i]);
- texture[i] = 0;
- }
+ tx = texWidth;
+ ty = texHeight;
}
+#endif
- if (data)
- free (data);
-
- size = (width + 2) * (height + 2);
+ size = (texWidth + 2) * (texHeight + 2);
data = calloc (1, (sizeof (float) * size * 2) +
- (sizeof (GLubyte) * width * height * 4));
+ (sizeof (GLubyte) * texWidth * texHeight * 4));
if (!data)
return;
@@ -810,88 +599,120 @@ WaterScreen::waterReset ()
d1 = (d0 + (size));
t0 = (unsigned char *) (d1 + (size));
- for (i = 0; i < height; i++)
- {
- for (j = 0; j < width; j++)
- {
- (t0 + (width * 4 * i + j * 4))[0] = 0xff;
- }
- }
-}
-
-void
-WaterWindow::glDrawTexture (GLTexture *texture,
- GLFragment::Attrib &attrib,
- unsigned int mask)
-{
- if (wScreen->count)
+ if (GL::fbo)
{
- GLFragment::Attrib fa (attrib);
- bool lighting = wScreen->gScreen->lighting ();
- int param, unit;
- GLFragment::FunctionId function;
- GLfloat plane[4];
-
- param = fa.allocParameters (1);
- unit = fa.allocTextureUnits (1);
-
- function = wScreen->getBumpMapFragmentFunction (texture, unit, param);
- if (function)
- {
- fa.addFunction (function);
-
- gScreen->setLighting (true);
-
- GL::activeTexture (GL_TEXTURE0_ARB + unit);
+ program[SET] = new GLProgram (set_water_vertices_vertex_shader,
+ set_water_vertices_fragment_shader);
+
+ if (target == GL_TEXTURE_2D)
+ sprintf (buf, update_water_vertices_fragment_shader.c_str (),
+ "2D", "2D",
+ 1.0f / (float) texWidth, 1.0f / (float) texWidth,
+ 1.0f / (float) texHeight, 1.0f / (float) texHeight,
+ "2D", "2D", "2D", "2D");
+ else
+ sprintf (buf, update_water_vertices_fragment_shader.c_str (),
+ "RECT", "RECT",
+ 1.0f, 1.0f, 1.0f, 1.0f,
+ "RECT", "RECT", "RECT", "RECT");
- glBindTexture (wScreen->target,
- wScreen->texture[TINDEX (wScreen, 0)]);
+ buffer.assign (buf);
+ program[UPDATE] = new GLProgram (update_water_vertices_vertex_shader,
+ buffer);
- plane[1] = plane[2] = 0.0f;
- plane[0] = wScreen->tx / (GLfloat) screen->width ();
- plane[3] = 0.0f;
+ sprintf (buf, paint_water_vertices_fragment_shader.c_str (),
+ screen->width (), screen->height ());
- glTexGeni (GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
- glTexGenfv (GL_S, GL_EYE_PLANE, plane);
- glEnable (GL_TEXTURE_GEN_S);
+ buffer.assign (buf);
+ program[PAINT] = new GLProgram (paint_water_vertices_vertex_shader,
+ buffer);
- plane[0] = plane[2] = 0.0f;
- plane[1] = wScreen->ty / (GLfloat) screen->height ();
- plane[3] = 0.0f;
+ vertexBuffer[SET] = new GLVertexBuffer (GL_DYNAMIC_DRAW);
+ vertexBuffer[SET]->setProgram (program[SET]);
- glTexGeni (GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
- glTexGenfv (GL_T, GL_EYE_PLANE, plane);
- glEnable (GL_TEXTURE_GEN_T);
+ vertexBuffer[UPDATE] = new GLVertexBuffer (GL_STATIC_DRAW);
+ vertexBuffer[UPDATE]->setProgram (program[UPDATE]);
- GL::activeTexture (GL_TEXTURE0_ARB);
+ vertexBuffer[PAINT] = new GLVertexBuffer (GL_STATIC_DRAW);
+ vertexBuffer[PAINT]->setProgram (program[PAINT]);
+ }
- GL::programEnvParameter4f (GL_FRAGMENT_PROGRAM_ARB, param,
- texture->matrix ().yy *
- wScreen->offsetScale,
- -texture->matrix ().xx *
- wScreen->offsetScale,
- 0.0f, 0.0f);
+ if (GL::fbo)
+ {
+ CompSize size(texWidth, texHeight);
+ for (int i = 0; i < TEXTURE_NUM; i++)
+ {
+ waterFbo[i] = new GLFramebufferObject ();
+ waterFbo[i]->allocate (size, (char *) t0,
+ GL_BGRA, GL_UNSIGNED_BYTE);
+ // check if FBOs are working. If not, fallback to software textures
+ oldFbo = waterFbo[i]->bind ();
+ waterFbo[i]->rebind (oldFbo);
+ if (!waterFbo[i]->checkStatus ())
+ {
+ useFbo = false;
+ delete waterFbo[i];
+ break;
+ }
}
-
- /* to get appropriate filtering of texture */
- mask |= PAINT_WINDOW_ON_TRANSFORMED_SCREEN_MASK;
-
- gWindow->glDrawTexture (texture, fa, mask);
-
- if (function)
+ }
+#ifndef USE_GLES
+ if (!useFbo)
+ {
+ for (int i = 0; i < TEXTURE_NUM; i++)
{
- GL::activeTexture (GL_TEXTURE0_ARB + unit);
- glDisable (GL_TEXTURE_GEN_T);
- glDisable (GL_TEXTURE_GEN_S);
- glBindTexture (wScreen->target, 0);
- GL::activeTexture (GL_TEXTURE0_ARB);
-
- gScreen->setLighting (lighting);
+ texture[i] = 0;
}
}
- else
+#endif
+}
+
+void
+WaterScreen::glPaintCompositedOutput (const CompRegion &tmpRegion,
+ GLFramebufferObject *scratchFbo,
+ bool fullRepaint)
+{
+ if (count)
{
- gWindow->glDrawTexture (texture, attrib, mask);
+ if (GL::vbo && GL::shaders)
+ {
+ GLFramebufferObject::rebind (oldFbo);
+ glViewport (oldViewport[0], oldViewport[1],
+ oldViewport[2], oldViewport[3]);
+
+ vertexBuffer[PAINT]->begin ();
+ vertexBuffer[PAINT]->addVertices (6, &vertexData[0]);
+ vertexBuffer[PAINT]->addTexCoords (0, 6, &textureData[0]);
+ vertexBuffer[PAINT]->end ();
+
+ glEnable (GL_TEXTURE_2D);
+
+ glActiveTexture (GL_TEXTURE0);
+ scratchFbo->tex ()->setFilter (GL_LINEAR);
+ glBindTexture (GL_TEXTURE_2D, scratchFbo->tex ()->name ());
+ vertexBuffer[PAINT]->addUniform ("baseTex", 0);
+
+ glActiveTexture (GL_TEXTURE1);
+ waterFbo[INDEX (this, 0)]->tex ()->setFilter (GL_LINEAR);
+ glBindTexture (GL_TEXTURE_2D,
+ waterFbo[INDEX (this, 0)]->tex ()->name ());
+ vertexBuffer[PAINT]->addUniform ("waveTex", 1);
+
+ vertexBuffer[PAINT]->addUniform3f ("lightVec",
+ lightVec[0],
+ lightVec[1],
+ lightVec[2]);
+ vertexBuffer[PAINT]->addUniform ("offsetScale", offsetScale);
+ GLboolean isBlendingEnabled;
+ glGetBooleanv (GL_BLEND, &isBlendingEnabled);
+ glDisable (GL_BLEND);
+ vertexBuffer[PAINT]->render ();
+ if (isBlendingEnabled)
+ glEnable (GL_BLEND);
+
+ glBindTexture (GL_TEXTURE_2D, 0);
+ glDisable (GL_TEXTURE_2D);
+ }
}
}
@@ -982,7 +803,7 @@ WaterScreen::preparePaint (int msSinceLastPaint)
}
- waterUpdate (0.8f);
+ waterUpdate (0.8);
}
cScreen->preparePaint (msSinceLastPaint);
@@ -995,15 +816,10 @@ WaterScreen::donePaint ()
cScreen->damageScreen ();
else
{
- WaterWindow *ww;
-
cScreen->preparePaintSetEnabled (this, false);
+ gScreen->glPaintOutputSetEnabled (this, false);
+ gScreen->glPaintCompositedOutputSetEnabled (this, false);
cScreen->donePaintSetEnabled (this, false);
- foreach (CompWindow *w, screen->windows ())
- {
- ww = WaterWindow::get (w);
- ww->gWindow->glDrawTextureSetEnabled (ww, false);
- }
}
cScreen->donePaint ();
@@ -1026,7 +842,6 @@ WaterScreen::handleMotionEvent ()
cScreen->damageScreen ();
}
-
}
static bool
@@ -1056,7 +871,7 @@ waterInitiate (CompAction *action,
p.x = waterLastPointerX = xRoot;
p.y = waterLastPointerY = yRoot;
- ws->waterVertices (GL_POINTS, &p, 1, 0.8f);
+ ws->waterVertices (GL_POINTS, &p, 1, 1.0f);
ws->cScreen->damageScreen ();
}
@@ -1252,7 +1067,7 @@ WaterScreen::optionChange (WaterOptions::Options num)
{
switch (num) {
case WaterOptions::OffsetScale:
- offsetScale = optionGetOffsetScale () * 50.0f;
+ offsetScale = optionGetOffsetScale () * 10.0f;
break;
case WaterOptions::RainDelay:
if (rainTimer.active ())
@@ -1261,6 +1076,15 @@ WaterScreen::optionChange (WaterOptions::Options num)
(float)optionGetRainDelay () * 1.2);
}
break;
+ case WaterOptions::LightVecX:
+ lightVec[0] = optionGetLightVecX();
+ break;
+ case WaterOptions::LightVecY:
+ lightVec[1] = optionGetLightVecY();
+ break;
+ case WaterOptions::LightVecZ:
+ lightVec[2] = optionGetLightVecZ();
+ break;
default:
break;
}
@@ -1271,21 +1095,20 @@ WaterScreen::WaterScreen (CompScreen *screen) :
cScreen (CompositeScreen::get (screen)),
gScreen (GLScreen::get (screen)),
grabIndex (0),
- width (0),
- height (0),
- program (0),
+ oldFbo (NULL),
+ fboIndex (0),
+ useFbo (true),
+
+ texWidth (0),
+ texHeight (0),
- tIndex (0),
target (0),
tx (0),
ty (0),
count (0),
- fbo (0),
- fboStatus (0),
-
data (NULL),
d0 (NULL),
d1 (NULL),
@@ -1293,20 +1116,22 @@ WaterScreen::WaterScreen (CompScreen *screen) :
wiperAngle (0),
wiperSpeed (0),
-
- bumpMapFunctions ()
+ lightVec(GLVector(optionGetLightVecX(),
+ optionGetLightVecY(),
+ optionGetLightVecZ()))
{
- offsetScale = optionGetOffsetScale () * 50.0f;
-
- memset (texture, 0, sizeof (GLuint) * TEXTURE_NUM);
+ offsetScale = optionGetOffsetScale () * 10.0f;
wiperTimer.setCallback (boost::bind (&WaterScreen::wiperTimeout, this));
rainTimer.setCallback (boost::bind (&WaterScreen::rainTimeout, this));
- waterReset ();
+ waterSetup ();
optionSetOffsetScaleNotify (boost::bind (&WaterScreen::optionChange, this, _2));
- optionSetRainDelayNotify (boost::bind (&WaterScreen::optionChange, this, _2));
+ optionSetRainDelayNotify (boost::bind (&WaterScreen::optionChange, this, _2));
+ optionSetLightVecXNotify (boost::bind (&WaterScreen::optionChange, this, _2));
+ optionSetLightVecYNotify (boost::bind (&WaterScreen::optionChange, this, _2));
+ optionSetLightVecZNotify (boost::bind (&WaterScreen::optionChange, this, _2));
optionSetInitiateKeyInitiate (waterInitiate);
optionSetInitiateKeyTerminate (waterTerminate);
@@ -1318,29 +1143,28 @@ WaterScreen::WaterScreen (CompScreen *screen) :
ScreenInterface::setHandler (screen, false);
CompositeScreenInterface::setHandler (cScreen, false);
+ GLScreenInterface::setHandler (gScreen, false);
}
WaterScreen::~WaterScreen ()
{
- if (fbo)
- GL::deleteFramebuffers (1, &fbo);
+ if (program[SET])
+ delete program[SET];
- for (unsigned int i = 0; i < TEXTURE_NUM; i++)
+ if (program[UPDATE])
+ delete program[UPDATE];
+
+ if (program[PAINT])
+ delete program[PAINT];
+
+ for (int i = 0; i < TEXTURE_NUM; i++)
{
- if (texture[i])
- glDeleteTextures (1, &texture[i]);
+ if (waterFbo[i])
+ delete waterFbo[i];
}
- if (program)
- GL::deletePrograms (1, &program);
-
if (data)
free (data);
-
- foreach (WaterFunction &f, bumpMapFunctions)
- {
- GLFragment::destroyFragmentFunction (f.id);
- }
}
bool
diff --git a/plugins/water/src/water.h b/plugins/water/src/water.h
index 5b48159..83ec3b3 100644
--- a/plugins/water/src/water.h
+++ b/plugins/water/src/water.h
@@ -21,6 +21,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Author: David Reveman <davidr@novell.com>
+ * Frederic Plourde <frederic.plourde@collabora.co.uk>
*/
#include <stdio.h>
@@ -36,6 +37,8 @@
#include <composite/composite.h>
#include <opengl/opengl.h>
+#include <opengl/framebufferobject.h>
+#include "shaders.h"
#include "water_options.h"
@@ -46,27 +49,22 @@
#define K 0.1964f
-#define TEXTURE_NUM 3
+#define TEXTURE_NUM 3
+#define PROG_NUM 3
-#define TINDEX(ws, i) (((ws)->tIndex + (i)) % TEXTURE_NUM)
+#define INDEX(ws, i) (((ws)->fboIndex + (i)) % TEXTURE_NUM)
-#define WATER_INITIATE_MODIFIERS_DEFAULT (ControlMask | CompSuperMask)
-
-struct WaterFunction {
- GLFragment::FunctionId id;
-
- int target;
- int param;
- int unit;
-};
+enum programTypes { SET, UPDATE, PAINT};
class WaterScreen :
public ScreenInterface,
+ public GLScreenInterface,
public CompositeScreenInterface,
public PluginClassHandler<WaterScreen,CompScreen>,
public WaterOptions
{
public:
+
WaterScreen (CompScreen *screen);
~WaterScreen ();
@@ -74,34 +72,34 @@ class WaterScreen :
void handleEvent (XEvent *);
+ void glPaintCompositedOutput (const CompRegion &tmpRegion,
+ GLFramebufferObject *scratchFbo,
+ bool partialRepaint);
void preparePaint (int);
void donePaint ();
- GLFragment::FunctionId
- getBumpMapFragmentFunction (GLTexture *texture,
- int unit,
- int param);
-
- void allocTexture (int index);
-
- bool fboPrologue (int tIndex);
+ bool fboPrologue (int fboIndex);
void fboEpilogue ();
- bool fboUpdate (float dt, float fade);
+ bool fboUpdate (float dt, float fade);
bool fboVertices (GLenum type, XPoint *p, int n, float v);
+ #ifndef USE_GLES
+ void allocTexture (int index);
+
void softwareUpdate (float dt, float fade);
void softwarePoints (XPoint *p, int n, float add);
- void softwareLines (XPoint *p, int n, float v);
+ void softwareLines (XPoint *p, int n, float v);
void softwareVertices (GLenum type, XPoint *p, int n, float v);
+ #endif
- void waterUpdate (float dt);
+ void waterUpdate (float dt);
void scaleVertices (XPoint *p, int n);
void waterVertices (GLenum type, XPoint *p, int n, float v);
bool rainTimeout ();
bool wiperTimeout ();
- void waterReset ();
+ void waterSetup ();
void handleMotionEvent ();
@@ -112,20 +110,31 @@ class WaterScreen :
CompScreen::GrabHandle grabIndex;
- int width, height;
+ GLProgram *program[PROG_NUM];
+ GLVertexBuffer *vertexBuffer[PROG_NUM];
- GLuint program;
+ static GLfloat vertexData[18];
+
+ static GLfloat textureData[12];
+
+ GLFramebufferObject *waterFbo[TEXTURE_NUM];
+
+ #ifndef USE_GLES
GLuint texture[TEXTURE_NUM];
+ #endif
- int tIndex;
+ GLFramebufferObject *oldFbo;
+ GLint oldViewport[4];
+ int fboIndex;
+ bool useFbo;
+
+ //GLTexture *textdure[TEXTURE_NUM];
+ int texWidth, texHeight;
GLenum target;
GLfloat tx, ty;
int count;
- GLuint fbo;
- GLint fboStatus;
-
void *data;
float *d0;
float *d1;
@@ -137,35 +146,11 @@ class WaterScreen :
float wiperAngle;
float wiperSpeed;
- std::vector<WaterFunction> bumpMapFunctions;
-};
-
-class WaterWindow :
- public GLWindowInterface,
- public PluginClassHandler<WaterWindow,CompWindow>
-{
- public:
- WaterWindow (CompWindow *window) :
- PluginClassHandler<WaterWindow,CompWindow> (window),
- window (window),
- gWindow (GLWindow::get (window)),
- wScreen (WaterScreen::get (screen)),
- gScreen (GLScreen::get (screen))
- {
- GLWindowInterface::setHandler (gWindow, false);
- }
-
- void glDrawTexture (GLTexture *texture, GLFragment::Attrib &,
- unsigned int);
-
- CompWindow *window;
- GLWindow *gWindow;
- WaterScreen *wScreen;
- GLScreen *gScreen;
+ GLVector lightVec;
};
class WaterPluginVTable :
- public CompPlugin::VTableForScreenAndWindow<WaterScreen,WaterWindow>
+ public CompPlugin::VTableForScreen<WaterScreen>
{
public:
diff --git a/plugins/water/water.xml.in b/plugins/water/water.xml.in
index 4171ed3..c74aa7c 100644
--- a/plugins/water/water.xml.in
+++ b/plugins/water/water.xml.in
@@ -46,6 +46,30 @@
<min>1</min>
<max>3600000</max>
</option>
+ <option name="light_vec_x" type="float">
+ <_short>lightVec X</_short>
+ <_long>Light vector X coordinate</_long>
+ <default>1.0</default>
+ <min>-1</min>
+ <max>1</max>
+ <precision>0.1</precision>
+ </option>
+ <option name="light_vec_y" type="float">
+ <_short>lightVec Y</_short>
+ <_long>Light vector Y coordinate</_long>
+ <default>1.0</default>
+ <min>-1</min>
+ <max>1</max>
+ <precision>0.1</precision>
+ </option>
+ <option name="light_vec_z" type="float">
+ <_short>lightVec Z</_short>
+ <_long>Light vector Z coordinate</_long>
+ <default>1.0</default>
+ <min>0.1</min>
+ <max>1</max>
+ <precision>0.1</precision>
+ </option>
<option name="title_wave" type="bell">
<_short>Title wave</_short>
<_long>Wave effect from window title</_long>