[A5] Front-to-back Alpha Blending
for my GUI code its essential that what I draw last gets drawn above everything drawn after it. So I want to reverse the usual painters algorithm.
I tried figuring out how to do this using al_set_blender or al_set_separate_blender, but I failed.
Can someone help me out?
Draw them in the order you want, simple as that. Blending won't help. When you draw something, OpenGL/DX renders pixels to a frame buffer. There is only one framebuffer so once those pixels are there, anything you draw goes on top of them.
If you were using OpenGL you could set an orthogonal perspective and use the depth buffer along with 3d vertices, incrementing the Z value a bit for everything you drew.
for my GUI code its essential that what I draw last gets drawn above everything drawn after it.
This does not make sense - there can't be anything drawn after the last one gets drawn by definition of the term 'last'. Like Trent said, draw from the bottom up. There's no other way to do it.
Besides the depth buffer as Arthur said, you could also use the stencil buffer.
Why not just draw them recursively, I simply do:
and then the whole gui is painted!
1void AguiWidget::paintChildren(const AguiPaintEventArgs &paintargs )
3 stackOffset = paintargs.graphics()->getOffset();
4 stackRects = paintargs.graphics()->getClippingStack();
9void AguiWidget::recursiveDrawChildren( AguiWidget *root, bool enabled,
10 AguiGraphicsManager *graphicsContext )
12 //recursively calls itself to render widgets from back to front
19 bool widgetEnabled = root->isEnabled();
21 if(enabled == false)
23 widgetEnabled = false;
26 if(root != this)
38 for(std::vector<AguiWidget*>::iterator it =
40 it != root->getPrivateChildEnd(); ++it)
44 for(std::vector<AguiWidget*>::iterator it =
46 it != root->getChildEnd(); ++it)
Thanks for your answers so far, really! I read them all carefully.
But I probably described very badly what I want to do, so to give you some details:
Sol IMGui Tutorial
Molly Rocket Immediate Mode GUI Forums
The problem is that I can only draw the frame background image after the buttons/labels inside of it are drawn.
Take a look at this example code, to see how it works:
gui.begin_frame(); // We do not yet know how big the frame will have to be.
// We also do not know if it's active, because one of the buttons/labels
// could become active, but we do not know about them yet.
printf("The button was pressed!\n");
// Now that we _do_ know about the widgets in the frame, we could draw the frame.
// but this place doesn't really fit the rendering order.
I do know that there are other solutions to this (buffer images, render queues). Anyway, I would like to know if there is a way to draw the frame right by just using blending in A5. Like sean from Molly Rocket points out:
4. Process widgets front-to-back and draw with the crazy front-to-back blend mode that still lets you use alpha values for anti-aliased edges.
Thread #607035. Printed from Allegro.cc
Destination alpha is a possibility but I don't think that is very well supported by video cards. Especially for the framebuffer itself... I don't know about using a buffer with destination alpha though it seems clear you don't want to do that.