OGRE RenderWindow and Qt4

w63f

16-07-2009 04:54:41

Hi, all!
I'm trying to connect OGRE and Qt4 with python-ogre and PyQt4 tools. By using example from python-ogre site i have the next peace of code:


from PyQt4 import QtOpenGL,QtCore,QtGui
import ogre.renderer.OGRE as Ogre
import sys

class OgreScene (QtGui.QGraphicsScene):
def __init__(self,parent = None):
QtGui.QGraphicsScene.__init__(self,parent)
self.root = None
self.renderwindow = None
self.camera = None
self.viewport = None
self.scene = None

self.setRoot()
self.preload()


self.timer = QtCore.QTimer(self)
self.connect(self.timer,QtCore.SIGNAL("timeout()"),self,QtCore.SLOT("update()"))
self.timer.start(100)

def setRoot(self):
self.root = Ogre.Root("plugins.cfg","ogre.cfg","ogre.log")
if self.root.restoreConfig() or self.root.showConfigDialog():
self.root.initialise(False)

self.connect(self, QtCore.SIGNAL("sceneRectChanged(const QRectF &)"), self.handleResize)

def preload(self):
hello = QtGui.QDialog()
hello.setWindowOpacity(0.8)
hello.setWindowTitle("Hello, world!")
hello.setLayout(QtGui.QVBoxLayout())

label = QtGui.QLabel(QtCore.QString("Hullo."))
hello.layout().addWidget(label)

self.addWidget(hello)

for item in self.items():
item.setFlag(QtGui.QGraphicsItem.ItemIsMovable)
item.setCacheMode(QtGui.QGraphicsItem.DeviceCoordinateCache)
item.setPos(QtCore.QPointF(0, 0))

def handleResize(self,rect):
if self.renderwindow:
#self.renderwindow.resize(int(rect.x()*100.0), int(rect.y()*100.0))

self.renderwindow.windowMovedOrResized()

def drawBackground(self,painter,rect):
if self.renderwindow == None:
#assert(self.painter.paintEngine().type() == QtGui.QPaintEngine.OpenGL)
self.initOgre();

self.root.renderOneFrame()

def initOgre(self):
params = Ogre.NameValuePairList()
#params['currentWindowHandle'] = Ogre.UTFString("0")
params["currentGLContext"] = Ogre.UTFString("True")

self.renderwindow = self.root.createRenderWindow("MainRenderWindow", 640, 480, False, params)

if self.renderwindow == None:
print 'Error: Render window doesn\'t init!'
return

#self.renderwindow.setVisible(True)

self.loadResources()

self.scene = self.root.createSceneManager("DefaultSceneManager", "g3d SceneManager")
self.camera = self.scene.createCamera("g3d Camera")
self.viewport = self.renderwindow.addViewport(self.camera)
self.viewport.setBackgroundColour(Ogre.ColourValue(0.1, 0.1, 0.1, 1.0))
self.scene.setAmbientLight(Ogre.ColourValue(0.5, 0.5, 0.5))
l = self.scene.createLight("MainLight")
l.setPosition(200, 80, 100)
l.setDiffuseColour(Ogre.ColourValue(1.0, 0.5, 0.0))

sphereEnt = self.scene.createEntity("Sphere", "sphere.mesh")
sphereNode = self.scene.getRootSceneNode().createChildSceneNode("SphereNode")

sphereNode.setVisible(True)
sphereNode.attachObject(sphereEnt)

sphereNode.setPosition(0, 0, 0)
self.camera.setPosition(50, 50, 400)
self.camera.lookAt(50, 50, 400)

self.renderwindow.setVisible(True)

print 'Ogre has been inited'

def loadResources(self):
config = Ogre.ConfigFile()
config.load('resources.cfg')

seci = config.getSectionIterator()
while (seci.hasMoreElements()):
secName = seci.peekNextKey()
settings = seci.getNext()
for i in settings:
typeName = i.key
archName = i.value
Ogre.ResourceGroupManager.getSingleton().addResourceLocation(archName,typeName,secName)

Ogre.ResourceGroupManager.getSingleton().initialiseAllResourceGroups()


if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)

mwin = QtGui.QWidget()
scene = OgreScene()
gr = QtGui.QGridLayout()
view = QtGui.QGraphicsView(scene)
gr.addWidget(view,0,0)
mwin.setLayout(gr)
mwin.show()

sys.exit(app.exec_())


You can see the result of the run of this python script in attachment. It is the pair of windows: qt's mainwindow and OGRE's renderwindow.

Yes, it works fine, but i want another work (not bad, ofcorse =)). I want to embed Ogre's RenderWindow to Qt's mainwindow (Now they are separated).
The question is: "How can i embed Ogre's renderwindow into Qt's Widgets (if it is possible)...?"

p.s. Sorry, if my english is very bad =)

andy

16-07-2009 05:24:39

look at demos/ogre/OgewWX.py and OgreWindowWX.py to see how this is done..

Basically you use the 'externalWindowHandle' capabilities of Ogre (search for 'renderParameters ' in OgreWindowWX.py)

Regards
Andy

Mohican

17-05-2011 15:09:47

I managed to do it, after reading this article: http://www.ogre3d.org/tikiwiki/QtOgre
I am pasting my code below:

from PyQt4 import QtCore,QtGui,QtOpenGL
import ogre.renderer.OGRE as ogre
import sys, random

class ogreWidget(QtOpenGL.QGLWidget):

renderwindow = None

def __init__(self,Ogre,parent = None):

QtOpenGL.QGLWidget.__init__(self,parent)
self.Ogre = Ogre

def initializeGL(self):

params = ogre.NameValuePairList()
params['parentWindowHandle'] = str(int(self.parentWidget().winId()))
position = self.pos()
params['left'] = str(position.x())
params['top'] = str(position.y())
self.renderwindow = self.Ogre.createRenderWindow(str(random.random()), self.width(), self.height(), False, params)
self.renderwindow.setActive(True)

# Initialise Resources and Scene Manager
ogre.ResourceGroupManager.getSingleton().initialiseAllResourceGroups()

self.scene = self.Ogre.createSceneManager(ogre.ST_GENERIC)
self.camera = self.scene.createCamera("Camera")
self.viewport = self.renderwindow.addViewport(self.camera)
self.viewport.setBackgroundColour(ogre.ColourValue(0.1, 0.1, 0.1, 1.0))
self.scene.setAmbientLight(ogre.ColourValue(0.5, 0.5, 0.5))
l = self.scene.createLight("MainLight")
l.setPosition(200, 80, 100)
l.setDiffuseColour(ogre.ColourValue(1.0, 0.5, 0.0))

sphereEnt = self.scene.createEntity("Nomad", "nomad.mesh")
sphereNode = self.scene.getRootSceneNode().createChildSceneNode("SphereNode")

sphereNode.setVisible(True)
sphereNode.attachObject(sphereEnt)
sphereNode.setPosition(0, 0, 0)

self.camera.setPosition(200+200*random.random(), 50, 200+200*random.random())
self.camera.lookAt(0, 0, 0)

self.timer = QtCore.QTimer(self)
self.connect(self.timer,QtCore.SIGNAL("timeout()"),self,QtCore.SLOT("update()"))
self.timer.start(50)

def resizeGL(self,width,height):
self.renderwindow.windowMovedOrResized()

def paintGL(self):
self.Ogre.renderOneFrame()


if __name__ == "__main__":
# Init Ogre
Ogre = ogre.Root('config/plugins_windows.cfg','config/ogre.cfg','config/ogre.log')

# Read 'resources.cfg'
cfg = ogre.ConfigFile()
cfg.load('config/resources_client.cfg')

# Iterate through resources file
seci = cfg.getSectionIterator()
while seci.hasMoreElements():
secName = seci.peekNextKey()
settings = seci.getNext()
for item in settings:
typeName = item.key
archName = item.value
ogre.ResourceGroupManager.getSingleton().addResourceLocation(archName, typeName, secName)

# Show config dialog if no 'ogre.cfg' file exists
if not Ogre.restoreConfig() and not Ogre.showConfigDialog():
raise Exception("User canceled config dialog! (setupRenderSystem)")

Ogre.initialise(False)


# Initialize Qt
app = QtGui.QApplication(sys.argv)

mwin = QtGui.QDialog()
mwin.setWindowTitle("Test")
mwin.setGeometry(20,20,1024,768)

layout = QtGui.QGridLayout()
layout.addWidget(ogreWidget(Ogre))
layout.addWidget(ogreWidget(Ogre))
layout.addWidget(ogreWidget(Ogre))
layout.addWidget(ogreWidget(Ogre))
layout.addWidget(QtGui.QLineEdit("Write something...does it work?"))
mwin.setLayout(layout)
mwin.show()

sys.exit(app.exec_())

thios

02-07-2011 16:50:33

@Mohican:
Thanks for the example. I can however only get ogre to render if I modify it as follows:
replace:
layout = QtGui.QGridLayout()
layout.addWidget(ogreWidget(Ogre))
layout.addWidget(ogreWidget(Ogre))
layout.addWidget(ogreWidget(Ogre))
layout.addWidget(ogreWidget(Ogre))
layout.addWidget(QtGui.QLineEdit("Write something...does it work?"))
mwin.setLayout(layout)
mwin.show()


with:
ow = ogreWidget(Ogre)
layout.addWidget(ow)
#layout.addWidget(ogreWidget(Ogre))
#layout.addWidget(ogreWidget(Ogre))
#layout.addWidget(ogreWidget(Ogre))
#layout.addWidget(ogreWidget(Ogre))
layout.addWidget(QtGui.QLineEdit("Write something...does it work?"))
mwin.setLayout(layout)

ow.initializeGL()

mwin.show()


I'm on ubuntu natty with a default PyQt4 installation and latest python-ogre.

Furthermore if I try to animate the mesh (I used robot.mesh instead of your nomad) the frame changes don't appear. Through experimentation I found out that I can briefly get the animation to show by adding self.glDraw() at the start of paintGL(). This briefly shows the animation before I get a "maximum recursion depth exceeded" error (makes sense as glDraw calls paintGL).

Any thoughts?

My code:
from PyQt4 import QtCore,QtGui,QtOpenGL
import ogre.renderer.OGRE as ogre
import sys, random, time

class ogreWidget(QtOpenGL.QGLWidget):

renderwindow = None

def __init__(self,Ogre,parent = None):

QtOpenGL.QGLWidget.__init__(self,parent)
self.Ogre = Ogre

def initializeGL(self):

params = ogre.NameValuePairList()
params['parentWindowHandle'] = str(int(self.parentWidget().winId()))
position = self.pos()
params['left'] = str(position.x())
params['top'] = str(position.y())
self.renderwindow = self.Ogre.createRenderWindow(str(random.random()), self.width(), self.height(), False, params)
self.renderwindow.setActive(True)

# Initialise Resources and Scene Manager
ogre.ResourceGroupManager.getSingleton().initialiseAllResourceGroups()

self.scene = self.Ogre.createSceneManager(ogre.ST_GENERIC)
self.camera = self.scene.createCamera("Camera")
self.viewport = self.renderwindow.addViewport(self.camera)
self.viewport.setBackgroundColour(ogre.ColourValue(0.1, 0.1, 0.1, 1.0))
self.scene.setAmbientLight(ogre.ColourValue(0.5, 0.5, 0.5))
l = self.scene.createLight("MainLight")
l.setPosition(200, 80, 100)
l.setDiffuseColour(ogre.ColourValue(1.0, 0.5, 0.0))

sphereEnt = self.scene.createEntity("Robot", "robot.mesh")
sphereNode = self.scene.getRootSceneNode().createChildSceneNode("SphereNode")

sphereNode.setVisible(True)
sphereNode.attachObject(sphereEnt)
sphereNode.setPosition(0, 0, 0)

self.animation = sphereEnt.getAnimationState ( 'Walk' )
self.animation.setLoop ( True )
self.animation.setEnabled ( True )

self.camera.setPosition(200+200*random.random(), 50, 200+200*random.random())
self.camera.lookAt(0, 0, 0)

self.timer = QtCore.QTimer(self)
self.connect(self.timer,QtCore.SIGNAL("timeout()"),self,QtCore.SLOT("update()"))
self.timer.start(50)

self.previousTime = 0


def resizeGL(self,width,height):
self.renderwindow.windowMovedOrResized()

def paintGL(self):

#self.glDraw() # ugly hack which briefly renders the animation and causes a maximum recursion depth exceeded error

self.Ogre.renderOneFrame()

timeNow = time.time()

timePassed = timeNow - self.previousTime

self.animation.addTime ( timePassed )

self.previousTime = timeNow


if __name__ == "__main__":
# Init Ogre
Ogre = ogre.Root('../config/plugins_linux_editor.cfg','../config/ogre.cfg','ogre.log')

# Read 'resources.cfg'
cfg = ogre.ConfigFile()
cfg.load('../config/resources_editor.cfg')

# Iterate through resources file
seci = cfg.getSectionIterator()
while seci.hasMoreElements():
secName = seci.peekNextKey()
settings = seci.getNext()
for item in settings:
typeName = item.key
archName = item.value
ogre.ResourceGroupManager.getSingleton().addResourceLocation(archName, typeName, secName)

# Show config dialog if no 'ogre.cfg' file exists
if not Ogre.restoreConfig() and not Ogre.showConfigDialog():
raise Exception("User canceled config dialog! (setupRenderSystem)")

Ogre.initialise(False)


# Initialize Qt
app = QtGui.QApplication(sys.argv)

mwin = QtGui.QDialog()
mwin.setWindowTitle("Test")
mwin.setGeometry(20,20,1024,768)

layout = QtGui.QGridLayout()

ow = ogreWidget(Ogre)
layout.addWidget(ow)
#layout.addWidget(ogreWidget(Ogre))
#layout.addWidget(ogreWidget(Ogre))
#layout.addWidget(ogreWidget(Ogre))
#layout.addWidget(ogreWidget(Ogre))
layout.addWidget(QtGui.QLineEdit("Write something...does it work?"))
mwin.setLayout(layout)

ow.initializeGL()

mwin.show()

sys.exit(app.exec_())

dermont

02-07-2011 21:41:09

You are probably better off using a currentGLContext with a QGLWidget:


...
#params['parentWindowHandle'] = str(int(self.parentWidget().winId()))
self.makeCurrent()
params["currentGLContext"] = "true"
..
self.connect(self.timer,QtCore.SIGNAL("timeout()"),self,QtCore.SLOT("updateGL()"))

def resizeGL(self,width,height):
self.renderwindow.resize(width, height)
self.renderwindow.windowMovedOrResized()
self.viewport._updateDimensions()

def updateGL(self):
timeNow = time.time()
timePassed = timeNow - self.previousTime
self.animation.addTime ( timePassed )
self.previousTime = timeNow
self.Ogre.renderOneFrame()
QtOpenGL.QGLWidget.updateGL(self)


You can also use an ordinary QWidget with an externalWindowHandle, the following example is for PySide but should be easy to switch to PyQt.


import sys
sys.path.insert(0,'..')
import PythonOgreConfig

from PySide import QtGui, QtCore
import ogre.renderer.OGRE as ogre
import os
import time

def getPluginPath():
""" Return the absolute path to a valid plugins.cfg file.
look in the current directory for plugins.cfg followed by plugins.cfg.nt|linux
If not found look one directory up
"""
paths = [os.path.join(os.getcwd(), 'plugins.cfg'),
os.path.join(os.getcwd(), 'plugins.cfg.'+os.name),
os.path.join(os.getcwd(), '..','plugins.cfg'),
os.path.join(os.getcwd(), '..','plugins.cfg.'+os.name),
]
for path in paths:
if os.path.exists(path):
return path

sys.stderr.write("\n"
"** Warning: Unable to locate a suitable plugins.cfg file.\n"
"** Warning: Please check your ogre installation and copy a\n"
"** Warning: working plugins.cfg file to the current directory.\n\n")
raise ogre.Exception(0, "can't locate a suitable 'plugins' file", "")

## ---------------------------------------------------------
## Ogre Animation Tree
## ---------------------------------------------------------
class OgreAnimationTree(QtGui.QTreeWidget):

animation_signal = QtCore.Signal(str)

def __init__(self):
QtGui.QTreeWidget.__init__(self, None)
self.setGeometry(100, 100, 300, 200)
self.setWindowOpacity(0.3)

# tree header
self.setColumnCount(3)
sList = [ ] #QtCore.QStringList()
sList.append("Animation")
sList.append("Length")
sList.append("State")
self.setHeaderLabels(sList)
self.setColumnWidth ( 0, 100 )
self.setColumnWidth ( 1, 70 )
self.setColumnWidth ( 2, 70 )
self.entity = None
self.animationStates = []
self.node = None
self.rootItems = []
self.previousItem = None

@QtCore.Slot(list)
def changeEntity(self, entity_list):

# returns animation state
def getEnableStr(anim):
if anim.getEnabled():
return 'Enabled'
return 'Disabled'

# fill tree with animations from entity
self.entity = entity_list[0]
it = self.entity.getAllAnimationStates().getAnimationStateIterator()
while it.hasMoreElements():
anim = it.getNext()
rootItem = QtGui.QTreeWidgetItem()
rootItem.setText( 0, self.tr(anim.getAnimationName()))
rootItem.setIcon( 0, QtGui.QIcon( "./icons/chart_organisation.png" ) )
rootItem.setText( 1, self.tr( str(anim.getLength()) ))
rootItem.setText( 2, self.tr( getEnableStr(anim) ))
if anim.getAnimationName()=="Walk":
self.setCurrentItem(rootItem)
self.previousItem = rootItem

self.addTopLevelItem( rootItem )
self.rootItems.append( rootItem )

# sort by name
self.sortItems( 0 , QtCore.Qt.AscendingOrder )
# tree events
self.connect(self, QtCore.SIGNAL("itemPressed(QTreeWidgetItem *,int)"), self.OnItemPressed)

# event handler animation tree
def OnItemPressed(self, selectedWidgetItem, indexNum):

#disable prviously selected item and remove for animationState list
self.previousItem.setText( 2, 'Disabled')
selectedWidgetItem.setText( 2, 'Enabled' )
self.animation_signal.emit(str(selectedWidgetItem.text(0)))

# enable selected item and add to animationState list
self.previousItem = self.currentItem()

## ---------------------------------------------------------
## Ogre View Widget
## ---------------------------------------------------------
class OgreView(QtGui.QWidget, QtCore.QObject):

entity_signal = QtCore.Signal(list)
stats_signal = QtCore.Signal(str)
render_signal = QtCore.Signal(list)

def __init__(self):
QtGui.QWidget.__init__(self, None)

self.setAttribute(QtCore.Qt.WA_PaintOnScreen, True)
self.setAttribute(QtCore.Qt.WA_OpaquePaintEvent, True)

self.renderWindow = None
self.sceneManager = None
self.viewport = None

self.animationStates = []
self.entity = None
self.node = None
# keep reference to root to allow correct order deletion
self.root = ogre.Root.getSingletonPtr()

## ----------------------------------------------------------
def setupView(self):

# renderWindow already created return
if not self.renderWindow is None:
return

#create our render window options
params = ogre.NameValuePairList()
params["externalWindowHandle"] = str(self.winId())
root = self.root

## create our render window
self.renderWindow = root.createRenderWindow("TestWin", self.width() , self.height(), False, params )
self.renderWindow.setActive(True)
self.renderWindow.setAutoUpdated(False)
windowHnd = self.renderWindow.getCustomAttributeInt("WINDOW")

self.renderWindow.reposition(self.x(), self.y() )
self.renderWindow.resize(self.width(), self.height())
self.renderWindow.windowMovedOrResized()

self.render_signal.emit([self.renderWindow])

## create scenemanager
self.sceneManager = root.createSceneManager(ogre.ST_GENERIC)
sceneManager = self.sceneManager
sceneManager.setAmbientLight(ogre.ColourValue(1, 1, 1))

## create camera
self.camera = self.sceneManager.createCamera('PlayerCam')
self.camera.setPosition(ogre.Vector3(0, 0, 500))
self.camera.lookAt(ogre.Vector3(0, 0, -300))
self.camera.setAutoAspectRatio(True)
self.camera.setNearClipDistance(5)
camera = self.camera

## create viewport
viewport = self.renderWindow.addViewport(camera)
viewport.setBackgroundColour(ogre.ColourValue(0.18, 0.15, 0.76, 1))
self.viewport = viewport
camera.setAspectRatio((viewport.getActualWidth()) /
(viewport.getActualHeight()))

ogre.TextureManager.getSingleton().setDefaultNumMipmaps (5)
ogre.MaterialManager.getSingleton().setDefaultTextureFiltering(
ogre.TFO_ANISOTROPIC)
ogre.MaterialManager.getSingleton().setDefaultAnisotropy(2)

## resources
ogre.ResourceGroupManager.getSingleton().initialiseAllResourceGroups()

## create head entity
headNode = self.sceneManager.getRootSceneNode().createChildSceneNode()
entity = self.sceneManager.createEntity('robot', 'robot.mesh')
headNode.attachObject(entity)
self.entity = entity
self.node = headNode
self.animationStates.append(entity.getAnimationState('Walk'))
self.animationStates[0].Enabled = True

self.entity_signal.emit([self.entity])

@QtCore.Slot(str)
def switchAnimation(self, animation_state):

a = self.animationStates.pop()
a.setEnabled(False)
del a

self.animationStates.append(self.entity.getAnimationState(animation_state))
self.animationStates[0].Enabled = True

def paintEvent(self, evt):
#evt.ignore()
if(self.renderWindow is None):
self.setupView()


def update(self):
if(self.renderWindow):
self.updateAnim()
self.renderWindow.update(True)
if(self.renderWindow.isPrimary()):
self.stats_signal.emit('Avg FPS: %u Batches: %u Trianges: %u' %(self.renderWindow.getLastFPS(), self.renderWindow.batchCount,self.renderWindow.getTriangleCount()))

def updateAnim(self):
for a in self.animationStates:
a.addTime(self.renderWindow.getBestFPS()/10000)

def resizeRenderWindow(self, w, h):
if (self.renderWindow):
if sys.platform.startswith ('linux'):
self.renderWindow.resize(w, h)
self.renderWindow.windowMovedOrResized()
if (self.viewport):
self.viewport._updateDimensions()


def resizeEvent(self, evt):
self.resizeRenderWindow( evt.size().width(), evt.size().height() )
evt.ignore()


## =================================================================
## Ogre Log Widget
## =================================================================
class OgreLogWindow(QtGui.QWidget):

def __init__(self, *args):
apply(QtGui.QWidget.__init__, (self,) + args)

self.logTextCtrl = QtGui.QPlainTextEdit()
self.logTextCtrl.setReadOnly(True)
self.logTextCtrl.setSizePolicy(QtGui.QSizePolicy.Ignored, QtGui.QSizePolicy.Ignored)
self.logTextCtrl.setMinimumSize(100, 53)

self.logLayout = QtGui.QVBoxLayout()
self.logLayout.addWidget(self.logTextCtrl)
self.setLayout(self.logLayout)

self.logListener = self.LogListener(self.logTextCtrl)

## get default log and add listener
if ogre.LogManager.getSingletonPtr():
log = ogre.LogManager.getSingletonPtr().getDefaultLog()
log.addListener(self.logListener)

## ----------------------------------------------------------
def clearLog(self):
self.logTextCtrl.setText("")

## ----------------------------------------------------------
def __del__(self):
if ogre.LogManager.getSingletonPtr():
log = ogre.LogManager.getSingletonPtr().getDefaultLog()
if log: log.removeListener(self.logListener)
del self.logListener

## ----------------------------------------------------------
## Log Listener nested class, since had problems with multiple inheritance
## from sip and boost classes
class LogListener(ogre.LogListener):

def __init__(self, textControl):
ogre.LogListener.__init__(self)
m = "Created LogListener.............\n"
self.textControl = textControl
self.textControl.insertPlainText(m)

## ----------------------------------------------------------
def messageLogged(self, message, level, maskDebug, logName):
"""Capture Messages to our Log."""
m = "%s: %s\n" % (time.ctime(), message )
self.textControl.insertPlainText(m)

## ---------------------------------------------------------
## Main Window
## ---------------------------------------------------------
class MainWindow(QtGui.QMainWindow):

def __init__(self, *args):
apply(QtGui.QMainWindow.__init__, (self,) + args)

self.setWindowTitle('Python Ogre Qt Example')
self.statusBar().showMessage('Ready')


mSplitterMain = QtGui.QSplitter(self)
mSplitterMain.setOrientation(QtCore.Qt.Vertical)
self.mSplitterMain = mSplitterMain

mSplitterGraphics = QtGui.QSplitter(mSplitterMain)
mSplitterGraphics.setOrientation(QtCore.Qt.Horizontal)

## Ogre View
ogreView = OgreView()
ogreView.setFocusPolicy(QtCore.Qt.ClickFocus)
#ogreView.setMinimumSize(105, 355)
self.ogreView = ogreView

## Ogre Log
self.InfoTabWidget = QtGui.QTabWidget()

self.ogreLog = OgreLogWindow()
self.InfoTabWidget.addTab(self.ogreLog, "Log")

##imageLabel = QtGui.QLabel()
##image = QtGui.QImage("/media/sda8/Libraries/PYTHON/python-ogre/demos/media/materials/textures/leaf.png")
##imageLabel.setPixmap(QtGui.QPixmap.fromImage(image))

##scrollArea = QtGui.QScrollArea()
##scrollArea.setBackgroundRole(QtGui.QPalette.Dark)
##scrollArea.setWidget(imageLabel)
#self.InfoTabWidget.addTab(scrollArea, "Textures")

# create animation state tree
self.tree = OgreAnimationTree()
ogreView.entity_signal.connect(self.tree.changeEntity)
ogreView.stats_signal.connect(self.updateStats)
ogreView.render_signal.connect(self.createScene)
self.tree.animation_signal.connect(self.ogreView.switchAnimation)

mSplitterGraphics.addWidget(self.tree)
mSplitterGraphics.addWidget(self.ogreView)
mSplitterGraphics.setSizes ( [100,500] )

mSplitterMain.addWidget(mSplitterGraphics)
mSplitterMain.addWidget(self.InfoTabWidget)
mSplitterMain.setSizes ( [500,150] )
self.setGeometry(50, 50, 800, 600)
self.setCentralWidget( mSplitterMain )

self.startTimer(3) ## start timer

@QtCore.Slot(str)
def updateStats(self, stats):
self.statusBar().showMessage(stats)

@QtCore.Slot(list)
def createScene(self, rw_list):
print dir(rw_list[0])

def timerEvent(self, evt):
evt.ignore()
root = ogre.Root.getSingletonPtr()
root._fireFrameStarted()
self.ogreView.update()
root._fireFrameRenderingQueued()
root._fireFrameEnded()

def __del__(self):
print "Deleting ......."
del self.ogreView
del self.ogreLog
self.destroy()

class OgreQtApplication(QtGui.QApplication):
def __init__(self, args):
QtGui.QApplication.__init__(self, args)

self.logName = "QtOGRE.log"
# create our log
self.logManager = ogre.LogManager()
ogre.LogManager.getSingletonPtr().createLog(self.logName, True, True, False)
# ogre root
self.root = ogre.Root( getPluginPath(), "" )

self.OnConfigOgre()

self.win=MainWindow()
self.win.show()
self.connect(self, QtCore.SIGNAL("lastWindowClosed()"),
self, QtCore.SLOT("quit()"))
self.exec_()

def OnConfigOgre(self):
carryOn = self.root.restoreConfig() or self.root.showConfigDialog()
if not carryOn:
sys.exit('Config Dialog Error')

# load resources
config = ogre.ConfigFile()
config.load("../resources.cfg")
seci = config.getSectionIterator()
while seci.hasMoreElements():
SectionName = seci.peekNextKey()
Section = seci.getNext()
for item in Section:
print item.value, item.key, SectionName
ogre.ResourceGroupManager.getSingleton().\
addResourceLocation(item.value, item.key, SectionName)

# set OpenGL render system
root = ogre.Root.getSingletonPtr()
root.setRenderSystem(root.getRenderSystemByName("OpenGL Rendering Subsystem") )
root.initialise(False)

def cleanup(self):
"""Clean Up"""
self.win.destroy()
if self.root:
del self.root
if self.logManager:
del self.logManager
print "Deleted Qt Application Viewer"

def main(args):
app = OgreQtApplication(args)
app.cleanup()
if __name__=="__main__":
main(sys.argv)

dermont

03-07-2011 01:23:54

Sorry I missed your comment regarding calling ow.initializeGL(), try manually updating the renderwindow without swapping the buffers, there are probably other ways of doing this, e.g:


import sys
sys.path.insert(0,'..')
import PythonOgreConfig

from PySide import QtGui, QtCore, QtOpenGL
import ogre.renderer.OGRE as ogre
import sys, random, time

class ogreWidget(QtOpenGL.QGLWidget):

renderwindow = None

def __init__(self,Ogre,parent = None):

QtOpenGL.QGLWidget.__init__(self,parent)
self.Ogre = Ogre

def initializeGL(self):
params = ogre.NameValuePairList()
params["currentGLContext"] = "true"

position = self.pos()
params['left'] = str(position.x())
params['top'] = str(position.y())
self.renderwindow = self.Ogre.createRenderWindow(str(random.random()), self.width(), self.height(), False, params)
self.renderwindow.setActive(True)
self.renderwindow.setAutoUpdated(True)
# Initialise Resources and Scene Manager
ogre.ResourceGroupManager.getSingleton().initialiseAllResourceGroups()

self.scene = self.Ogre.createSceneManager(ogre.ST_GENERIC)
self.camera = self.scene.createCamera("Camera")
self.viewport = self.renderwindow.addViewport(self.camera)
self.viewport.setBackgroundColour(ogre.ColourValue(0.1, 0.1, 0.1, 1.0))
self.camera.setAspectRatio((self.viewport.getActualWidth()) /
(self.viewport.getActualHeight()))


self.scene.setAmbientLight(ogre.ColourValue(0.5, 0.5, 0.5))
l = self.scene.createLight("MainLight")
l.setPosition(200, 80, 100)
l.setDiffuseColour(ogre.ColourValue(1.0, 0.5, 0.0))

sphereEnt = self.scene.createEntity("Robot", "robot.mesh")
sphereNode = self.scene.getRootSceneNode().createChildSceneNode("SphereNode")

sphereNode.setVisible(True)
sphereNode.attachObject(sphereEnt)
sphereNode.setPosition(0, 0, 0)

self.animation = sphereEnt.getAnimationState ( 'Walk' )
self.animation.setLoop ( True )
self.animation.setEnabled ( True )

self.camera.setPosition(200+200*random.random(), 50, 200+200*random.random())
self.camera.lookAt(0, 0, 0)

self.timer = QtCore.QTimer(self)
self.connect(self.timer,QtCore.SIGNAL("timeout()"),self,QtCore.SLOT("updateGL()"))
self.timer.start(5)

self.previousTime = 0


def resizeGL(self,width,height):
if (self.renderwindow):
self.renderwindow.resize(width, height)
self.renderwindow.windowMovedOrResized()
self.viewport._updateDimensions()

def updateGL(self):
timeNow = time.time()
timePassed = timeNow - self.previousTime
self.animation.addTime ( timePassed )
self.previousTime = timeNow
self.Ogre._fireFrameStarted()
self.renderwindow.update(False)
self.Ogre._fireFrameRenderingQueued()
self.Ogre._fireFrameEnded()
#self.Ogre.renderOneFrame()
QtOpenGL.QGLWidget.updateGL(self)

if __name__ == "__main__":
# Init Ogre
Ogre = ogre.Root('../plugins.cfg.posix','ogre.cfg','ogre.log')

# Read 'resources.cfg'
cfg = ogre.ConfigFile()
cfg.load('../resources.cfg')

# Iterate through resources file
seci = cfg.getSectionIterator()
while seci.hasMoreElements():
secName = seci.peekNextKey()
settings = seci.getNext()
for item in settings:
typeName = item.key
archName = item.value
ogre.ResourceGroupManager.getSingleton().addResourceLocation(archName, typeName, secName)

# Show config dialog if no 'ogre.cfg' file exists
if not Ogre.restoreConfig() and not Ogre.showConfigDialog():
raise Exception("User canceled config dialog! (setupRenderSystem)")

Ogre.initialise(False)

# Initialize Qt
app = QtGui.QApplication(sys.argv)

mwin = QtGui.QDialog()
mwin.setWindowTitle("Test")
mwin.setGeometry(20,20,1024,768)

layout = QtGui.QGridLayout()

ow = ogreWidget(Ogre)
layout.addWidget(ow)
#layout.addWidget(ogreWidget(Ogre))
#layout.addWidget(ogreWidget(Ogre))
#layout.addWidget(ogreWidget(Ogre))
#layout.addWidget(ogreWidget(Ogre))
layout.addWidget(QtGui.QLineEdit("Write something...does it work?"))
mwin.setLayout(layout)
#ow.show()
#mwin.setCentralWidget( ow )
#ow.resizeGL(100,100)
#ow.initializeGL()

mwin.show()

sys.exit(app.exec_())


thios

03-07-2011 04:07:08

Dermont, that worked amazingly well. Thanks a lot!