Get DXMaterial Interface

 
 
 
Posted by:Snoelk
Data created:1 June 2011

how do i get the Interface for working with dxmaterial ?

when i tr<y to get the interface, the InterfaceID enums doesnt contain the right interface for working with DirectX Shaders.

i tried to make a workaround with IGameScene but this got me nothing too.

i cant access the IGameFX inside the IGameMaterial. its always null with my effect files. the defualt max effect files work but any other shader wont.

is the DXMaterial interface not castet in the wrapper yet ?

 

thanks in advance :)

 


Mario Röske
Technical Artist
Piranha-Bytes

tried many stuff now but i cant get it right

here is the c++ code i tried to clone as c#

// Get scene materials
Interface* ip = GetCOREInterface();
MtlBaseLib* lib = ip->GetSceneMtls();
if (!lib)
    return 0;
// Loop over the scene materials
const int NumMtls = lib->Count();
for (int i = 0; i < NumMtls; i++)
{
    // Get current material
    MtlBase* mtl = static_cast<MtlBase*>((*lib)[i]);
    if (!mtl)
        continue;
    // DxMaterial or extend ?
    IDxMaterial* dxMtl =
    (IDxMaterial*)mtl->GetInterface(IDXMATERIAL_INTERFACE);
    if (dxMtl)
        ProcessDxMaterial(dxMtl);
}

and now the c# implementation

IInterface_ID iidDxMat = SceneManager.MaxGlobal.Interface_ID.Create(1437802525, 699105219);

IMtlBaseLib MtlLib = SceneManager.MaxCore.SceneMtls;

for (int i = 0; i < MtlLib.Count; i++)
{
    IMtlBase mtl = MtlLib[(IntPtr)i];

    string strName = mtl.Name;

    IIDxMaterial dxMtl = (IIDxMaterial)mtl.GetInterface(iidDxMat);
}

the last line always gets an exception that i cant cast BaseInterface to IIDxMaterial.

what's the error. im banging my head since one week on my table due to this problem.


Mario Röske
Technical Artist
Piranha-Bytes

Hello,

Sorry for the late reply. I believe this is due to the fact that max.net isn't currently upcasting the IIDxMaterial interface. This stuff I need to specify manually for upcasting whe compiling max.net and I haven't done so for IIDxMaterial. Is this something you still need?

Marsel Khadiyev (Software Developer, EPHERE Inc.)

hello

would be great if its supported in the future.

right now im parsing through the entire paramblock2 and get each parameter by hand. this interface would make things a lot easier.

after we purchased the source from you i thought of looking into it and fixing myself *g*

but this takes more time when you do it ^^

 

P.S

why the auto assembly loading isnt working anymore ? right now i have to restart max in order to reload the plugin with new code. if i try theres always an error with some dependencies that cant be reloaded.


Mario Röske
Technical Artist
Piranha-Bytes

Ok I'll note it down for future versions. Basically an entry needs to be added that detects and converts any native IDXMaterial objects into Autodesk::Max::Wrappers::IDXMaterial wrapper inside UpCast(...) function in NetWrapGen.cpp

Assembly (re)loading is working fine for me. Perhaps you have reset/deleted your MaxDotNet.config file (its in your local user /stdplugs directory)? If you're using Autodesk.Max.Wrappers.dlu you can go to Utilities->More->MaxDotNet in 3dsmax and in the panel check the "Allow plugin unloading" option.

Alternatively you can edit MaxDotNet.config file directly to have something like:

<?xml version="1.0" encoding="utf-8"?>
<Configuration xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <HandleExceptions>true</HandleExceptions>
  <ReloadSceneOnUnload>true</ReloadSceneOnUnload>
  <UnloadRemovedAssemblies>true</UnloadRemovedAssemblies>
  <LoadAddedAssemblies>true</LoadAddedAssemblies>
  <LoadAssembliesOnStartup>true</LoadAssembliesOnStartup>
  <RemotingPort>9998</RemotingPort>
  <AllowPluginUnloading>true</AllowPluginUnloading>
  <AllowRemoting>false</AllowRemoting>
</Configuration>

Marsel Khadiyev (Software Developer, EPHERE Inc.)

ok now the plugin realy wants to reload (other crash now)

but this time its an target invokation error.

i have seperate windows in my plugin and i remember tthe window settings with an xml file.

this xml file will be loaded on startup with the xml deserializer

if (File.Exists(a_strConfigFile))
                {
                    XmlSerializer xmlCurrentConfig = new XmlSerializer(typeof(UserConfig));
                    FileStream fsCurrentConfig = new FileStream(a_strConfigFile, FileMode.Open, FileAccess.Read, FileShare.Read);

                    try
                    {
                        confMaster = (UserConfig)xmlCurrentConfig.Deserialize(fsCurrentConfig);
                        fsCurrentConfig.Close();
                        return confMaster;
                    }
                    catch (Exception e)
                    {
                        fsCurrentConfig.Close();
                        Logger.LogMessage(e.Message);
                        return null;
                    }

(UserConfig)xmlCurrentConfig.Deserialize(fsCurrentConfig) this will throw an target invokation error.

the exception details show me that an object is not set to an instance. if im starting the plugin on startup of max all is fine.

i think something went wrong with reload plugins and the assembly cache ?

 

trying to solve this with dfeaulf settings in case this happens *g*


Mario Röske
Technical Artist
Piranha-Bytes

Serialization is one of the things that doesn't play well with plugin reloading. It is actually an issue I run into with Zookeeper as well. Basically, if I need to do serialization (such as reloading ZK info from a scene) I have to restart Max. If I just set stuff up from scratch in a new scene then I reuse the same Max session.

The problem is that when max.NET reloads a plugin there is no way of removing the previous plugin types from current .NET app domain, so it just remains there. The .NET serializer (for a newly reloaded assembly) then looks for the type in that app domain to instantiate and finds the previously loaded type. This is an issue because you are now trying to cast previously loaded type to your newly loaded type, and that'll produce an exception.

This is a current .NET framework limitation (there are many people complaining to Microsoft about it) about not being able to unload assemblies from an app domain.

I think the best solution is to do a compromize and try not to (de)serialize stuff between assemblies when you do plugin reloading. Also, I think XML serilization can be somewhat fixed but you need to make sure that newly reloaded plugin has a different version from previous plugin.

In your AssemblyInfo.cs change the last number of the assembly version to * so it looks something like:

[assembly: AssemblyVersion( "1.8.3.*" )]

for example. This should randomly generate different build numbers for each build of your project. Hope this helps.

Marsel Khadiyev (Software Developer, EPHERE Inc.)

i tried to debug the steps but it wont step into the upcast functions

when i look inside those upcast function there is an entry with iidxmaterial


Mario Röske
Technical Artist
Piranha-Bytes