HELP: dynamic texture (HardwarePixelBuffer & PixelBox)

saladin

02-05-2007 06:23:39

Hi,

I'm trying to convert this tutorial to a python-ogre demo here.
http://www.ogre3d.org/wiki/index.php/Cr ... c_textures

After I retrieved the pixelBox I'm stuck. Cuz there doesn't seem to be a pixelBox.data function. And I don't know how to use the ogre.HardwarePixelBuffer.readData()/writeData() functions either. (Mainly because they both require a void pointer to be passed in as argument)

Can any one help?

Cheers.

roman.yakovenko

02-05-2007 13:00:54

Take a look on next thread: http://groups.google.com/group/python-o ... c56c?hl=en

Look for ctypes. This is the way Python-Ogre works around "void*" issues.

bharling

02-05-2007 22:47:53

Ah, this helps with the collision tree loading I was struggling with! so, am I right in saying you need to use ctypes when dealing with ogre shared pointers and suchlike things?

roman.yakovenko

03-05-2007 10:06:28

Ah, this helps with the collision tree loading I was struggling with! so, am I right in saying you need to use ctypes when dealing with ogre shared pointers and suchlike things?

No. You need to use ctypes, when Ogre uses "void*" type as function argument. SharedPtr is wrapped in a such way, that you don't feel the difference between object and its smart pointer instantiation.

bharling

03-05-2007 11:44:49

hmm, so how could I make a dataStreamPtr from a python file object? (sorry if this is not related to the thread)

saladin

03-05-2007 14:33:16

Take a look on next thread: http://groups.google.com/group/python-o ... c56c?hl=en

Look for ctypes. This is the way Python-Ogre works around "void*" issues.


Thanks for that. But can you be a bit more specific as to which object I should use when asked for 'void const*'. I tried ctypes.c_void_p(0) and following is the error message I got:
ArgumentError: Python argument types in
HardwarePixelBuffer.writeData(HardwarePixelBuffer, int, int, c_void_p)
did not match C++ signature:
writeData(struct HardwarePixelBuffer_wrapper {lvalue}, unsigned int offset, unsigned int length, void const * pSource, bool discardWholeBuffer=False)
writeData(class Ogre::HardwarePixelBuffer {lvalue}, unsigned int offset, unsigned int length, void const * pSource, bool discardWholeBuffer=False)


By the way, I still want to know why the 'data' member of ogre.pixelBox class is not wrapped. seems to me like an utterly important component.

andy

04-05-2007 10:19:54

I'll convert the C++ example in question to Python-Ogre over the next couple of days and post my findings..

Cheers

Andy

andy

04-05-2007 15:06:42

You can try something like:

## Test pixel stuff..
# Create the texture
texture = ogre.TextureManager.getSingleton().createManual(
"DynamicTexture", # name
ogre.ResourceGroupManager.DEFAULT_RESOURCE_GROUP_NAME,
ogre.TEX_TYPE_2D, # type
256, 256, # width & height
0, # number of mipmaps
ogre.PF_BYTE_BGRA, # pixel format
ogre.TU_DEFAULT) # usage; should be TU_DYNAMIC_WRITE_ONLY_DISCARDABLE for
# textures updated very often (e.g. each frame)

# Get the pixel buffer
pixelBuffer = texture.getBuffer()
# Lock the pixel buffer and get a pixel box
pointer=pixelBuffer.lock(0,256*256,ogre.HardwareBuffer.HBL_NORMAL) # for best performance use HBL_DISCARD!
storageclass = ctypes.c_uint8 * (256)
cbuffer=storageclass.from_address(ogre.CastInt(pointer))
pos=0
for j in range(256):
for i in range( 256 ) :
buffer[pos]=255 # B
pos+=1
buffer[pos]=0 # G
pos+=1
buffer[pos]=0 # R
pos+=1
buffer[pos]=127 # A
pos+=1
# Unlock the pixel buffer
pixelBuffer.unlock()

# Create a material using the texture
material = ogre.MaterialManager.getSingleton().create(
"DynamicTextureMaterial", # name
ogre.ResourceGroupManager.DEFAULT_RESOURCE_GROUP_NAME)

material.getTechnique(0).getPass(0).createTextureUnitState("DynamicTexture")
material.getTechnique(0).getPass(0).setSceneBlending(ogre.SBT_TRANSPARENT_ALPHA)



I don't have a full demo to test this with so if you complete it please send it my way :)

Cheers
Andy

saladin

05-05-2007 11:55:17

Wow thanks Andy. I owe u one. cbuffer=storageclass.from_address(ogre.CastInt(pointer))
This is the code I spent hours trying to find/work around. It's a pitty so much treasure is hidden in python-ogre. We do need more docs and demos i guess.

Here's the working (no garantee) function I ended up with:

#Texture is a manually created Texture
#dataArray is an array of pixel colour data
def setTextureManual(self, texture, width, height, dataArray):
import ctypes
# Get the pixel buffer
pixelBuffer = texture.getBuffer()
# Lock the pixel buffer and get a pixel box
pointer = pixelBuffer.lock(0,width*height,ogre.HardwareBuffer.HBL_NORMAL)
#number 4 here is use to accommodate the bytes for r, g, b, a may vary with different pixel formats
storageclass = ctypes.c_uint8 * (width*height*4)
cbuffer=storageclass.from_address(ogre.CastInt(pointer))
pos=0
for j in range(height):
for i in range( width ) :
cbuffer[pos]=dataArray[pos] # B
pos+=1
cbuffer[pos]=dataArray[pos] # G
pos+=1
cbuffer[pos]=dataArray[pos] # R
pos+=1
cbuffer[pos]=dataArray[pos] # A
pos+=1
# Unlock the pixel buffer
pixelBuffer.unlock()