Frozenology Elemental
Frozenology Elemental

Reputation: 23

XNA 4.0 and Effect Code

I'm developing a game using XNA 4.0 library (not using game class and ContentManager) As i known XNA 4.0 doesn't support compile effect at runtime. I tried to compile .fx file with fxc compiler and load to Effect constructor like this code

FileStream f = new FileStream(FName, FileMode.Open);
byte[] fData = new byte[f.Length];
f.Read(fData, 0, FData.Length);
f.Close();
Effect ef = new Effect(GfxDev, fData);

I got exception error messages at this point "You can only construct Effect with data that was already compiled. This data is not a compiled effect."

What the code i need to use for Effect constructor? I checked MSDN and no explanation.

Thanks

Upvotes: 2

Views: 1962

Answers (1)

Andrew Russell
Andrew Russell

Reputation: 27195

The output from fxc is subtly different to the output of the effect compiler in XNA. I cannot remember the exact details - but I believe that there are differences in the file header - something about enumerating the effect parameters, I think.

The solution, then, is to use the effect compiler that comes with XNA's content pipeline, in place of fxc. The class you need is Microsoft.Xna.Framework.Content.Pipeline.Processors.EffectProcessor.

Here is an example of how to use it. You can put this into a simple command-line project:

string fx = File.ReadAllText("Effect1.fx");

EffectProcessor effectProcessor = new EffectProcessor();
var effect = effectProcessor.Process(new EffectContent { EffectCode = fx }, new MyContext());

byte[] yourEffectCode = effect.GetEffectCode();

Note that you need a context class, derived from ContentProcessorContext. There are lots of methods you need to override, but only three are required to actually do anything for the above code to work:

class MyContext : ContentProcessorContext
{
    public override string BuildConfiguration { get { return ""; } }
    public override TargetPlatform TargetPlatform { get { return TargetPlatform.Windows; } }
    public override GraphicsProfile TargetProfile { get { return GraphicsProfile.HiDef; } }
    // ... other overrides ...
}

Note that (as well as Microsoft.Xna.Framework.Graphics.dll) this requires that your project references Microsoft.Xna.Framework.Content.Pipeline.dll. This requires that you project is built against the full .NET 4.0 framework (not the "Client Profile"). Also this content pipeline DLL is not redistributable (but then I'm not sure fxc is either).

Upvotes: 4

Related Questions