Sign in to follow this  
Burhan66

Setting effect objects in managed directx

Recommended Posts

Hello, I have defined a structure in an effect file as : struct Mtrl { float4 Diffuse; float4 Ambient; float4 Specular; float4 Emissive; float SpecularSharpness; }; And a global variable as: uniform extern Mtrl g_Mtrl; In C++ we can set this object by writing: m_pFX->SetValue( "g_Mtrl", &mtrl, sizeof(MaterialX) ); MaterialX is the corresponding class defined in C++ and mtrl is a MaterialX object. This way we can set whole effect structures in C++. But I couldn't find a way to do this in Managed DirectX with C#. There are some methods of the Effect class that takes void* and GraphicsStream but I couldn't figure out how to use them. Is there any one who can do this. Please if anyone knows the solution I will be very grateful.

Share this post


Link to post
Share on other sites

I never used this myself before, but after digging around it seems you can convert a C# struct to a pointer using Marchal.StructureToPtr or GCHandle.Alloc (Marshal copies, GCHandle pins). I'm far from an interop specialist, but I think neither of these solutions will do, since you can't reliably determine when you can free/unpin the struct because the CPU and GPU run asynchronously. I may be entirely of on the wrong track here though, so anyone please correct me if I'm wrong.

Anyway if the above is correct, you're stuck with the GraphicsStream. I don't have a MDX installation around atm, but from experience it's about as accessible and flexible as a xenophobic clamshell... I was thinking you could write the struct to a MemoryStream and try to wrap that into a GraphicsStream, but even if this works it seems quite a messy way to get this done.

MDX also acts a bit sketchy on more exotic parts like this, so I'd say you'd be better of with less elegantly setting the struct's member values to the effect. Alternatively you might want to look into SlimDX which is a community effort to replace MDX (since MDX got replaced with XNA by MS). I'd imagine they have a better way to do this.

Share this post


Link to post
Share on other sites
Thank you for your reply. I have searched and tried some solutions using Marchal.StructureToPtr and finally I found the solution. The following code works and I can set Effect structure objects.

public unsafe void SetStructure(string parameter, object obj)
{
int nSize = Marshal.SizeOf(obj);
IntPtr unmanagedPointer = Marshal.AllocHGlobal(nSize);
Marshal.StructureToPtr(obj, unmanagedPointer, true);

m_Fx.SetValue(parameter, unmanagedPointer.ToPointer(), nSize);
Marshal.FreeHGlobal(unmanagedPointer);
}

But this doesn't works for class objects it works for only structure objects.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this