-
Notifications
You must be signed in to change notification settings - Fork 5
Getting Effect .fx files to compile and run Hints, Tips and Gotchas
Summary of some gotchas and work arounds I came across in the process of transferring my effects files across to MonoGame from XNA.
(a.k.a. things I wish I had known 3 days ago).
If you are just starting look at these pages first:
(0) https://github.com/mono/MonoGame/wiki/MonoGame-Content-Processing
(1) https://github.com/mono/MonoGame/wiki/Effects-And-Shaders
Then come back here for troubleshooting hints and tips.
For shader .fx files, the version of the of the content processor you are using to compile your xnb files (ie. MonoGameContentProcessors.dll) must be aligned with the version of the runtime you are running your game against (ie. MonoGame.Framework.dll)
Otherwise you may get "Wrong MGFX file version!" raised by ReadEffect() in Effect.cs when you do a content.Load [because the version written in to the .xnb file is not a match with the value of MGFXVersion that has been put in the run time].
So if you have this error, the first thing to check is that your content processor is the same up-to-dateness as the version of the runtime you are running your game against.
(a) For OpenGL versions of MonoGame (eg. Mac, Linus, WindowsGL) the shader model must be SM 3.0 or lower
(b) For DirectX versions of MonoGame (eg. WinRT, Windows8) the shader model must be SM 4.0 or higher.
(see: https://monogame.codeplex.com/discussions/432060 )
In the DirectX case it is typical for people to use the:
vs_4_0_level_9_1
and
ps_4_0_level_9_1
compilation profiles, because these provide backwards compatibility for Shader Model 2 shaders.
(see https://github.com/mono/MonoGame/wiki/Effects-And-Shaders )
(a) The "Windows8" build configuration is used internally in the MonoGame content processor code to indicate compilation to target DX11.
Look at the code on line 29 of MGEffectProcessor.cs!
options.DX11Profile = platform == MonoGamePlatform.Windows8 ? true : false;
(again see: https://monogame.codeplex.com/discussions/432060 )
The ContentHelper.cs file in the ContentProcessors project reads the build configuration name you are using then does this:
switch (platform.ToUpper())
{
case "WINDOWS":
return MonoGamePlatform.Windows;
case "WINDOWS8":
return MonoGamePlatform.Windows8;
case "IOS":
return MonoGamePlatform.iOS;
case "ANDROID":
return MonoGamePlatform.Android;
case "LINUX":
return MonoGamePlatform.Linux;
case "OSX":
return MonoGamePlatform.OSX;
case "PSM":
return MonoGamePlatform.PSM;
etc.
}
Which then gets used by MGEffectProcessor.cs (as above)
options.DX11Profile = platform == MonoGamePlatform.Windows8 ? true : false;
to set the flag specifying DX11.
In other words, in order to compile .xnb files from your .fx files that will be able to run against the Windows DirectX version of MonoGame, you MUST use build profile that is specifically called "Windows8" !! ... either the one supplied with the project code or one you make yourself.
At some point (which I haven't tracked down, yet) this getting written into a registry key
called "MONOGAME_PLATFORM" (HKEY_CURRENT_USER/Environment/MONOGAME_PLATFORM),
and then gets read back from that key via:
var platform = Environment.GetEnvironmentVariable("MONOGAME_PLATFORM", EnvironmentVariableTarget.User);
If you don't realize this, having just converted all your .fx files to run against
SM 4.0, when you come to compile them for DX11, you will cryptically be told:
"Vertex shader 'SimpleVS' must be SM 3.0 or lower!"
(And your brain says:
"Ein minuten, bitter! I just specifically changed them all to SM 4.0!"
as per the previous tip.)
(b) The "Windows" build configuration is used for the WindowsGL target.
(c) Aside: The WindowsGL version of MonoGame is primarily intended to be a test environment. Don't necessarily expect great performance from this build.
When compiling for the Windows8, DX11 profile, the POSITION and POSITION0 semantics must be replaced by SV_POSITION.
Otherwise you will get: A first chance exception of type 'SharpDX.SharpDXException' occurred in SharpDX.DLL Additional information: HRESULT: [0x80070057], Module: [Unknown], ApiCode: [Unknown/Unknown], Message: The parameter is incorrect.
in
new SharpDX.Direct3D11.InputLayout
There may be other similars.