From aeafa63a94c7bfe8e5aab89974c37aad103a9ca3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lubo=C5=A1=20Lu=C5=88=C3=A1k?= Date: Wed, 8 Nov 2006 19:10:07 +0000 Subject: [PATCH] Move some OpenGL code to glutils.* . Add support for changing window brightness. Add DialogParent effect that makes windows that are unaccessible because of modal dialogs darker. Patch by Rivo Laks. svn path=/branches/work/kwin_composite/; revision=603384 --- CMakeLists.txt | 2 + COMPOSITE_TODO | 1 + effects.cpp | 2 + effects.h | 2 + effects/dialogparent.cpp | 117 ++++++++++++++++++++++++++++++++++++ effects/dialogparent.h | 47 +++++++++++++++ glutils.cpp | 84 ++++++++++++++++++++++++++ glutils.h | 84 ++++++++++++++++++++++++++ scene_opengl.cpp | 125 ++++++++++++++------------------------- 9 files changed, 382 insertions(+), 82 deletions(-) create mode 100644 effects/dialogparent.cpp create mode 100644 effects/dialogparent.h create mode 100644 glutils.cpp create mode 100644 glutils.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 1f3f29ae82..aef1298c08 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -50,6 +50,7 @@ set(kwin_KDEINIT_SRCS scene_basic.cpp scene_xrender.cpp scene_opengl.cpp + glutils.cpp effects.cpp effects/fadein.cpp effects/maketransparent.cpp @@ -57,6 +58,7 @@ set(kwin_KDEINIT_SRCS effects/shakymove.cpp effects/shiftworkspaceup.cpp effects/howto.cpp + effects/dialogparent.cpp ) kde4_automoc(kwin ${kwin_KDEINIT_SRCS}) diff --git a/COMPOSITE_TODO b/COMPOSITE_TODO index d3d587ddf4..7d7f12e395 100644 --- a/COMPOSITE_TODO +++ b/COMPOSITE_TODO @@ -147,6 +147,7 @@ XRender TODO - note that the matrix used seems to be weird (it doesn't act like the normal transformation matrix as far as I can tell) + SceneXrender::Window::performPaint() doesn't use saturation ++ SceneXrender::Window::performPaint() doesn't use brightness Effects framework TODO diff --git a/effects.cpp b/effects.cpp index 7861c5b643..da0afd6ac3 100644 --- a/effects.cpp +++ b/effects.cpp @@ -14,6 +14,7 @@ License. See the file "COPYING" for the exact licensing terms. #include "client.h" #include "scene.h" +#include "effects/dialogparent.h" #include "effects/fadein.h" #include "effects/howto.h" #include "effects/maketransparent.h" @@ -94,6 +95,7 @@ EffectsHandler::EffectsHandler( Workspace* ws ) // effects.append( new ShiftWorkspaceUpEffect( ws )); // effects.append( new FadeInEffect ); // effects.append( new ScaleInEffect ); +// effects.append( new DialogParentEffect ); } EffectsHandler::~EffectsHandler() diff --git a/effects.h b/effects.h index 0e3837965d..adc3df952f 100644 --- a/effects.h +++ b/effects.h @@ -31,6 +31,7 @@ class WindowPaintData int xTranslate; int yTranslate; float saturation; + float brightness; }; class ScreenPaintData @@ -92,6 +93,7 @@ WindowPaintData::WindowPaintData() , xTranslate( 0 ) , yTranslate( 0 ) , saturation( 1 ) + , brightness( 1 ) { } diff --git a/effects/dialogparent.cpp b/effects/dialogparent.cpp new file mode 100644 index 0000000000..24754d975c --- /dev/null +++ b/effects/dialogparent.cpp @@ -0,0 +1,117 @@ +/***************************************************************** + KWin - the KDE window manager + This file is part of the KDE project. + +Copyright (C) 2006 Rivo Laks + +You can Freely distribute this program under the GNU General Public +License. See the file "COPYING" for the exact licensing terms. +******************************************************************/ + + +#include "dialogparent.h" + +#include + +// Note that currently effects need to be manually enabled in the EffectsHandler +// class constructor (in effects.cpp). + +namespace KWinInternal +{ + +void DialogParentEffect::prePaintWindow( Scene::Window* w, int* mask, QRegion* region, int time ) + { + // How long does it take for the effect to get it's full strength (in ms) + const float changeTime = 200; + + // Check if this window has a modal dialog and change the window's + // effect's strength accordingly + bool hasDialog = hasModalWindow(w->window()); + if( hasDialog ) + { + // Increase effect strength of this window + effectStrength[w] = qMin(1.0f, effectStrength[w] + time/changeTime); + } + else + { + effectStrength[w] = qMax(0.0f, effectStrength[w] - time/changeTime); + } + + // Call the next effect + effects->prePaintWindow( w, mask, region, time ); + } + +void DialogParentEffect::paintWindow( Scene::Window* w, int mask, QRegion region, WindowPaintData& data ) + { + float s = effectStrength[w]; + if(s > 0.0f) + { + // Brightness will be within [1.0; 0.6] + data.brightness *= (1.0 - s * 0.4); + // Saturation within [1.0; 0.4] + data.saturation *= (1.0 - s * 0.6); + } + + // Call the next effect. + effects->paintWindow( w, mask, region, data ); + } + +void DialogParentEffect::postPaintWindow( Scene::Window* w ) + { + float s = effectStrength[w]; + + // If strength is between 0 and 1, the effect is still in progress and the + // window has to be repainted during the next pass + if( s > 0.0 && s < 1.0 ) + w->window()->addDamageFull(); // trigger next animation repaint + + // Call the next effect. + effects->postPaintWindow( w ); + } + +void DialogParentEffect::windowActivated( Toplevel* t ) + { + // If this window is a dialog, we need to damage it's parent window, so + // that the effect could be run for it + // Set the window to be faded (or NULL if no window is active). + Client* c = qobject_cast(t); + if ( c && c->isModal() ) + { + // c is a modal dialog + Client* parent = c->transientFor(); + if ( parent ) + parent->addDamageFull(); + } + } + +void DialogParentEffect::windowDeleted( Toplevel* t ) + { + // If this window is a dialog, we need to damage it's parent window, so + // that the effect could be run for it + // Set the window to be faded (or NULL if no window is active). + Client* c = qobject_cast(t); + if ( c && c->isModal() ) + { + // c is a modal dialog + Client* parent = c->transientFor(); + if ( parent ) + parent->addDamageFull(); + } + } + +bool DialogParentEffect::hasModalWindow( Toplevel* t ) + { + Client* c = qobject_cast(t); + if( !c ) + return false; + + // Check if any of the direct transients (children) of this window is modal + for( ClientList::ConstIterator it = c->transients().begin(); it != c->transients().end(); ++it ) + if( (*it)->isModal() && (*it)->transientFor() == c ) + return true; + + return false; + } + + +} // namespace diff --git a/effects/dialogparent.h b/effects/dialogparent.h new file mode 100644 index 0000000000..aa622e654b --- /dev/null +++ b/effects/dialogparent.h @@ -0,0 +1,47 @@ +/***************************************************************** + KWin - the KDE window manager + This file is part of the KDE project. + +Copyright (C) 2006 Rivo Laks + +You can Freely distribute this program under the GNU General Public +License. See the file "COPYING" for the exact licensing terms. +******************************************************************/ + +#ifndef KWIN_DIALOGPARENT_H +#define KWIN_DIALOGPARENT_H + +// Include with base class for effects. +#include + + +namespace KWinInternal +{ + +/** + * An effect which changes saturation and brighness of windows which have + * active modal dialogs. + * This should make the dialog seem more important and emphasize that the + * window is inactive until the dialog is closed. + **/ +class DialogParentEffect + : public Effect + { + public: + virtual void prePaintWindow( Scene::Window* w, int* mask, QRegion* region, int time ); + virtual void paintWindow( Scene::Window* w, int mask, QRegion region, WindowPaintData& data ); + virtual void postPaintWindow( Scene::Window* w ); + + virtual void windowDeleted( Toplevel* c ); + virtual void windowActivated( Toplevel* c ); + + protected: + bool hasModalWindow( Toplevel* t ); + private: + // The progress of the fading. + QMap effectStrength; + }; + +} // namespace + +#endif diff --git a/glutils.cpp b/glutils.cpp new file mode 100644 index 0000000000..728c466a35 --- /dev/null +++ b/glutils.cpp @@ -0,0 +1,84 @@ +/***************************************************************** + KWin - the KDE window manager + This file is part of the KDE project. + +Copyright (C) 2006 Rivo Laks + +You can Freely distribute this program under the GNU General Public +License. See the file "COPYING" for the exact licensing terms. +******************************************************************/ + +#include "glutils.h" + +#include + + +namespace KWinInternal +{ +// Variables +// GL version, use MAKE_OPENGL_VERSION() macro for comparing with a specific version +int glVersion; +// List of all supported GL extensions +QStringList glExtensions; +int glTextureUnitsCount; + +// Function pointers +glXGetProcAddress_func glXGetProcAddress; +// texture_from_pixmap extension functions +glXReleaseTexImageEXT_func glXReleaseTexImageEXT; +glXBindTexImageEXT_func glXBindTexImageEXT; +// glActiveTexture +glActiveTexture_func glActiveTexture; + + +// Functions +static glXFuncPtr getProcAddress( const char* name ) + { + glXFuncPtr ret = NULL; + if( glXGetProcAddress != NULL ) + ret = glXGetProcAddress( ( const GLubyte* ) name ); + if( ret == NULL ) + ret = ( glXFuncPtr ) dlsym( RTLD_DEFAULT, name ); + return ret; + } + +void initGLX() +{ + // handle OpenGL extensions functions + glXGetProcAddress = (glXGetProcAddress_func) getProcAddress( "glxGetProcAddress" ); + if( glXGetProcAddress == NULL ) + glXGetProcAddress = (glXGetProcAddress_func) getProcAddress( "glxGetProcAddressARB" ); + glXBindTexImageEXT = (glXBindTexImageEXT_func) getProcAddress( "glXBindTexImageEXT" ); + glXReleaseTexImageEXT = (glXReleaseTexImageEXT_func) getProcAddress( "glXReleaseTexImageEXT" ); +} + +void initGL() +{ + // handle OpenGL extensions functions + glActiveTexture = (glActiveTexture_func) getProcAddress( "glActiveTexture" ); + if( !glActiveTexture ) + glActiveTexture = (glActiveTexture_func) getProcAddress( "glActiveTextureARB" ); + + + // Get OpenGL version + QString glversionstring = QString((const char*)glGetString(GL_VERSION)); + QStringList glversioninfo = glversionstring.left(glversionstring.indexOf(' ')).split('.'); + glVersion = MAKE_OPENGL_VERSION(glversioninfo[0].toInt(), glversioninfo[1].toInt(), + glversioninfo.count() > 2 ? glversioninfo[2].toInt() : 0); + // Get list of supported OpenGL extensions + glExtensions = QString((const char*)glGetString(GL_EXTENSIONS)).split(" "); + // Get number of texture units + glGetIntegerv(GL_MAX_TEXTURE_UNITS, &glTextureUnitsCount); +} + +bool hasGLVersion(int major, int minor, int release) +{ + return glVersion >= MAKE_OPENGL_VERSION(major, minor, release); +} +bool hasGLExtension(const QString& extension) +{ + return glExtensions.contains(extension); +} + + +} // namespace diff --git a/glutils.h b/glutils.h new file mode 100644 index 0000000000..dc6a135871 --- /dev/null +++ b/glutils.h @@ -0,0 +1,84 @@ +/***************************************************************** + KWin - the KDE window manager + This file is part of the KDE project. + +Copyright (C) 2006 Rivo Laks + +You can Freely distribute this program under the GNU General Public +License. See the file "COPYING" for the exact licensing terms. +******************************************************************/ + +#ifndef KWIN_GLUTILS_H +#define KWIN_GLUTILS_H + + +#include "utils.h" + +#include + +#include +#include +#include +#include + + +#define MAKE_OPENGL_VERSION(major, minor, release) ( ((major) << 16) | ((minor) << 8) | (release) ) + + +namespace KWinInternal +{ + + +// Initializes GLX function pointers +void initGLX(); +// Initializes OpenGL stuff. This includes resolving function pointers as +// well as checking for GL version and extensions +// Note that GL context has to be created by the time this function is called +void initGL(); + + +// Number of supported texture units +extern int glTextureUnitsCount; + + +bool hasGLVersion(int major, int minor, int release = 0); +bool hasGLExtension(const QString& extension); + + +// Defines +/* +** GLX_EXT_texture_from_pixmap +*/ +#define GLX_BIND_TO_TEXTURE_RGB_EXT 0x20D0 +#define GLX_BIND_TO_TEXTURE_RGBA_EXT 0x20D1 +#define GLX_BIND_TO_MIPMAP_TEXTURE_EXT 0x20D2 +#define GLX_BIND_TO_TEXTURE_TARGETS_EXT 0x20D3 +#define GLX_Y_INVERTED_EXT 0x20D4 + +#define GLX_TEXTURE_FORMAT_EXT 0x20D5 +#define GLX_TEXTURE_TARGET_EXT 0x20D6 +#define GLX_MIPMAP_TEXTURE_EXT 0x20D7 + +#define GLX_TEXTURE_FORMAT_NONE_EXT 0x20D8 +#define GLX_TEXTURE_FORMAT_RGB_EXT 0x20D9 +#define GLX_TEXTURE_FORMAT_RGBA_EXT 0x20DA + + +// Function pointers +// finding of OpenGL extensions functions +typedef void (*glXFuncPtr)(); +typedef glXFuncPtr (*glXGetProcAddress_func)( const GLubyte* ); +extern glXGetProcAddress_func glXGetProcAddress; +// texture_from_pixmap extension functions +typedef void (*glXBindTexImageEXT_func)( Display* dpy, GLXDrawable drawable, + int buffer, const int* attrib_list ); +typedef void (*glXReleaseTexImageEXT_func)( Display* dpy, GLXDrawable drawable, int buffer ); +extern glXReleaseTexImageEXT_func glXReleaseTexImageEXT; +extern glXBindTexImageEXT_func glXBindTexImageEXT; +// glActiveTexture +typedef void (*glActiveTexture_func)(GLenum); +extern glActiveTexture_func glActiveTexture; + +} // namespace + +#endif diff --git a/scene_opengl.cpp b/scene_opengl.cpp index 0821ec6d29..8b23cc5c78 100644 --- a/scene_opengl.cpp +++ b/scene_opengl.cpp @@ -58,30 +58,7 @@ Sources and other compositing managers: #include "utils.h" #include "client.h" #include "effects.h" - -#include - -#include -#include -#include - -/* -** GLX_EXT_texture_from_pixmap -*/ -#define GLX_BIND_TO_TEXTURE_RGB_EXT 0x20D0 -#define GLX_BIND_TO_TEXTURE_RGBA_EXT 0x20D1 -#define GLX_BIND_TO_MIPMAP_TEXTURE_EXT 0x20D2 -#define GLX_BIND_TO_TEXTURE_TARGETS_EXT 0x20D3 -#define GLX_Y_INVERTED_EXT 0x20D4 - -#define GLX_TEXTURE_FORMAT_EXT 0x20D5 -#define GLX_TEXTURE_TARGET_EXT 0x20D6 -#define GLX_MIPMAP_TEXTURE_EXT 0x20D7 - -#define GLX_TEXTURE_FORMAT_NONE_EXT 0x20D8 -#define GLX_TEXTURE_FORMAT_RGB_EXT 0x20D9 -#define GLX_TEXTURE_FORMAT_RGBA_EXT 0x20DA - +#include "glutils.h" namespace KWinInternal { @@ -102,30 +79,7 @@ bool SceneOpenGL::db; // destination drawable is double-buffered bool SceneOpenGL::copy_buffer_hack; // workaround for nvidia < 1.0-9xxx drivers bool SceneOpenGL::supports_saturation; -// finding of OpenGL extensions functions -typedef void (*glXFuncPtr)(); -typedef glXFuncPtr (*glXGetProcAddress_func)( const GLubyte* ); -glXGetProcAddress_func glXGetProcAddress; -static glXFuncPtr getProcAddress( const char* name ) - { - glXFuncPtr ret = NULL; - if( glXGetProcAddress != NULL ) - ret = glXGetProcAddress( ( const GLubyte* ) name ); - if( ret == NULL ) - ret = ( glXFuncPtr ) dlsym( RTLD_DEFAULT, name ); - return ret; - } - -// texture_from_pixmap extension functions -typedef void (*glXBindTexImageEXT_func)( Display* dpy, GLXDrawable drawable, - int buffer, const int* attrib_list ); -typedef void (*glXReleaseTexImageEXT_func)( Display* dpy, GLXDrawable drawable, int buffer ); -glXReleaseTexImageEXT_func glXReleaseTexImageEXT; -glXBindTexImageEXT_func glXBindTexImageEXT; -// glActiveTexture -typedef void (*glActiveTexture_func)(GLenum); -glActiveTexture_func glActiveTexture; // detect OpenGL error (add to various places in code to pinpoint the place) static void checkGLError( const char* txt ) @@ -212,12 +166,7 @@ SceneOpenGL::SceneOpenGL( Workspace* ws ) int dummy; if( !glXQueryExtension( display(), &dummy, &dummy )) return; - // handle OpenGL extensions functions - glXGetProcAddress = (glXGetProcAddress_func) getProcAddress( "glxGetProcAddress" ); - if( glXGetProcAddress == NULL ) - glXGetProcAddress = (glXGetProcAddress_func) getProcAddress( "glxGetProcAddressARB" ); - glXBindTexImageEXT = (glXBindTexImageEXT_func) getProcAddress( "glXBindTexImageEXT" ); - glXReleaseTexImageEXT = (glXReleaseTexImageEXT_func) getProcAddress( "glXReleaseTexImageEXT" ); + initGLX(); tfp_mode = ( glXBindTexImageEXT != NULL && glXReleaseTexImageEXT != NULL ); // use copy buffer hack from glcompmgr (called COPY_BUFFER there) - nvidia drivers older than // 1.0-9xxx don't update pixmaps properly, so do a copy first @@ -243,24 +192,17 @@ SceneOpenGL::SceneOpenGL( Workspace* ws ) ctxbuffer = glXCreateNewContext( display(), fbcbuffer, GLX_RGBA_TYPE, NULL, GL_FALSE ); ctxdrawable = glXCreateNewContext( display(), fbcdrawable, GLX_RGBA_TYPE, ctxbuffer, GL_FALSE ); glXMakeContextCurrent( display(), glxbuffer, glxbuffer, ctxbuffer ); + + // Initialize OpenGL + initGL(); if( db ) glDrawBuffer( GL_BACK ); - // Get OpenGL version - QString glversionstring = QString((const char*)glGetString(GL_VERSION)); - QStringList glversioninfo = glversionstring.left(glversionstring.indexOf(' ')).split('.'); - int glversionmajor = glversioninfo[0].toInt(); - int glversionminor = glversioninfo[1].toInt(); - int glversion = glversionmajor*100 + glversionminor; - // Get list of supported OpenGL extensions - QStringList extensions = QString((const char*)glGetString(GL_EXTENSIONS)).split(" "); - // Get number of texture units - int textureUnitsCount; - glGetIntegerv(GL_MAX_TEXTURE_UNITS, &textureUnitsCount); + // Check whether certain features are supported - glActiveTexture = (glActiveTexture_func) getProcAddress( "glActiveTexture" ); - supports_saturation = ((extensions.contains("GL_ARB_texture_env_crossbar") - && extensions.contains("GL_ARB_texture_env_dot3")) || glversion >= 104) - && (textureUnitsCount >= 4) && glActiveTexture != NULL; + supports_saturation = ((hasGLExtension("GL_ARB_texture_env_crossbar") + && hasGLExtension("GL_ARB_texture_env_dot3")) || hasGLVersion(1, 4)) + && (glTextureUnitsCount >= 4) && glActiveTexture != NULL; + // OpenGL scene setup glMatrixMode( GL_PROJECTION ); glLoadIdentity(); @@ -777,9 +719,8 @@ void SceneOpenGL::Window::performPaint( int mask, QRegion region, WindowPaintDat glEnable( GL_TEXTURE_RECTANGLE_ARB ); glBindTexture( GL_TEXTURE_RECTANGLE_ARB, texture ); - if( toplevel->hasAlpha() ) + if( toplevel->hasAlpha() || data.brightness != 1.0f ) { - // Modulate both color and alpha by window's opacity glActiveTexture( GL_TEXTURE3 ); glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE ); glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE ); @@ -787,37 +728,57 @@ void SceneOpenGL::Window::performPaint( int mask, QRegion region, WindowPaintDat glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR ); glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_PRIMARY_COLOR ); glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR ); - // Here we have to multiply original texture's alpha by our opacity - glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE ); - glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_TEXTURE0 ); - glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA ); - glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_ALPHA, GL_PRIMARY_COLOR ); - glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA ); + if( toplevel->hasAlpha() ) + { + // The color has to be multiplied by both opacity and brightness + float opacityByBrightness = data.opacity * data.brightness; + glColor4f( opacityByBrightness, opacityByBrightness, opacityByBrightness, data.opacity ); + // Also multiply original texture's alpha by our opacity + glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE ); + glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_TEXTURE0 ); + glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA ); + glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_ALPHA, GL_PRIMARY_COLOR ); + glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA ); + } + else + { + // Color has to be multiplied only by brightness + glColor4f( data.brightness, data.brightness, data.brightness, data.opacity ); + // Alpha will be taken from previous stage + glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE ); + glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_PREVIOUS ); + glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA ); + } glEnable( GL_TEXTURE_RECTANGLE_ARB ); glBindTexture( GL_TEXTURE_RECTANGLE_ARB, texture ); } glActiveTexture(GL_TEXTURE0 ); } - else if( data.opacity != 1.0 ) + else if( data.opacity != 1.0 || data.brightness != 1.0 ) { // the window is additionally configured to have its opacity adjusted, // do it if( toplevel->hasAlpha()) { + float opacityByBrightness = data.opacity * data.brightness; glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); - glColor4f( data.opacity, data.opacity, data.opacity, + glColor4f( opacityByBrightness, opacityByBrightness, opacityByBrightness, data.opacity); } else { - float constant_alpha[] = { 0, 0, 0, data.opacity }; + // Multiply color by brightness and replace alpha by opacity + float constant[] = { data.brightness, data.brightness, data.brightness, data.opacity }; glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE ); - glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_REPLACE ); + glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE ); glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE ); + glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR ); + glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_CONSTANT ); + glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR ); glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE ); glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_CONSTANT ); - glTexEnvfv( GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, constant_alpha ); + glTexEnvfv( GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, constant ); } } glEnable( GL_TEXTURE_RECTANGLE_ARB ); @@ -840,7 +801,7 @@ void SceneOpenGL::Window::performPaint( int mask, QRegion region, WindowPaintDat } glEnd(); glPopMatrix(); - if( data.opacity != 1.0 || data.saturation != 1.0 ) + if( data.opacity != 1.0 || data.saturation != 1.0 || data.brightness != 1.0f ) { if( data.saturation != 1.0 && supports_saturation ) {