Beispiel #1
0
static Bool
waterToggleWiper (CompDisplay     *d,
		  CompAction      *action,
		  CompActionState state,
		  CompOption      *option,
		  int	          nOption)
{
    CompScreen *s;

    s = findScreenAtDisplay (d, getIntOptionNamed (option, nOption, "root", 0));
    if (s)
    {
	WATER_SCREEN (s);

	if (!ws->wiperHandle)
	{
	    ws->wiperHandle = compAddTimeout (2000, 2400, waterWiperTimeout, s);
	}
	else
	{
	    compRemoveTimeout (ws->wiperHandle);
	    ws->wiperHandle = 0;
	}
    }

    return FALSE;
}
Beispiel #2
0
static bool
waterLine (CompAction         *action,
	   CompAction::State  state,
	   CompOption::Vector &options)
{
    XPoint p[2];
    float  amp;

    WATER_SCREEN (screen);

    p[0].x = CompOption::getIntOptionNamed (options, "x0",
					    screen->width () / 4);
    p[0].y = CompOption::getIntOptionNamed (options, "y0",
					    screen->height () / 2);

    p[1].x = CompOption::getIntOptionNamed (options, "x1",
					    screen->width () -
					    screen->width () / 4);
    p[1].y = CompOption::getIntOptionNamed (options, "y1",
					    screen->height () / 2);

    amp = CompOption::getFloatOptionNamed (options, "amplitude", 0.25f);

    ws->waterVertices (GL_LINES, p, 2, amp);

    ws->cScreen->damageScreen ();

    return false;
}
Beispiel #3
0
static void
waterHandleMotionEvent (CompDisplay *d,
			Window	    root)
{
    CompScreen *s;

    s = findScreenAtDisplay (d, root);
    if (s)
    {
	WATER_SCREEN (s);

	if (ws->grabIndex)
	{
	    XPoint p[2];

	    p[0].x = waterLastPointerX;
	    p[0].y = waterLastPointerY;

	    p[1].x = waterLastPointerX = pointerX;
	    p[1].y = waterLastPointerY = pointerY;

	    waterVertices (s, GL_LINES, p, 2, 0.2f);

	    damageScreen (s);
	}
    }
}
Beispiel #4
0
static bool
waterTitleWave (CompAction         *action,
		CompAction::State  state,
		CompOption::Vector &options)
{
    CompWindow *w;
    int	       xid;

    WATER_SCREEN (screen);

    xid = CompOption::getIntOptionNamed (options, "window",
					 screen->activeWindow ());

    w = screen->findWindow (xid);
    if (w)
    {
	const CompWindow::Geometry &g = w->geometry ();
	XPoint p[2];

	p[0].x = g.x () - w->border ().left;
	p[0].y = g.y () - w->border ().top / 2;

	p[1].x = g.x () + g.width () + w->border ().right;
	p[1].y = p[0].y;

	ws->waterVertices (GL_LINES, p, 2, 0.15f);

	ws->cScreen->damageScreen ();
    }

    return false;
}
Beispiel #5
0
static void
softwarePoints (CompScreen *s,
		XPoint	   *p,
		int	   n,
		float	   add)
{
    WATER_SCREEN (s);

    while (n--)
    {
	SET (p->x - 1, p->y - 1, add);
	SET (p->x, p->y - 1, add);
	SET (p->x + 1, p->y - 1, add);

	SET (p->x - 1, p->y, add);
	SET (p->x, p->y, add);
	SET (p->x + 1, p->y, add);

	SET (p->x - 1, p->y + 1, add);
	SET (p->x, p->y + 1, add);
	SET (p->x + 1, p->y + 1, add);

	p++;
    }
}
Beispiel #6
0
static Bool
waterToggleRain(CompDisplay * d,
		CompAction * action,
		CompActionState state, CompOption * option, int nOption)
{
	CompScreen *s;

	WATER_DISPLAY(d);

	s = findScreenAtDisplay(d,
				getIntOptionNamed(option, nOption, "root", 0));
	if (s) {
		WATER_SCREEN(s);

		if (!ws->rainHandle) {
			int delay;

			delay =
			    wd->opt[WATER_DISPLAY_OPTION_RAIN_DELAY].value.i;
			ws->rainHandle =
			    compAddTimeout(delay, (float)delay * 1.2,
					   waterRainTimeout, s);
		} else {
			compRemoveTimeout(ws->rainHandle);
			ws->rainHandle = 0;
		}
	}

	return FALSE;
}
Beispiel #7
0
static void
allocTexture (CompScreen *s,
	      int	 index)
{
    WATER_SCREEN (s);

    glGenTextures (1, &ws->texture[index]);
    glBindTexture (ws->target, ws->texture[index]);

    glTexParameteri (ws->target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri (ws->target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri (ws->target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri (ws->target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

    glTexImage2D (ws->target,
		  0,
		  GL_RGBA,
		  ws->width,
		  ws->height,
		  0,
		  GL_BGRA,

#if IMAGE_BYTE_ORDER == MSBFirst
		  GL_UNSIGNED_INT_8_8_8_8_REV,
#else
		  GL_UNSIGNED_BYTE,
#endif

		  ws->t0);

    glBindTexture (ws->target, 0);
}
Beispiel #8
0
static bool
waterToggleRain (CompAction         *action,
		 CompAction::State  state,
		 CompOption::Vector &options)
{
    /* Remember StateCancel and StateCommit will be broadcast to all actions
       so we need to verify that we are actually being toggled... */
    if (!(state & CompAction::StateTermKey))
        return false;
    /* And only respond to key taps */
    if (!(state & CompAction::StateTermTapped))
        return false;

    WATER_SCREEN (screen);

    if (!ws->rainTimer.active ())
    {
	int delay;

	delay = ws->optionGetRainDelay ();
	ws->rainTimer.start (delay, (float) delay * 1.2);
    }
    else
    {
	ws->rainTimer.stop ();
    }

    return false;
}
Beispiel #9
0
static int fboVertices(CompScreen * s, GLenum type, XPoint * p, int n, float v)
{
	WATER_SCREEN(s);

	if (!fboPrologue(s, TINDEX(ws, 0)))
		return 0;

	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 / ws->width, 1.0f / ws->height, 1.0);
	glTranslatef(0.5f, 0.5f, 0.0f);

	glBegin(type);

	while (n--) {
		glVertex2i(p->x, p->y);
		p++;
	}

	glEnd();

	glColor4usv(defaultColor);
	glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);

	fboEpilogue(s);

	return 1;
}
Beispiel #10
0
static void scaleVertices(CompScreen * s, XPoint * p, int n)
{
	WATER_SCREEN(s);

	while (n--) {
		p[n].x = (ws->width * p[n].x) / s->width;
		p[n].y = (ws->height * p[n].y) / s->height;
	}
}
Beispiel #11
0
static void waterReset(CompScreen * s)
{
	int size, i, j;

	WATER_SCREEN(s);

	ws->height = TEXTURE_SIZE;
	ws->width = (ws->height * s->width) / s->height;

	if (s->textureNonPowerOfTwo ||
	    (POWER_OF_TWO(ws->width) && POWER_OF_TWO(ws->height))) {
		ws->target = GL_TEXTURE_2D;
		ws->tx = ws->ty = 1.0f;
	} else {
		ws->target = GL_TEXTURE_RECTANGLE_NV;
		ws->tx = ws->width;
		ws->ty = ws->height;
	}

	if (!s->fragmentProgram)
		return;

	if (s->fbo) {
		loadWaterProgram(s);
		if (!ws->fbo)
			(*s->genFramebuffers) (1, &ws->fbo);
	}

	ws->fboStatus = 0;

	for (i = 0; i < TEXTURE_NUM; i++) {
		if (ws->texture[i]) {
			glDeleteTextures(1, &ws->texture[i]);
			ws->texture[i] = 0;
		}
	}

	if (ws->data)
		free(ws->data);

	size = (ws->width + 2) * (ws->height + 2);

	ws->data = calloc(1, (sizeof(float) * size * 2) +
			  (sizeof(GLubyte) * ws->width * ws->height * 4));
	if (!ws->data)
		return;

	ws->d0 = ws->data;
	ws->d1 = (ws->d0 + (size));
	ws->t0 = (unsigned char *)(ws->d1 + (size));

	for (i = 0; i < ws->height; i++) {
		for (j = 0; j < ws->width; j++) {
			(ws->t0 + (ws->width * 4 * i + j * 4))[0] = 0xff;
		}
	}
}
Beispiel #12
0
static void waterDonePaintScreen(CompScreen * s)
{
	WATER_SCREEN(s);

	if (ws->count)
		damageScreen(s);

	UNWRAP(ws, s, donePaintScreen);
	(*s->donePaintScreen) (s);
	WRAP(ws, s, donePaintScreen, waterDonePaintScreen);
}
Beispiel #13
0
static int
fboPrologue (CompScreen *s,
	     int	tIndex)
{
    WATER_SCREEN (s);

    if (!ws->fbo)
	return 0;

    if (!ws->texture[tIndex])
	allocTexture (s, tIndex);

    (*s->bindFramebuffer) (GL_FRAMEBUFFER_EXT, ws->fbo);

    (*s->framebufferTexture2D) (GL_FRAMEBUFFER_EXT,
				GL_COLOR_ATTACHMENT0_EXT,
				ws->target, ws->texture[tIndex],
				0);

    glDrawBuffer (GL_COLOR_ATTACHMENT0_EXT);
    glReadBuffer (GL_COLOR_ATTACHMENT0_EXT);

    /* check status the first time */
    if (!ws->fboStatus)
    {
	ws->fboStatus = (*s->checkFramebufferStatus) (GL_FRAMEBUFFER_EXT);
	if (ws->fboStatus != GL_FRAMEBUFFER_COMPLETE_EXT)
	{
	    compLogMessage ("water", CompLogLevelError,
			    "framebuffer incomplete");

	    (*s->bindFramebuffer) (GL_FRAMEBUFFER_EXT, 0);
	    (*s->deleteFramebuffers) (1, &ws->fbo);

	    glDrawBuffer (GL_BACK);
	    glReadBuffer (GL_BACK);

	    ws->fbo = 0;

	    return 0;
	}
    }

    glViewport (0, 0, ws->width, ws->height);
    glMatrixMode (GL_PROJECTION);
    glPushMatrix ();
    glLoadIdentity ();
    glOrtho (0.0, 1.0, 0.0, 1.0, -1.0, 1.0);
    glMatrixMode (GL_MODELVIEW);
    glPushMatrix ();
    glLoadIdentity ();

    return 1;
}
Beispiel #14
0
static Bool
waterSetDisplayOption (CompPlugin      *plugin,
		       CompDisplay     *display,
		       const char      *name,
		       CompOptionValue *value)
{
    CompOption *o;
    int	       index;

    WATER_DISPLAY (display);

    o = compFindOption (wd->opt, NUM_OPTIONS (wd), name, &index);
    if (!o)
	return FALSE;

    switch (index) {
    case WATER_DISPLAY_OPTION_OFFSET_SCALE:
	if (compSetFloatOption (o, value))
	{
	    wd->offsetScale = o->value.f * 50.0f;
	    return TRUE;
	}
	break;
    case WATER_DISPLAY_OPTION_RAIN_DELAY:
	if (compSetIntOption (o, value))
	{
	    CompScreen *s;

	    for (s = display->screens; s; s = s->next)
	    {
		WATER_SCREEN (s);

		if (!ws->rainHandle)
		    continue;

		compRemoveTimeout (ws->rainHandle);
		ws->rainHandle = compAddTimeout (value->i,
						 (float)value->i * 1.2,
						 waterRainTimeout, s);
	    }
	    return TRUE;
	}
	break;
    default:
	return compSetDisplayOption (display, o, value);
    }

    return FALSE;
}
Beispiel #15
0
static Bool waterWiperTimeout(void *closure)
{
	CompScreen *s = closure;

	WATER_SCREEN(s);

	if (ws->count) {
		if (ws->wiperAngle == 0.0f)
			ws->wiperSpeed = 2.5f;
		else if (ws->wiperAngle == 180.0f)
			ws->wiperSpeed = -2.5f;
	}

	return TRUE;
}
Beispiel #16
0
static bool
waterTerminate (CompAction         *action,
	        CompAction::State  state,
	        CompOption::Vector &options)
{
    WATER_SCREEN (screen);

    if (ws->grabIndex)
    {
	screen->removeGrab (ws->grabIndex, 0);
	ws->grabIndex = 0;
	screen->handleEventSetEnabled (ws, false);
    }

    return false;
}
Beispiel #17
0
static void waterUpdate(CompScreen * s, float dt)
{
	GLfloat fade = 1.0f;

	WATER_SCREEN(s);

	if (ws->count < 1000) {
		if (ws->count > 1)
			fade = 0.90f + ws->count / 10000.0f;
		else
			fade = 0.0f;
	}

	if (!fboUpdate(s, dt, fade))
		softwareUpdate(s, dt, fade);
}
Beispiel #18
0
static void
waterVertices(CompScreen * s, GLenum type, XPoint * p, int n, float v)
{
	WATER_SCREEN(s);

	if (!s->fragmentProgram)
		return;

	scaleVertices(s, p, n);

	if (!fboVertices(s, type, p, n, v))
		softwareVertices(s, type, p, n, v);

	if (ws->count < 3000)
		ws->count = 3000;
}
Beispiel #19
0
static void
waterFiniScreen (CompPlugin *p,
		 CompScreen *s)
{
    WaterFunction *function, *next;
    int		  i;

    WATER_SCREEN (s);

    if (ws->rainHandle)
	compRemoveTimeout (ws->rainHandle);

    if (ws->wiperHandle)
	compRemoveTimeout (ws->wiperHandle);

    if (ws->fbo)
	(*s->deleteFramebuffers) (1, &ws->fbo);

    for (i = 0; i < TEXTURE_NUM; i++)
    {
	if (ws->texture[i])
	    glDeleteTextures (1, &ws->texture[i]);
    }

    if (ws->program)
	(*s->deletePrograms) (1, &ws->program);

    if (ws->data)
	free (ws->data);

    function = ws->bumpMapFunctions;
    while (function)
    {
	destroyFragmentFunction (s, function->handle);

	next = function->next;
	free (function);
	function = next;
    }

    UNWRAP (ws, s, preparePaintScreen);
    UNWRAP (ws, s, donePaintScreen);
    UNWRAP (ws, s, drawWindowTexture);

    free (ws);
}
Beispiel #20
0
static bool
waterToggleWiper (CompAction         *action,
		  CompAction::State  state,
		  CompOption::Vector &options)
{
    WATER_SCREEN (screen);

    if (!ws->wiperTimer.active ())
    {
	ws->wiperTimer.start (2000, 2400);
    }
    else
    {
	ws->wiperTimer.stop ();
    }

    return false;
}
Beispiel #21
0
static Bool
waterTerminate(CompDisplay * d,
	       CompAction * action,
	       CompActionState state, CompOption * option, int nOption)
{
	CompScreen *s;

	for (s = d->screens; s; s = s->next) {
		WATER_SCREEN(s);

		if (ws->grabIndex) {
			removeScreenGrab(s, ws->grabIndex, 0);
			ws->grabIndex = 0;
		}
	}

	return FALSE;
}
Beispiel #22
0
static Bool
waterInitiate (CompDisplay     *d,
	       CompAction      *action,
	       CompActionState state,
	       CompOption      *option,
	       int	       nOption)
{
    CompScreen   *s;
    unsigned int ui;
    Window	 root, child;
    int	         xRoot, yRoot, i;

    for (s = d->screens; s; s = s->next)
    {
	WATER_SCREEN (s);

	if (otherScreenGrabExist (s, "water", NULL))
	    continue;

	if (!ws->grabIndex)
	    ws->grabIndex = pushScreenGrab (s, None, "water");

	if (XQueryPointer (d->display, s->root, &root, &child, &xRoot, &yRoot,
			   &i, &i, &ui))
	{
	    XPoint p;

	    p.x = waterLastPointerX = xRoot;
	    p.y = waterLastPointerY = yRoot;

	    waterVertices (s, GL_POINTS, &p, 1, 0.8f);

	    damageScreen (s);
	}
    }

    if (state & CompActionStateInitButton)
	action->state |= CompActionStateTermButton;

    if (state & CompActionStateInitKey)
	action->state |= CompActionStateTermKey;

    return FALSE;
}
Beispiel #23
0
static int loadWaterProgram(CompScreen * s)
{
	char buffer[1024];

	WATER_SCREEN(s);

	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(s, &ws->program, buffer);
}
Beispiel #24
0
static bool
waterInitiate (CompAction         *action,
	       CompAction::State  state,
	       CompOption::Vector &options)
{
    unsigned int ui;
    Window	 root, child;
    int	         xRoot, yRoot, i;

    WATER_SCREEN (screen);

    if (!screen->otherGrabExist ("water", NULL))
    {
	if (!ws->grabIndex)
	{
	    ws->grabIndex = screen->pushGrab (None, "water");
	    screen->handleEventSetEnabled (ws, true);
	}

	if (XQueryPointer (screen->dpy (), screen->root (), &root, &child,
			   &xRoot, &yRoot, &i, &i, &ui))
	{
	    XPoint p;

	    p.x = waterLastPointerX = xRoot;
	    p.y = waterLastPointerY = yRoot;

 	    ws->waterVertices (GL_POINTS, &p, 1, 1.0f);

	    ws->cScreen->damageScreen ();
	}
    }

    if (state & CompAction::StateInitButton)
	action->setState (action->state () | CompAction::StateTermButton);

    if (state & CompAction::StateInitKey)
	action->setState (action->state () | CompAction::StateTermKey);

    return false;
}
Beispiel #25
0
static void
waterHandleEvent (CompDisplay *d,
		  XEvent      *event)
{
    CompScreen *s;

    WATER_DISPLAY (d);

    switch (event->type) {
    case ButtonPress:
	s = findScreenAtDisplay (d, event->xbutton.root);
	if (s)
	{
	    WATER_SCREEN (s);

	    if (ws->grabIndex)
	    {
		XPoint p;

		p.x = pointerX;
		p.y = pointerY;

		waterVertices (s, GL_POINTS, &p, 1, 0.8f);
		damageScreen (s);
	    }
	}
	break;
    case EnterNotify:
    case LeaveNotify:
	waterHandleMotionEvent (d, event->xcrossing.root);
	break;
    case MotionNotify:
	waterHandleMotionEvent (d, event->xmotion.root);
    default:
	break;
    }

    UNWRAP (wd, d, handleEvent);
    (*d->handleEvent) (d, event);
    WRAP (wd, d, handleEvent, waterHandleEvent);
}
Beispiel #26
0
static bool
waterPoint (CompAction         *action,
	    CompAction::State  state,
	    CompOption::Vector &options)
{
    XPoint p;
    float  amp;

    WATER_SCREEN (screen);

    p.x = CompOption::getIntOptionNamed (options, "x",
					 screen->width () / 2);
    p.y = CompOption::getIntOptionNamed (options, "y",
					 screen->height () / 2);

    amp = CompOption::getFloatOptionNamed (options, "amplitude", 0.5f);

    ws->waterVertices (GL_POINTS, &p, 1, amp);

    ws->cScreen->damageScreen ();

    return false;
}
Beispiel #27
0
/* bresenham */
static void softwareLines(CompScreen * s, XPoint * p, int n, float v)
{
	int x1, y1, x2, y2;
	Bool steep;
	int tmp;
	int deltaX, deltaY;
	int error = 0;
	int yStep;
	int x, y;

	WATER_SCREEN(s);

#define SWAP(v0, v1) \
    tmp = v0;	     \
    v0 = v1;	     \
    v1 = tmp

	while (n > 1) {
		x1 = p->x;
		y1 = p->y;

		p++;
		n--;

		x2 = p->x;
		y2 = p->y;

		p++;
		n--;

		steep = abs(y2 - y1) > abs(x2 - x1);
		if (steep) {
			SWAP(x1, y1);
			SWAP(x2, y2);
		}

		if (x1 > x2) {
			SWAP(x1, x2);
			SWAP(y1, y2);
		}
#undef SWAP

		deltaX = x2 - x1;
		deltaY = abs(y2 - y1);

		y = y1;
		if (y1 < y2)
			yStep = 1;
		else
			yStep = -1;

		for (x = x1; x <= x2; x++) {
			if (steep) {
				SET(y, x, v);
			} else {
				SET(x, y, v);
			}

			error += deltaY;
			if (2 * error >= deltaX) {
				y += yStep;
				error -= deltaX;
			}
		}
	}
}
Beispiel #28
0
static void
waterDrawWindowTexture(CompWindow * w,
		       CompTexture * texture,
		       const FragmentAttrib * attrib, unsigned int mask)
{
	WATER_SCREEN(w->screen);

	if (ws->count) {
		FragmentAttrib fa = *attrib;
		Bool lighting = w->screen->lighting;
		int param, function, unit;
		GLfloat plane[4];

		WATER_DISPLAY(w->screen->display);

		param = allocFragmentParameters(&fa, 1);
		unit = allocFragmentTextureUnits(&fa, 1);

		function =
		    getBumpMapFragmentFunction(w->screen, texture, unit, param);
		if (function) {
			addFragmentFunction(&fa, function);

			screenLighting(w->screen, TRUE);

			(*w->screen->activeTexture) (GL_TEXTURE0_ARB + unit);

			glBindTexture(ws->target, ws->texture[TINDEX(ws, 0)]);

			plane[1] = plane[2] = 0.0f;
			plane[0] = ws->tx / (GLfloat) w->screen->width;
			plane[3] = 0.0f;

			glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
			glTexGenfv(GL_S, GL_EYE_PLANE, plane);
			glEnable(GL_TEXTURE_GEN_S);

			plane[0] = plane[2] = 0.0f;
			plane[1] = ws->ty / (GLfloat) w->screen->height;
			plane[3] = 0.0f;

			glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
			glTexGenfv(GL_T, GL_EYE_PLANE, plane);
			glEnable(GL_TEXTURE_GEN_T);

			(*w->screen->activeTexture) (GL_TEXTURE0_ARB);

			(*w->screen->
			 programEnvParameter4f) (GL_FRAGMENT_PROGRAM_ARB, param,
						 texture->matrix.yy *
						 wd->offsetScale,
						 -texture->matrix.xx *
						 wd->offsetScale, 0.0f, 0.0f);
		}

		/* to get appropriate filtering of texture */
		mask |= PAINT_WINDOW_ON_TRANSFORMED_SCREEN_MASK;

		UNWRAP(ws, w->screen, drawWindowTexture);
		(*w->screen->drawWindowTexture) (w, texture, &fa, mask);
		WRAP(ws, w->screen, drawWindowTexture, waterDrawWindowTexture);

		if (function) {
			(*w->screen->activeTexture) (GL_TEXTURE0_ARB + unit);
			glDisable(GL_TEXTURE_GEN_T);
			glDisable(GL_TEXTURE_GEN_S);
			glBindTexture(ws->target, 0);
			(*w->screen->activeTexture) (GL_TEXTURE0_ARB);

			screenLighting(w->screen, lighting);
		}
	} else {
		UNWRAP(ws, w->screen, drawWindowTexture);
		(*w->screen->drawWindowTexture) (w, texture, attrib, mask);
		WRAP(ws, w->screen, drawWindowTexture, waterDrawWindowTexture);
	}
}
Beispiel #29
0
static void softwareUpdate(CompScreen * s, float dt, float fade)
{
	float *dTmp;
	int i, j;
	float v0, v1, inv;
	float accel, value;
	unsigned char *t0, *t;
	int dWidth, dHeight;
	float *d01, *d10, *d11, *d12;

	WATER_SCREEN(s);

	if (!ws->texture[TINDEX(ws, 0)])
		allocTexture(s, TINDEX(ws, 0));

	dt *= K * 2.0f;
	fade *= 0.99f;

	dWidth = ws->width + 2;
	dHeight = ws->height + 2;

#define D(d, j) (*((d) + (j)))

	d01 = ws->d0 + dWidth;
	d10 = ws->d1;
	d11 = d10 + dWidth;
	d12 = d11 + dWidth;

	for (i = 1; i < dHeight - 1; i++) {
		for (j = 1; j < dWidth - 1; j++) {
			accel = dt * (D(d10, j) +
				      D(d12, j) +
				      D(d11, j - 1) +
				      D(d11, j + 1) - 4.0f * D(d11, j));

			value = (2.0f * D(d11, j) - D(d01, j) + accel) * fade;

			CLAMP(value, 0.0f, 1.0f);

			D(d01, j) = value;
		}

		d01 += dWidth;
		d10 += dWidth;
		d11 += dWidth;
		d12 += dWidth;
	}

	/* update border */
	memcpy(ws->d0, ws->d0 + dWidth, dWidth * sizeof(GLfloat));
	memcpy(ws->d0 + dWidth * (dHeight - 1),
	       ws->d0 + dWidth * (dHeight - 2), dWidth * sizeof(GLfloat));

	d01 = ws->d0 + dWidth;

	for (i = 1; i < dHeight - 1; i++) {
		D(d01, 0) = D(d01, 1);
		D(d01, dWidth - 1) = D(d01, dWidth - 2);

		d01 += dWidth;
	}

	d10 = ws->d1;
	d11 = d10 + dWidth;
	d12 = d11 + dWidth;

	t0 = ws->t0;

	/* update texture */
	for (i = 0; i < ws->height; i++) {
		for (j = 0; j < ws->width; j++) {
			v0 = (D(d12, j) - D(d10, j)) * 1.5f;
			v1 = (D(d11, j - 1) - D(d11, j + 1)) * 1.5f;

			/* 0.5 for scale */
			inv = 0.5f / sqrtf(v0 * v0 + v1 * v1 + 1.0f);

			/* add scale and bias to normal */
			v0 = v0 * inv + 0.5f;
			v1 = v1 * inv + 0.5f;

			/* store normal map in RGB components */
			t = t0 + (j * 4);
			t[0] = (unsigned char)((inv + 0.5f) * 255.0f);
			t[1] = (unsigned char)(v1 * 255.0f);
			t[2] = (unsigned char)(v0 * 255.0f);

			/* store height in A component */
			t[3] = (unsigned char)(D(d11, j) * 255.0f);
		}

		d10 += dWidth;
		d11 += dWidth;
		d12 += dWidth;

		t0 += ws->width * 4;
	}

#undef D

	/* swap height maps */
	dTmp = ws->d0;
	ws->d0 = ws->d1;
	ws->d1 = dTmp;

	if (ws->texture[TINDEX(ws, 0)]) {
		glBindTexture(ws->target, ws->texture[TINDEX(ws, 0)]);
		glTexImage2D(ws->target,
			     0, GL_RGBA, ws->width, ws->height, 0, GL_BGRA,
#if IMAGE_BYTE_ORDER == MSBFirst
			     GL_UNSIGNED_INT_8_8_8_8_REV,
#else
			     GL_UNSIGNED_BYTE,
#endif
			     ws->t0);
	}
}
Beispiel #30
0
/* TODO: a way to control the speed */
static void waterPreparePaintScreen(CompScreen * s, int msSinceLastPaint)
{
	WATER_SCREEN(s);

	if (ws->count) {
		ws->count -= 10;
		if (ws->count < 0)
			ws->count = 0;

		if (ws->wiperHandle) {
			float step, angle0, angle1;
			Bool wipe = FALSE;
			XPoint p[3];

			p[1].x = s->width / 2;
			p[1].y = s->height;

			step = ws->wiperSpeed * msSinceLastPaint / 20.0f;

			if (ws->wiperSpeed > 0.0f) {
				if (ws->wiperAngle < 180.0f) {
					angle0 = ws->wiperAngle;

					ws->wiperAngle += step;
					ws->wiperAngle =
					    MIN(ws->wiperAngle, 180.0f);

					angle1 = ws->wiperAngle;

					wipe = TRUE;
				}
			} else {
				if (ws->wiperAngle > 0.0f) {
					angle1 = ws->wiperAngle;

					ws->wiperAngle += step;
					ws->wiperAngle =
					    MAX(ws->wiperAngle, 0.0f);

					angle0 = ws->wiperAngle;

					wipe = TRUE;
				}
			}

#define TAN(a) (tanf ((a) * (M_PI / 180.0f)))

			if (wipe) {
				if (angle0 > 0.0f) {
					p[2].x =
					    s->width / 2 -
					    s->height / TAN(angle0);
					p[2].y = 0;
				} else {
					p[2].x = 0;
					p[2].y = s->height;
				}

				if (angle1 < 180.0f) {
					p[0].x =
					    s->width / 2 -
					    s->height / TAN(angle1);
					p[0].y = 0;
				} else {
					p[0].x = s->width;
					p[0].y = s->height;
				}

				/* software rasterizer doesn't support triangles yet so wiper
				   effect will only work with FBOs right now */
				waterVertices(s, GL_TRIANGLES, p, 3, 0.0f);
			}
#undef TAN

		}

		waterUpdate(s, 0.8f);
	}

	UNWRAP(ws, s, preparePaintScreen);
	(*s->preparePaintScreen) (s, msSinceLastPaint);
	WRAP(ws, s, preparePaintScreen, waterPreparePaintScreen);
}