Change from orthographic projection to a perspective projection. This allows to change z-values and rotations.

Therefore zScale, zTranslate and new RotationData are added to ScreenPaintData and WindowPaintData. So it is possible to define zTranslation and rotations without using OpenGL directly. The change only affects OpenGL compositing. XRender is not changed.

svn path=/trunk/KDE/kdebase/workspace/; revision=842018
This commit is contained in:
Martin Gräßlin 2008-08-04 14:07:45 +00:00
parent 8bbc6af734
commit cb4ed769aa
3 changed files with 102 additions and 7 deletions

View file

@ -64,11 +64,14 @@ WindowPaintData::WindowPaintData( EffectWindow* w )
, decoration_opacity( 1.0 )
, xScale( 1 )
, yScale( 1 )
, zScale( 1 )
, xTranslate( 0 )
, yTranslate( 0 )
, zTranslate( 0 )
, saturation( 1 )
, brightness( 1 )
, shader( NULL )
, rotation( NULL )
{
quads = w->buildQuads();
}
@ -76,8 +79,20 @@ WindowPaintData::WindowPaintData( EffectWindow* w )
ScreenPaintData::ScreenPaintData()
: xScale( 1 )
, yScale( 1 )
, zScale( 1 )
, xTranslate( 0 )
, yTranslate( 0 )
, zTranslate( 0 )
, rotation( NULL )
{
}
RotationData::RotationData()
: axis( ZAxis )
, angle( 0.0 )
, xRotationPoint( 0.0 )
, yRotationPoint( 0.0 )
, zRotationPoint( 0.0 )
{
}

View file

@ -56,6 +56,7 @@ class Effect;
class WindowQuad;
class GLRenderTarget;
class GLShader;
class RotationData;
class WindowQuadList;
class WindowPrePaintData;
class WindowPaintData;
@ -162,7 +163,7 @@ X-KDE-Library=kwin4_effect_cooleffect
#define KWIN_EFFECT_API_MAKE_VERSION( major, minor ) (( major ) << 8 | ( minor ))
#define KWIN_EFFECT_API_VERSION_MAJOR 0
#define KWIN_EFFECT_API_VERSION_MINOR 50
#define KWIN_EFFECT_API_VERSION_MINOR 51
#define KWIN_EFFECT_API_VERSION KWIN_EFFECT_API_MAKE_VERSION( \
KWIN_EFFECT_API_VERSION_MAJOR, KWIN_EFFECT_API_VERSION_MINOR )
@ -873,8 +874,10 @@ class KWIN_EXPORT WindowPaintData
double decoration_opacity;
double xScale;
double yScale;
double zScale;
int xTranslate;
int yTranslate;
double zTranslate;
/**
* Saturation of the window, in range [0; 1]
* 1 means that the window is unchanged, 0 means that it's completely
@ -895,6 +898,7 @@ class KWIN_EXPORT WindowPaintData
* Shader to be used for rendering, if any.
*/
GLShader* shader;
RotationData* rotation;
};
class KWIN_EXPORT ScreenPaintData
@ -903,8 +907,11 @@ class KWIN_EXPORT ScreenPaintData
ScreenPaintData();
double xScale;
double yScale;
double zScale;
int xTranslate;
int yTranslate;
double zTranslate;
RotationData* rotation;
};
class KWIN_EXPORT ScreenPrePaintData
@ -914,6 +921,23 @@ class KWIN_EXPORT ScreenPrePaintData
QRegion paint;
};
class KWIN_EXPORT RotationData
{
public:
RotationData();
enum RotationAxis
{
XAxis,
YAxis,
ZAxis
};
RotationAxis axis;
float angle;
float xRotationPoint;
float yRotationPoint;
float zRotationPoint;
};
/**
* @short Helper class for restricting painting area only to allowed area.
*

View file

@ -159,8 +159,16 @@ SceneOpenGL::SceneOpenGL( Workspace* ws )
// OpenGL scene setup
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
float fovy = 60.0f;
float aspect = 1.0f;
float zNear = 0.1f;
float zFar = 100.0f;
float ymax = zNear * tan( fovy * M_PI / 360.0f );
float ymin = -ymax;
float xmin = ymin * aspect;
float xmax = ymax * aspect;
// swap top and bottom to have OpenGL coordinate system match X system
glOrtho( 0, displayWidth(), displayHeight(), 0, 0, 65535 );
glFrustum( xmin, xmax, ymin, ymax, zNear, zFar );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
if( checkGLError( "Init" ))
@ -171,6 +179,9 @@ SceneOpenGL::SceneOpenGL( Workspace* ws )
kDebug( 1212 ) << "DB:" << db << ", TFP:" << tfp_mode << ", SHM:" << shm_mode
<< ", Direct:" << bool( glXIsDirect( display(), ctxbuffer )) << endl;
init_ok = true;
float scaleFactor = 1.1 * tan( fovy * M_PI / 360.0f )/ymax;
glTranslatef( xmin*scaleFactor, ymax*scaleFactor, -1.1 );
glScalef( (xmax-xmin)*scaleFactor/displayWidth(), -(ymax-ymin)*scaleFactor/displayHeight(), 0.001 );
}
SceneOpenGL::~SceneOpenGL()
@ -715,8 +726,30 @@ void SceneOpenGL::paintGenericScreen( int mask, ScreenPaintData data )
if( mask & PAINT_SCREEN_TRANSFORMED )
{ // apply screen transformations
glPushMatrix();
glTranslatef( data.xTranslate, data.yTranslate, 0 );
glScalef( data.xScale, data.yScale, 1 );
glTranslatef( data.xTranslate, data.yTranslate, data.zTranslate );
if( data.rotation )
{
// translate to rotation point, rotate, translate back
glTranslatef( data.rotation->xRotationPoint, data.rotation->yRotationPoint, data.rotation->zRotationPoint );
float xAxis = 0.0;
float yAxis = 0.0;
float zAxis = 0.0;
switch( data.rotation->axis )
{
case RotationData::XAxis:
xAxis = 1.0;
break;
case RotationData::YAxis:
yAxis = 1.0;
break;
case RotationData::ZAxis:
zAxis = 1.0;
break;
}
glRotatef( data.rotation->angle, xAxis, yAxis, zAxis );
glTranslatef( -data.rotation->xRotationPoint, -data.rotation->yRotationPoint, -data.rotation->zRotationPoint );
}
glScalef( data.xScale, data.yScale, data.zScale );
}
Scene::paintGenericScreen( mask, data );
if( mask & PAINT_SCREEN_TRANSFORMED )
@ -1243,14 +1276,37 @@ void SceneOpenGL::Window::performPaint( int mask, QRegion region, WindowPaintDat
// do required transformations
int x = toplevel->x();
int y = toplevel->y();
double z = 0.0;
if( mask & PAINT_WINDOW_TRANSFORMED )
{
x += data.xTranslate;
y += data.yTranslate;
z += data.zTranslate;
}
glTranslatef( x, y, z );
if(( mask & PAINT_WINDOW_TRANSFORMED ) && ( data.xScale != 1 || data.yScale != 1 || data.zScale != 1 ))
glScalef( data.xScale, data.yScale, data.zScale );
if(( mask & PAINT_WINDOW_TRANSFORMED ) && data.rotation )
{
glTranslatef( data.rotation->xRotationPoint, data.rotation->yRotationPoint, data.rotation->zRotationPoint );
float xAxis = 0.0;
float yAxis = 0.0;
float zAxis = 0.0;
switch( data.rotation->axis )
{
case RotationData::XAxis:
xAxis = 1.0;
break;
case RotationData::YAxis:
yAxis = 1.0;
break;
case RotationData::ZAxis:
zAxis = 1.0;
break;
}
glRotatef( data.rotation->angle, xAxis, yAxis, zAxis );
glTranslatef( -data.rotation->xRotationPoint, -data.rotation->yRotationPoint, -data.rotation->zRotationPoint );
}
glTranslatef( x, y, 0 );
if(( mask & PAINT_WINDOW_TRANSFORMED ) && ( data.xScale != 1 || data.yScale != 1 ))
glScalef( data.xScale, data.yScale, 1 );
region.translate( toplevel->x(), toplevel->y() ); // Back to screen coords
texture.bind();