Use GL_CONSTANT_ALPHA instead of reducing the opacity in the fragment shader.

This makes the blending work correctly when the alpha bits are zero,
which is apparently the case with NVidia.

svn path=/trunk/KDE/kdebase/workspace/; revision=1102471
This commit is contained in:
Fredrik Höglund 2010-03-12 16:10:57 +00:00
parent c82351488e
commit 69ab6ec3b7
3 changed files with 6 additions and 31 deletions

View file

@ -191,7 +191,6 @@ void BlurEffect::drawWindow(EffectWindow *w, int mask, QRegion region, WindowPai
shader->bind();
shader->setDirection(Qt::Horizontal);
shader->setPixelDistance(1.0 / r.width());
shader->setOpacity(1.0);
glBegin(GL_QUADS);
glTexCoord2f(0, 1); glVertex2i(0, 0);
@ -214,11 +213,10 @@ void BlurEffect::drawWindow(EffectWindow *w, int mask, QRegion region, WindowPai
// Modulate the blurred texture with the window opacity if the window isn't opaque
const float opacity = data.opacity * data.contents_opacity;
if (opacity < 1.0) {
shader->setOpacity(opacity);
glPushAttrib(GL_COLOR_BUFFER_BIT);
glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
glBlendColor(0, 0, 0, opacity);
glBlendFunc(GL_CONSTANT_ALPHA, GL_ONE_MINUS_CONSTANT_ALPHA);
}
int vertexCount = shape.rectCount() * 4;

View file

@ -137,15 +137,6 @@ void GLSLBlurShader::setPixelDistance(float val)
glUniform2fv(uPixelSize, 1, pixelSize);
}
void GLSLBlurShader::setOpacity(float val)
{
if (!isValid())
return;
const float opacity[4] = { val, val, val, val };
glUniform4fv(uOpacity, 1, opacity);
}
void GLSLBlurShader::bind()
{
if (!isValid())
@ -239,7 +230,7 @@ void GLSLBlurShader::init()
stream << "\n";
stream << "void main(void)\n";
stream << "{\n";
stream << " gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;\n";
stream << " gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;\n\n";
for (int i = 0; i < center; i++)
stream << " samplePos" << i << " = gl_TexCoord[0].st + pixelSize * vec2("
@ -257,8 +248,7 @@ void GLSLBlurShader::init()
// ===================================================================
QTextStream stream2(&fragmentSource);
stream2 << "uniform sampler2D texUnit;\n";
stream2 << "uniform vec4 opacity;\n\n";
stream2 << "uniform sampler2D texUnit;\n\n";
for (int i = 0; i < size; i++)
stream2 << "varying vec2 samplePos" << i << ";\n";
stream2 << "\n";
@ -272,7 +262,7 @@ void GLSLBlurShader::init()
for (int i = 1; i < size; i++)
stream2 << " sum += texture2D(texUnit, samplePos" << i << ") * kernel"
<< (i > center ? size - i - 1 : i) << ";\n";
stream2 << " gl_FragColor = sum * opacity;\n";
stream2 << " gl_FragColor = sum;\n";
stream2 << "}\n";
stream2.flush();
@ -291,7 +281,6 @@ void GLSLBlurShader::init()
if (program) {
uTexUnit = glGetUniformLocation(program, "texUnit");
uPixelSize = glGetUniformLocation(program, "pixelSize");
uOpacity = glGetUniformLocation(program, "opacity");
}
setIsValid(program != 0);
@ -337,11 +326,6 @@ void ARBBlurShader::setPixelDistance(float val)
}
}
void ARBBlurShader::setOpacity(float val)
{
glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 2, val, val, val, val);
}
void ARBBlurShader::bind()
{
if (!isValid())
@ -388,7 +372,6 @@ void ARBBlurShader::init()
stream << "PARAM firstSample = program.local[0];\n"; // Distance from gl_TexCoord[0] to the next sample
stream << "PARAM nextSample = program.local[1];\n"; // Distance to the subsequent sample
stream << "PARAM opacity = program.local[2];\n"; // The opacity with which to modulate the pixels
stream << "TEMP coord;\n"; // The coordinate we'll be sampling
stream << "TEMP sample;\n"; // The sampled value
@ -415,7 +398,7 @@ void ARBBlurShader::init()
stream << "TEX sample, coord, texture[0], 2D;\n"; // sample = texture2D(tex, coord)
stream << "MAD sum, sample, kernel" << center - i << ", sum;\n"; // sum += sample * kernel[center - i]
}
stream << "MUL result.color, sum, opacity;\n"; // gl_FragColor = sum * opacity
stream << "MOV result.color, sum;\n"; // gl_FragColor = sum
stream << "END\n";
stream.flush();

View file

@ -46,9 +46,6 @@ public:
// Sets the distance between two pixels
virtual void setPixelDistance(float val) = 0;
// The opacity of the resulting pixels is multiplied by this value
virtual void setOpacity(float val) = 0;
virtual void bind() = 0;
virtual void unbind() = 0;
@ -78,7 +75,6 @@ public:
~GLSLBlurShader();
void setPixelDistance(float val);
void setOpacity(float val);
void bind();
void unbind();
@ -94,7 +90,6 @@ private:
GLuint program;
int uTexUnit;
int uPixelSize;
int uOpacity;
};
@ -110,7 +105,6 @@ public:
~ARBBlurShader();
void setPixelDistance(float val);
void setOpacity(float val);
void bind();
void unbind();