Don't understand


#1

if anyone has a moment, could you try something out for me, please?

On windows, run the jucedemo and drag the little component that says “try dragging this onto the desktop etc…” onto the desktop.

Is it the same colour when it’s on the desktop as when it’s in the window, or does it look a bit murky?

I’m just a bit confused because in the past to get transparent windows working, I had to pre-multiply the image’s alpha channel, but I just noticed that on my PC, it now only looks right if I don’t premultiply.

So I’m wondering if this is something broken in my graphics card, and whether it does the same thing on all machines. Could be that my machine was actually getting it wrong when I first wrote the code, but don’t have any way of knowing which one’s right!


#2

I thought that was programmed in to make it more distinguished that you moved it off, but checked the code, nope…

It is a nice green when in the component, turns to being a very greyish green when on the desktop. It did not act like this in 1.11-.


#3

According to the windows documentation, you’re definitely supposed to premultply the image - which is what the code does. But that doesn’t work now. doh??

How sure are you that it worked in 1.11?


#4

FYI

I figured this out - seems that if you initialise the GDI+, UpdateLayeredWindow no longer takes a premultiplied image. Of course that’s not what the documentation says. If anyone from Microsoft’s graphics team is reading this, you owe me several hours of my life that I just wasted.


#5

rats.

That wasn’t it… will keep looking.


#6

Got a picture of what is happening at home

see here:
http://crashreport.free.fr/Transbug.png

It happened between 1.11 and 1.12 (or maybe 1.10 and 1.11 as I didn’t check the demo for 1.11)

By looking to the colors themselves, on 1.10, when the component was inside the window, its background was (183, 208, 199) and, when added to the desktop, its overlapping part (with the dialog) was (184, 210, 200) which is almost the same but not exactly

With the 1.12 version, inside the dialog the color is (184, 209, 200), but the same color when added to the desktop becomes (184, 189, 200).

As far as I can see, it seems that the previous version contained some (limited) rounding errors on the process, while the new version doesn’t have errors, but doesn’t compute the green value correctly. It smells like copy and paste error somewhere, I don’t think it’s due to any Win32 API misunderstanding (I have used UpdateLayeredWindow a lot before, and the premultiplication is required, at least on WinXP). It is clearly not a premultiplication problem as the red and blue component are correct.

Maybe you can do a diff on the two versions, and try to find the bug in the generated patch file.

I hope it helps


#7

[quote=“jules”]rats.

That wasn’t it… will keep looking.[/quote]

really? i tried disabling the premultiply step and it seems to make the window behave correctly.

there’s gotta be some alpha modulation happening still cuz if you change the color of that component to white with a 0.01 alpha, the white goes away even with the PixelARGB.premultiply method completely deactivated (commented out).

i’m guessing there’s an alpha multiply somewhere upstream … maybe in the fill routine somewhere?

edit:
** found where the problem is, i think

i think it’s in the nativeFill routine. if you hardwire to not use this routine, everyting looks fine. i’m guessing windows multiplies the color by the alpha in the gdifillrectangle call… just a guess.


#8

i see.

the nativefill routine is actually not replacing the contents – the replaceflag is false, so it’s comping the solid color thru the alpha into a blank image before being used later in the system.


void Graphics::fillAll (const Colour& colourToUse)
{
    image.fillRect (clipLeft, clipTop, clipWidth, clipHeight,
                    colourToUse, false);
}

probably should be true instead of false.

edit:

cept i don’t see how this is used in the gdi fillRectangle call! d’oh!

back to my original thought that this routine simply multiplies the color values by the alpha value (which strikes me as bizarre).


#9

could this be the culprit?

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdicpp/GDIPlus/GDIPlusReference/Classes/GraphicsClass/GraphicsMethods/SetCompositingMode.asp

there are two variations, copy and composite. they seem to affect the gdi drawing routines. i’m not sure how the hooks into the system work, but i’m sure you can probably stick that in nativeFill pretty quickly to see if that’s the solution.

yeah, i think this is it.

from the link:

Suppose you create a SolidBrush object based on a color that has an alpha component of 192, which is about 75 percent of 255. If your Graphics object has its compositing mode set to CompositingModeSourceOver, then areas filled with the solid brush are a blend that is 75 percent brush color and 25 percent background color. If your Graphics object has its compositing mode set to CompositingModeSourceCopy, then the background color is not blended with the brush color. However, the color rendered by the brush has an intensity that is 75 percent of what it would be if the alpha component were 255.


#10

I’ve looked inside the code for 1.10 version, and the premultiply is called. So I don’t see why this could be the culprit (because it wouldn’t have worked in both version)

Good luck.

PS: I don’t know how you compiled the 1.12 demo. If you compiled it with GDIPLUS declared, try to switch it off, to see if it is GDI+ related. (I’ve compiled 1.10 without it)


#11

Ok, I found it - the problem was that I was using the GDI+ to draw rectangles, but this assumes the target image is premultiplied. so it works perfectly on an opaque image, but not a transparent one, and this only shows up with transparent windows.

I’ll figure something out for the next release… In the meantime if it’s a problem for anyone, just disable the USE_GDIPLUS flag in juce_win32_Windowing.cpp


#12

yeah, i’ve been reading a bit about this gdi+ stuff. the brush alphas automatically apply themselves to your color and you’ve only got 8 bits of color to work with so you can’t “unpremultiply” your rgb values to offset the multiplication. serious limitation. i guess they don’t figure anybody cares about the alpha layer of the resultant image…

what were they thinking?


#13

Apparently it can handle non-premult images too, though I’ve not done much research on it yet.


#14