Demo_WX.py causes segment fault

mrkissinger

30-06-2007 09:56:10

Using the last SVN version.
Can anyone help?

amd64:/backup/Softwares/ogre/python-ogre/demos/ogre# python Demo_WX.py
/usr/lib/python2.4/site-packages/ogre/renderer/OGRE/__init__.py:6:
RuntimeWarning: to-Python converter for std::pair<std::string const,
std::string> already registered; second conversion method ignored.
from _ogre_ import *
Creating resource group General
Creating resource group Internal
Creating resource group Autodetect
SceneManagerFactory for type 'DefaultSceneManager' registered.
Registering ResourceManager for type Material
Registering ResourceManager for type Mesh
Registering ResourceManager for type Skeleton
MovableObjectFactory for type 'ParticleSystem' registered.
OverlayElementFactory for type Panel registered.
OverlayElementFactory for type BorderPanel registered.
OverlayElementFactory for type TextArea registered.
Registering ResourceManager for type Font
ArchiveFactory for archive type FileSystem registered.
ArchiveFactory for archive type Zip registered.
FreeImage version: 3.9.3
This program uses FreeImage, a free, open source image library
supporting all common bitmap formats. See http://freeimage.sourceforge.net
for details
Supported formats:
bmp,ico,jpg,jif,jpeg,jpe,jng,koa,iff,lbm,mng,pbm,pbm,pcd,pcx,pgm,pgm,png,ppm,ppm,ras,tga,targa,tif,tiff,wap,wbmp,wbm,psd,cut,xbm,xpm,gif,hdr,g3,sgi
DDS codec registering
Registering ResourceManager for type HighLevelGpuProgram
Registering ResourceManager for type Compositor
MovableObjectFactory for type 'Entity' registered.
MovableObjectFactory for type 'Light' registered.
MovableObjectFactory for type 'BillboardSet' registered.
MovableObjectFactory for type 'ManualObject' registered.
MovableObjectFactory for type 'BillboardChain' registered.
MovableObjectFactory for type 'RibbonTrail' registered.
Loading library /usr/local/lib/OGRE/RenderSystem_GL
Installing plugin: GL RenderSystem
OpenGL Rendering Subsystem created.
Plugin successfully installed
Loading library /usr/local/lib/OGRE/Plugin_ParticleFX
Installing plugin: ParticleFX
Particle Emitter Type 'Point' registered
Particle Emitter Type 'Box' registered
Particle Emitter Type 'Ellipsoid' registered
Particle Emitter Type 'Cylinder' registered
Particle Emitter Type 'Ring' registered
Particle Emitter Type 'HollowEllipsoid' registered
Particle Affector Type 'LinearForce' registered
Particle Affector Type 'ColourFader' registered
Particle Affector Type 'ColourFader2' registered
Particle Affector Type 'ColourImage' registered
Particle Affector Type 'ColourInterpolator' registered
Particle Affector Type 'Scaler' registered
Particle Affector Type 'Rotator' registered
Particle Affector Type 'DirectionRandomiser' registered
Particle Affector Type 'DeflectorPlane' registered
Plugin successfully installed
Loading library /usr/local/lib/OGRE/Plugin_BSPSceneManager
Installing plugin: BSP Scene Manager
Plugin successfully installed
Loading library /usr/local/lib/OGRE/Plugin_OctreeSceneManager
Installing plugin: Octree & Terrain Scene Manager
Plugin successfully installed
*-*-* OGRE Initialising
*-*-* Version 1.4.0RC2 (Eihort)
Creating resource group Bootstrap
Added resource location '../media/packs/OgreCore.zip' of type 'Zip' to
resource group 'Bootstrap'
Added resource location '../media' of type 'FileSystem' to resource
group 'General'
Added resource location '../media/fonts' of type 'FileSystem' to
resource group 'General'
Added resource location '../media/materials/programs' of type
'FileSystem' to resource group 'General'
Added resource location '../media/materials/scripts' of type
'FileSystem' to resource group 'General'
Added resource location '../media/materials/textures' of type
'FileSystem' to resource group 'General'
Added resource location '../media/models' of type 'FileSystem' to
resource group 'General'
Added resource location '../media/overlays' of type 'FileSystem' to
resource group 'General'
Added resource location '../media/particle' of type 'FileSystem' to
resource group 'General'
Added resource location '../media/packs/cubemap.zip' of type 'Zip' to
resource group 'General'
Added resource location '../media/packs/cubemapsJS.zip' of type 'Zip'
to resource group 'General'
Added resource location '../media/packs/dragon.zip' of type 'Zip' to
resource group 'General'
Added resource location '../media/packs/fresneldemo.zip' of type 'Zip'
to resource group 'General'
Added resource location '../media/packs/ogretestmap.zip' of type 'Zip'
to resource group 'General'
Added resource location '../media/packs/skybox.zip' of type 'Zip' to
resource group 'General'

(python:14857): Gtk-WARNING **: gtk_disable_setlocale() must be called
before gtk_init()
CPU Identifier & Features
-------------------------
* CPU ID: Unknown
-------------------------
******************************
*** Starting GLX Subsystem ***
******************************

(python:14857): Gdk-WARNING **: /build/buildd/gtk+2.0-2.10.13/gdk/x11/
gdkdrawable-x11.c:878 drawable is not a pixmap or window
GLRenderSystem::createRenderWindow "wxPython render window", 640x480
windowed miscParams: externalWindowHandle=0
GLXWindow::create
Parsing miscParams
Segmentation fault
amd64:/backup/Softwares/ogre/python-ogre/demos/ogre#

mrkissinger

29-07-2007 21:22:57

Any suggestion?

mrkissinger

29-07-2007 22:13:05

I found this line in OgreWindowWx.py.

renderParameters['externalWindowHandle'] = str(self.GetHandle())

But self.GetHandle() return a zero/null.

I think this is the problem, but I have no solution for this.

I'm using Debian Linux.

andy

30-07-2007 12:41:54

Have you tried running the WX demos that come with PythonWX??

It would seem that WX isn't returning it's window handle which might be caused by an earlier failure (to create the window)?

Andy...

Game_Ender

31-07-2007 01:40:40

There is no way the standard wxPython + Python-Ogre demo will work. You have to apply the method shown on the Ogre wiki, but that requires a native code extension. I do it my project by using ctypes with a python wrapper that ensures only the proper types are passed in. This just takes in the window handle from wxPython (as a void* pointer because CTypes needs a C function) and returns the proper window handle.

Consider the code under the BSD license.

Here is my C++ Source:

// Copyright (C) 2007 Maryland Robotics Club
// Copyright (C) 2007 Joseph Lisee <jlisee@umd.edu>
// All rights reserved.
//
// Author: Joseph Lisee <jlisee@umd.edu>
// File: utility/wxogre_util/src/wxogre_util.h

extern "C"
{
/** Returns a window handle string from a wxWindow in Ogre form
@param window
Must be a pointer to a wxWindow or its subclass.
@return
The window handle in its display:xid form.
*/
char* get_window_handle_str(void* window);
}

// std includes
#include <sstream>
#include <string>
#include <cstring>

// wxWidgets includes
#include <wx/window.h>

// Platform specific includes
#ifdef __WXGTK__
// Needed for random GTK/GDK macros and functions
#include <gdk/gdkx.h>
#include <gtk/gtk.h>

// Needed for crazy GTK_PIZZA stuff
#include <wx/gtk/win_gtk.h>
#endif

char* get_window_handle_str(void* _window)
{
// Assume its a wxObject (can be dangerous)
wxObject* window_obj = (wxObject*)_window;

// Preform a dynamic cast to a wxWindow
wxWindow* window = wxDynamicCast(window_obj, wxWindow);

if (window)
{
std::string handle;
#ifdef __WXGTK__
// Should help reduce flickering
//SetBackgroundStyle(wxBG_STYLE_CUSTOM);
std::stringstream handleStream;

// wxWidgets uses serverl internal GtkWidgets, the GetHandle method returns
// a different one then this, but wxWidgets GLCanvas uses this one to
// interact with GLX with, so we will do the same.
GtkWidget* private_handle = window->m_wxwindow;

// Prevents flicker
gtk_widget_set_double_buffered( private_handle, FALSE );

// Grabs the window for use in the below macros
GdkWindow *window = GTK_PIZZA(private_handle)->bin_window;
Display* display = GDK_WINDOW_XDISPLAY(window);
Window wid = GDK_WINDOW_XWINDOW(window);

// Display
handleStream << (unsigned long)display << ':';

/*#if OGRE_PATCH_VERSION == 0
// Screen (returns ":display.screen ")
std::string screenStr = DisplayString(display);
int dotpos = screenStr.find(".", 0);
screenStr = screenStr.substr(dotpos + 1, screenStr.length() - dotpos);
handleStream << screenStr << ':';
#endif
*/
// XID (typedef of an unsigned int)
handleStream << wid;
handle = handleStream.str();
#else
#error External/Parent Window handle not supported on this platform
#endif

// Allocate string for the return
char* ret = new char[handle.length() + 1];
strcpy(ret, handle.c_str());
return ret;
}

return 0;
}


Python Wrapper:


# Copyright (C) 2007 Maryland Robotics Club
# Copyright (C) 2007 Joseph Lisee <jlisee@umd.edu>
# All rights reserved.
#
# Author: Joseph Lisee <jlisee@umd.edu>

# Standard python imports
import ctypes as __ctypes
import os.path as __path

# Library Imports
import wx as __wx

# Load library
__lib_path = __path.join('..','build','utility','wxogre_util','libwxogre_util.so')
__lib = __ctypes.cdll.LoadLibrary(__path.abspath(__lib_path))
# Look up function
__get_window_handle_str = __lib.get_window_handle_str
# Set types to match prototype: char* get_window_handle_str(void*)
__get_window_handle_str.restype = __ctypes.c_char_p
__get_window_handle_str.argtypes = [__ctypes.c_void_p]

def get_window_handle_str(window):
"""
Returns the Ogre friendly window format. It will not allow itself to be
called with an invalid type, but calling the underlying C wrapped C++
function with anything but a wxWindow or a subclass of it, will result in
a hard crash.
"""
if not isinstance(window, __wx.Window):
raise TypeError, 'Must be called with a wx.Window or a subclass'

# This automatically performs the int -> void* cast
return __get_window_handle_str(int(window.this))


You will probably need to tweak the exact handle grabbing strategy. Check the Ogre wiki and forums (you probably need the screen part which is commented out).

andy

01-08-2007 00:22:00

I'll add a fix to this for the next Linux release as it should probably be a helper function within Python-Ogre

Cheers
Andy

samo83

08-08-2007 04:04:15

Hi Andy
Any idea when the next linux binary will be released? I really want to use Demo_WX.py in my project, but don't understand how to use the wrappers discussed on this forum.
Cheers, Sam

andy

09-08-2007 00:38:36

New windows binary in a couple of days -- Linux binary next, so perhaps 2 weeks (might be less, depends on how things go)

You could do your initial development on Windows and move back to Linux once fixed (yes, I know this isn't ideal :) )

Andy

dermont

09-08-2007 19:56:17

@Game_Ender, thank you for sharing the above code, after tweaking it works a treat.

Game_Ender

10-08-2007 00:08:23

Glad I could be of help, that took me way to long to do the first time. If you don't mind me asking what kind of tweaking was required?

mrkissinger

10-08-2007 03:55:04

Got a "Segmentation fault" error.

amd64:/backup/Softwares/ogre/python-ogre/demos/ogre# python Demo_WX.py
/usr/lib/python2.4/site-packages/ogre/renderer/OGRE/__init__.py:6: RuntimeWarning: to-Python converter for std::pair<std::string const, std::string> already registered; second conversion method ignored.
from _ogre_ import *
-----------------------------begin!
here
===============================PythonC
===============================Running
===============================private_handle: 20565744
===============================1
===============================windows: 0
Segmentation fault
amd64:/backup/Softwares/ogre/python-ogre/demos/ogre#


The codes are:

printf("===============================Running\n");

// wxWidgets uses serverl internal GtkWidgets, the GetHandle method returns
// a different one then this, but wxWidgets GLCanvas uses this one to
// interact with GLX with, so we will do the same.
GtkWidget* private_handle = window->m_wxwindow;
printf("===============================private_handle: %d\n",private_handle);

// Prevents flicker
gtk_widget_set_double_buffered( private_handle, FALSE );

printf("===============================1\n");

// Grabs the window for use in the below macros
GdkWindow *window = GTK_PIZZA(private_handle)->bin_window;
printf("===============================windows: %d\n",window);
Display* display = GDK_WINDOW_XDISPLAY(window);
printf("===============================3\n");
Window wid = GDK_WINDOW_XWINDOW(window);
printf("===============================4\n");



Seems GDK_WINDOW_XDISPLAY(window) return a wrong pointer.
I am not familiar with GDK, so I don't know what caused this wrong.

Any help?

____________________
AMD64/2G/300G + Debian + GeForce 8500 GT

Game_Ender

10-08-2007 04:01:53

You have to make sure you have called "Show(True)" on your main application frame before creating the window like this. If you don't the GTK stuff is not setup properly and this will crash. Maybe I should put a check in for that? Patches welcome.

mrkissinger

10-08-2007 04:35:16

"Segmentation fault" again.

I found the API reference this param like this:

Key: "externalWindowHandle" [API specific] Description: External window handle, for embedding the OGRE context Values: positive integer for W32 (HWND handle) poslong:posint:poslong (display*:screen:windowHandle) or poslong:posint:poslong:poslong (display*:screen:windowHandle:XVisualInfo*) for GLX Default: 0 (None)


So, I added the codes that you commented out and blocked by #ifdef.

std::string screenStr = DisplayString(display);
int dotpos = screenStr.find(".", 0);
screenStr = screenStr.substr(dotpos + 1, screenStr.length() - dotpos);
handleStream << screenStr << ':';


The result it like this:

Plugin successfully installed
*-*-* OGRE Initialising
*-*-* Version 1.4.0RC2 (Eihort)

(python:21180): Gtk-WARNING **: gtk_disable_setlocale() must be called before gtk_init()
===============================PythonC
===============================Running
===============================private_handle: 16832736
===============================1
===============================windows: 16407920
===============================display: 16346688
===============================wid: 48234536
-----------------------------Handle=16346688:0:48234536
GLRenderSystem::createRenderWindow "wxPython render window", 800x600 windowed miscParams: externalWindowHandle=16346688:0:48234536
GLXWindow::create
Segmentation fault



My python program:

import wx
import ogre.renderer.OGRE as ogre
import ctypes as __ctypes
import os.path as __path

__lib_path = __path.join('gui','wxh.so')
__lib = __ctypes.cdll.LoadLibrary(__path.abspath(__lib_path))
# Look up function
__get_window_handle_str = __lib.get_window_handle_str
# Set types to match prototype: char* get_window_handle_str(void*)
__get_window_handle_str.restype = __ctypes.c_char_p
__get_window_handle_str.argtypes = [__ctypes.c_void_p]

def get_window_handle_str(window):
"""
Returns the Ogre friendly window format. It will not allow itself to be
called with an invalid type, but calling the underlying C wrapped C++
function with anything but a wxWindow or a subclass of it, will result in
a hard crash.
"""
if not isinstance(window, wx.Window):
raise TypeError, 'Must be called with a wx.Window or a subclass'

# This automatically performs the int -> void* cast
return __get_window_handle_str(int(window.this))

class Greeter(wx.App):
def OnInit(self):
frame = wx.Frame(None, -1, "Hello wxPython world")
frame.Show(True)
self.SetTopWindow(frame)
#print str(frame.GetHandle())

root = ogre.Root()
#config = ogre.ConfigFile()

carryOn = root.showConfigDialog()
if not carryOn:
sys.exit('Quit from Config Dialog')

handle=get_window_handle_str(frame)
print ("-----------------------------Handle=%s" % (handle) )
renderParameters = ogre.NameValuePairList()
renderParameters['externalWindowHandle']=handle
#renderParameters['externalWindowHandle'] = str(self.GetHandle())
renderWindow = root.createRenderWindow('wxPython render window', 800,
600, False, renderParameters)
print 'created'
renderWindow.active = True
self.renderWindow = renderWindow

return True

firstapp = Greeter(0)
firstapp.MainLoop()

dermont

10-08-2007 07:50:16

@mrkissinger
The seg fault is because you're missing a 'root.initialise', i.e:


..
carryOn = root.showConfigDialog()
if not carryOn:
sys.exit('Quit from Config Dialog')
root.initialise(False)
..


Here's a complete (not fully tested) example here, where wx_util.py is a file containing the ctypes implementation of Game_enders code:


import wx
import wx.aui as aui
import wx_util as wxHandle
import ogre.renderer.OGRE as ogre
import os

## =================================================================
## Ogre Window
## =================================================================
class OgreWindow(wx.PyWindow):

def __init__(self, parent, ID, size = wx.Size(640,480), **kwargs):
wx.PyWindow.__init__(self, parent, ID, size = size, **kwargs)
self.renderWindow = None
self.sceneManager = None
self.viewport = None
self.root = None
self.camera = None
self.size = size

## Event bindings
self.Bind(wx.EVT_CLOSE, self._OnCloseWindow)
self.Bind(wx.EVT_ERASE_BACKGROUND, self._OnEraseBackground)
self.Bind(wx.EVT_SIZE, self._OnSize)

## ----------------------------------------------------------
def __del__(self):

## "Remove and destroy ViewPort"

if self.viewport:
self.renderWindow.removeViewport(self.viewport.getZOrder())
del self.viewport

## "Detach render Window"
if self.renderWindow:

self.root.detachRenderTarget(self.renderWindow)
self.root.getRenderSystem().destroyRenderWindow(self.renderWindow.getName())
## "Delete Camera"

if not self.camera is None:
del self.camera

## "Delete RenderWindow"

if not self.renderWindow is None:
del self.renderWindow

## "Delete SceneManager"

if not self.sceneManager is None:
del self.sceneManager

if not self.root is None:
del root

## ----------------------------------------------------------
def setupResources(self):

## load resource locations
"""This sets up Ogre's resources, which are required to be in
resources.cfg."""
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)



## ----------------------------------------------------------
def createOgreRenderWindow(self):
self.root = ogre.Root( "plugins.cfg", "" )
root = self.root
self.setupResources()

carryOn = self.root.showConfigDialog()
if not carryOn:
sys.exit('Quit from Config Dialog')
self.root.initialise(False)


handle = wxHandle.get_window_handle_str(self)
renderParameters = ogre.NameValuePairList()
renderParameters['externalWindowHandle'] = handle
renderWindow = root.createRenderWindow('wxPython render window',
self.size[0], self.size[1],
False, renderParameters)
renderWindow.active = True
self.renderWindow = renderWindow
ogre.ResourceGroupManager.getSingleton().initialiseAllResourceGroups()

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

self.camera = self.sceneManager.createCamera('PlayerCam')

self.camera.setPosition(ogre.Vector3(0, 0, 500))

self.camera.lookAt(ogre.Vector3(0, 0, -300))

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

s = self.GetSize()
#camera.setAspectRatio((viewport.getActualWidth()) / (viewport.getActualHeight()))
camera.setAspectRatio( s[0]/s[1])

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

ogre.ResourceGroupManager.getSingleton().initialiseAllResourceGroups()

## create head entity
headNode = self.sceneManager.getRootSceneNode().createChildSceneNode()
entity = self.sceneManager.createEntity('head', 'ogrehead.mesh')
headNode.attachObject(entity)

## force resize
self.renderWindow.windowMovedOrResized()

## ----------------------------------------------------------
def _OnSize(self, event):

if (self.renderWindow is None):
return
size = event.GetSize()
self.renderWindow.resize( size.x , size.y )

## Letting Ogre know the window has been resized;
self.renderWindow.windowMovedOrResized()

# Set the aspect ratio for the new size;
if (self.camera):
self.camera.setAspectRatio( float(size.x) / float(size.y) )
self.update()

## ----------------------------------------------------------
def _OnEraseBackground(self, event):
self.update()

## ----------------------------------------------------------
def _OnCloseWindow(self, event):
self.Destroy()

## ----------------------------------------------------------
def AcceptsFocus(self):
return True

## ----------------------------------------------------------
def update(self):
if(not self.renderWindow is None):
ogre.Root.getSingletonPtr().renderOneFrame()




## =================================================================
## Main wxPython Frame
## =================================================================
class DemoFrame(wx.Frame):

def __init__(self, *args, **kwds):
kwds["style"] = wx.DEFAULT_FRAME_STYLE
wx.Frame.__init__(self, *args, **kwds)

self.statusbar = self.CreateStatusBar(2, wx.ST_SIZEGRIP)
self.statusbar.SetStatusWidths([-2, -3])
self.statusbar.SetStatusText("Ready", 0)
self.statusbar.SetStatusText("Welcome To Python Ogre!", 1)
self.m_mgr = wx.aui.AuiManager(self)

## Ogre Win
self.ogreWin = OgreWindow(self, -1)
self.m_mgr.AddPane(self.ogreWin, wx.CENTER, "Ogre Pane")

## tell the manager to "commit" all the changes just made
self.m_mgr.Update()
self.Show(True)
self.ogreWin.createOgreRenderWindow()

## =================================================================
## Application
## =================================================================
class MyApplication(wx.App):
def OnInit(self):
self.MainFrame = DemoFrame(None, -1, "")
self.SetTopWindow(self.MainFrame)
return True


if __name__ == "__main__":
myApp = MyApplication(0)
myApp.MainLoop()


dermont

10-08-2007 08:09:18

@Game_Ender, the tweaks were as per what you mentioned above.

wxogre_util.cpp

// Copyright (C) 2007 Maryland Robotics Club
// Copyright (C) 2007 Joseph Lisee <jlisee@umd.edu>
// All rights reserved.
//
// Author: Joseph Lisee <jlisee@umd.edu>
// File: utility/wxogre_util/src/wxogre_util.h

// std includes
#include <sstream>
#include <string>
#include <cstring>
#include <iostream>
using namespace std;

// wxWidgets includes
#include <wx/window.h>

// Platform specific includes
#ifdef __WXGTK__
// Needed for random GTK/GDK macros and functions
#include <gdk/gdkx.h>
#include <gtk/gtk.h>

// Needed for crazy GTK_PIZZA stuff
#include <wx/gtk/win_gtk.h>
#include <GL/glx.h>
#endif


extern "C"
{
/** Returns a window handle string from a wxWindow in Ogre form
@param window
Must be a pointer to a wxWindow or its subclass.
@return
The window handle in its display:xid form.
*/
extern char* get_window_handle_str(void* window);
}

char* get_window_handle_str(void* _window)
{
// Assume its a wxObject (can be dangerous)
wxObject* window_obj = (wxObject*)_window;

// Preform a dynamic cast to a wxWindow
wxWindow* window = wxDynamicCast(window_obj, wxWindow);

if (window)
{
std::string handle;
#ifdef __WXGTK__
// Should help reduce flickering
//SetBackgroundStyle(wxBG_STYLE_CUSTOM);
std::stringstream handleStream;

// wxWidgets uses serverl internal GtkWidgets, the GetHandle method returns
// a different one then this, but wxWidgets GLCanvas uses this one to
// interact with GLX with, so we will do the same.
GtkWidget* private_handle = window->m_wxwindow;

// Prevents flicker
gtk_widget_set_double_buffered( private_handle, FALSE );

// Grabs the window for use in the below macros
GdkWindow *gdkWin = GTK_PIZZA(private_handle)->bin_window;
Display* display = GDK_WINDOW_XDISPLAY(gdkWin);
Window wid = GDK_WINDOW_XWINDOW(gdkWin);

// Display
handleStream << (unsigned long)display << ':';

// screen (returns "display.screen")
std::string screenStr = DisplayString(display);
std::string::size_type dotPos = screenStr.find(".");
screenStr = screenStr.substr(dotPos+1, screenStr.size());
handleStream << screenStr << ':';

// XID
handleStream << wid << ':';

// retrieve XVisualInfo
int attrlist[] = { GLX_RGBA, GLX_DOUBLEBUFFER, GLX_DEPTH_SIZE, 16, GLX_STENCIL_SIZE, 8, None };
XVisualInfo* vi = glXChooseVisual(display, DefaultScreen(display), attrlist);
handleStream << (unsigned long)vi;

handle = handleStream.str();
#else
#error External/Parent Window handle not supported on this platform
#endif

// Allocate string for the return
char* ret = new char[handle.length() + 1];
strcpy(ret, handle.c_str());
return ret;
}

return 0;
}


wxogre_util.py

# Copyright (C) 2007 Maryland Robotics Club
# Copyright (C) 2007 Joseph Lisee <jlisee@umd.edu>
# All rights reserved.
#
# Author: Joseph Lisee <jlisee@umd.edu>

# Standard python imports
import ctypes as __ctypes
import os.path as __path

# Library Imports
import wx as __wx

# Load library
__lib_path = __path.join('/usr/local/lib', 'libwxogre_util.so')
__lib = __ctypes.cdll.LoadLibrary(__path.abspath(__lib_path))
# Look up function
__get_window_handle_str = __lib.get_window_handle_str
# Set types to match prototype: char* get_window_handle_str(void*)
__get_window_handle_str.restype = __ctypes.c_char_p
__get_window_handle_str.argtypes = [__ctypes.c_void_p]

def get_window_handle_str(window):
"""
Returns the Ogre friendly window format. It will not allow itself to be
called with an invalid type, but calling the underlying C wrapped C++
function with anything but a wxWindow or a subclass of it, will result in
a hard crash.
"""
if not isinstance(window, __wx.Window):
raise TypeError, 'Must be called with a wx.Window or a subclass'

# This automatically performs the int -> void* cast
return __get_window_handle_str(int(window.this))


Compile

g++ -shared `/usr/lib/wx/config/gtk2-unicode-release-2.8 --cflags` `pkg-config gtk+-2.0 --cflags` `/usr/lib/wx/config/gtk2-unicode-release-2.8 --libs` `pkg-config gtk+-2.0 --libs` -lGL wxogre_util.cpp -o libwxogre_util.so

- copied across libwxogre_util.so to relevant dir in my case "'/usr/local/lib"
- sudo ldconfig

mrkissinger

11-08-2007 02:18:26

root.initialise(False) solved this problem, THANKS!

mrkissinger

11-08-2007 06:04:39

Do I have to use wx.aui package?
On my debian/x64, only wxgtk2.6/wxpython2.6 are provided. Seems wx.aui is a new package in 2.8

I tried to use wx.BoxSizer instead of wx.aui.AuiManager, but I got 2 seperated windows: 1 for wx, 1 for ogre.

My codes:


class DemoFrame(wx.Frame):

def __init__(self, *args, **kwds):
kwds["style"] = wx.DEFAULT_FRAME_STYLE
wx.Frame.__init__(self, *args, **kwds)

self.statusbar = self.CreateStatusBar(2, wx.ST_SIZEGRIP)
self.statusbar.SetStatusWidths([-2, -3])
self.statusbar.SetStatusText("Ready", 0)
self.statusbar.SetStatusText("Welcome To Python Ogre!", 1)
#self.m_mgr = wx.aui.AuiManager(self)

## Ogre Win
self.ogreWin = OgreWindow(self, -1)
#self.m_mgr.AddPane(self.ogreWin, wx.CENTER, "Ogre Pane")

## tell the manager to "commit" all the changes just made
#self.m_mgr.Update()

self.Show(True)

self.ogreWin.createOgreRenderWindow()
sizer_1 = wx.BoxSizer(wx.VERTICAL)
sizer_1.Add(self.ogreWin, 2, wx.EXPAND, 0)
self.SetAutoLayout(True)
self.SetSizer(sizer_1)
sizer_1.Fit(self)
sizer_1.SetSizeHints(self)
self.Layout()


The handle I got is sth like: 16352736:0:48234542, is it correct?

dermont

11-08-2007 09:17:59

1) Do I have to use wx.aui package?
No, the wx.BoxSizer code you posted should work fine.

2) The handle I got is sth like: 16352736:0:48234542, is it correct?
Don't know, the handle will change and be relevant to your machine only. For me:
  1. a) handle (display*:screen:windowHandle) resulted in 2 separate windows.

    b) handle (display*:screen:windowHandle:XVisualInfo*) works fine.
    - http://www.ogre3d.org/phpBB2/viewtopic. ... ght=wxogre

    The wxogre_util.cpp code I used is posted on the previous page.
    [/list:u]

mrkissinger

11-08-2007 20:31:18

dermont, by using your cpp program, the ogre window is in wx window now.

THANKS for help from Game_Ender and dermont.

Aperion

20-09-2007 22:21:39

Hey I've tried the solution posted here but I too get a crash, the program dies here:
Display* display = GDK_WINDOW_XDISPLAY(gdkWin);
And I'm assuming it's dieing there because the line before it is setting gdkWin to NULL
GdkWindow *gdkWin = TK_PIZZA(private_handle)->bin_window;

I know nothing about GTK and I made sure it was being initilized. So help would be appriciated, let me know what additional information is needed. Thanks.

Game_Ender

21-09-2007 18:27:40

Have you made sure to "Show(True)" your main frame before trying to create the Ogre window.

Aperion

21-09-2007 18:40:36

Have you made sure to "Show(True)" your main frame before trying to create the Ogre window.I'm not sure, but I have a feeling that will be the case. Here's why, my initial attempt to port the application over to linux I passed None as the renderParameters. This causes all the separate render windows to show up before the main frame. I will be gone this weekend so I will let you know if that is what is wrong. Thanks for the tip.

Edit: Just to confirm, this looks like it did solve my problems with the frameHandle. Thanks.

tdev

18-10-2008 22:20:02

sorry to dig up such an old topic, but i still have a problem with it. Since there is no new linux release of pythonOgre i think it is still a problem?

for me that works:
> window handle: 147581824:0:3774899414896
at least the program does not crash, but all windows are separate and not in the correct place.

i modified:

handleStream << wid;

// retrieve XVisualInfo
//int attrlist[] = { GLX_RGBA, GLX_DOUBLEBUFFER, GLX_DEPTH_SIZE, 16, GLX_STENCIL_SIZE, 8, None };
//XVisualInfo* vi = glXChooseVisual(display, DefaultScreen(display), attrlist);
//handleStream << (unsigned long)vi;


with the original implementation, i get this string:
> window handle: 147581824:0:37748901:152368616

and it will crash:
******************************
*** Starting GLX Subsystem ***
******************************
> window handle: 147581824:0:37748901:152368616
GLRenderSystem::createRenderWindow "wxPythonWxOgreRenderWindow0", 200x200 windowed miscParams: externalWindowHandle=147581824:0:37748901:152368616
GLXWindow::create
Parsing miscParams
GLXWindow::create -- using external window handle
The program 'python' received an X Window System error.
This probably reflects a bug in the program.
The error was 'BadMatch (invalid parameter attributes)'.
(Details: serial 582 error_code 8 request_code 159 minor_code 5)
(Note to programmers: normally, X errors are reported asynchronously;
that is, you will receive the error a while after causing it.
To debug your program, run it with the --sync command line
option to change this behavior. You can then get a meaningful
backtrace from your debugger if you break on the gdk_x_error() function.)


any ideas? thanks!