OGRE Wiki
Support and community documentation for Ogre3D
Ogre Forums
ogre3d.org
Log in
Username:
Password:
CapsLock is on.
Remember me (for 1 year)
Log in
Home
Tutorials
Tutorials Home
Basic Tutorials
Intermediate Tutorials
Mad Marx Tutorials
In Depth Tutorials
Older Tutorials
External Tutorials
Cookbook
Cookbook Home
CodeBank
Snippets
Experiences
Ogre Articles
Libraries
Libraries Home
Alternative Languages
Assembling A Toolset
Development Tools
OGRE Libraries
List of Libraries
Tools
Tools Home
DCC Tools
DCC Tutorials
DCC Articles
DCC Resources
Assembling a production pipeline
Development
Development Home
Roadmap
Building Ogre
Installing the Ogre SDK
Setting Up An Application
Ogre Wiki Tutorial Framework
Frequently Asked Questions
Google Summer Of Code
Help Requested
Ogre Core Articles
Community
Community Home
Projects Using Ogre
Recommended Reading
Contractors
Wiki
Immediate Wiki Tasklist
Wiki Ideas
Wiki Guidelines
Article Writing Guidelines
Wiki Styles
Wiki Page Tracker
Ogre Wiki Help
Ogre Wiki Help Overview
Help - Basic Syntax
Help - Images
Help - Pages and Structures
Help - Wiki Plugins
Toolbox
Freetags
Categories
List Pages
Structures
Trackers
Statistics
Rankings
List Galleries
Ogre Lexicon
Comments
History: Ogre overlays using Qt
View page
Source of version: 1
(current)
__How to draw Ogre overlays using Qt framework 2D drawing functionality__ __The background:__ If you'd like to display 2D graphics over the top of the Ogre rendered 3D output the overlay functionality works nicely. If the overlays are dynamic that introduces the requirement for a 2D drawing library to create the overlays on the fly. In my application I was already using the Qt framework for the user interface. Qt also includes the ability to draw 2D graphics and text using the QPainter class. I found a simple solution to use the Qt framework with Ogre overlays. In my project (the Landefall MMO) I need a "Heads Up Display". I decided to create a single Ogre overlay panel the same size as the render window. I haven't tested it but I believe a single large overlay panel will be faster to render than a number of smaller panels. The panel will have a material with a single texture containing an image of the HUD. The majority of the texture will be transparent so the 3D render window can actually be seen (that's always good). __The solution:__ The Qt framework provides the QPainter class to render on any of a variety of backing stores. If you use a backing store that's an in memory bitmap then you can use QPainter to draw the HUD then paste it into the Ogre overlay panel texture. __Making it smaller and faster:__ This works very well but I wanted to reduce the overhead as much as possible. The QImage documentation reveals that it's possible to draw on an already allocated memory buffer. I found there's an image storage format that's the same in both the Qt QImage and the Ogre pixel buffer code. I locate the pixel buffer already create by Ogre and pass this to QImage as its buffer to store the image. This eliminates the need to convert the image from one format to another and copy the image from the QImage buffer to the Ogre pixel buffer. It uses less memory, less code, and should be faster. __Example code:__ {BOX(title="Setup")}Ogre::Overlay* overlay; Ogre::TexturePtr HudTexture; QImage ImageHudSpeed; // get template image to use used later from the App resource area ImageHudSpeed = QImage( ":images/Hud-Speed.png" );{BOX} {BOX(title="Programmatically create the overlay material:")}// Create the texture HudTexture = Ogre::TextureManager::getSingleton().createManual( "HUDTexture", // name Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, Ogre::TEX_TYPE_2D, // type width(), height(), // width & height of the render window 0, // number of mipmaps Ogre::PF_A8R8G8B8, // pixel format chosen to match a format Qt can use Ogre::TU_DEFAULT // usage ); // Create a material using the texture Ogre::MaterialPtr HudMaterial = Ogre::MaterialManager::getSingleton().create( "HUDMaterial", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME ); HudMaterial->getTechnique( 0 )->getPass( 0 )->createTextureUnitState( "HUDTexture" ); HudMaterial->getTechnique( 0 )->getPass( 0 )->setSceneBlending( Ogre::SBT_TRANSPARENT_ALPHA );{BOX} {BOX(title="Programmatically create the overlay panel:")}// Create an overlay Ogre::OverlayManager& overlayManager = Ogre::OverlayManager::getSingleton(); overlay = overlayManager.create( "OverlayName" ); // Create a panel Ogre::OverlayContainer* panel = static_cast<Ogre::OverlayContainer*>( overlayManager.createOverlayElement( "Panel", "PanelName" ) ); panel->setPosition( 0.0, 0.0 ); panel->setDimensions( 1.0, 1.0 ); // cover the entire window panel->setMaterialName( "HUDMaterial" ); // Add the panel to the overlay overlay->add2D( panel ); // Show the overlay overlay->show();{BOX} {BOX(title="Update the HUD texture image:")}// Get the pixel buffer Ogre::HardwarePixelBufferSharedPtr pixelBuffer = HudTexture->getBuffer(); // Lock the pixel buffer and get a pixel box pixelBuffer->lock( Ogre::HardwareBuffer::HBL_NORMAL ); // for best performance use HBL_DISCARD! const Ogre::PixelBox& pixelBox = pixelBuffer->getCurrentLock(); Ogre::uint8* pDest = static_cast<Ogre::uint8*> ( pixelBox.data ); // construct HUD image directly in the texture buffer { // fill to get 100% transparent image // the buffer content is the colors R,G,B,A. Filling with zeros gets a 100% transparent image memset( pDest, 0, HudTexture->getWidth() * HudTexture->getHeight() ); // tell QImage to use OUR buffer and a compatible image buffer format QImage Hud( pDest, HudTexture->getWidth(), HudTexture->getHeight(), QImage::Format_ARGB32 ); // paste in HUD speedometer. I resize the image and offset it by 8 pixels from // the bottom left edge of the render window QPainter painter( &Hud ); uint8_t Offset = 8; uint16_t w = ImageHudSpeed.width() / 2; uint16_t h = ImageHudSpeed.height() / 2; painter.drawImage( QRect( Offset, HudTexture->getHeight() - h - Offset, w, h ), ImageHudSpeed, QRect( 0, 0, ImageHudSpeed.width(), ImageHudSpeed.height() ) ); // do any other drawing you would like here using painter // done painter.end(); } // note the QImage is destroyed. Bad things will happen if you reuse the QImage! // Unlock the pixel buffer pixelBuffer->unlock();{BOX} That's it. Here's an example of my output {img fileId="2131" thumb="y" rel="box[g]"}
Search by Tags
Search Wiki by Freetags
Latest Changes
Minimal Ogre Collision
Artifex Terra
OpenMB
Advanced Mogre Framework
MogreSocks
Critter AI
Mogre Add-ons
MOGRE
Mogre MyGUI wrapper
MOGRE Editable Terrain Manager
...more
Search
Find
Advanced
Search Help
Online Users
41 online users