Plugin Material extending DirectX Shader issues

Plugin Material extending DirectX Shader issues

Anonymous
Not applicable
609 Views
5 Replies
Message 1 of 6

Plugin Material extending DirectX Shader issues

Anonymous
Not applicable
Morning all,

I'm actually a C++ programmer who's new to MaxScript, so go easy on me :)

Using Max 2010 SP1, I'm using MaxScript to define a UI for a complex shader by declaring a Material plugin which extends DirectX_9_Shader. I control the shader underneath through the delegate keyword. When editing a scene, the whole thing is working very well indeed. The issues I have are with behaviour when reloading a scene, which I've so far been unable to solve.

Firstly, if I close the material editor then reload my scene, everything works fine. If, however, I reload the scene whilst keeping the material editor open, I get a large number of errors in the format Unknown property: "X" in undefined, where X is the name of a bool value in the delegate controlling a feature. My UI components are initialised using delegate values, so it appears that the delegate shader goes out of scope during the load process. Is there any way I can disable or delay the initialisation of the UI until the delegate is back in scope? I've tried using the loading keyword without success, and also experimented with setting flags in the on Load and on PostLoad handlers too, but this doesn't seem to do the trick. An absolute last resort might be to close the material editor when opening a scene, but it seems that the earliest event I can catch is the onLoad handler, and adding a matEditor.Close() call here doesn't solve the problem. I've started looking into the possibility of registering a callback, which I think may do the trick, but if anyone can suggest a neater solution I'd be very grateful :)

Secondly, the shader allows the artist to select three point lights for lighting visualisation inside Max. I use the following code for getting the data for each light in the shader...


float4 PosLightPos0 : POSITION <string UIName = "Point light 1"; string Object = "PointLight"; string Space = "World"; int refID = 0; > = {1.0f, 0.0f, 0.0f, 1.0f};
float4 PosLightCol0 : LIGHTCOLOR <int LightRef = 0; >;
float4 PosLightDir0 : DIRECTION <int LightRef = 0; >;


I can't find a way of automatically connecting parameters to the attenuation values of the lights, so instead I have a timer which is called once a second, which copies the light parameters into the relevant shader properties. For neatness &#40;and until I've got everything working correctly&#41;, when the artist selects a new light for one of the three slots, I simply store the light's index, then reassign the light pos as part of the timer tick code...


on light_clock tick do
&#40;
if m_light0 > 0 and not &#36;Lights == undefined then
&#40;
delegate.PosLightPos0 = m_light0
light0.caption = &#36;Lights.name
delegate.PosLightAttnStart0 = &#36;Lights.farAttenStart
delegate.PosLightAttnEnd0 = &#36;Lights.farAttenEnd
&#41;

.. repeated for other two lights
&#41;


This all works fine whilst editing the scene. However, if you reload the scene with the material editor closed &#40;which is currently necessary because of the first issue!&#41;, all three lights are set to the first light index. When you open the material editor and the timer code above is called, the lights are assigned correctly. This seems like designed behaviour, so I copied the tick code into the on PostLoad handler, which I verified is called on load even if the material editor is closed. I also verified that the light indices are valid at this point - they are identical to the indices used when the material editor is subsequently opened and the lighting corrects itself. The problem is that this approach does not fix the problem! Is the shader fx file compiled after &#40;or even during&#41; the on PostLoad handler that would result in the loss of these properties being set? I have also tried forcing a redraw of the scene, but the problem persists.

Apologies for the length &#40;and complexity&#41; of this post! Any advice would be very much appreciated!

Joel.
0 Likes
610 Views
5 Replies
Replies (5)
Message 2 of 6

Anonymous
Not applicable
May I ask you a question in matter of your first problem? Where do you place your scripted material in MAX directories? Do you place it in ...max...\stdplugs\stdscripts or anywhere else?
0 Likes
Message 3 of 6

Anonymous
Not applicable
Hi Denis, thanks for your reply.

It's in "3ds Max 2010\Scripts\Startup". I just tried moving it to "3ds Max 2010\stdplugs\stdscripts", but I get the following error when I run Max...

"--Runtime Error: Extends class must be same superclass as scripted plugin, not: DirectX_9_Shader"

Thanks,

Joel.
0 Likes
Message 4 of 6

Anonymous
Not applicable
Looking at the first issue some more, when reloading the scene it appears that events occur in the following order...

on open called on rollouts
on load called on plugin
on postLoad called on plugin

The problem is that I'm using the on open handler to initialise my UI to values in the delegate. Even if I start with a valid delegate, when I reload, the delegate is undefined when on open is called, and is only initialised in the on load handler, which is called by Max after the on open for each rollout!

I don't explicitly add my rollouts to the plugin - they just appear where I declare them. Is there a way I can stop them from automatically adding themselves and add them in the load or postLoad handlers, where the delegate should be set up?

Thanks again,

Joel.
0 Likes
Message 5 of 6

Anonymous
Not applicable
Aha! With a bit of help, the problem appears to be fixed through the use of callbacks - one filePreOpenProcess to close the Material Editor when the scene is reloaded &#40;not ideal, but doesn't seem too much of an issue in practice&#41;, and one filePostOpenProcess to store the light IDs, and redraw the scene :&#41;

Joel.
0 Likes
Message 6 of 6

Anonymous
Not applicable
JoelG,

i asked about your scripted material place to be sure that you are in right position. The scripted material that extends DirectX shader has to be in ...\startup\. Using any startup script try to create an instance of your material before loading any file.
0 Likes