PyOgre and overlay - how ?

BerndWill

20-03-2006 20:04:39

Hi folks,

in my PyOgre game, I would like to have a partly transparent (non rectangular) user interface lying over the pyogre window.

Please have a look at this example:
http://www.ogre3d.org/index.php?set_alb ... _photo.php

How can I achieve this result using python and pyogre ?
If available somewhere: Could someone please help me out with a source example for user interfaces and PyOgre ?

Thanks in advance
Bernd

dermont

26-03-2006 11:52:06

Use a png texture for an overlay with an alpha channel. Do a search on the main forum for Overlay/Alpha Channel.

Here's the example target overlay from OgreOde:



target.material


material OgreOdeDemos/TargetSights
{
technique
{
pass
{
lighting off
scene_blend alpha_blend
texture_unit
{
texture target.png
}
}
}
}


ogreodedemos.overlay



OgreOdeDemos/Target
{
zorder 500
container Panel(OgreOdeDemos/Sights)
{
metrics_mode relative
left 0.475
top 0.475
width 0.05
height 0.05
transparent false
material OgreOdeDemos/TargetSights
}
}


Example Code:


#get the overlay manager
overlayMgr = ogre.OverlayManager.getSingleton()

#Here we create a panel and set its position and size.
#Create a panel
overlay = overlayMgr.create("MyDemo/Target")
overlay.zOrder = 500
panel = overlayMgr.createOverlayElement("Panel", "OgreOdeDemos/Target")
panel.metricsMode = ogre.GMM_RELATIVE
panel.setPosition(0.475, 0.475)
panel.setDimensions(0.05, 0.05)
panel.materialName="OgreOdeDemos/TargetSights"
panel.transparent=False
overlay.add2D(panel)
overlay.show()

dermont

26-03-2006 12:02:36

And if you want interactive gui, you'll have to handle the mouse creation and button clicks yourself, eg:

Media from http://pizzagame.sourceforge.net/




material Gui/Toolbar/SelectButton/Normal
{
technique
{
pass
{
lighting off
depth_check off
scene_blend alpha_blend

texture_unit
{
texture selectButtonNormal.png
alpha_rejection greater_equal 128
}
}
}
}

material Gui/Toolbar/SelectButton/Pressed
{
technique
{
pass
{
lighting off
depth_check off
scene_blend alpha_blend

texture_unit
{
texture selectButtonPressed.png
alpha_rejection greater_equal 128
}
}
}
}


And an old crappy example:


# This code is in the Public Domain

import sys ;
import pyogre.ogre as ogre
import SampleFramework as sf



class GUIElement(object):
def __init__(self):
#get the overlay manager
overlayMgr = ogre.OverlayManager.getSingleton()
self.overlay = overlayMgr.create("MyDemo/Target")
self.overlay.zOrder = 510

for i in xrange(0,5):
button_name = 'button%i.png' % i
panel = overlayMgr.createOverlayElement("Panel", button_name)
panel.metricsMode = ogre.GMM_RELATIVE
panel.setPosition(0.5, 0.09*i)
panel.setDimensions(0.08, 0.08)
panel.materialName="Gui/Toolbar/SelectButton/Normal"
panel.transparent=False
self.overlay.add2D(panel)
self.panel = panel
self.element = None
self.overlay.show()


self.o = overlayMgr.create("MyDemo/Test2")
self.o.zOrder = 500
container = overlayMgr.createOverlayElement("Panel", "GUIDemo")
container.metricsMode = ogre.GMM_RELATIVE
container.setPosition(0.45, 0.00)
container.setDimensions(0.15, 0.60)
container.materialName='Examples/TransparentTest'
self.o.add2D(container)
self.o.show()

def buttonUp(self):
if self.element:
self.element.materialName="Gui/Toolbar/SelectButton/Normal"
self.element = None

def buttonDown(self):
if self.element :
self.element.materialName="Gui/Toolbar/SelectButton/Pressed"

def isSelected(self,x,y):
self.element = self.overlay.findElementAt(x,y)
print "Mouse x,y",x,y
#print "Panel5 x,y",self.button.left,self.button.top,self.button.width,self.button.height

if self.element :
print "ELEMENT IS ",self.element.name
else:
print "None"


# it would be much nicer to inherit from the MouseMotionListener, MouseListener however we can't at present with swig
# mouse code taken from: #http://www.ogre3d.org/wiki/index.php/How_to_show_the_Mouse_Cursor_W/O_CEGUI

class Mouse(object):
def __init__(self, renderWindow):
self.mousState = 0
self.renderWindow = renderWindow
self.m_vMousePos = ogre.Vector2(0.0,0.0)

#get the overlay manager
overlayMgr = ogre.OverlayManager.getSingleton()

#Here we create a panel and set its position and size.
#Create a panel
self.guiOverlay = overlayMgr.create("GuiMouse")
self.guiOverlay.zOrder = 600
self.mousePanel = overlayMgr.createOverlayElement("Panel", "GUIMouse")
self.mousePanel.setPosition(0.0, 0.0)
self.mousePanel.setDimensions(0.0, 0.0)
mat=ogre.MaterialManager.getSingleton().create("MouseCursor/default", "General")
# ugly hack to get Material
self.mouseMaterial=ogre.MaterialPointer(ogre.MaterialManager.getSingleton().getByName("MouseCursor/default"))

self.mousePanel.materialName=self.mouseMaterial.name
#self.mousePanel.materialName="OgreOdeDemos/TargetSights"

self.mousePanel.transparent=False

mouseContainer = overlayMgr.createOverlayElement("Panel", "GUIContainer")
self.guiOverlay.add2D(mouseContainer)

mouseContainer.addChild(self.mousePanel)
self.guiOverlay.show()
self.maxHeight = 1.0
self.maxWidth = 1.0

self.m_bMouseButton = False


def setMouseImage(self, filename):
if(filename):
m_pMouseTexture = ogre.TextureManager.getSingleton().load(filename,"General")
print dir(self.mouseMaterial)
if (self.mouseMaterial.getTechnique(0).getPass(0).numTextureUnitStates):
pTexState = self.mouseMaterial.getTechnique(0).getPass(0).getTextureUnitState(0)
else:
name = m_pMouseTexture.name
pTexState = self.mouseMaterial.getTechnique(0).getPass(0).createTextureUnitState(name)
pTexState.textureAddressingMode =ogre.TextureUnitState.TAM_CLAMP
self.mouseMaterial.getTechnique(0).getPass(0).setSceneBlending(ogre.SBT_TRANSPARENT_ALPHA)
self.mousePanel.materialName=self.mouseMaterial.name
# mm division by integers
w = (m_pMouseTexture.width *1.0)/(self.renderWindow.width * 1.0)
h = (m_pMouseTexture.height *1.0)/(self.renderWindow.height * 1.0)
self.maxHeight = 1.0 - h/2
self.maxWidth = 1.0 - w/2
self.mousePanel.setDimensions(w,h)

def show(self, bShow):
if(bShow):
self.mousePanel.show()
else:
self.mousePanel.hide()

def getMouseX(self):
return self.m_vMousePos.x
def getMouseY(self):
return self.m_vMousePos.y

def mouseDragged(self, evt):
self.mouseMoved(evt)

def mousePressed(self, evt):
self.m_bMouseButton = True
evt.consume()

def mouseReleased(self, evt):
self.m_bMouseButton = False
evt.consume()

def mouseClicked(self, evt):
pass

def mouseEntered(self, evt):
pass

def mouseExited(self, evt):
pass

def mouseMoved(self, evt):
self.m_vMousePos.x += evt.relX
self.m_vMousePos.y += evt.relY
evt.consume()
def update(self):
self.m_vMousePos.x = min(self.m_vMousePos.x, self.maxWidth)
self.m_vMousePos.x = max(self.m_vMousePos.x, 0.0)
self.m_vMousePos.y = min(self.m_vMousePos.y, self.maxHeight)
self.m_vMousePos.y = max(self.m_vMousePos.y, 0.0)
self.mousePanel.setPosition(self.m_vMousePos.x, self.m_vMousePos.y)

class InputListener(sf.FrameListener):
def __init__(self, renderWindow, camera, sceneManager):
sf.FrameListener.__init__(self, renderWindow, camera)
self.keepRendering = True # whether to continue rendering or not
self.sceneManager = sceneManager
self.renderWindow = renderWindow
self.mouse = Mouse(self.renderWindow)
self.mouse.setMouseImage('cursor.png')
self.guiElement = GUIElement()



def _setupInput(self):
self.eventProcessor = ogre.EventProcessor()
self.eventProcessor.initialise(self.renderWindow)
self.eventProcessor.startProcessingEvents()
self.inputDevice = self.eventProcessor.getInputReader()

# register as a listener for events
self.eventProcessor.addKeyListener(self)
self.eventProcessor.addMouseListener(self)
self.eventProcessor.addMouseMotionListener(self)

def keyPressed(self, evt):
if evt.key == ogre.KC_ESCAPE:
self.keepRendering = False

def mouseMoved(self, evt):
self.mouse.mouseMoved(evt)

def mouseDragged(self, evt):
self.mouse.mouseDragged(evt)

def mousePressed(self, evt):
self.mouse.mousePressed(evt)
x = self.mouse.getMouseX()
y = self.mouse.getMouseY()
self.guiElement.isSelected(x,y)
self.guiElement.buttonDown()

def mouseReleased(self, evt):
self.mouse.mouseReleased(evt)
self.guiElement.buttonUp()

def mouseClicked(self, evt):
self.mouse.mouseClicked(evt)

def mouseEntered(self, evt):
self.mouse.mouseEntered(evt)

def mouseExited(self, evt):
self.mouse.mouseExited(evt)

def frameStarted(self, frameEvent):
if self.keepRendering : self.mouse.update()
return self.keepRendering


class SmokeApplication(sf.Application):
def _createScene(self):
sceneManager = self.sceneManager
camera = self.camera

sceneManager.ambientLight = (0.5, 0.5, 0.5)
sceneManager.setSkyDome(True, 'Examples/CloudySky', 5.0, 8.0)

self.fountainNode = sceneManager.rootSceneNode.createChildSceneNode()
#self.camera.yaw(5.5)
print "Here"
psm = ogre.ParticleSystemManager.getSingleton()
particleSystem2 = psm.createSystem('fountain1', 'Examples/Smoke')
node = self.fountainNode.createChildSceneNode()
node.attachObject(particleSystem2)
def _createFrameListener(self):
self.frameListener = InputListener(self.renderWindow, self.camera, self.sceneManager)
self.root.addFrameListener(self.frameListener)

if __name__ == '__main__':
application = SmokeApplication()
application.go()


Alternatively you could look into using pyCegui.

HTH

pkdawson

26-03-2006 22:59:57

Thanks for your posts, dermont! The pizzagame code looks like it will be a huge help to me, even though it's in C++.