[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    branches/work/kwin_composite
From:       Luboš Luňák <l.lunak () kde ! org>
Date:       2006-09-30 18:09:43
Message-ID: 1159639783.905071.16486.nullmailer () svn ! kde ! org
[Download RAW message or body]

SVN commit 590751 by lunakl:

Opengl transparency.



 M  +1 -0      manage.cpp  
 M  +78 -24    scene_opengl.cpp  
 M  +6 -1      scene_opengl.h  
 M  +7 -0      toplevel.h  
 M  +1 -0      unmanaged.cpp  


--- branches/work/kwin_composite/manage.cpp #590750:590751
@@ -54,6 +54,7 @@
     embedClient( w, attr );
     
     vis = attr.visual;
+    depth = attr.depth;
 
     setupCompositing();
 
--- branches/work/kwin_composite/scene_opengl.cpp #590750:590751
@@ -28,6 +28,7 @@
 
 GLXFBConfig SceneOpenGL::fbcdrawable;
 GLXContext SceneOpenGL::context;
+GLXPixmap SceneOpenGL::glxroot;
 
 const int root_attrs[] =
     {
@@ -88,7 +89,7 @@
     glMatrixMode( GL_PROJECTION );
     glLoadIdentity();
     glOrtho( 0, displayWidth(), 0, displayHeight(), 0, 65535 );
-// TODO    glEnable( GL_DEPTH_TEST );
+    glEnable( GL_DEPTH_TEST );
     checkGLError( "Init" );
     }
 
@@ -122,31 +123,40 @@
     grabXServer();
     glXWaitX();
     glClearColor( 0, 0, 0, 1 );
-    glClear( GL_COLOR_BUFFER_BIT /* TODO| GL_DEPTH_BUFFER_BIT*/ );
-    for( ToplevelList::ConstIterator it = windows.begin();
-         it != windows.end();
-         ++it )
+    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
+    int depth = 0;
+    for( int i = windows.count() - 1; // top to bottom
+         i >= 0;
+         --i )
         {
-        QRect r = (*it)->geometry().intersect( QRect( 0, 0, displayWidth(), displayHeight()));
-        if( !r.isEmpty())
-            {
-            assert( this->windows.contains( *it ));
-            Window& w = this->windows[ *it ];
-            w.bindTexture();
-// TODO for double-buffered root            glDrawBuffer( GL_BACK );
-            glXMakeContextCurrent( display(), glxroot, glxroot, context );
-            glPushMatrix();
-            glTranslatef( w.glX(), w.glY(), 0 );
-            glEnable( GL_TEXTURE_RECTANGLE_ARB );
-            glBegin( GL_QUADS );
-            foreach( QRect r, w.shape().rects())
-                quadDraw( r.x(), w.height() - r.y() - r.height(), r.width(), r.height());
-            glEnd();
-            glPopMatrix();
-            glDisable( GL_TEXTURE_RECTANGLE_ARB );
-            glBindTexture( GL_TEXTURE_RECTANGLE_ARB, 0 );
-            }
+        Toplevel* c = windows[ i ];
+        assert( this->windows.contains( c ));
+        Window& w = this->windows[ c ];
+        w.setDepth( --depth );
+        if( !w.isVisible())
+            continue;
+        if( !w.isOpaque())
+            continue;
+        w.bindTexture();
+        w.draw();
         }
+    for( int i = 0;
+         i < windows.count();
+         ++i )
+        {
+        Toplevel* c = windows[ i ];
+        assert( this->windows.contains( c ));
+        Window& w = this->windows[ c ];
+        if( !w.isVisible())
+            continue;
+        if( w.isOpaque())
+            continue;
+        w.bindTexture();
+        glEnable( GL_BLEND );
+        glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
+        w.draw();
+        glDisable( GL_BLEND );
+        }
     glFlush();
     glXWaitGL();
     XCopyArea( display(), buffer, rootWindow(), gcroot, 0, 0, displayWidth(), displayHeight(), 0, 0 );
@@ -183,6 +193,7 @@
     , glxpixmap( None )
     , texture( None )
     , shape_valid( false )
+    , depth( 0 )
     {
     }
 
@@ -204,12 +215,26 @@
     return glxpixmap;
     }
 
+// for relative window positioning
+void SceneOpenGL::Window::setDepth( int d )
+    {
+    depth = d;
+    }
+
 void SceneOpenGL::Window::bindTexture()
     {
     GLXDrawable pixmap = glxPixmap();
     glXMakeContextCurrent( display(), pixmap, pixmap, context );
     glReadBuffer( GL_FRONT );
     glDrawBuffer( GL_FRONT );
+    if( !toplevel->hasAlpha() && toplevel->opacity() != 1.0 )
+        {
+        // TODO this doesn't quite work with the decoration
+        glColorMask( 0, 0, 0, 1 );
+        glClearColor( 0, 0, 0, toplevel->opacity());
+        glClear( GL_COLOR_BUFFER_BIT );
+        glColorMask( 1, 1, 1, 1 );
+        }
     if( texture == None )
         {
         glGenTextures( 1, &texture );
@@ -266,4 +291,33 @@
     return shape_region;
     }
 
+void SceneOpenGL::Window::draw()
+    {
+// TODO for double-buffered root            glDrawBuffer( GL_BACK );
+    glXMakeContextCurrent( display(), glxroot, glxroot, context );
+    glPushMatrix();
+    glTranslatef( glX(), glY(), depth );
+    glEnable( GL_TEXTURE_RECTANGLE_ARB );
+    glBegin( GL_QUADS );
+    foreach( QRect r, shape().rects())
+        quadDraw( r.x(), height() - r.y() - r.height(), r.width(), r.height());
+    glEnd();
+    glPopMatrix();
+    glDisable( GL_TEXTURE_RECTANGLE_ARB );
+    glBindTexture( GL_TEXTURE_RECTANGLE_ARB, 0 );
+    }
+
+bool SceneOpenGL::Window::isVisible() const
+    {
+    // TODO mapping state?
+    return !toplevel->geometry()
+        .intersect( QRect( 0, 0, displayWidth(), displayHeight()))
+        .isEmpty();
+    }
+
+bool SceneOpenGL::Window::isOpaque() const
+    {
+    return toplevel->opacity() == 1.0 && !toplevel->hasAlpha();
+    }
+
 } // namespace
--- branches/work/kwin_composite/scene_opengl.h #590750:590751
@@ -36,7 +36,7 @@
         Pixmap buffer;
         GLXFBConfig fbcroot;
         static GLXFBConfig fbcdrawable;
-        GLXPixmap glxroot;
+        static GLXPixmap glxroot;
         static GLXContext context;
         class Window;
         QMap< Toplevel*, Window > windows;
@@ -52,6 +52,10 @@
         int glY() const;
         int width() const;
         int height() const;
+        void setDepth( int depth );
+        void draw();
+        bool isVisible() const;
+        bool isOpaque() const;
         GLXPixmap glxPixmap() const;
         void bindTexture();
         QRegion shape() const;
@@ -65,6 +69,7 @@
         Texture texture;
         mutable QRegion shape_region;
         mutable bool shape_valid;
+        int depth;
     };
 
 inline
--- branches/work/kwin_composite/toplevel.h #590750:590751
@@ -57,6 +57,7 @@
         Visual* visual() const;
         bool shape() const;
         virtual double opacity() const = 0;
+        bool hasAlpha() const;
         void setupCompositing();
         void finishCompositing();
         void addDamage( const QRect& r );
@@ -70,6 +71,7 @@
         void damageNotifyEvent( XDamageNotifyEvent* e );
         QRect geom;
         Visual* vis;
+        int depth;
         virtual void debug( kdbgstream& stream ) const = 0;
         friend kdbgstream& operator<<( kdbgstream& stream, const Toplevel* );
     private:
@@ -197,6 +199,11 @@
     return is_shape;
     }
 
+inline bool Toplevel::hasAlpha() const
+    {
+    return depth == 32;
+    }
+
 #ifdef NDEBUG
 inline
 kndbgstream& operator<<( kndbgstream& stream, const Toplevel* ) { return stream; }
--- branches/work/kwin_composite/unmanaged.cpp #590750:590751
@@ -39,6 +39,7 @@
     setHandle( w );
     geom = QRect( attr.x, attr.y, attr.width, attr.height );
     vis = attr.visual;
+    depth = attr.depth;
     unsigned long properties[ 2 ];
     properties[ NETWinInfo::PROTOCOLS ] =
         NET::WMWindowType |
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic