From 392acfb28c778c10aacaf20dfbfe3e6e05647a8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lubo=C5=A1=20Lu=C5=88=C3=A1k?= Date: Thu, 12 Oct 2006 21:12:51 +0000 Subject: [PATCH] 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 --- scene_opengl.cpp | 23 ++++++++++++++++++----- scene_opengl.h | 10 +++++----- 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/scene_opengl.cpp b/scene_opengl.cpp index 6e9df83c07..bd3aaf4574 100644 --- a/scene_opengl.cpp +++ b/scene_opengl.cpp @@ -265,8 +265,11 @@ void SceneOpenGL::paint( QRegion, ToplevelList windows ) { grabXServer(); glXWaitX(); + glPushMatrix(); glClearColor( 0, 0, 0, 1 ); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); + glScalef( 1, -1, 1 ); + glTranslatef( 0, -displayHeight(), 0 ); int depth = 0; QList< Window* > phase2; for( int i = windows.count() - 1; // top to bottom @@ -296,6 +299,7 @@ void SceneOpenGL::paint( QRegion, ToplevelList windows ) w.draw(); glDisable( GL_BLEND ); } + glPopMatrix(); if( root_db ) glXSwapBuffers( display(), glxroot ); else @@ -437,7 +441,9 @@ void SceneOpenGL::Window::bindTexture() bound_glxpixmap = glXCreatePixmap( display(), fbcdrawable, pix, attrs ); int 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 ); glXBindTexImageEXT( display(), bound_glxpixmap, GLX_FRONT_LEFT_EXT, NULL ); } @@ -451,6 +457,7 @@ void SceneOpenGL::Window::bindTexture() { glGenTextures( 1, &texture ); glBindTexture( GL_TEXTURE_RECTANGLE_ARB, texture ); + texture_y_inverted = true; // conversion to OpenGL coordinates glCopyTexImage2D( GL_TEXTURE_RECTANGLE_ARB, 0, toplevel->hasAlpha() ? GL_RGBA : GL_RGB, 0, 0, toplevel->width(), toplevel->height(), 0 ); @@ -462,7 +469,11 @@ void SceneOpenGL::Window::bindTexture() { 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, 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 ); glXMakeContextCurrent( display(), glxroot, glxroot, context ); glPushMatrix(); - glTranslatef( glX(), glY(), depth ); + glTranslatef( x(), y(), depth ); if( toplevel->opacity() != 1.0 ) { if( toplevel->hasAlpha()) @@ -574,8 +585,10 @@ void SceneOpenGL::Window::draw() glEnable( GL_TEXTURE_RECTANGLE_ARB ); glBegin( GL_QUADS ); 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(); glPopMatrix(); if( toplevel->opacity() != 1.0 ) diff --git a/scene_opengl.h b/scene_opengl.h index 39b300ba23..01b4b751f8 100644 --- a/scene_opengl.h +++ b/scene_opengl.h @@ -53,8 +53,8 @@ class SceneOpenGL::Window Window( Toplevel* c ); ~Window(); void free(); // is often copied by value, use manually instead of dtor - int glX() const; // remap to OpenGL coordinates - int glY() const; + int x() const; + int y() const; int width() const; int height() const; void setDepth( int depth ); @@ -78,15 +78,15 @@ class SceneOpenGL::Window }; inline -int SceneOpenGL::Window::glX() const +int SceneOpenGL::Window::x() const { return toplevel->x(); } inline -int SceneOpenGL::Window::glY() const +int SceneOpenGL::Window::y() const { - return displayHeight() - toplevel->y() - toplevel->height(); + return toplevel->y(); } inline