[Solved] Render 2D screens with Overlays + pass transparency

Problems building or running the engine, queries about how to use features etc.
Post Reply
User avatar
Jekteir
Halfling
Posts: 80
Joined: Mon Jun 19, 2006 9:13 pm

[Solved] Render 2D screens with Overlays + pass transparency

Post by Jekteir »

Hi, I tried using QuickGUI but it wouldn't compile, so I thought for now that I might just try using the OGRE3D overlays system directly to show the flash screens (just 2D images shown on fullscreen for a couple of seconds) when my game is loading. I'm still very much learning Ogre, and I'll probably use a GUI library for my menu system, but for now I thought it would be worthwhile to try and learn to use overlays to display an image.

My core module calls these functions like so:

Code: Select all

    ogre->renderUp();           // start up new rendering system and window

    ogre->loadMenuResources();

    if (!ogre->displayFlashScreens())   // if user cancels/exits during flash screens
    {
        return;
    }
In their module, those functions look like:

Code: Select all


void ClientOgre::renderUp()
{
    window = root->initialise(true,"Game Title");
}

void ClientOgre::loadMenuResources()
{
    resgrpmgr->addResourceLocation("./data/menu","FileSystem","Menu");
    resgrpmgr->initialiseResourceGroup("Menu");
}

bool ClientOgre::displayFlashScreens()
{
    Ogre::Overlay *flashscreen = Ogre::OverlayManager::getSingleton().create("flashscreen");
    flashscreen->show();

    Ogre::OverlayContainer *screenpanel = static_cast<Ogre::OverlayContainer*>(Ogre::OverlayManager::getSingleton().createOverlayElement("Panel","myflashscreen"));

    screenpanel->setMaterialName("iccflashscreen.gif");

    flashscreen->add2D(screenpanel);
    screenpanel->show();

    root->startRendering();

    Sleep(2);

    flashscreen->remove2D(screenpanel);
    Ogre::OverlayManager::getSingleton().destroyOverlayElement(screenpanel);
    screenpanel = NULL;

    Ogre::OverlayManager::getSingleton().destroy(flashscreen);
    flashscreen = NULL;

    return true;
}
Now I'm guessing that startRendering() actually wouldn't end if this were to run, but it doesn't matter because I get an exception in the logfile before that:
13:52:17: Creating resource group Menu
13:52:17: Added resource location './data/menu' of type 'FileSystem' to resource group 'Menu'
13:52:17: Initialising resource group Menu
13:52:17: Parsing scripts for resource group Menu
13:52:17: Finished parsing scripts for resource group Menu
13:52:17: OGRE EXCEPTION(5:ItemIdentityException): Could not find material iccflashscreen.gif in OverlayElement::setMaterialName at C:\SoftwareDevelopment\C++\MinGW\ogrenew_HEAD_clean\OgreMain\src\OgreOverlayElement.cpp (line 330)
The image does exist at .\data\menu\iccflashscreen.gif . I'm guessing that I shouldn't be calling this a 'material', or I need to do something else entirely. If someone could point me towards the right approach I'd really appreciate it -- I've been looking in QuickGUI's source for some idea of how this type of thing works, but it's a little dense for me to get to grips with right now.
Last edited by Jekteir on Tue Jul 10, 2007 5:43 pm, edited 1 time in total.
User avatar
Jekteir
Halfling
Posts: 80
Joined: Mon Jun 19, 2006 9:13 pm

Post by Jekteir »

Last edited by Jekteir on Sun Jul 08, 2007 1:16 pm, edited 1 time in total.
User avatar
HexiDave
OGRE Expert User
OGRE Expert User
Posts: 1538
Joined: Sat Jan 14, 2006 8:00 pm
x 1

Post by HexiDave »

I'm not sure if it will render an animated GIF properly, but you're trying to declare a texture, not a material.

You could do:

Code: Select all

MaterialPtr material = MaterialManager::getSingleton().create(
    "FlashMaterial1", // name
    ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);

material->getTechnique(0)->getPass(0)->createTextureUnitState("iccflashscreen.gif");
That creates a material named FlashMaterial1 and then sets the first technique's first pass's texture to iccflashscreen.gif.

If you want to animate the gif, you'll probably want to search the forums.
User avatar
Jekteir
Halfling
Posts: 80
Joined: Mon Jun 19, 2006 9:13 pm

Post by Jekteir »

Heya, thanks very much for your reply. With a bit of extra tweaking, and now understanding just a tiny bit better what goes on with materials and textures, I thought I'd post back the code my function now uses in case it helps anyone else. Thanks again -- and I'll post back with any further questions! Cheers.

Code: Select all

bool ClientOgre::displayFlashScreens()
{
    Ogre::Overlay *flashscreen = ovrlayMgr->create("ovrFlashscreen");

    Ogre::OverlayContainer *ovrcntScreenpanel = static_cast<Ogre::OverlayContainer*>(Ogre::OverlayManager::getSingleton().createOverlayElement("Panel","ovrcntFlashscreen"));

    ovrcntScreenpanel->setMetricsMode(Ogre::GMM_PIXELS);
    ovrcntScreenpanel->setPosition(0, 0);
    ovrcntScreenpanel->setDimensions(1280, 1024);

    Ogre::MaterialPtr mtrlFlashICC = Ogre::MaterialManager::getSingleton().create(
    "mtrlFlashICC", // name
    "Menu");

    //flashmaterial->getTechnique(0)->getPass(0)->createTextureUnitState("iccflashscreen.gif");
    mtrlFlashICC->getTechnique(0)->getPass(0)->createTextureUnitState("testy.bmp");

    ovrcntScreenpanel->setMaterialName("mtrlFlashICC");
    ovrcntScreenpanel->show();

    flashscreen->add2D(ovrcntScreenpanel);

    flashscreen->show();

    for (int i = 0;i<5;++i)
    {
        root->renderOneFrame();
        Sleep(1000);
    }

    flashscreen->remove2D(ovrcntScreenpanel);
    Ogre::OverlayManager::getSingleton().destroyOverlayElement(ovrcntScreenpanel);
    ovrcntScreenpanel = NULL;

    Ogre::OverlayManager::getSingleton().destroy(flashscreen);
    flashscreen = NULL;

    return true;
}
User avatar
Jekteir
Halfling
Posts: 80
Joined: Mon Jun 19, 2006 9:13 pm

Setting Alpha Transparency

Post by Jekteir »

Hi, thanks again for that last bit of help. I'm now experimenting with using overlays to set up a menu system, and am looking for a bit of help with transparency if possible.

I've found the setAlphaRejectSettings (CompareFunction func, unsigned char value) function in a pass, and I was thinking about doing something like:

Code: Select all

    mtrlFlash->getTechnique(0)->getPass(0)->createTextureUnitState("navbar.jpg");
mtrlFlash->getTechnique(0)->getPass(0)->setAlphaRejectSettings(Ogre::CMPF_ALWAYS_FAIL,[some alpha value here]);
The idea is to have a full-screen texture which has a navbar with a gradient that fades into the middle, and behind that totally transparent middle area would be another texture with an image of the game.

This is probably simple, if I'm headed in the right direction: I just don't know how to create JPGs with an alpha value that follows the gradient, or how to access that value at any point in the image when working on it in Photoshop. Could you tell me if this is the right way to be approaching this transparency issue, and whether there is a document somewhere you could point me to that explains how to control and access an 'alpha value' for pixels using Photoshop? I'm assuming that the setAlphaRejectValue (unsigned char val)-style value is a number from 0 to 255?
User avatar
Jekteir
Halfling
Posts: 80
Joined: Mon Jun 19, 2006 9:13 pm

Post by Jekteir »

OK, I've got a little bit further, and found this page on making PNG files in Photoshop with transparency useful:

http://www.davidchess.com/words/pngalpha.html

I'm now using what I imagine is the default single 0 pass to put a sample background image on the screen, and then creating a new pass for the navbar stuff that has transparency. My code is currently:

Code: Select all

    Ogre::MaterialPtr mtrlFlash = mtrlMgr->create("mtrlFlash", "Menu");

    mtrlFlash->getTechnique(0)->setDepthCheckEnabled(false);  // think i need this so they can combine
    mtrlFlash->getTechnique(0)->getPass(0)->createTextureUnitState("testbackground.jpg");
    mtrlFlash->getTechnique(0)->createPass();
    mtrlFlash->getTechnique(0)->getPass(1)->createTextureUnitState("overmenu.png");

    mtrlFlash->getTechnique(0)->getPass(1)->setAlphaRejectSettings(Ogre::CMPF_GREATER,130);

    ovrcntPanel->setMaterialName("mtrlFlash");
I picked 130 as roughly half-way between none and total transparency. Now I've experimented with different AlphaRejectSettings, but I can't figure out how to get the gradient of transparency in my Photoshop image to grade on the Ogre display. Right now, whatever I do it seems to have a very on/off result.

How it's meant to look:

http://bayimg.com/nadOAaaBh

How it does look:

http://bayimg.com/madOPAaBh

I'm guessing this is because Ogre is basically rejecting whatever doesn't fit in the numerical range defined by the AlphaRejectSettings, so when I set that number further in and out of my gradient of transparency, wherever the actual cut-off is, it displays the black pixels on one side of that line only (my gradient is black to transparent), so there's never any gradient between my background image and the one on top. I'm guessing, therefore, that what I need to do is to reject only the _totally transparent_ pixels in the very middle of the screen, and then for all the somewhat-transparent, somewhat-black ones, somehow blend their color with the color behind them in the other pass's texture, or something... and I don't know how to do that. If you could point me to some kind of pass blending function or whatever would actually be appropriate for this, I'd really appreciate it.
User avatar
Jekteir
Halfling
Posts: 80
Joined: Mon Jun 19, 2006 9:13 pm

Post by Jekteir »

Hi, I still haven't been able to resolve this problem. If anyone could point me the right way it would be much appreciated.
big_o
Goblin
Posts: 279
Joined: Sun Feb 19, 2006 1:08 am

Post by big_o »

Did you set the material to use scene_blend alpha_blend? Without that it will simply treat the partially transparent pixels that aren't being alpha rejected as being fully opaque.
User avatar
Jekteir
Halfling
Posts: 80
Joined: Mon Jun 19, 2006 9:13 pm

Post by Jekteir »

Hey, thanks a lot for your suggestion. With that little bit of reference I managed to find Ogre::Pass::setSceneBlending, which uses an Ogre::SceneBlendType . Because I'm doing this programmatically a materials script with scene_blend alpha_blend wasn't quite what I had to put in, but I got it to create the right transparency with:

Code: Select all

    mtrlFlash->getTechnique(0)->setDepthCheckEnabled(false);
    mtrlFlash->getTechnique(0)->getPass(0)->createTextureUnitState("testbackground.jpg");
    mtrlFlash->getTechnique(0)->createPass();
    mtrlFlash->getTechnique(0)->getPass(1)->createTextureUnitState(screenname);
    //mtrlFlash->getTechnique(0)->getPass(1)->setAlphaRejectSettings(Ogre::CMPF_GREATER,0);
    mtrlFlash->getTechnique(0)->getPass(1)->setSceneBlending(Ogre::SBT_TRANSPARENT_ALPHA);
Thanks so much for getting back to me. Until the next time!
Post Reply