A really nice trick from Compiz. OpenGL coordinates have Y upside
down ( [0,0] is bottomleft, unlike topleft with X ), so simply flip the whole scene upside down and move it up -> the coordinates match, except for when mapping pixmap to textures. svn path=/branches/work/kwin_composite/; revision=594942
This commit is contained in:
parent
5de53a53e6
commit
392acfb28c
2 changed files with 23 additions and 10 deletions
|
@ -265,8 +265,11 @@ void SceneOpenGL::paint( QRegion, ToplevelList windows )
|
||||||
{
|
{
|
||||||
grabXServer();
|
grabXServer();
|
||||||
glXWaitX();
|
glXWaitX();
|
||||||
|
glPushMatrix();
|
||||||
glClearColor( 0, 0, 0, 1 );
|
glClearColor( 0, 0, 0, 1 );
|
||||||
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
|
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
|
||||||
|
glScalef( 1, -1, 1 );
|
||||||
|
glTranslatef( 0, -displayHeight(), 0 );
|
||||||
int depth = 0;
|
int depth = 0;
|
||||||
QList< Window* > phase2;
|
QList< Window* > phase2;
|
||||||
for( int i = windows.count() - 1; // top to bottom
|
for( int i = windows.count() - 1; // top to bottom
|
||||||
|
@ -296,6 +299,7 @@ void SceneOpenGL::paint( QRegion, ToplevelList windows )
|
||||||
w.draw();
|
w.draw();
|
||||||
glDisable( GL_BLEND );
|
glDisable( GL_BLEND );
|
||||||
}
|
}
|
||||||
|
glPopMatrix();
|
||||||
if( root_db )
|
if( root_db )
|
||||||
glXSwapBuffers( display(), glxroot );
|
glXSwapBuffers( display(), glxroot );
|
||||||
else
|
else
|
||||||
|
@ -437,7 +441,9 @@ void SceneOpenGL::Window::bindTexture()
|
||||||
bound_glxpixmap = glXCreatePixmap( display(), fbcdrawable, pix, attrs );
|
bound_glxpixmap = glXCreatePixmap( display(), fbcdrawable, pix, attrs );
|
||||||
int value;
|
int value;
|
||||||
glXGetFBConfigAttrib( display(), fbcdrawable, GLX_Y_INVERTED_EXT, &value );
|
glXGetFBConfigAttrib( display(), fbcdrawable, GLX_Y_INVERTED_EXT, &value );
|
||||||
texture_y_inverted = value ? true : false;
|
// this is swapped in order to get a conversion of OpenGL coordinates
|
||||||
|
// (binding to a texture is not affected by transforming the OpenGL scene)
|
||||||
|
texture_y_inverted = value ? false : true;
|
||||||
glBindTexture( GL_TEXTURE_RECTANGLE_ARB, texture );
|
glBindTexture( GL_TEXTURE_RECTANGLE_ARB, texture );
|
||||||
glXBindTexImageEXT( display(), bound_glxpixmap, GLX_FRONT_LEFT_EXT, NULL );
|
glXBindTexImageEXT( display(), bound_glxpixmap, GLX_FRONT_LEFT_EXT, NULL );
|
||||||
}
|
}
|
||||||
|
@ -451,6 +457,7 @@ void SceneOpenGL::Window::bindTexture()
|
||||||
{
|
{
|
||||||
glGenTextures( 1, &texture );
|
glGenTextures( 1, &texture );
|
||||||
glBindTexture( GL_TEXTURE_RECTANGLE_ARB, texture );
|
glBindTexture( GL_TEXTURE_RECTANGLE_ARB, texture );
|
||||||
|
texture_y_inverted = true; // conversion to OpenGL coordinates
|
||||||
glCopyTexImage2D( GL_TEXTURE_RECTANGLE_ARB, 0,
|
glCopyTexImage2D( GL_TEXTURE_RECTANGLE_ARB, 0,
|
||||||
toplevel->hasAlpha() ? GL_RGBA : GL_RGB,
|
toplevel->hasAlpha() ? GL_RGBA : GL_RGB,
|
||||||
0, 0, toplevel->width(), toplevel->height(), 0 );
|
0, 0, toplevel->width(), toplevel->height(), 0 );
|
||||||
|
@ -462,7 +469,11 @@ void SceneOpenGL::Window::bindTexture()
|
||||||
{
|
{
|
||||||
foreach( QRect r, toplevel->damage().rects())
|
foreach( QRect r, toplevel->damage().rects())
|
||||||
{
|
{
|
||||||
int gly = height() - r.y() - r.height(); // to opengl coords
|
// convert to OpenGL coordinates (this is mapping
|
||||||
|
// the pixmap to a texture, this is not affected
|
||||||
|
// by transforming the OpenGL scene)
|
||||||
|
int gly = toplevel->height() - r.y() - r.height();
|
||||||
|
texture_y_inverted = true;
|
||||||
glCopyTexSubImage2D( GL_TEXTURE_RECTANGLE_ARB, 0,
|
glCopyTexSubImage2D( GL_TEXTURE_RECTANGLE_ARB, 0,
|
||||||
r.x(), gly, r.x(), gly, r.width(), r.height());
|
r.x(), gly, r.x(), gly, r.width(), r.height());
|
||||||
}
|
}
|
||||||
|
@ -550,7 +561,7 @@ void SceneOpenGL::Window::draw()
|
||||||
// TODO for double-buffered root glDrawBuffer( GL_BACK );
|
// TODO for double-buffered root glDrawBuffer( GL_BACK );
|
||||||
glXMakeContextCurrent( display(), glxroot, glxroot, context );
|
glXMakeContextCurrent( display(), glxroot, glxroot, context );
|
||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
glTranslatef( glX(), glY(), depth );
|
glTranslatef( x(), y(), depth );
|
||||||
if( toplevel->opacity() != 1.0 )
|
if( toplevel->opacity() != 1.0 )
|
||||||
{
|
{
|
||||||
if( toplevel->hasAlpha())
|
if( toplevel->hasAlpha())
|
||||||
|
@ -574,8 +585,10 @@ void SceneOpenGL::Window::draw()
|
||||||
glEnable( GL_TEXTURE_RECTANGLE_ARB );
|
glEnable( GL_TEXTURE_RECTANGLE_ARB );
|
||||||
glBegin( GL_QUADS );
|
glBegin( GL_QUADS );
|
||||||
foreach( QRect r, shape().rects())
|
foreach( QRect r, shape().rects())
|
||||||
quadDraw( r.x(), height() - r.y() - r.height(),
|
{
|
||||||
r.x() + r.width(), height() - r.y(), texture_y_inverted );
|
quadDraw( r.x(), r.y(), r.x() + r.width(), r.y() + r.height(),
|
||||||
|
texture_y_inverted );
|
||||||
|
}
|
||||||
glEnd();
|
glEnd();
|
||||||
glPopMatrix();
|
glPopMatrix();
|
||||||
if( toplevel->opacity() != 1.0 )
|
if( toplevel->opacity() != 1.0 )
|
||||||
|
|
|
@ -53,8 +53,8 @@ class SceneOpenGL::Window
|
||||||
Window( Toplevel* c );
|
Window( Toplevel* c );
|
||||||
~Window();
|
~Window();
|
||||||
void free(); // is often copied by value, use manually instead of dtor
|
void free(); // is often copied by value, use manually instead of dtor
|
||||||
int glX() const; // remap to OpenGL coordinates
|
int x() const;
|
||||||
int glY() const;
|
int y() const;
|
||||||
int width() const;
|
int width() const;
|
||||||
int height() const;
|
int height() const;
|
||||||
void setDepth( int depth );
|
void setDepth( int depth );
|
||||||
|
@ -78,15 +78,15 @@ class SceneOpenGL::Window
|
||||||
};
|
};
|
||||||
|
|
||||||
inline
|
inline
|
||||||
int SceneOpenGL::Window::glX() const
|
int SceneOpenGL::Window::x() const
|
||||||
{
|
{
|
||||||
return toplevel->x();
|
return toplevel->x();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
int SceneOpenGL::Window::glY() const
|
int SceneOpenGL::Window::y() const
|
||||||
{
|
{
|
||||||
return displayHeight() - toplevel->y() - toplevel->height();
|
return toplevel->y();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
|
|
Loading…
Reference in a new issue