On Wed, 2007-04-11 at 01:08 +0200, Dennis Kasprzyk wrote:
> Am Mittwoch, 11. April 2007 00:30 schrieb Danny Baumann:
> > Hi,
> >
> > > > In wall, we translate and scale painted screen when in expo mode, hence
> > > > we want to apply these changes to the clip planes, too. Without that
> > > > (current code), single outputs become blanked under certain conditions
> > > > (e.g. initiation of switcher in multihead mode).
> > >
> > > I don't understand. The additional clipping planes are used to clip
> > > window geometry to the output area. The clipping planes are affected by
> > > any screen transformation you apply and the only time you would have to
> > > set them up differently would be if you would want them not to match
> > > your transformations and I'm not aware of a use case for this yet.
> >
> > Well, I will try if it's really needed in wall, but one use case for
> > that is definitely the 3D plugin (guess you know that one ;-) -
> > http://www.youtube.com/watch?v=CUMqh1dg8Cc) where the windows come out
> > of the screen (are translated in the z axis). Those windows will be
> > clipped when the normal clipping planes are applied. The solution here
> > is to arrange the clipping planes differently (not around the viewport,
> > but tilted so they cross in the center of the cube - I can draw a figure
> > if you like).
> >
>
> Here is the beryl cube setClipPlanes code (not using the paint Region for
> calculation)
>
> static void cubeSetClipPlanes (CompScreen *s, int output)
> {
> CUBE_SCREEN(s);
>
> glTranslatef(cs->outputXOffset, -cs->outputYOffset, 0.0f);
> glScalef( cs->outputXScale, cs->outputYScale, 1.0f);
>
> UNWRAP(cs, s, setClipPlanes);
> (*s->setClipPlanes) (s, output);
> WRAP(cs, s, setClipPlanes, cubeSetClipPlanes);
>
>
> if (cs->invert == 1)
> {
> GLdouble clipPlane0[] = { 1.0, 0.0, 0.5 / cs->distance,
> 0.0 };
> GLdouble clipPlane1[] = { -1.0, 0.0, 0.5 / cs->distance,
> 0.0 };
> GLdouble clipPlane2[] = { 0.0, -1.0, 0.5 / cs->distance,
> 0.0 };
> GLdouble clipPlane3[] = { 0.0, 1.0, 0.5 / cs->distance,
> 0.0 };
> glClipPlane (GL_CLIP_PLANE0, clipPlane0);
> glClipPlane (GL_CLIP_PLANE1, clipPlane1);
> glClipPlane (GL_CLIP_PLANE2, clipPlane2);
> glClipPlane (GL_CLIP_PLANE3, clipPlane3);
> }
> else
> {
> GLdouble clipPlane0[] = { -1.0, 0.0, -0.5 / cs->distance,
> 0.0 };
> GLdouble clipPlane1[] = { 1.0, 0.0, -0.5 / cs->distance,
> 0.0 };
> GLdouble clipPlane2[] = { 0.0, 1.0, -0.5 / cs->distance,
> 0.0 };
> GLdouble clipPlane3[] = { 0.0, -1.0, -0.5 / cs->distance,
> 0.0 };
> glClipPlane (GL_CLIP_PLANE0, clipPlane0);
> glClipPlane (GL_CLIP_PLANE1, clipPlane1);
> glClipPlane (GL_CLIP_PLANE2, clipPlane2);
> glClipPlane (GL_CLIP_PLANE3, clipPlane3);
> }
>
> }
>
>
> > > > > > - For expo mode, we need a global (not per-output) perspective. We
> > > > > > also mentioned that before and you said you think it's the best
> > > > > > idea to put this into the CompTransform struct, right?
> > > > >
> > > > > What do you mean by "global (not per-output) perspective"? The
> > > > > perspective matrix is currently the same for all outputs. Do you mean
> > > > > that it needs to be different? Can you please explain more why you
> > > > > need this?
> > > >
> > > > We want to achieve that plugins can disable per-output drawing and
> > > > paint to the whole screen area as if it was one single area. This could
> > > > be solved either by some flag or by having different projection
> > > > matrices per output which are adjusted appropriately.
> > >
> > > Can't we adjust the modelview matrix appropriately to get this behavior?
> >
> > We can do this, but we believe it's far more efficient and straight
> > forward to adjust the projection matrix itself than inverting it and
> > multiplying it with the modelview matrix.
> > Additionally, that inversion and multiplication would have to be done in
> > every plugin which wants to have "one big output". Currently, that's
> > only wall, but I also can imagine something like that for cube ("one big
> > cube" is it called in Beryl, where there is only one cube side per
> > viewport containing both outputs). Sorry I don't have a youtube link
> > by-hand.
> >
> > Regards,
> >
> > Danny
>
> For some plugins it makes sense to paint the whole screen area. In my opinion
> it would be the best to pass the CompOutput struct to paintScreen instead of
> the output number. Then we could set a mask in preparePaintScreen to force
> core to execute paintScreen with a whole screen CompOutput struct instead of
> executing it for each output. Or something like that:
>
> eventLoop():
> s->preparePaintScreen(ms, s->output, s->nOutputDev)
>
> core preparePaintScreen:
> preparePaintScreen (int ms, CompOutput * oDevs, int nODevs)
> {
> for (i = 0; i < nODevs; i++)
> s->paintScreen(...oDevs[1]...)
> }
>
Yes, something like that might work.
- David