Converting WriteToTexture into Python-Ogre

team23

28-08-2007 15:54:07

I'm trying to convert the following code to Python-Ogre for use in my project, but I'm hitting an issue.

http://www.ogre3d.org/wiki/index.php/HowTo:_Write_text_on_texture

The portion of the code that is currently causing me problems.

def writeToTexture(self, text, destTexture, destRectangle, font, color, justify = 'l' , wordwrap = True ):

if destTexture.getHeight() < destRectangle.bottom:
destRectangle.bottom = destTexture.getHeight()
if destTexture.getWidth() < destRectangle.right:
destRectangle.right = destTexture.getWidth()

if not font.isLoaded():
font.load()

fontTexture = ogre.TextureManager.getSingleton().getByName(font.getMaterial().getTechnique(0).getPass(0).getTextureUnitState(0).getTextureName())

fontBuffer = fontTexture.getBuffer()
destBuffer = destTexture.getBuffer()

destPb = destBuffer.lock(destRectangle, ogre.HardwareBuffer.HBL_NORMAL)

#nBuffSize = fontBuffer.getSizeInBytes()
#buffer calloc call

fontPb = ogre.PixelBox(fontBuffer.getWidth(), fontBuffer.getHeight(), fontBuffer.getDepth(), fontBuffer.getFormat())

fontBuffer.blitToMemory(fontPb)


I'm hitting a "RuntimeError: unidentifiable C++ exception" on the blitToMemory call.

And from what I can see the only difference between my code and the wiki code is the missing calloc call, which I'm not sure how I would port to python.

SiWi

28-08-2007 17:01:58

That could mean the function doesn´t exist or you passed wrong arguments. Search in the documation for the function and find out if it exists and wha arguments it takes.

andy

29-08-2007 15:45:09

[EDIT] Had another look and don't believe it will work - hole in Python-Ogre I need to look at, basically I need to change void *'s to unsigned int's in constructors (currently only done on member functions)

It's likely you'll need to play some games with ctypes etc to make this work -- have a look at demo_bezier etc ..

You'll have to create a ctype buffer and pass that as the final argument when creating the PixelBox (using ctypes.addressof(buffer) )

I'll have another look tomorrow if you are still having problems..

Cheers
Andy

team23

30-08-2007 04:09:40

Ok, so I tried a more literal adaption of the original source using ctypes, at least I think its a literal adaptation of it. I've tried sending buffer and sending addressof(buffer), neither works.

I'm actually looking at translating the MovableText source code too, although I'm guessing I'll hit an issue similar to this at some point in that.

Edit:
BTW I haven't coded in C for a long time, so I may be totally screwing this all up.



bufferP = POINTER(c_uint8)

libc = cdll.msvcrt

bufferAddy = libc.calloc(nBuffSize, sizeof(c_uint8))

buffer = bufferP.from_address(bufferAddy)

fontPb = ogre.PixelBox(fontBuffer.getWidth(), fontBuffer.getHeight(), fontBuffer.getDepth(), fontBuffer.getFormat(), buffer)

team23

30-08-2007 04:54:10

Bleh, and now that I'm about 1/3 through MovableText I'm unable to continue beacuse I can't set the vertexData in RenderOperation.

I think Python is telling me to stop trying to be fancy with my text rendering...

andy

30-08-2007 05:26:05

Don't give in :)

I'll do a convert for you so you can see how it's done -- I think you are fighting two problems with this conversion.

1. The buffer allocation which can be fixed like this

## create a buffer
nBuffSize = fontBuffer.getSizeInBytes();
## Here we show the difference in C++ and Python
## uint8* buff = (uint8*)calloc(nBuffSize, sizeof(uint8));
storageclass = ctypes.c_uint8 * (nBufferSize) # allocate a buffer class
buff=storageclass()

## the PixelBox call needs a pointer to the buffer and here's how we do this in Python-Ogre
VoidPointer = ogre.CastAsVoidPointer(ctypes.addressof(buff))

## create pixel box using the copy of the buffer
fontPb = ogre.PixelBox(fontBuffer.getWidth(), fontBuffer.getHeight(),fontBuffer.getDepth(), fontBuffer.getFormat(), VoidPointer);


2. I didn't expose the internal PixelBox data buffer which means you can't go any further :(

Give me a few days and I'll ensure this works with Python-Ogre 1.1

Cheers
Andy

team23

30-08-2007 08:29:58

Ahh, CastVoidPtr is what I was missing. I'm using the following to access the data I can't access via the PixelBox.data


destVoidPtr = destBuffer.lock(0, destBuffer.getSizeInBytes(), ogre.HardwareBuffer.HBL_NORMAL)
destPb = destBuffer.getCurrentLock()



Its running now anyway, and from some initial debug spew it looks like it may actually work. But either I'm not writing the memory back correctly or something else is going wrong atm. And I'm out of time to investigate tonight...

andy

30-08-2007 15:14:06

Ok so I have this working and will post it on the wiki etc..

Unfortunately you'll need to wait for me to release Python-Ogre 1.1 as I had to add a helper function to expose the 'data' variable in PixelBox..

Expect an update late next week

Cheers
Andy

team23

31-08-2007 06:23:31

Woo hoo, got it working. Not sure if its 100% working, but I'm reading text, so thats good.

I can post my source if it would be helpful to anyone else, atm is sorta messy as I was doing some serious debugging on this thing.

Thanks for the help andy, I look forward to checking out your solution to this.

team23

01-09-2007 23:08:44

This is how I got around the PixelBox.data issue:

nBuffSize = fontBuffer.getSizeInBytes()
dBuffSize = destBuffer.getSizeInBytes()

destVoidPtr = destBuffer.lock(0, destBuffer.getSizeInBytes(), ogre.HardwareBuffer.HBL_NORMAL)
fontVoidPtr = fontBuffer.lock(0, fontBuffer.getSizeInBytes(), ogre.HardwareBuffer.HBL_NORMAL)

destPb = destBuffer.getCurrentLock()
fontPb = fontBuffer.getCurrentLock()

storageclass = c_uint8 * dBuffSize
storageclass2 = c_uint8 * nBuffSize

destData=storageclass.from_address(ogre.CastInt(destVoidPtr))
fontData=storageclass2.from_address(ogre.CastInt(fontVoidPtr))

andy

02-09-2007 14:38:04

Clever fix !!! -- I hadn't thought about using 'lock' to get the pointer to data..

The 1.1 release will have a getData() helper function to make this functionality less obtuse :)

Cheers

Andy

bharling

29-01-2008 14:36:39

I just attempted to start converting this myself, then looked on the forum and here it is already done!

except I cant find the complete source anywhere, team23 / Andy, could you post the source for the WriteToTexture function somewhere? its just what I need for a current project.

many thanks ;)

Game_Ender

29-01-2008 15:13:46

Its in the Ogre demos tests directory. A direct link.

bharling

29-01-2008 15:46:46

groovy - thanks game_ender.

bharling

29-01-2008 15:53:25

hmm..

doesn't seem to work anymore :

File "c:\python25\Lib\site-packages\ogre\renderer\OGRE\sf_OIS.py", line 60, in go
if not self._setUp():
File "c:\python25\Lib\site-packages\ogre\renderer\OGRE\sf_OIS.py", line 101, in _setUp
self._createScene()
File "C:\PythonOgre\demos\ogre\tests\Test_WriteToTexture.py", line 195, in _createScene
WriteToTexture("Andy was here!",texture,ogre.Box(25,275,370,500),font,ogre.ColourValue(1.0,1.0,1.0,1.0),'c')
File "C:\PythonOgre\demos\ogre\tests\Test_WriteToTexture.py", line 167, in WriteToTexture
ogre.PixelUtil.unpackColour(pix,destPb.format,address)
Boost.Python.ArgumentError: Python argument types in
PixelUtil.unpackColour(ColourValue, PixelFormat, int)
did not match C++ signature:
unpackColour(unsigned int r, unsigned int g, unsigned int b, unsigned int a, enum Ogre::PixelFormat pf, void const * src)
unpackColour(unsigned int r, unsigned int g, unsigned int b, unsigned int a, enum Ogre::PixelFormat pf, void const * src)
unpackColour(class Ogre::ColourValue * colour, enum Ogre::PixelFormat pf, void const * src)
Unregistering ResourceManager for type BspLevel
*-*-* OGRE Shutdown


looks like something has changed in ogre somewhere. Anyone have any useful ideas ? :)

BTW: am using the latest snapshot, will try downgrading to 1.1 and see if it works

bharling

29-01-2008 16:26:35

Well, it works with latest stable release, but tis broken in the new snapshot - my fault for using the bleeding edge i guess!

andy

30-01-2008 02:08:49

No my fault -- and please continue to use the snapshot as it's there so I can fix things before the next major release :)

ReI made significant changes in the code generation before building the snapshot, primarily in automating much of the functional transformation (wrapping variables that aren't python friendly etc), along with new gcc support etc -- and it turns out I didn't handle "constant" void pointers correctly - they were being ignored and not wrapped.

This has been fixed and is in the SVN -- and will be in the next snapshot...

Thanks
Andy

bharling

01-02-2008 15:08:59

Well, this is actually for a commercial project ( I finally managed to convince my boss to let me develop something in python-ogre, when the suitable project came along - whoopee! :lol: ), so I'll stick to stable version for this at the moment. I'm still using the bleeding edge at home and for the techdemo etc.

if it gets off the ground and I'm allowed to, I'll post some details soon. I've already written a whole bunch of ( I think ) quite neat functions for it!

team23

11-03-2009 01:48:44

Figured its been about a year, might as well gravedig this.

Attempting to get this working on OS X and it looks like PixelBox doesn't have getData in the wrapping I generated. The Windows binary does. Do I need to run something in particular to get this function wrapped?

Edit:
Not sure if this works with OpenGL tho, its failing for me on Windows.