GpuProgramParameters.setNamedConstant - No matching function

enn0x

16-04-2006 19:17:45

Hello,

I have problems with the method GpuProgramParameters.setNamedConstant( ) using PyOgre 1.0.6 and Python 2.4.3. Looking at the distribution file 'ogre.py' I see that the following should be valid parameters for this method:

setNamedConstant(self, String name, Real val)
setNamedConstant(self, String name, int val)
setNamedConstant(self, String name, Vector4 vec)
setNamedConstant(self, String name, Vector3 vec)
setNamedConstant(self, String name, Matrix4 m)
setNamedConstant(self, String name, Matrix4 m, size_t numEntries)
setNamedConstant(self, String name, float val, size_t count) setNamedConstant(self, String name, double val, size_t count)
setNamedConstant(self, String name, ColourValue colour)
setNamedConstant(self, String name, int val, size_t count)

What I try to do is:

preRotatedQuad = ogre.Matrix4( ... )
mm = ogre.MaterialManager.getSingleton( )
material = ogre.MaterialPointer( mm.getByName( '...' ) )
params = ogre.GpuProgramParametersPtr( material.getTechnique( 0 ).getPass( 0 ).getVertexProgramParameters( ) )
params.setNamedConstant( '...', preRotatedQuad, 16 )

What I get is

'No matching function for overloaded 'GpuProgramParameters_setNamedConstant'.

I have already tested a couple of other parameters sets, like ( string, int ), but nothing worked so far. One idea that still could work is that the first paramter is the problem, so I tried to pass

ogre.StringPtr( '...' )

instead of a python string, but no success either. This is not the usual get/set problem. I have checked dir( params ) first. Any ideas would be welcome.

Thanks for your attention

dermont

17-04-2006 09:35:23

Not quite sure you can do this in pyogre.

1) The setNamedConstant methods that accept lists have not been wrapped:


OgreGpuProgram.i

// Ignore functions which expect a list of items
%ignore Ogre::GpuProgramParameters::setConstant(size_t, const Matrix4 *, size_t);
%ignore Ogre::GpuProgramParameters::setConstant(size_t, const float *, size_t);
%ignore Ogre::GpuProgramParameters::setConstant(size_t, const double *, size_t);
%ignore Ogre::GpuProgramParameters::setConstant(size_t, const int *, size_t);
%ignore Ogre::GpuProgramParameters::setNamedConstant(const Ogre::String &, const Matrix4 *, size_t);
%ignore Ogre::GpuProgramParameters::setNamedConstant(const Ogre::String &, const float *, size_t);
%ignore Ogre::GpuProgramParameters::setNamedConstant(const Ogre::String &, const double *, size_t);
%ignore Ogre::GpuProgramParameters::setNamedConstant(const Ogre::String &, const int *, size_t);

2) The pass.getDefaultParameters() returns a GpuProgramParametersSharedPtr, I'm not too sure why the shared pointer template was ommitted. Maybe it's something obvious I'm missing. The only way I've been able to do this is to update OgreGpuProgram.i, and before the above ignore functions, add:


%template(GpuProgramParametersSharedPtr) Ogre::SharedPtr<Ogre::GpuProgramParameters>;


Then in code:

mat=ogre.MaterialPointer(ogre.MaterialManager.getSingleton().getByName('Examples/MyVertexMetrial'))
_pass=mat.getTechnique(0).getPass(0)
params = _pass.getVertexProgramParameters( ).get()
params.setNamedConstant("testParameter", 45.0)

enn0x

17-04-2006 12:11:04

Thank you for the fast reply, dermont. My motivation has been a demo by Falagard from this thread:

http://www.ogre3d.org/phpBB2addons/viewtopic.php?t=50
http://www.larabie.net/ogre/LegendsOfTa ... Demo01.zip

He showes a technology similar to SpeedTree ( e.g. used in 'TES 4: Oblivion' ) for rendering trees or other vegetation. I have tried to do a python port of his demo, and for now the following code is working with out-of-the-box PyOgre-1.0.6:

from pyogre import ogre
import SampleFramework

class TreeApplication( SampleFramework.Application ):
def _createScene( self ):
sceneManager = self.sceneManager
camera = self.camera

sceneManager.ambientLight = ( 0.2, 0.2, 0.2 )
sceneManager.setSkyBox( True, 'Examples/CloudyNoonSkyBox', 50 )


treeEntity = sceneManager.createEntity( 'tree1', 'tree.mesh' )

leavesEntity = sceneManager.createEntity( 'leaves1', 'leaves.mesh' )
leavesEntity.setMaterialName( 'LOTTreeLeavesNoBones' )

node = sceneManager.rootSceneNode.createChildSceneNode( )
node.attachObject( treeEntity )
node.attachObject( leavesEntity )

self.leavesEntity = leavesEntity

def _createFrameListener( self ):
self.frameListener = TreeListener( self.renderWindow, self.camera, self.leavesEntity )
self.root.addFrameListener( self.frameListener )

class TreeListener( SampleFramework.FrameListener ):
def __init__( self, renderWindow, camera, leavesEntity ):
SampleFramework.FrameListener.__init__( self, renderWindow, camera )
self.leavesEntity = leavesEntity

def frameStarted( self, frameEvent ):

vCenter = ogre.Vector3( 0, 0, 0 )
vRight = self.camera.derivedDirection.crossProduct( ogre.Vector3.UNIT_Y )
vUp = self.camera.up

vRight.normalise( )
vUp.normalise( )

vPoint0 = vCenter + ( -vRight - vUp )
vPoint1 = vCenter + ( vRight - vUp )
vPoint2 = vCenter + ( vRight + vUp )
vPoint3 = vCenter + ( -vRight + vUp )

# Updating a single tree
v0 = ogre.Vector4( vPoint0.x, vPoint0.y, vPoint0.z, 0.0 )
v1 = ogre.Vector4( vPoint1.x, vPoint1.y, vPoint1.z, 0.0 )
v2 = ogre.Vector4( vPoint2.x, vPoint2.y, vPoint2.z, 0.0 )
v3 = ogre.Vector4( vPoint3.x, vPoint3.y, vPoint3.z, 0.0 )

self.leavesEntity.getSubEntity( 0 ).setCustomParameter( 1, v0 )
self.leavesEntity.getSubEntity( 0 ).setCustomParameter( 2, v1 )
self.leavesEntity.getSubEntity( 0 ).setCustomParameter( 3, v2 )
self.leavesEntity.getSubEntity( 0 ).setCustomParameter( 4, v3 )

# Updating all trees, not supported by PyOgre 1.0.6
#preRotatedQuad = ogre.Matrix4(
# vPoint0.x, vPoint0.y, vPoint0.z, 0.0,
# vPoint1.x, vPoint1.y, vPoint1.z, 0.0,
# vPoint2.x, vPoint2.y, vPoint2.z, 0.0,
# vPoint3.x, vPoint3.y, vPoint3.z, 0.0
#)

#mm = ogre.MaterialManager.getSingleton( )
#leafMaterial = ogre.MaterialPointer( mm.getByName( 'LOTTreeLeavesNoBones' ) )
#params = ogre.GpuProgramParametersPtr( leafMaterial.getTechnique( 0 ).getPass( 0 ).getVertexProgramParameters( ) )
#params.setNamedConstant( 'preRotatedQuad[0]', preRotatedQuad, 16 )

return SampleFramework.FrameListener.frameStarted( self, frameEvent )

if __name__ == '__main__':
try:
application = TreeApplication( )
application.go( )
except ogre.OgreException, e:
print e


To run the python demo you need the following media from LegendsOfTacendiaTreeDemo01.zip, and you should edit both material scripts by moving the lines with alpha_rejection from texture_unit to pass:

- Bark1.tga
- Branch1.tga
- Leaf1.tga
- leaves.mesh
- Tree.mesh
- LOTTreeLeaves.cg
- LOTTreeLeaves.material
- LOTTreeTrunk.material

The difference is that the python demo updates the vertex program for each tree once a frame. So large forests are not possible this way, since a costly loop over all leaveEntities would be required. Using setNamedConstant would allow to update the vertex program with one call per frame for all tree.

SubEntity.setCustomParameter( ) uses similar arguments as GpuProgramParameters.setNamedConstant( ), which makes me confident that the GpuProgramParameters Methods can be implemented too. So far I have been using PyOgre from binary installers, so my next tasks will be to find out how to compile PyOgre myself using VC Toolkit 2003, and then try to modify it.

dermont

17-04-2006 15:12:30

Nice, deserves a screenshot.

enn0x

17-04-2006 17:52:58

No problem. Here are two screenshots, one from some distance, and one close up.

http://www.dachau.net/users/pfrogner/screenshot_0.png
http://www.dachau.net/users/pfrogner/screenshot_1.png