I've responded to your first question at the Ogre3D forum.
As for your second question, it doesn't support it natively but you could add it yourself. Canvas maintains an internal list of quads ("quadList" member variable) whose order determines the z-order (or depth) of a quad. If you really wanted to, you could modify some of the draw_____ API calls so you can specify a z-order and then sort those quads by z-order in Canvas::updateGeometry.
You're welcome, I'm glad my little rendering library has been useful for you.
If you wish to accommodate multiple atlases/textures, you should first be aware that every time you switch textures in a list of quads it will require another batch call.
For example: say you had a bunch of quads layered one on top of each other with textures "A" and "B", with an order of: AAABAABBBBAAABBAABAAAABA
Even though you only have two unique texture-atlases, you've suddenly increased your batch count to 11! This is why I pack all of the assets (glyphs and images) as tightly as I can into a single atlas so I can avoid crazy batching calls.
However, I do concede that this is not realistic for every scenario-- especially for applications that tend to have a large number of image assets (for example, RPGs and icons for items), it's just not feasible to pack all of them into a single texture.
For these cases, you might be able to build a system on top of Canvas that allows you to reference multiple atlases. I would recommend putting your most commonly used assets into a single Atlas (common fonts and user-interface elements) and then arbitrarily creating other Atlases for other groups of assets. You can then maintain a pool of Canvas elements to use for each batch of draw calls with a different Atlas.
Here's some pseudo-code for "MultiCanvas", a special class that allows you to draw from multiple atlases by maintaining a pool of Canvases and switching between them for each batch:
- Code: Select all
void MultiCanvas::drawRectangle(int x, int y, int width, int height, const Fill& fill, const Border& border, Atlas* atlas)
{
// If the texture-atlas changed since the last draw call,
// switch to a new canvas, effectively creating a new batch
if(atlas != currentAtlas)
{
currentCanvas = getOrCreateCanvasFromPool(atlas, canvasZOrder++);
currentAtlas = atlas;
}
currentCanvas->drawRectangle(x, y, width, height, fill, border);
}
Canvas* MultiCanvas::getOrCreateCanvasFromPool(Atlas* atlas, int canvasZOrder)
{
std::vector<Canvas*>::iterator i = canvasPool.findEmptyCanvas();
// If there is an empty Canvas in the pool
// change its z-order and atlas and return the canvas
if(i != canvasPool.end())
{
(*i)->setZOrder(canvasZOrder);
(*i)->setAtlas(atlas);
return *i;
}
else
{
Canvas* canvas = new Canvas(atlas, canvasZOrder);
canvasPool.push_back(canvas);
return canvas;
}
}
You will need to modify Canvas.h/Canvas.cpp so that you can set each Canvas's global z-order (set renderQueueID to Ogre::RENDER_QUEUE_OVERLAY + zOrder) and change its Atlas at runtime.