summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ksmserver/shutdowndlg.cpp20
-rw-r--r--twin/compton-tde/common.h31
-rw-r--r--twin/compton-tde/compton.c156
-rw-r--r--twin/compton-tde/opengl.c242
4 files changed, 338 insertions, 111 deletions
diff --git a/ksmserver/shutdowndlg.cpp b/ksmserver/shutdowndlg.cpp
index 5c50602cb..6573f8bd2 100644
--- a/ksmserver/shutdowndlg.cpp
+++ b/ksmserver/shutdowndlg.cpp
@@ -87,6 +87,11 @@ KSMShutdownFeedback::KSMShutdownFeedback()
m_grayImage.setAlphaBuffer(false);
m_grayImage.fill(0); // Set the alpha buffer to 0 (fully transparent)
m_grayImage.setAlphaBuffer(true);
+
+ // Signal that we want a greyscale filter on the transparency
+ Atom kde_wm_transparent_greyscale_filter;
+ kde_wm_transparent_greyscale_filter = XInternAtom(tqt_xdisplay(), "_TDE_TRANSPARENCY_FILTER_GREYSCALE_BLEND", False);
+ XChangeProperty(tqt_xdisplay(), winId(), kde_wm_transparent_greyscale_filter, XA_INTEGER, 32, PropModeReplace, (unsigned char *) "TRUE", 1L);
}
else {
// The hacks below aren't needed any more because Qt3 supports true transparency for the fading logout screen when composition is available
@@ -135,10 +140,10 @@ void KSMShutdownFeedback::slotPaintEffect()
m_root.resize( width(), height() );
TQImage blendedImage = m_grayImage;
TQPainter p;
- p.begin( &m_root );
- blendedImage.setAlphaBuffer(false);
- p.drawImage( 0, 0, blendedImage );
- p.end();
+ p.begin( &m_root );
+ blendedImage.setAlphaBuffer(false);
+ p.drawImage( 0, 0, blendedImage );
+ p.end();
setBackgroundPixmap( m_root );
setGeometry( TQApplication::desktop()->geometry() );
@@ -150,7 +155,7 @@ void KSMShutdownFeedback::slotPaintEffect()
uchar * end = m_grayImage.bits() + m_grayImage.numBytes();
while ( r != end ) {
- *reinterpret_cast<TQRgb*>(r) = tqRgba(0, 0, 0, 128);
+ *reinterpret_cast<TQRgb*>(r) = tqRgba(0, 0, 0, 255);
r += 4;
}
@@ -220,7 +225,6 @@ void KSMShutdownFeedback::slotPaintEffect()
{
TQImage img( imgWidth, y2-start_y1, 32 );
memcpy( img.bits(), m_grayImage.scanLine( start_y1 ), ( y2-start_y1 ) * imgWidth * 4 );
- register uchar * rs = m_unfadedImage.scanLine( start_y1 );
register uchar * rd = img.bits();
for( int y = start_y1; y < y2; ++y )
{
@@ -228,8 +232,8 @@ void KSMShutdownFeedback::slotPaintEffect()
short int opac = static_cast<short int>( 128 - cosf( M_PI*(y-y1)/heightUnit )*128.0f );
for( short int x = 0; x < imgWidth; ++x )
{
- *reinterpret_cast<TQRgb*>(rd) = tqRgba(0, 0, 0, ((255.0-opac)/(255.0/127.0)));
- rs += 4; rd += 4;
+ *reinterpret_cast<TQRgb*>(rd) = tqRgba(0, 0, 0, ((255.0-opac)));
+ rd += 4;
}
}
bitBlt( this, 0, start_y1, &img );
diff --git a/twin/compton-tde/common.h b/twin/compton-tde/common.h
index 759e64698..9ff5a2148 100644
--- a/twin/compton-tde/common.h
+++ b/twin/compton-tde/common.h
@@ -490,6 +490,21 @@ typedef struct {
} glx_blur_cache_t;
typedef struct {
+ /// Fragment shader for greyscale.
+ GLuint frag_shader;
+ /// GLSL program for greyscale.
+ GLuint prog;
+ /// Location of uniform "greyscale_weights" in greyscale GLSL program.
+ GLint unifm_greyscale_weights;
+ /// Location of uniform "enable_blend" in greyscale GLSL program.
+ GLint unifm_enable_blend;
+ /// Location of uniform "tex_scr" in greyscale GLSL program.
+ GLint unifm_tex_scr;
+ /// Location of uniform "alpha_scr" in greyscale GLSL program.
+ GLint unifm_alpha_scr;
+} glx_greyscale_t;
+
+typedef struct {
/// Framebuffer used for greyscale conversion.
GLuint fbo;
/// Textures used for greyscale conversion.
@@ -817,6 +832,9 @@ typedef struct {
#ifdef CONFIG_VSYNC_OPENGL_GLSL
glx_blur_pass_t blur_passes[MAX_BLUR_PASS];
#endif
+#ifdef CONFIG_VSYNC_OPENGL_GLSL
+ glx_greyscale_t greyscale_glsl;
+#endif
} glx_session_t;
#define CGLX_SESSION_INIT { .context = NULL }
@@ -1068,6 +1086,8 @@ typedef struct _session_t {
Atom atom_win_type_tde_transparent_to_desktop;
/// Atom of property <code>_TDE_TRANSPARENCY_FILTER_GREYSCALE</code>.
Atom atom_win_type_tde_transparency_filter_greyscale;
+ /// Atom of property <code>_TDE_TRANSPARENCY_FILTER_GREYSCALE_BLEND</code>.
+ Atom atom_win_type_tde_transparency_filter_greyscale_blend;
/// Array of atoms of all possible window types.
Atom atoms_wintypes[NUM_WINTYPES];
/// Linked list of additional atoms to track.
@@ -1263,6 +1283,11 @@ typedef struct _win {
/// Background state on last paint.
bool greyscale_background_last;
+ /// Whether to set window background to blended greyscale.
+ bool greyscale_blended_background;
+ /// Blended greyscale alpha divisor.
+ int greyscale_blended_background_alpha_divisor;
+
/// Whether to show black background
bool show_black_background;
@@ -2202,6 +2227,9 @@ glx_on_root_change(session_t *ps);
bool
glx_init_blur(session_t *ps);
+bool
+glx_init_greyscale(session_t *ps);
+
#ifdef CONFIG_VSYNC_OPENGL_GLSL
bool
glx_load_prog_main(session_t *ps,
@@ -2245,7 +2273,7 @@ glx_dim_dst(session_t *ps, int dx, int dy, int width, int height, float z,
bool
glx_greyscale_dst(session_t *ps, int dx, int dy, int width, int height, float z,
- XserverRegion reg_tgt, const reg_data_t *pcache_reg, glx_greyscale_cache_t *pbc);
+ glx_texture_t *ptex, XserverRegion reg_tgt, const reg_data_t *pcache_reg, glx_greyscale_cache_t *pbc);
bool
glx_render_(session_t *ps, const glx_texture_t *ptex,
@@ -2342,7 +2370,6 @@ free_glx_bc(session_t *ps, glx_blur_cache_t *pbc) {
static inline void
free_glx_gc_resize(session_t *ps, glx_greyscale_cache_t *pbc) {
free_texture_r(ps, &pbc->textures[0]);
- free_texture_r(ps, &pbc->textures[1]);
pbc->width = 0;
pbc->height = 0;
}
diff --git a/twin/compton-tde/compton.c b/twin/compton-tde/compton.c
index dea363f60..d2095123f 100644
--- a/twin/compton-tde/compton.c
+++ b/twin/compton-tde/compton.c
@@ -944,6 +944,9 @@ static Bool
determine_window_transparency_filter_greyscale(const session_t *ps, Window w);
static Bool
+determine_window_transparency_filter_greyscale_blended(const session_t *ps, Window w);
+
+static Bool
determine_window_transparent_to_black(const session_t *ps, Window w);
static Bool
@@ -1590,6 +1593,7 @@ xr_greyscale_dst(session_t *ps, Picture tgt_buffer,
XRenderComposite(ps->dpy, PictOpSrc, ps->black_picture, None,
tmp_picture, 0, 0, 0, 0, 0, 0, wid, hei);
+
XRenderComposite(ps->dpy, PictOpHSLLuminosity, tgt_buffer, None,
tmp_picture, x, y, 0, 0, 0, 0, wid, hei);
@@ -1723,7 +1727,7 @@ win_greyscale_background(session_t *ps, win *w, Picture tgt_buffer,
#ifdef CONFIG_VSYNC_OPENGL_GLSL
case BKEND_GLX:
glx_greyscale_dst(ps, x, y, wid, hei, ps->psglx->z - 0.5,
- reg_paint, pcache_reg, &w->glx_greyscale_cache);
+ NULL, reg_paint, pcache_reg, &w->glx_greyscale_cache);
break;
#endif
default:
@@ -1821,6 +1825,71 @@ win_paint_win(session_t *ps, win *w, XserverRegion reg_paint,
Picture pict = w->paint.pict;
+ if (w->greyscale_blended_background) {
+ // Set window background to greyscale
+ switch (ps->o.backend) {
+ case BKEND_XRENDER:
+ case BKEND_XR_GLX_HYBRID:
+ {
+ // Blend here such that 0 window alpha is fully colored and 100 window alpha is fully greyscale
+ // PictOpInReverse is used to copy alpha from the source to the destination while preserving destination color
+ // provided that the source has alpha set to 1 (equivalent of CAIRO_OPERATOR_DEST_IN)
+ const int x = w->a.x;
+ const int y = w->a.y;
+ const int wid = w->widthb;
+ const int hei = w->heightb;
+ XserverRegion reg_clip = reg_paint;
+ Picture tgt_buffer = ps->tgt_buffer.pict;
+
+ // Apply clipping region to save some CPU
+ if (reg_paint) {
+ XserverRegion reg = copy_region(ps, reg_paint);
+ XFixesTranslateRegion(ps->dpy, reg, -x, -y);
+ XFixesSetPictureClipRegion(ps->dpy, pict, 0, 0, reg);
+ free_region(ps, &reg);
+ }
+
+ // Create greyscale version of background
+ Picture greyscale_picture = xr_build_picture(ps, wid, hei, w->pictfmt);
+ XRenderComposite(ps->dpy, PictOpSrc, tgt_buffer, None,
+ greyscale_picture, x, y, 0, 0, 0, 0, wid, hei);
+ win_greyscale_background(ps, w, greyscale_picture, reg_paint, pcache_reg);
+
+ Picture tmp_picture = xr_build_picture(ps, wid, hei, w->pictfmt);
+
+ if (!tmp_picture) {
+ printf_errf("(): Failed to build intermediate Picture.");
+ }
+ else {
+ if (reg_clip && tmp_picture)
+ XFixesSetPictureClipRegion(ps->dpy, tmp_picture, reg_clip, 0, 0);
+
+ // Transfer greyscale picture to temporary picture
+ XRenderComposite(ps->dpy, PictOpSrc, greyscale_picture, None,
+ tmp_picture, 0, 0, 0, 0, 0, 0, wid, hei);
+
+ // Transfer alpha of window to temporary picture
+ XRenderComposite(ps->dpy, PictOpInReverse, pict, None,
+ tmp_picture, 0, 0, 0, 0, 0, 0, wid, hei);
+
+ // Blend greyscale picture over main color buffer
+ XRenderComposite(ps->dpy, PictOpOver, tmp_picture, None, tgt_buffer,
+ 0, 0, 0, 0, x, y, wid, hei);
+
+ free_picture(ps, &tmp_picture);
+ free_picture(ps, &greyscale_picture);
+ }
+ }
+ break;
+#ifdef CONFIG_VSYNC_OPENGL
+ case BKEND_GLX:
+ glx_greyscale_dst(ps, x, y, wid, hei, ps->psglx->z - 0.5,
+ w->paint.ptex, reg_paint, pcache_reg, &w->glx_greyscale_cache);
+ break;
+#endif
+ }
+ }
+
// Invert window color, if required
if (bkend_use_xrender(ps) && w->invert_color) {
Picture newpict = xr_build_picture(ps, wid, hei, w->pictfmt);
@@ -1846,7 +1915,12 @@ win_paint_win(session_t *ps, win *w, XserverRegion reg_paint,
}
}
- const double dopacity = get_opacity_percent(w);
+ double dopacity = get_opacity_percent(w);
+
+ if (w->greyscale_blended_background) {
+ double scaling_factor = (1.0 / w->greyscale_blended_background_alpha_divisor);
+ dopacity = dopacity * scaling_factor;
+ }
if (!w->frame_opacity) {
win_render(ps, w, 0, 0, wid, hei, dopacity, reg_paint, pcache_reg, pict);
@@ -2439,6 +2513,7 @@ map_win(session_t *ps, Window id) {
/* This needs to be here since we don't get PropertyNotify when unmapped */
w->opacity = wid_get_opacity_prop(ps, w->id, OPAQUE);
w->greyscale_background = determine_window_transparency_filter_greyscale(ps, id);
+ w->greyscale_blended_background = determine_window_transparency_filter_greyscale_blended(ps, id);
w->show_root_tile = determine_window_transparent_to_desktop(ps, id);
w->show_black_background = determine_window_transparent_to_black(ps, id);
@@ -2632,6 +2707,28 @@ get_window_transparency_filter_greyscale(const session_t *ps, Window w)
}
static Bool
+get_window_transparency_filter_greyscale_blended(const session_t *ps, Window w)
+{
+ Atom actual;
+ int format;
+ unsigned long n, left;
+
+ unsigned char *data;
+ int result = XGetWindowProperty (ps->dpy, w, ps->atom_win_type_tde_transparency_filter_greyscale_blend, 0L, 1L, False,
+ XA_ATOM, &actual, &format,
+ &n, &left, &data);
+
+ if (result == Success && data != None && format == 32 )
+ {
+ Atom a;
+ a = *(long*)data;
+ XFree ( (void *) data);
+ return True;
+ }
+ return False;
+}
+
+static Bool
get_window_transparent_to_desktop(const session_t *ps, Window w)
{
Atom actual;
@@ -2711,6 +2808,41 @@ determine_window_transparency_filter_greyscale (const session_t *ps, Window w)
}
static Bool
+determine_window_transparency_filter_greyscale_blended (const session_t *ps, Window w)
+{
+ Window root_return, parent_return;
+ Window *children = NULL;
+ unsigned int nchildren, i;
+ Bool type;
+
+ type = get_window_transparency_filter_greyscale_blended (ps, w);
+ if (type == True) {
+ return True;
+ }
+
+ if (!XQueryTree (ps->dpy, w, &root_return, &parent_return, &children,
+ &nchildren))
+ {
+ /* XQueryTree failed. */
+ if (children)
+ XFree ((void *)children);
+ return False;
+ }
+
+ for (i = 0;i < nchildren;i++)
+ {
+ type = determine_window_transparency_filter_greyscale_blended (ps, children[i]);
+ if (type == True)
+ return True;
+ }
+
+ if (children)
+ XFree ((void *)children);
+
+ return False;
+}
+
+static Bool
determine_window_transparent_to_desktop (const session_t *ps, Window w)
{
Window root_return, parent_return;
@@ -3449,6 +3581,8 @@ add_win(session_t *ps, Window id, Window prev) {
.blur_background = false,
.greyscale_background = false,
+ .greyscale_blended_background = false,
+ .greyscale_blended_background_alpha_divisor = 2,
.show_black_background = false,
.show_root_tile = false,
@@ -6696,6 +6830,7 @@ init_atoms(session_t *ps) {
ps->atom_win_type_tde_transparent_to_black = get_atom(ps, "_TDE_TRANSPARENT_TO_BLACK");
ps->atom_win_type_tde_transparent_to_desktop = get_atom(ps, "_TDE_TRANSPARENT_TO_DESKTOP");
ps->atom_win_type_tde_transparency_filter_greyscale = get_atom(ps, "_TDE_TRANSPARENCY_FILTER_GREYSCALE");
+ ps->atom_win_type_tde_transparency_filter_greyscale_blend = get_atom(ps, "_TDE_TRANSPARENCY_FILTER_GREYSCALE_BLEND");
}
#ifdef CONFIG_XRANDR
@@ -7136,6 +7271,22 @@ init_filters(session_t *ps) {
}
}
+ // Greyscale filter
+ switch (ps->o.backend) {
+ case BKEND_XRENDER:
+ case BKEND_XR_GLX_HYBRID:
+ {
+ break;
+ }
+#ifdef CONFIG_VSYNC_OPENGL
+ case BKEND_GLX:
+ {
+ if (!glx_init_greyscale(ps))
+ return false;
+ }
+#endif
+ }
+
return true;
}
@@ -7666,6 +7817,7 @@ session_init(session_t *ps_old, int argc, char **argv) {
.atom_win_type_tde_transparent_to_black = None,
.atom_win_type_tde_transparent_to_desktop = None,
.atom_win_type_tde_transparency_filter_greyscale = None,
+ .atom_win_type_tde_transparency_filter_greyscale_blend = None,
.atoms_wintypes = { 0 },
.track_atom_lst = NULL,
diff --git a/twin/compton-tde/opengl.c b/twin/compton-tde/opengl.c
index de485de74..4cbfeb455 100644
--- a/twin/compton-tde/opengl.c
+++ b/twin/compton-tde/opengl.c
@@ -531,6 +531,106 @@ glx_init_blur(session_t *ps) {
#endif
}
+// RAJJA FIXME
+/**
+ * Initialize GLX greyscale filter.
+ */
+bool
+glx_init_greyscale(session_t *ps) {
+#ifdef CONFIG_VSYNC_OPENGL_GLSL
+ {
+ char *lc_numeric_old = mstrcpy(setlocale(LC_NUMERIC, NULL));
+ // Enforce LC_NUMERIC locale "C" here to make sure decimal point is sane
+ setlocale(LC_NUMERIC, "C");
+
+ // Adapted from http://trac.openscenegraph.org/projects/osg//wiki/Support/Tutorials/ShadersSampleGrayingOut
+ static const char *FRAG_SHADER_GREYSCALE =
+ "#version 110\n"
+ "uniform sampler2D tex_scr;\n"
+ "uniform sampler2D alpha_scr;\n"
+ "uniform int enable_blend;\n"
+ "uniform vec4 greyscale_weights; // [0.3, 0.59, 0.11, 1.0]\n"
+ "\n"
+ "void main( void )\n"
+ "{\n"
+ " // Fetch the regular RGB texel color from the source texture\n"
+ " vec4 texel_color = texture2D( tex_scr, gl_TexCoord[0].xy );\n"
+ "\n"
+ " //\n"
+ " // Converting to grayscale:\n"
+ " //\n"
+ " // Converting an image to grayscale is done by taking a weighted average of\n"
+ " // the red, green and blue color components. The standard weights for this\n"
+ " // type of conversion are (0.30, 0.59, 0.11). Therefore, the gray component\n"
+ " // or luminance that we need to compute can be defined as a luminance\n"
+ " // filter like so:\n"
+ " //\n"
+ " // luminance = 0.30*R + 0.59*G + 0.11*B\n"
+ " //\n"
+ " // If we think of our RGB colors as vectors, we can see that this \n"
+ " // calculation is actually just a dot product.\n"
+ " //\n"
+ "\n"
+ " vec4 scaledColor = texel_color * greyscale_weights;\n"
+ " float luminance = scaledColor.r + scaledColor.g + scaledColor.b;\n"
+ "\n"
+ " if (enable_blend == 1) {\n"
+ " // Fetch the regular RGB texel color from the blend texture\n"
+ " vec4 blend_texel = texture2D( alpha_scr, vec2(gl_TexCoord[0].x, 1.0 - gl_TexCoord[0].y) );\n"
+ " vec4 grey_pixel = vec4(luminance,luminance,luminance,1);\n"
+ " gl_FragColor = mix(texel_color, grey_pixel, blend_texel.a);\n"
+ " }\n"
+ " else {\n"
+ " gl_FragColor = vec4(luminance,luminance,luminance,1);\n"
+ " }\n"
+ "\n"
+ "}";
+
+ glx_greyscale_t *greyscale_glsl = &ps->psglx->greyscale_glsl;
+ greyscale_glsl->frag_shader = glx_create_shader(GL_FRAGMENT_SHADER, FRAG_SHADER_GREYSCALE);
+
+ if (!greyscale_glsl->frag_shader) {
+ printf_errf("(): Failed to create fragment shader.");
+ return false;
+ }
+
+ // Build program
+ greyscale_glsl->prog = glx_create_program(&greyscale_glsl->frag_shader, 1);
+ if (!greyscale_glsl->prog) {
+ printf_errf("(): Failed to create GLSL program.");
+ return false;
+ }
+
+ // Get uniform addresses
+#define P_GET_UNIFM_LOC(name, target) { \
+ greyscale_glsl->target = glGetUniformLocation(greyscale_glsl->prog, name); \
+ if (greyscale_glsl->target < 0) { \
+ printf_errf("(): Failed to get location of uniform '" name "'. Might be troublesome."); \
+ } \
+ }
+
+ P_GET_UNIFM_LOC("greyscale_weights", unifm_greyscale_weights);
+ P_GET_UNIFM_LOC("enable_blend", unifm_enable_blend);
+ P_GET_UNIFM_LOC("tex_scr", unifm_tex_scr);
+ P_GET_UNIFM_LOC("alpha_scr", unifm_alpha_scr);
+
+#undef P_GET_UNIFM_LOC
+
+ // Restore LC_NUMERIC
+ setlocale(LC_NUMERIC, lc_numeric_old);
+ free(lc_numeric_old);
+ }
+
+
+ glx_check_err(ps);
+
+ return true;
+#else
+ printf_errf("(): GLSL support not compiled in. Cannot do greyscale with GLX backend.");
+ return false;
+#endif
+}
+
#ifdef CONFIG_VSYNC_OPENGL_GLSL
/**
@@ -1387,113 +1487,62 @@ glx_blur_dst_end:
bool
glx_greyscale_dst(session_t *ps, int dx, int dy, int width, int height, float z,
- XserverRegion reg_tgt, const reg_data_t *pcache_reg, glx_greyscale_cache_t *pbc) {
+ glx_texture_t *ptex, XserverRegion reg_tgt, const reg_data_t *pcache_reg, glx_greyscale_cache_t *gsc) {
+
+ glx_greyscale_t *greyscale_glsl = &ps->psglx->greyscale_glsl;
+ assert(greyscale_glsl->prog);
+
bool ret = false;
// Calculate copy region size
glx_greyscale_cache_t ibc = { .width = 0, .height = 0 };
- if (!pbc)
- pbc = &ibc;
+ if (!gsc)
+ gsc = &ibc;
#ifdef DEBUG_GLX
printf_dbgf("(): %d, %d, %d, %d\n", dx, dy, width, height);
#endif
// Free textures if size inconsistency discovered
- if (width != pbc->width || height != pbc->height)
- free_glx_gc_resize(ps, pbc);
+ if (width != gsc->width || height != gsc->height)
+ free_glx_gc_resize(ps, gsc);
- // Generate FBO and textures if needed
- if (!pbc->textures[0])
- pbc->textures[0] = glx_gen_texture(ps, GL_TEXTURE_2D, width, height);
- GLuint tex_scr1 = pbc->textures[0];
- pbc->width = width;
- pbc->height = height;
+ // Generate textures
+ if (!gsc->textures[0])
+ gsc->textures[0] = glx_gen_texture(ps, GL_TEXTURE_2D, width, height);
+ GLuint tex_scr1 = gsc->textures[0];
+ gsc->width = width;
+ gsc->height = height;
if (!tex_scr1) {
printf_errf("(): Failed to allocate texture.");
goto glx_greyscale_dst_end;
}
- // Texture scaling factor
- GLfloat texfac_x = 1.0f, texfac_y = 1.0f;
- texfac_x /= width;
- texfac_y /= height;
-
- // Greyscale conversion in OpenGL ES taken nearly verbatim from this answer on Stack Overflow: http://stackoverflow.com/a/9690145
-
- // Enable texture unit 0 to divide RGB values in our texture by 2
- glActiveTexture(GL_TEXTURE0);
glEnable(GL_TEXTURE_2D);
+ glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, tex_scr1);
+ if (ptex) {
+ glActiveTexture(GL_TEXTURE1);
+ glBindTexture(GL_TEXTURE_2D, ptex->texture);
+ }
+ glActiveTexture(GL_TEXTURE0);
// Read destination pixels into the GL texture
glx_copy_region_to_tex(ps, GL_TEXTURE_2D, dx, dy, dx, dy, width, height);
- // Finish setting up texture
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
- glClientActiveTexture(GL_TEXTURE0);
-
- // GL_MODULATE is Arg0 * Arg1
- glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);
-
- // Configure Arg0
- glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_TEXTURE);
- glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
-
- // Configure Arg1
- float multipliers[4] = {.5, .5, .5, 0.0};
- glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_CONSTANT);
- glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
- glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, (GLfloat*)&multipliers);
-
- // Enable texture unit 1 to increase RGB values by .5
- glActiveTexture(GL_TEXTURE1);
- glEnable(GL_TEXTURE_2D);
- glBindTexture(GL_TEXTURE_2D, tex_scr1);
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
- glClientActiveTexture(GL_TEXTURE1);
-
- // GL_ADD is Arg0 + Arg1
- glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_ADD);
-
- // Configure Arg0
- glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PREVIOUS);
- glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
-
- // Configure Arg1
- GLfloat additions[4] = {.5, .5, .5, 0.0};
- glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_CONSTANT);
- glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
- glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, (GLfloat*)&additions);
+ // Texture scaling factor
+ GLfloat texfac_x = 1.0f, texfac_y = 1.0f;
+ texfac_x /= width;
+ texfac_y /= height;
- // Enable texture combiner 2 to get a DOT3_RGB product of your RGB values
- glActiveTexture(GL_TEXTURE2);
- glEnable(GL_TEXTURE_2D);
- glBindTexture(GL_TEXTURE_2D, tex_scr1);
- glClientActiveTexture(GL_TEXTURE2);
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
-
- // GL_DOT3_RGB is 4*((Arg0r - 0.5) * (Arg1r - 0.5) + (Arg0g - 0.5) * (Arg1g - 0.5) + (Arg0b - 0.5) * (Arg1b - 0.5))
- glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_DOT3_RGB);
-
- // Configure Arg0
- glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PREVIOUS);
- glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
-
- // Configure Arg1
- // We want this to adjust our DOT3 by R*0.3 + G*0.59 + B*0.11
- // So, our actual adjustment will need to take into consideration
- // the fact that OpenGL will subtract .5 from our Arg1
- // and we need to also take into consideration that we have divided
- // our RGB values by 2 and we are multiplying the entire
- // DOT3 product by 4
- // So, for Red adjustment you will get :
- // .65 = (4*(0.3))/2 + 0.5 = (0.3/2) + 0.5
- GLfloat weights[4] = {.65, .795, .555, 1.};
- glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_CONSTANT);
- glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
- glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, (GLfloat*)&weights);
+// glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+ glUseProgram(greyscale_glsl->prog);
+ // These coefficients exactly match the non-GL greyscale conversion which uses the XRender PictOpHSLLuminosity operation
+ glUniform4f(greyscale_glsl->unifm_greyscale_weights, 0.3, 0.59, 0.11, 1.0);
+ glUniform1i(greyscale_glsl->unifm_enable_blend, ((ptex)?1:0));
+ glUniform1i(greyscale_glsl->unifm_tex_scr, 0);
+ glUniform1i(greyscale_glsl->unifm_alpha_scr, 1);
// Render!
{
@@ -1527,26 +1576,21 @@ glx_greyscale_dst(session_t *ps, int dx, int dy, int width, int height, float z,
P_PAINTREG_END();
}
- glEnd();
-
- // Clean up by disabling your texture combiners or texture units.
- glActiveTexture(GL_TEXTURE2);
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
- glDisable(GL_TEXTURE_2D);
-
- glActiveTexture(GL_TEXTURE1);
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
- glDisable(GL_TEXTURE_2D);
-
- glActiveTexture(GL_TEXTURE0);
- glClientActiveTexture(GL_TEXTURE0);
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+ glUseProgram(0);
ret = true;
glx_greyscale_dst_end:
- if (&ibc == pbc) {
- free_glx_gc(ps, pbc);
+ if (ptex) {
+ glActiveTexture(GL_TEXTURE1);
+ glBindTexture(GL_TEXTURE_2D, 0);
+ }
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, 0);
+ glDisable(GL_TEXTURE_2D);
+
+ if (&ibc == gsc) {
+ free_glx_gc(ps, gsc);
}
glx_check_err(ps);