I’m having some frustrating issues with transparency. I’m creating some grass that basically consist of a lot of faces with a partially-transparent texture on it.
Here’s how it looks: (click to enlarge)
Looks good so far. The problem occurs when I clear model nodes and then call flattenStrong. (I need that because otherwise the number of meshes becomes too much)
The alpha is set to MAlpha, MBinary and MDual, respectively. Click to enlarge.
Any ideas how I can merge the grass planes into one mesh but still keep correct transparency sorting? MBinary is the only setting that looks correct but unfortunately it doesn’t seem to respect 0.0 < alpha < 1.0 values.
Clearly, once you have flattened the nodes into one mesh, alpha sorting is no longer possible (because correct alpha sorting would now require breaking apart the mesh and re-sorting it internally according to the viewing direction, completely defeating the advantage of flattening it in the first place).
So, you need a transparency mode that doesn’t require sorting at all to give correct results. MBinary is one such mode, but as you have observed, it doesn’t respect grayscale alpha values, so it looks pixelly.
You could also try MMultisample. This requires “framebuffer-multisample 1” and “multisamples 2” (or better). I haven’t tried it in a long time, so I’m not 100% sure it still works.
I did try MMultisample and MMultisampleMask, but they give exactly the same result as MBinary, with and without the config variables you suggested.
It appears to be broken or so. Multisample antialiasing doesn’t work either.
Any ideas where I should start debugging, or is there maybe a better idea to do sorting in my case?
Hmm, MMultisample does work for me on my Windows box, but not on my Linux box. It looks like I’m not getting any multisamples on my Linux box, regardless of the setting of framebuffer-multisample. (Check base.win.getFbProperties() to see if you get any either.)
This might be a bug in glxdisplay window creation, or it might just mean that my Linux hardware doesn’t support multisamples. I’ll look a little closer later today.
I’ve just checked in some additional debugging output to glxdisplay. Now, when you have “notify-level-display debug” enabled, when you open a window it prints a list of the available frame buffer configs. For instance, on my silly little GeForce 5200, I get this:
And so on. (Further down the list, it starts to indentify the configs that have multisamples.)
Interestingly, every single one of my available framebuffer configs is tagged “(slow)”, which isn’t precisely defined in the glx spec, but is supposed to mean there’s something slower about this config than the other configs. The Panda configurator is designed to filter out the (slow) configs, unless all of them are tagged (slow). My suspicion is that on your system, the multisample configs happen to be tagged (slow), and the non-multisample configs are not, so that it ends up filtering out all the multisample configs.
Looks like there’s either a bug in the code that detects whether it’s ‘slow’ or not, or, we’d have to make the code still accept ‘slow’ framebuffer modes (if no ‘fast’ mode can be found to satisfy the user’s request)
(We could maybe create a config var for that, something like allow-slow-configs)
EDIT: Yay! If I change this line in glxGraphicsStateGuardian.cxx:
slow = true;
and replace ‘true’ with ‘false’, I can see sweet antialiasing and the transparency works, too!
Ah, turns out there was a bug in that logic. It was assuming that GLX_SLOW_CONFIG was a bitmask, but it’s not, it’s a discrete value. Treating as a bitmask gives a false positive.
I’ve just checked in the fix, and now none of my framebuffer configs are tagged “(slow)”.
Hmm, it suddenly doesn’t seem to work anymore. Debug output does print the right modes, without (slow), but I’m getting “FrameBufferProperties available less than requested.” even if I just request 2 multisamples and nothing more.
Wait, there’s something VERY odd going on.
When I run it with ‘notify-level-display debug’, I do get multisamples: pastebin.ubuntu.com/132109/
When I run it at ‘info’, I don’t get multisamples: pastebin.ubuntu.com/132114/
Hmm, yet it’s working for me. This might just mean that there is a problem somewhere with an uninitialized variable or something along those lines, so that randomly shaking the box (by running with different debug settings, for instance) might be enough to change whether the coin falls heads-up or tails-up.
Oh, I just saw the links. I’ll see if I can figure out anything from your logs.
Hmm, I don’t see anything obviously wrong. Would you mind putting a cerr statement in glxGraphicsStateGuardian.cxx, choose_pixel_format() function, to show the quality value it computes for each fbconfig? It’s supposed to choose the fbconfig with the highest quality value, and if you see it reporting a different set of quality values with debug output enabled, then the particular values it’s reporting in each case will be a clue as to exactly where it’s going wrong.
Wow, that’s delicious. Compiler bug? It’s been a long time since I’ve run across a good compiler bug, but this one is starting to smell like one. What is your output for “gcc -v”? I get:
gcc version 4.3.2 20081105 (Red Hat 4.3.2-7) (GCC)
Usually compiler bugs are triggered by weird once-in-a-blue-moon combinations of variable and loop optimizations. Working around them means changing things up just enough to not trigger the bug any more. Try declaring the quality variable “atomic”, or even “static”, and/or scoping it outside of the loop, or changing its type to a long long, or things along these lines.
I’ve tried renaming, moving it out of the loop, making it a “double” or so, casting it to three different types first, declaring static, but to no avail.
This is even weirder: redefining it doesn’t even give a warning in the compiler. (Though I’m certain HAVE_GLXFBCONFIG is defined.)
Darn it, I just hope this won’t delay 1.6.0 too much. If you want, I can set up an ssh sandbox on my machine so you can access it while I’m asleep.
Or maybe we can find a workaround by moving some stuff around (or even outputting the fb_props to a stringstream and then do nothing with it).
Maybe this is a bug related to the i64 version of gcc only; that’s plausible.
What if you take out the is_debug() check, and always write the fbprops to glxdisplay_cat.debug()? That results in the same effort of formatting the fbprops for output and so on, but it gets dropped on the floor at the end of the output.