Opengl transparency.
svn path=/branches/work/kwin_composite/; revision=590751icc-effect-5.14.5
parent
ace6b4ad8a
commit
d65ebbcb5f
|
@ -54,6 +54,7 @@ bool Client::manage( Window w, bool isMapped )
|
|||
embedClient( w, attr );
|
||||
|
||||
vis = attr.visual;
|
||||
depth = attr.depth;
|
||||
|
||||
setupCompositing();
|
||||
|
||||
|
|
102
scene_opengl.cpp
102
scene_opengl.cpp
|
@ -28,6 +28,7 @@ namespace KWinInternal
|
|||
|
||||
GLXFBConfig SceneOpenGL::fbcdrawable;
|
||||
GLXContext SceneOpenGL::context;
|
||||
GLXPixmap SceneOpenGL::glxroot;
|
||||
|
||||
const int root_attrs[] =
|
||||
{
|
||||
|
@ -88,7 +89,7 @@ SceneOpenGL::SceneOpenGL( Workspace* ws )
|
|||
glMatrixMode( GL_PROJECTION );
|
||||
glLoadIdentity();
|
||||
glOrtho( 0, displayWidth(), 0, displayHeight(), 0, 65535 );
|
||||
// TODO glEnable( GL_DEPTH_TEST );
|
||||
glEnable( GL_DEPTH_TEST );
|
||||
checkGLError( "Init" );
|
||||
}
|
||||
|
||||
|
@ -122,30 +123,39 @@ void SceneOpenGL::paint( QRegion, ToplevelList windows )
|
|||
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();
|
||||
|
@ -183,6 +193,7 @@ SceneOpenGL::Window::Window( Toplevel* c )
|
|||
, glxpixmap( None )
|
||||
, texture( None )
|
||||
, shape_valid( false )
|
||||
, depth( 0 )
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -204,12 +215,26 @@ GLXPixmap SceneOpenGL::Window::glxPixmap() const
|
|||
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 @@ QRegion SceneOpenGL::Window::shape() const
|
|||
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
|
||||
|
|
|
@ -36,7 +36,7 @@ class SceneOpenGL
|
|||
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 @@ class SceneOpenGL::Window
|
|||
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 @@ class SceneOpenGL::Window
|
|||
Texture texture;
|
||||
mutable QRegion shape_region;
|
||||
mutable bool shape_valid;
|
||||
int depth;
|
||||
};
|
||||
|
||||
inline
|
||||
|
|
|
@ -57,6 +57,7 @@ class Toplevel
|
|||
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 @@ class Toplevel
|
|||
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 @@ inline bool Toplevel::shape() const
|
|||
return is_shape;
|
||||
}
|
||||
|
||||
inline bool Toplevel::hasAlpha() const
|
||||
{
|
||||
return depth == 32;
|
||||
}
|
||||
|
||||
#ifdef NDEBUG
|
||||
inline
|
||||
kndbgstream& operator<<( kndbgstream& stream, const Toplevel* ) { return stream; }
|
||||
|
|
|
@ -39,6 +39,7 @@ bool Unmanaged::track( Window w )
|
|||
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 |
|
||||
|
|
Loading…
Reference in New Issue