From 3589f4e4fe74d0e70e25bac52e19c118bbe1567e Mon Sep 17 00:00:00 2001 From: Roi Cohen Date: Tue, 12 Jun 2007 11:22:47 +0200 Subject: [PATCH] Added cube transparency. --- include/cube.h | 39 ++++++++----- metadata/cube.xml.in | 24 ++++++++ plugins/cube.c | 154 +++++++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 193 insertions(+), 24 deletions(-) diff --git a/include/cube.h b/include/cube.h index 00e5b47..1348e0e 100644 --- a/include/cube.h +++ b/include/cube.h @@ -40,22 +40,25 @@ typedef struct _CubeDisplay { CompOption opt[CUBE_DISPLAY_OPTION_NUM]; } CubeDisplay; -#define CUBE_SCREEN_OPTION_COLOR 0 -#define CUBE_SCREEN_OPTION_IN 1 -#define CUBE_SCREEN_OPTION_SCALE_IMAGE 2 -#define CUBE_SCREEN_OPTION_IMAGES 3 -#define CUBE_SCREEN_OPTION_SKYDOME 4 -#define CUBE_SCREEN_OPTION_SKYDOME_IMG 5 -#define CUBE_SCREEN_OPTION_SKYDOME_ANIM 6 -#define CUBE_SCREEN_OPTION_SKYDOME_GRAD_START 7 -#define CUBE_SCREEN_OPTION_SKYDOME_GRAD_END 8 -#define CUBE_SCREEN_OPTION_ACCELERATION 9 -#define CUBE_SCREEN_OPTION_SPEED 10 -#define CUBE_SCREEN_OPTION_TIMESTEP 11 -#define CUBE_SCREEN_OPTION_MIPMAP 12 -#define CUBE_SCREEN_OPTION_BACKGROUNDS 13 -#define CUBE_SCREEN_OPTION_ADJUST_IMAGE 14 -#define CUBE_SCREEN_OPTION_NUM 15 +#define CUBE_SCREEN_OPTION_COLOR 0 +#define CUBE_SCREEN_OPTION_IN 1 +#define CUBE_SCREEN_OPTION_SCALE_IMAGE 2 +#define CUBE_SCREEN_OPTION_IMAGES 3 +#define CUBE_SCREEN_OPTION_SKYDOME 4 +#define CUBE_SCREEN_OPTION_SKYDOME_IMG 5 +#define CUBE_SCREEN_OPTION_SKYDOME_ANIM 6 +#define CUBE_SCREEN_OPTION_SKYDOME_GRAD_START 7 +#define CUBE_SCREEN_OPTION_SKYDOME_GRAD_END 8 +#define CUBE_SCREEN_OPTION_ACCELERATION 9 +#define CUBE_SCREEN_OPTION_SPEED 10 +#define CUBE_SCREEN_OPTION_TIMESTEP 11 +#define CUBE_SCREEN_OPTION_MIPMAP 12 +#define CUBE_SCREEN_OPTION_BACKGROUNDS 13 +#define CUBE_SCREEN_OPTION_ADJUST_IMAGE 14 +#define CUBE_SCREEN_OPTION_ACTIVE_OPACITY 15 +#define CUBE_SCREEN_OPTION_INACTIVE_OPACITY 16 +#define CUBE_SCREEN_OPTION_FADE_TIME 17 +#define CUBE_SCREEN_OPTION_NUM 18 typedef void (*CubeGetRotationProc) (CompScreen *s, float *x, @@ -83,6 +86,7 @@ typedef struct _CubeScreen { PaintOutputProc paintOutput; PaintTransformedOutputProc paintTransformedOutput; PaintBackgroundProc paintBackground; + PaintWindowProc paintWindow; ApplyScreenTransformProc applyScreenTransform; SetScreenOptionProc setScreenOption; OutputChangeNotifyProc outputChangeNotify; @@ -133,6 +137,9 @@ typedef struct _CubeScreen { float outputXOffset; float outputYOffset; + float desktopOpacity; + float toOpacity; + CompTexture *bg; int nBg; } CubeScreen; diff --git a/metadata/cube.xml.in b/metadata/cube.xml.in index 0f674e7..23d93e0 100644 --- a/metadata/cube.xml.in +++ b/metadata/cube.xml.in @@ -134,6 +134,30 @@ <_long>Adjust top face image to rotation false + + + diff --git a/plugins/cube.c b/plugins/cube.c index 3e8b99d..3f43723 100644 --- a/plugins/cube.c +++ b/plugins/cube.c @@ -798,6 +798,8 @@ static void cubePreparePaintScreen (CompScreen *s, int msSinceLastPaint) { + int opt; + CUBE_SCREEN (s); if (cs->grabIndex) @@ -836,10 +838,38 @@ cubePreparePaintScreen (CompScreen *s, memset (cs->cleared, 0, sizeof (Bool) * s->nOutputDev); + /* Transparency handling */ + if (cs->xRotations != 0.0f) + opt = CUBE_SCREEN_OPTION_ACTIVE_OPACITY; + else + opt = CUBE_SCREEN_OPTION_INACTIVE_OPACITY; + + cs->toOpacity = (cs->opt[opt].value.f / 100.0f) * OPAQUE; + + if (cs->opt[CUBE_SCREEN_OPTION_FADE_TIME].value.f == 0.0f) + cs->desktopOpacity = cs->toOpacity; + else if (cs->desktopOpacity != cs->toOpacity) + { + float steps = (msSinceLastPaint * OPAQUE / 1000.0) / + cs->opt[CUBE_SCREEN_OPTION_FADE_TIME].value.f; + if (steps < 12) + steps = 12; + + if (cs->toOpacity > cs->desktopOpacity) + { + cs->desktopOpacity += steps; + cs->desktopOpacity = MIN (cs->toOpacity, cs->desktopOpacity); + } + if (cs->toOpacity < cs->desktopOpacity) + { + cs->desktopOpacity -= steps; + cs->desktopOpacity = MAX (cs->toOpacity, cs->desktopOpacity); + } + } + UNWRAP (cs, s, preparePaintScreen); (*s->preparePaintScreen) (s, msSinceLastPaint); WRAP (cs, s, preparePaintScreen, cubePreparePaintScreen); - } static Bool @@ -854,7 +884,7 @@ cubePaintOutput (CompScreen *s, CUBE_SCREEN (s); - if (cs->grabIndex) + if (cs->grabIndex || cs->desktopOpacity != OPAQUE) { mask &= ~PAINT_SCREEN_REGION_MASK; mask |= PAINT_SCREEN_TRANSFORMED_MASK; @@ -876,7 +906,7 @@ cubeDonePaintScreen (CompScreen *s) { CUBE_SCREEN (s); - if (cs->grabIndex) + if (cs->grabIndex || cs->desktopOpacity != cs->toOpacity) damageScreen (s); UNWRAP (cs, s, donePaintScreen); @@ -1161,7 +1191,7 @@ cubePaintTopBottom (CompScreen *s, screenLighting (s, TRUE); - glColor3usv (cs->color); + glColor4us (cs->color[0], cs->color[1], cs->color[2], cs->desktopOpacity); glPushMatrix (); @@ -1175,6 +1205,13 @@ cubePaintTopBottom (CompScreen *s, glTranslatef (cs->outputXOffset, -cs->outputYOffset, 0.0f); glScalef (cs->outputXScale, cs->outputYScale, 1.0f); + if (cs->desktopOpacity != OPAQUE) + { + screenTexEnvMode (s, GL_MODULATE); + glEnable (GL_BLEND); + glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + } + glVertexPointer (3, GL_FLOAT, 0, cs->vertices); for (i = 0; i < 2; i++) @@ -1211,6 +1248,10 @@ cubePaintTopBottom (CompScreen *s, glColor4usv (defaultColor); glEnableClientState (GL_TEXTURE_COORD_ARRAY); + + screenTexEnvMode (s, GL_REPLACE); + glDisable (GL_BLEND); + glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA); } static void @@ -1228,6 +1269,7 @@ cubePaintTransformedOutput (CompScreen *s, GLenum filter = s->display->textureFilter; PaintOrder paintOrder; Bool clear; + Bool wasCulled = FALSE; int output = 0; CUBE_SCREEN (s); @@ -1237,6 +1279,13 @@ cubePaintTransformedOutput (CompScreen *s, hsize = s->hsize * cs->nOutput; size = hsize; + if (cs->desktopOpacity != OPAQUE) + { + wasCulled = glIsEnabled (GL_CULL_FACE); + if (wasCulled) + glDisable (GL_CULL_FACE); + } + if (!cs->fullscreenOutput) { cs->outputXScale = (float) s->width / s->outputDev[output].width; @@ -1330,13 +1379,14 @@ cubePaintTransformedOutput (CompScreen *s, paintOrder = BTF; } - if (cs->invert == -1) + if (cs->invert == -1 || cs->desktopOpacity != OPAQUE) cubePaintAllViewports (s, &sa,transform, region, outputPtr, mask, xMove, size, hsize, paintOrder); if (cs->grabIndex == 0 && hsize > 2 && - (cs->invert != 1 || sa.vRotate != 0.0f || sa.yTranslate != 0.0f)) + (cs->invert != 1 || cs->desktopOpacity != OPAQUE || + sa.vRotate != 0.0f || sa.yTranslate != 0.0f)) { (*cs->paintTopBottom) (s, &sa, transform, outputPtr, hsize); } @@ -1352,17 +1402,64 @@ cubePaintTransformedOutput (CompScreen *s, paintOrder = FTB; } - if (cs->invert == 1) + if (cs->invert == 1 || cs->desktopOpacity != OPAQUE) cubePaintAllViewports (s, &sa, transform, region, outputPtr, mask, xMove, size, hsize, paintOrder); s->display->textureFilter = filter; + if (wasCulled) + glEnable (GL_CULL_FACE); + WRAP (cs, s, paintTransformedOutput, cubePaintTransformedOutput); } static void +cubeSetBackgroundOpacity (CompScreen* s) +{ + CUBE_SCREEN (s); + + if (cs->desktopOpacity != OPAQUE) + { + if (s->desktopWindowCount) + { + glColor4us (0, 0, 0, 0); + glEnable (GL_BLEND); + } + else + { + glColor4us (0xffff, 0xffff, 0xffff, cs->desktopOpacity); + glEnable (GL_BLEND); + glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + } + } +} + +static void +cubeUnSetBackgroundOpacity (CompScreen* s) +{ + CUBE_SCREEN (s); + + if (cs->desktopOpacity != OPAQUE) + { + if (s->desktopWindowCount) + { + glColor3usv (defaultColor); + glDisable (GL_BLEND); + } + else + { + glColor3usv (defaultColor); + glDisable (GL_BLEND); + glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + screenTexEnvMode(s, GL_REPLACE); + } + } +} + +static void cubePaintBackground (CompScreen *s, Region region, unsigned int mask) @@ -1371,6 +1468,8 @@ cubePaintBackground (CompScreen *s, CUBE_SCREEN (s); + cubeSetBackgroundOpacity(s); + n = cs->opt[CUBE_SCREEN_OPTION_BACKGROUNDS].value.list.nValue; if (n) { @@ -1381,13 +1480,17 @@ cubePaintBackground (CompScreen *s, GLfloat *d, *data; if (!nBox) + { + cubeUnSetBackgroundOpacity(s); return; + } n = (s->x * cs->nOutput + cs->srcOutput) % n; if (s->desktopWindowCount) { cubeUnloadBackgrounds (s); + cubeUnSetBackgroundOpacity(s); return; } else @@ -1403,7 +1506,10 @@ cubePaintBackground (CompScreen *s, data = malloc (sizeof (GLfloat) * nBox * 16); if (!data) + { + cubeUnSetBackgroundOpacity(s); return; + } d = data; n = nBox; @@ -1460,6 +1566,31 @@ cubePaintBackground (CompScreen *s, (*s->paintBackground) (s, region, mask); WRAP (cs, s, paintBackground, cubePaintBackground); } + + cubeUnSetBackgroundOpacity(s); +} + +static Bool +cubePaintWindow (CompWindow *w, + const WindowPaintAttrib *attrib, + const CompTransform *transform, + Region region, + unsigned int mask) +{ + Bool status; + CompScreen* s = w->screen; + CUBE_SCREEN(s); + + WindowPaintAttrib wa = *attrib; + + if (w->type & CompWindowTypeDesktopMask) + wa.opacity = cs->desktopOpacity; + + UNWRAP (cs, s, paintWindow); + status = (*s->paintWindow) (w, &wa, transform, region, mask); + WRAP (cs, s, paintWindow, cubePaintWindow); + + return status; } static void @@ -1786,7 +1917,10 @@ static const CompMetadataOptionInfo cubeScreenOptionInfo[] = { { "timestep", "float", "0.1", 0, 0 }, { "mipmap", "bool", 0, 0, 0 }, { "backgrounds", "list", "string", 0, 0 }, - { "adjust_image", "bool", 0, 0, 0 } + { "adjust_image", "bool", 0, 0, 0 }, + { "active_opacity", "float", "0.0100.0", 0, 0 }, + { "inactive_opacity", "float", "0.0100.0", 0, 0 }, + { "fade_time", "float", "0.0", 0, 0 } }; static Bool @@ -1852,6 +1986,8 @@ cubeInitScreen (CompPlugin *p, cs->bg = NULL; cs->nBg = 0; + cs->desktopOpacity = OPAQUE; + memset (cs->cleared, 0, sizeof (cs->cleared)); cubeUpdateOutputs (s); @@ -1874,6 +2010,7 @@ cubeInitScreen (CompPlugin *p, WRAP (cs, s, paintOutput, cubePaintOutput); WRAP (cs, s, paintTransformedOutput, cubePaintTransformedOutput); WRAP (cs, s, paintBackground, cubePaintBackground); + WRAP (cs, s, paintWindow, cubePaintWindow); WRAP (cs, s, applyScreenTransform, cubeApplyScreenTransform); WRAP (cs, s, setScreenOption, cubeSetGlobalScreenOption); WRAP (cs, s, outputChangeNotify, cubeOutputChangeNotify); @@ -1896,6 +2033,7 @@ cubeFiniScreen (CompPlugin *p, UNWRAP (cs, s, paintOutput); UNWRAP (cs, s, paintTransformedOutput); UNWRAP (cs, s, paintBackground); + UNWRAP (cs, s, paintWindow); UNWRAP (cs, s, applyScreenTransform); UNWRAP (cs, s, setScreenOption); UNWRAP (cs, s, outputChangeNotify); -- 1.5.0.6