PDA

View Full Version : C++ API: Passing arbitrary vertex data from deformer to hardware shader


visjes
01-27-2011, 12:44 AM
:banghead:

Hello,

I have a deformer and a hardware shader and I want to pass a per-vertex value from one to the other. I've tried doing this via colorSet, which was a disastrous mess as any attempts to update colorSets from compute()/deform() just fail, and trying to manage which colorSet is used is also prone to disaster, i.e. trying to create a specific colorSet if it doesn't exist ends up sticking history nodes (even with history off) between the deformer and the mesh so the deformer never sees them anyway. That's the result anyway, if it's done oustide of compute().. inside compute() it just fails silently.

Another thing I tried was just to generate a float array myself and pass it via a plug as a kAddr, but any attempts to query that value from the MPxHwShaderNode::glGeometry just returns zero. I know that sucks because the shader could be applied to multiple meshes, and there's no guarantee that the pointer I'm given matches the geometry I'm being asked to render, etc. I'm just trying anything to get it to work. Maybe I am doing that wrong. Below is what should be the relevant code:

deformer::initialize
a_vertexDataPointer = na.createAddr( "vertexDataPointer", "vdp" );
na.setReadable( true );
na.setWritable( false );
na.setStorable( false );
na.setCached( false );
addAttribute( a_vertexDataPointer );deformer::compute
// float * m_vertexData;
if( plug == a_vertexDataPointer )
{
MDataHandle vdp_data = data.outputValue( a_vertexDataPointer );
vdp_data.asAddr() = (void *)m_vertexData;
vdp_data.setClean();
}hardwareshader::glGeometry
MPlug plug( thisMObject(), a_vertexData );
// now what? asInt()? there's no method for getting value as address..
float * addr = (float *)plug.asInt(); // returns 0This is pretty flakey, but at least if I can manage to get ahold of that pointer, I can reference the correct weight values via the vertexIDs passed to glGeometry, which are aligned with with the vertex position array. For what it's worth, it seems that compute() is never ever called for the vertexDataPointer plug in the deformer. Am I missing something or is there a scheme I'm just overlooking? Does blind data make any sense in this context? I don't see a way for it to follow the vertex data passed to hardware shaders. Any help on this will help to reduce the overall level of anxiety and frustration in the universe. :)

Thanks.

flaiver
01-27-2011, 08:56 AM
Hello

sorry that me answer will be quiet short but i am a little bit busy today. In my opinion it should work - I have done something quiet similiar.

I think, the trouble here is that your hardware shader isn't informed correctly when the mesh is deformed. The compute method of the hardware shader will be called just if the you are using Software Rendering. So just leave it as it is because you want hardware render your deformed mesh.

You first try can be to create an Attribute to your hardware shader of the type mesh.Connect your deformer output to this attribut - you can try to requested in the glGeometry method using MPlug. But be careful - everything will become very slow. My solution was, that each hardware renderer has a refresh attribute. glGeometry renders just internal members, which are updated just when the deformer node has been done its job. Unfortunately the deformer does its job when its be called by another node so you have to feak this (which can be end in a mess). But when it does its job, its iterate over all hardware shaders of my type and call refresh. This sounds like horrible design (and yes it is - but glGeometry is called much to often).

Best flaiver

CGTalk Moderation
01-27-2011, 08:56 AM
This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.