Additive (not linear) compositing when using GLX
Carsten Haitzler (The Rasterman)
raster at rasterman.com
Mon Oct 18 00:49:28 PDT 2010
On Sun, 17 Oct 2010 18:03:28 -0500 Rendaw <rendaw at zarbosoft.com> said:
x uses premultiplied alpha ARGB colorspace. (google for the info) but the
simple thing here is
r = r *a, g =g * a, b = b* a
that means r can NEVER be bigger than a, same with g and b. otherwise rendering
booboos happen as you saw. you are rendering with opengl - but you are not
producing a premultiplied alpha result. fix that and presto. :)
> I'm using xcompmgr for compositing. A window I paint using OpenGL is
> much brighter than a window painted the same way using Cairo.
> Specifically, with Red=1, Alpha=0, everything has full red. Using
> Cairo, there is no coloration.
>
> I'm not using glxcompmgr, but I noticed the line glBlendFunc(GL_ONE,
> GL_ONE_MINUS_SRC_ALPHA); in the code. Compositing like that would cause
> the output I showed above.
>
> Does anyone know from which package this behavior might stem? Since
> xcompmgr is pretty small, I doubt it is differentiating between GL
> rendered windows and xrender/whatever rendered ones, but that would have
> been my first guess.
>
> (I'm using Arch linux: xcompmgr 1.1.5-1, xf86-video-intel 2.12.0-1,
> xorg-server 1.8.1.902-1)
>
> Here's the code to reproduce. You'll have to change TargetVisual to use
> some RGBA supporting visual.
> #include <GL/glx.h>
> #include <GL/gl.h>
> #include <cairo/cairo-xlib.h>
> #include <unistd.h>
> #include <cassert>
> #include <string>
>
> const float ClearColor[4] = {1, 0, 0, 0.0f};
> int TargetVisual = 0x5e;
>
> void CairoDraw(Display *Context, Window Canvas, XVisualInfo *VisualData)
> {
> cairo_surface_t *BaseSurface = cairo_xlib_surface_create(Context,
> Canvas, VisualData->visual, 100, 100);
> cairo_t *CairoContext = cairo_create(BaseSurface);
>
> cairo_set_operator(CairoContext, CAIRO_OPERATOR_SOURCE);
> cairo_set_source_rgba(CairoContext, ClearColor[0], ClearColor[1],
> ClearColor[2], ClearColor[3]);
> cairo_paint(CairoContext);
>
> cairo_surface_write_to_png(BaseSurface, "Test.png");
> }
>
> void GLDraw(Display *Context, Window Canvas, XVisualInfo *VisualData)
> {
> GLXContext GLContext = glXCreateContext(Context, VisualData, NULL,
> GL_TRUE);
> glXMakeCurrent(Context, Canvas, GLContext);
>
> glClearColor(ClearColor[0], ClearColor[1], ClearColor[2],
> ClearColor[3]);
> glClear(GL_COLOR_BUFFER_BIT);
> glXSwapBuffers(Context, Canvas);
> }
>
> int main(int argc, char **argv)
> {
> Display *Context = XOpenDisplay(NULL);
>
> XVisualInfo Criteria, *FoundVisuals;
> int FoundVisualCount;
> Criteria.visualid = TargetVisual;
> FoundVisuals = XGetVisualInfo(Context, VisualIDMask, &Criteria,
> &FoundVisualCount);
> assert(FoundVisualCount != 0);
>
> XSetWindowAttributes NewAttributes;
> NewAttributes.colormap = XCreateColormap(Context,
> RootWindow(Context, FoundVisuals->screen), FoundVisuals->visual, AllocNone);
> NewAttributes.border_pixel = 0;
> NewAttributes.event_mask = StructureNotifyMask;
>
> Window TestWindow = XCreateWindow(Context, RootWindow(Context,
> FoundVisuals->screen),
> 0, 0, 100, 100, 0,
> FoundVisuals->depth, InputOutput, FoundVisuals->visual,
> CWBorderPixel | CWColormap | CWEventMask,
> &NewAttributes);
> XMapWindow(Context, TestWindow);
>
> XEvent Poll;
> do XNextEvent(Context, &Poll); while (Poll.type != MapNotify);
>
> if ((argc >= 2) && (std::string(argv[1]) == "cairo"))
> CairoDraw(Context, TestWindow, FoundVisuals);
> else GLDraw(Context, TestWindow, FoundVisuals);
>
> sleep(10);
> }
>
> _______________________________________________
> xorg-devel at lists.x.org: X.Org development
> Archives: http://lists.x.org/archives/xorg-devel
> Info: http://lists.x.org/mailman/listinfo/xorg-devel
>
--
------------- Codito, ergo sum - "I code, therefore I am" --------------
The Rasterman (Carsten Haitzler) raster at rasterman.com
More information about the xorg-devel
mailing list