Get named parameter value

chpod

06-08-2008 19:25:19

Hi all,

I am trying to read all named constants with their respective values for a fragment program.

Till now I managed to read the named constants (the keys). However, I am in trouble while trying to read the values.

Here is the code I use:
def getFragmentProgramKeys(self,fragmentProgramName):
mat = ogre.MaterialManager.getSingleton().getByName(fragmentProgramName)

# In case the material is not found
if (mat == None):
print "Material not found: ",fragmentProgramName
return([])

validkeys = []
if (mat.getTechnique(0).getPass(0).hasFragmentProgram()):
params = mat.getTechnique(0).getPass(0).getFragmentProgramParameters()
if (params.hasNamedParameters()):
it = params.getConstantDefinitionIterator()
while (True):
# Get the key
key = it.peekNextKey()
print "KEY: ",key
# And the corresponding value
from ctypes import c_ulong
p = c_ulong()
value = it.peekNextValue()
index = value.physicalIndex
size = value.elementSize
result = 0
params._readRawConstants (index, size, p)
print "VALUE: ",p
if (key.isalpha() and params._findNamedConstantDefinition(key)):
validkeys.append(key)
it.moveNext()
if (not it.hasMoreElements()):
break
return(validkeys)


And here is the error message:
GpuProgramParameters._readRawConstants(GpuProgramParameters, int, int, c_ulong)
did not match C++ signature:
_readRawConstants(class Ogre::GpuProgramParameters {lvalue} inst, unsigned int physicalIndex, unsigned int count, unsigned int dest)
_readRawConstants(class Ogre::GpuProgramParameters {lvalue} inst, unsigned int physicalIndex, unsigned int count, unsigned int dest)


There must be some pointer trouble between python and C++. I am a complete newbie regarding this kind of things, and I really fee lost...

Thx for you help,
chpod

andy

07-08-2008 08:00:33

Two problems.. One is a wrapper issue, the other in how you are using ctypes.

Wrapper Issue:
You've discovered a Python-Ogre issue that I'm resolving now -- basically I "auto-fixed" the _readRawConstants function (and a couple of others), however it's broken in that you can (likely) only get a 'float' constant - what was multiple functions in C++ (as the arguments are different) got translated into Python as multiple functions with the same arguments, hence only one is callable...
Should be fixed in the SVN in a day or 2

ctypes:
If you look at the error you are seeing the problem is that you are passing a c_ulong (I changed it to float as this should work) to the function however you need to pass the address of the pointer so it should look something like:
import ctypes
value = it.peekNextValue()
index = value.physicalIndex
size = value.elementSize
p = ctypes.c_float() * size ## allocate enough storage
result = 0
params._readRawConstants (index, size, ctypes.addressof(p) )


Regards

Andy

chpod

07-08-2008 11:13:27

Ok, so the wrapper issue is not an issue if I only read floats. The changes you plan to update to SVN are for the other data types.

I made several attemps with the code you kindly provided.

p = ctypes.c_float() * size ## allocate enough storage
This gives me an error: File "LayerManager.py", line 426, in getFragmentProgramKeys
p = ctypes.c_float() * size
TypeError: unsupported operand type(s) for *: 'c_float' and 'int'


For my tests, I removed the "* size", as in this case size is 4 and ctypes.sizeof(p) is also 4.

But then I have a full python crash (with Windows error message telling that Python.exe had to be closed).

This happens just when calling: params._readRawConstants (index, size, ctypes.addressof(p) )


Here is the full code I am using:
import ctypes
p = ctypes.c_float()
params._readRawConstants (index, size, ctypes.addressof(p) )
print "RESULT: ",p


chpod

andy

07-08-2008 11:43:20

Have a look through the ogre/demos directory for examples of ctypes usage (demo_bezier and demo_grass are examples)..

The line should have been...
p = ctypes.c_float * size ## allocate enough storageRegards
Andy

chpod

07-08-2008 12:27:49

Actually, I had already a look at the demos and tried with:
p = ctypes.c_float * size ## allocate enough storage

But with with code I had another (cast related?) error:
File "LayerManager.py", line 428, in getFragmentProgramKeys
params._readRawConstants (index, size, ctypes.addressof(p) )
TypeError: invalid type


Thx for you help,
chpod

dermont

08-08-2008 03:31:08

I think you may be wasting your time with this since the _readRawConstants Int version
will always be called but have you tried assigning values to the ctypes array:

p = (ctypes.c_float * size)(*([0.0]*size))

andy

08-08-2008 04:09:59

You are correct on the fact that the Int call is always being made -- fix is 'nearly' in the SVN...

Another way to fix the ctypes allocation issue is to do:
size = value.elementSize
storageclass = ctypes.c_float * size
p =storageclass(1.1)

Regards
Andy

chpod

08-08-2008 10:30:28

Thanks andy and dermont.

I tried your suggestions, but both result in making python crash...

Let's wait for the SVN release! Will this be in python-ogre 1.2? Or will I need to build it myself?

Cheers
chpod