rendered paste bodydiff --git a/plugins/cube.c b/plugins/cube.c
index f7c2e12..06effb2 100644
--- a/plugins/cube.c
+++ b/plugins/cube.c
@@ -134,6 +134,37 @@ typedef struct _CubeDisplay {
#define CUBE_SCREEN_OPTION_MIPMAP 12
#define CUBE_SCREEN_OPTION_NUM 13
+#define MULTM(x,y,z) \
+z[0] = x[0] * y[0] + x[4] * y[1] + x[8] * y[2] + x[12] * y[3]; \
+z[1] = x[1] * y[0] + x[5] * y[1] + x[9] * y[2] + x[13] * y[3]; \
+z[2] = x[2] * y[0] + x[6] * y[1] + x[10] * y[2] + x[14] * y[3]; \
+z[3] = x[3] * y[0] + x[7] * y[1] + x[11] * y[2] + x[15] * y[3]; \
+z[4] = x[0] * y[4] + x[4] * y[5] + x[8] * y[6] + x[12] * y[7]; \
+z[5] = x[1] * y[4] + x[5] * y[5] + x[9] * y[6] + x[13] * y[7]; \
+z[6] = x[2] * y[4] + x[6] * y[5] + x[10] * y[6] + x[14] * y[7]; \
+z[7] = x[3] * y[4] + x[7] * y[5] + x[11] * y[6] + x[15] * y[7]; \
+z[8] = x[0] * y[8] + x[4] * y[9] + x[8] * y[10] + x[12] * y[11]; \
+z[9] = x[1] * y[8] + x[5] * y[9] + x[9] * y[10] + x[13] * y[11]; \
+z[10] = x[2] * y[8] + x[6] * y[9] + x[10] * y[10] + x[14] * y[11]; \
+z[11] = x[3] * y[8] + x[7] * y[9] + x[11] * y[10] + x[15] * y[11]; \
+z[12] = x[0] * y[12] + x[4] * y[13] + x[8] * y[14] + x[12] * y[15]; \
+z[13] = x[1] * y[12] + x[5] * y[13] + x[9] * y[14] + x[13] * y[15]; \
+z[14] = x[2] * y[12] + x[6] * y[13] + x[10] * y[14] + x[14] * y[15]; \
+z[15] = x[3] * y[12] + x[7] * y[13] + x[11] * y[14] + x[15] * y[15];
+
+#define MULTMV(m, v) { \
+float v0 = m[0]*v[0] + m[4]*v[1] + m[8]*v[2] + m[12]*v[3]; \
+float v1 = m[1]*v[0] + m[5]*v[1] + m[9]*v[2] + m[13]*v[3]; \
+float v2 = m[2]*v[0] + m[6]*v[1] + m[10]*v[2] + m[14]*v[3]; \
+float v3 = m[3]*v[0] + m[7]*v[1] + m[11]*v[2] + m[15]*v[3]; \
+v[0] = v0; v[1] = v1; v[2] = v2; v[3] = v3; }
+
+#define DIVV(v) \
+v[0] /= v[3]; \
+v[1] /= v[3]; \
+v[2] /= v[3]; \
+v[3] /= v[3];
+
typedef struct _CubeScreen {
PreparePaintScreenProc preparePaintScreen;
DonePaintScreenProc donePaintScreen;
@@ -1230,6 +1261,59 @@ cubeDonePaintScreen (CompScreen *s)
WRAP (cs, s, donePaintScreen, cubeDonePaintScreen);
}
+static Bool
+cubeCheckFTB (CompScreen *s,
+ const ScreenPaintAttrib *sAttrib,
+ const CompTransform *transform,
+ int output)
+{
+ float mvp[16];
+ CompTransform sTransform = *transform;
+
+ (*s->applyScreenTransform) (s, sAttrib, output, &sTransform);
+ transformToScreenSpace (s, output, -sAttrib->zTranslate, &sTransform);
+
+ MULTM(s->projection, sTransform.m, mvp);
+
+ float pntA[4] = { s->outputDev[output].region.extents.x1,
+ s->outputDev[output].region.extents.y1,
+ 0, 1};
+
+ float pntB[4] = { s->outputDev[output].region.extents.x2,
+ s->outputDev[output].region.extents.y1,
+ 0, 1};
+
+ float pntC[4] = { s->outputDev[output].region.extents.x1 + s->outputDev[output].width / 2.0f,
+ s->outputDev[output].region.extents.y1 + s->outputDev[output].height / 2.0f,
+ 0, 1};
+
+ MULTMV(mvp, pntA);
+ DIVV(pntA);
+
+ MULTMV(mvp, pntB);
+ DIVV(pntB);
+
+ MULTMV(mvp, pntC);
+ DIVV(pntC);
+
+ float vecA[3] = { pntC[0] - pntA[0],
+ pntC[1] - pntA[1],
+ pntC[2] - pntA[2]};
+
+ float vecB[3] = { pntC[0] - pntB[0],
+ pntC[1] - pntB[1],
+ pntC[2] - pntB[2]};
+
+ float ortho[3] = { vecA[1] * vecB[2] - vecA[2] * vecB[1],
+ vecA[2] * vecB[0] - vecA[0] * vecB[2],
+ vecA[0] * vecB[1] - vecA[1] * vecB[0]};
+
+ if (ortho[2] > 0.0f) //The viewport is reversed, should be painted front to back.
+ return TRUE;
+
+ return FALSE;
+}
+
static void
cubeMoveViewportAndPaint (CompScreen *s,
const ScreenPaintAttrib *sAttrib,
@@ -1240,6 +1324,13 @@ cubeMoveViewportAndPaint (CompScreen *s,
{
CUBE_SCREEN (s);
+ Bool ftb = cubeCheckFTB(s, sAttrib, transform, output);
+
+ if (ftb && !(mask & PAINT_SCREEN_ORDER_FRONT_TO_BACK_MASK))
+ return;
+ if (!ftb && (mask & PAINT_SCREEN_ORDER_FRONT_TO_BACK_MASK))
+ return;
+
if (cs->nOutput > 1)
{
int cubeOutput, dView;
@@ -1279,6 +1370,76 @@ cubeMoveViewportAndPaint (CompScreen *s,
}
}
+void
+cubePaintAllViewports (CompScreen *s,
+ ScreenPaintAttrib *sAttrib,
+ const CompTransform *transform,
+ Region region,
+ int output,
+ unsigned int mask,
+ int xMove,
+ int size,
+ int hsize)
+{
+ CUBE_SCREEN(s);
+
+ ScreenPaintAttrib sa = *sAttrib;
+
+ int i;
+ int iFirstSign; // 1 if we do xMove += i first and -1 if we do xMove -= i first.
+
+ if (cs->invert == 1)
+ {
+ // xMove ==> dx for the viewport which is the nearest to the viewer in z axis.
+ // xMove +/- hsize / 2 ==> dx for the viewport which is the farest to the viewer in z axis.
+
+ if ((sa.xRotate < 0.0f && hsize % 2 == 1) ||
+ (sa.xRotate > 0.0f && hsize % 2 == 0))
+ {
+ xMove += hsize / 2;
+ sa.yRotate -= (hsize / 2) * 360.0f / size;
+ iFirstSign = 1;
+ }
+
+ else
+ {
+ xMove -= hsize / 2;
+ sa.yRotate += (hsize / 2) * 360.0f / size;
+ iFirstSign = -1;
+ }
+ }
+
+ else
+ {
+ // xMove is already the dx for farest viewport.
+
+ if (sa.xRotate > 0.0f)
+ iFirstSign = -1;
+ else
+ iFirstSign = 1;
+ }
+
+ for (i = 0; i <= hsize / 2; i++)
+ {
+ xMove += iFirstSign * i;
+ sa.yRotate -= cs->invert * iFirstSign * i * 360.0f / size;
+ cubeMoveViewportAndPaint (s, &sa, transform, output, mask,
+ xMove);
+ sa.yRotate += cs->invert * iFirstSign * i * 360.0f / size;
+ xMove -= iFirstSign * i;
+
+ if (i == 0 || i * 2 == hsize) // same viewport.
+ continue;
+
+ xMove -= iFirstSign * i;
+ sa.yRotate += cs->invert * iFirstSign * i * 360.0f / size;
+ cubeMoveViewportAndPaint (s, &sa, transform, output, mask,
+ xMove);
+ sa.yRotate -= cs->invert * iFirstSign * i * 360.0f / size;
+ xMove += iFirstSign * i;
+ }
+}
+
static void
cubePaintTransformedScreen (CompScreen *s,
const ScreenPaintAttrib *sAttrib,
@@ -1291,6 +1452,7 @@ cubePaintTransformedScreen (CompScreen *s,
int hsize, xMove = 0;
float size;
Bool clear;
+ GLenum filter = s->display->textureFilter;
CUBE_SCREEN (s);
@@ -1372,22 +1534,6 @@ cubePaintTransformedScreen (CompScreen *s,
/* distance we move the camera back when unfolding the cube.
currently hardcoded to 1.5 but it should probably be optional. */
sa.zCamera -= cs->unfold * 1.5f;
-
- sa.xRotate = sAttrib->xRotate * cs->invert;
- if (sa.xRotate > 0.0f)
- {
- cs->xrotations = (int) (hsize * sa.xRotate) / 360;
- sa.xRotate = sa.xRotate - (360.0f * cs->xrotations) / hsize;
- }
- else
- {
- cs->xrotations = (int) (hsize * sa.xRotate) / 360;
- sa.xRotate = sa.xRotate -
- (360.0f * cs->xrotations) / hsize + 360.0f / hsize;
- cs->xrotations--;
- }
-
- sa.xRotate = sa.xRotate / size * hsize;
}
else
{
@@ -1399,20 +1545,34 @@ cubePaintTransformedScreen (CompScreen *s,
sa.vRotate = sAttrib->vRotate;
sa.zTranslate = -cs->invert * cs->distance;
- sa.xRotate = sAttrib->xRotate * cs->invert;
- if (sa.xRotate > 0.0f)
- {
- cs->xrotations = (int) (size * sa.xRotate) / 360;
- sa.xRotate = sa.xRotate - (360.0f * cs->xrotations) / size;
- }
- else
- {
- cs->xrotations = (int) (size * sa.xRotate) / 360;
- sa.xRotate = sa.xRotate -
- (360.0f * cs->xrotations) / size + 360.0f / size;
- cs->xrotations--;
- }
}
+
+ sa.xRotate = sAttrib->xRotate;
+
+ if (sa.xRotate > 0.0f)
+ cs->xrotations = (int) (hsize * sa.xRotate + 180) / 360;
+ else
+ cs->xrotations = (int) (hsize * sa.xRotate - 180) / 360;
+
+ sa.xRotate -= (360.0f * cs->xrotations) / size;
+ sa.xRotate *= cs->invert;
+
+ xMove = cs->xrotations;
+
+ if (cs->grabIndex && cs->opt[CUBE_SCREEN_OPTION_MIPMAP].value.b)
+ s->display->textureFilter = GL_LINEAR_MIPMAP_LINEAR;
+
+ if (cs->invert == 1)
+ mask |= PAINT_SCREEN_ORDER_FRONT_TO_BACK_MASK; // Outside cube - start with FTB faces.
+ // Inside cube - start with BTF faces.
+
+ if (cs->paintAllViewports || cs->invert == -1)
+ cubePaintAllViewports(s, &sa, transform, region, output, mask, xMove, size, hsize);
+
+ if (cs->invert == 1)
+ mask &= ~PAINT_SCREEN_ORDER_FRONT_TO_BACK_MASK; // Outside cube - continue with caps and then BTF faces.
+ else
+ mask |= PAINT_SCREEN_ORDER_FRONT_TO_BACK_MASK; // Inside cube - continue with caps and then FTB faces.
if (!clear && cs->grabIndex == 0 && hsize > 2 &&
(cs->invert != 1 || sa.vRotate != 0.0f || sa.yTranslate != 0.0f))
@@ -1425,39 +1585,40 @@ cubePaintTransformedScreen (CompScreen *s,
glPushMatrix ();
- if (sAttrib->xRotate > 0.0f)
- {
- sa.yRotate += 360.0f / size;
- (*s->applyScreenTransform) (s, &sa, output, &sTransform);
- glLoadMatrixf (sTransform.m);
- glTranslatef (cs->outputXOffset, -cs->outputYOffset, 0.0f);
- glScalef (cs->outputXScale, cs->outputYScale, 1.0f);
- sa.yRotate -= 360.0f / size;
- }
- else
- {
- (*s->applyScreenTransform) (s, &sa, output, &sTransform);
- glLoadMatrixf (sTransform.m);
- glTranslatef (cs->outputXOffset, -cs->outputYOffset, 0.0f);
- glScalef (cs->outputXScale, cs->outputYScale, 1.0f);
- }
+ (*s->applyScreenTransform) (s, &sa, output, &sTransform);
+ glLoadMatrixf (sTransform.m);
+ glTranslatef (cs->outputXOffset, -cs->outputYOffset, 0.0f);
+ glScalef (cs->outputXScale, cs->outputYScale, 1.0f);
glVertexPointer (3, GL_FLOAT, 0, cs->vertices);
- glNormal3f (0.0f, -1.0f, 0.0f);
-
- if (cs->invert == 1 && hsize == 4 && cs->texture.name)
+ int i;
+ for (i = 0; i < 2; i++)
{
- enableTexture (s, &cs->texture, COMP_TEXTURE_FILTER_GOOD);
- glTexCoordPointer (2, GL_FLOAT, 0, cs->tc);
- glDrawArrays (GL_TRIANGLE_FAN, 0, cs->nvertices >> 1);
- disableTexture (s, &cs->texture);
- glDisableClientState (GL_TEXTURE_COORD_ARRAY);
- }
- else
- {
- glDisableClientState (GL_TEXTURE_COORD_ARRAY);
- glDrawArrays (GL_TRIANGLE_FAN, 0, cs->nvertices >> 1);
+ if ((i == 0 && sAttrib->vRotate < 0.0f) ||
+ (i == 1 && sAttrib->vRotate > 0.0f))
+ {
+ glNormal3f (0.0f, -1.0f, 0.0f);
+ if (cs->invert == 1 && hsize == 4 && cs->texture.name)
+ {
+ enableTexture (s, &cs->texture, COMP_TEXTURE_FILTER_GOOD);
+ glTexCoordPointer (2, GL_FLOAT, 0, cs->tc);
+ glDrawArrays (GL_TRIANGLE_FAN, 0, cs->nvertices >> 1);
+ disableTexture (s, &cs->texture);
+ glDisableClientState (GL_TEXTURE_COORD_ARRAY);
+ }
+ else
+ {
+ glDisableClientState (GL_TEXTURE_COORD_ARRAY);
+ glDrawArrays (GL_TRIANGLE_FAN, 0, cs->nvertices >> 1);
+ }
+ }
+ else
+ {
+ glNormal3f (0.0f, 1.0f, 0.0f);
+ glDrawArrays (GL_TRIANGLE_FAN, cs->nvertices >> 1,
+ cs->nvertices >> 1);
+ }
}
glNormal3f (0.0f, 1.0f, 0.0f);
@@ -1473,108 +1634,12 @@ cubePaintTransformedScreen (CompScreen *s,
glEnableClientState (GL_TEXTURE_COORD_ARRAY);
}
- /* outside cube */
- if (cs->invert == 1)
- {
- if (cs->grabIndex || hsize > 4)
- {
- GLenum filter;
- int i;
-
- xMove = cs->xrotations - ((hsize >> 1) - 1);
- sa.yRotate += (360.0f / size) * ((hsize >> 1) - 1);
-
- filter = s->display->textureFilter;
- if (cs->grabIndex && cs->opt[CUBE_SCREEN_OPTION_MIPMAP].value.b)
- s->display->textureFilter = GL_LINEAR_MIPMAP_LINEAR;
-
- for (i = 0; i < hsize; i++)
- {
- cubeMoveViewportAndPaint (s, &sa, transform, output, mask,
- xMove);
-
- sa.yRotate -= 360.0f / size;
- xMove++;
- }
-
- s->display->textureFilter = filter;
- }
- else
- {
- if (sAttrib->xRotate != 0.0f)
- {
- xMove = cs->xrotations;
-
- cubeMoveViewportAndPaint (s, &sa, transform, output, mask,
- xMove);
-
- xMove++;
- }
-
- sa.yRotate -= 360.0f / size;
-
- cubeMoveViewportAndPaint (s, &sa, transform, output, mask, xMove);
- }
- }
- else
- {
- if (sa.xRotate > 180.0f / size)
- {
- sa.yRotate -= 360.0f / size;
- cs->xrotations++;
- }
-
- sa.yRotate -= 360.0f / size;
- xMove = -1 - cs->xrotations;
-
- if (cs->grabIndex)
- {
- GLenum filter;
- int i;
-
- filter = s->display->textureFilter;
- if (cs->opt[CUBE_SCREEN_OPTION_MIPMAP].value.b)
- s->display->textureFilter = GL_LINEAR_MIPMAP_LINEAR;
-
- if (sa.xRotate > 180.0f / size)
- {
- xMove -= ((hsize >> 1) - 2);
- sa.yRotate -= (360.0f / size) * ((hsize >> 1) - 2);
- }
- else
- {
- xMove -= ((hsize >> 1) - 1);
- sa.yRotate -= (360.0f / size) * ((hsize >> 1) - 1);
- }
-
- for (i = 0; i < hsize; i++)
- {
- cubeMoveViewportAndPaint (s, &sa, transform, output, mask,
- xMove);
-
- sa.yRotate += 360.0f / size;
- xMove++;
- }
-
- s->display->textureFilter = filter;
- }
- else
- {
- cubeMoveViewportAndPaint (s, &sa, transform, output, mask, xMove);
-
- sa.yRotate += 360.0f / size;
- xMove = -cs->xrotations;
-
- cubeMoveViewportAndPaint (s, &sa, transform, output, mask, xMove);
-
- sa.yRotate += 360.0f / size;
- xMove = 1 - cs->xrotations;
-
- cubeMoveViewportAndPaint (s, &sa, transform, output, mask, xMove);
- }
- }
+ if (cs->paintAllViewports || cs->invert == 1)
+ cubePaintAllViewports(s, &sa, transform, region, output, mask, xMove, size, hsize);
WRAP (cs, s, paintTransformedScreen, cubePaintTransformedScreen);
+
+ s->display->textureFilter = filter;
}
static void cubeSetClipPlanes (CompScreen *s, Region region, int output)