Implement XNA / Mono Exclusion

As a preface, the same code works fine in XNA, but Monogame throws an exception. To do this, you probably need someone who is familiar with the Monogame rendering pipeline.

In the "Draw" section of my game, there is a ShadowmapResolver that displays a texture that is the final calculated light pattern from the given light. It gets an exception when rendering from the fact that EffectPass.Apply() is EffectPass.Apply() complaining that somewhere inside Mono theres an attempt is made from int32[] to Single[] . Here is my code that calls it:

 private void ExecuteTechnique(Texture2D source, RenderTarget2D destination, string techniqueName, Texture2D shadowMap) { graphicsDevice.SetRenderTarget(destination); graphicsDevice.Clear(Color.Transparent); resolveShadowsEffect.Parameters["renderTargetSizeX"].SetValue((float)baseSizeX); resolveShadowsEffect.Parameters["renderTargetSizeY"].SetValue((float)baseSizeY); if (source != null) resolveShadowsEffect.Parameters["InputTexture"].SetValue(source); if (shadowMap != null) resolveShadowsEffect.Parameters["ShadowMapTexture"].SetValue(shadowMap); resolveShadowsEffect.CurrentTechnique = resolveShadowsEffect .Techniques[techniqueName]; try { foreach (EffectPass pass in resolveShadowsEffect.CurrentTechnique.Passes) { pass.Apply(); // <--- InvalidCastException re-enters my program here quadRender.Render(Vector2.One * -1, Vector2.One); } } catch (Exception ex) { Util.Log(LogManager.LogLevel.Critical, ex.Message); } graphicsDevice.SetRenderTarget(null); } 

And here is the stacktrace:

 at Microsoft.Xna.Framework.Graphics.ConstantBuffer.SetData(Int32 offset, Int32 rows, Int32 columns, Object data) at Microsoft.Xna.Framework.Graphics.ConstantBuffer.SetParameter(Int32 offset, EffectParameter param) at Microsoft.Xna.Framework.Graphics.ConstantBuffer.Update(EffectParameterCollection parameters) at Microsoft.Xna.Framework.Graphics.EffectPass.Apply() at JASG.ShadowmapResolver.ExecuteTechnique(Texture2D source, RenderTarget2D destination, String techniqueName, Texture2D shadowMap) in C:\Users\[snip]\dropbox\Projects\JASG2\JASG\JASG\Rendering\ShadowmapResolver.cs:line 253 

So, it seems that one of the parameters of my shader, which I am trying to set, somehow confuses the monogame, but I do not understand what it can be. I click float, not int arrays. I even tried changing RenderTarget2D.SurfaceFormat from Color to Single for all my goals and textures, still giving the same error.

Outside of the function that I gave, in a wider range there are no other parameters that are set with another EffectPass.Apply . There are several other effects that render without error before.

In case this helps, here is the source for the MonoGame Framework regarding ConstantBuffer.SetData()

 private void SetData(int offset, int rows, int columns, object data) { // Shader registers are always 4 bytes and all the // incoming data objects should be 4 bytes per element. const int elementSize = 4; const int rowSize = elementSize * 4; // Take care of a single element. if (rows == 1 && columns == 1) { // EffectParameter stores all values in arrays by default. if (data is Array) Buffer.BlockCopy(data as Array, 0, _buffer, offset, elementSize); else { // TODO: When we eventually expose the internal Shader // API then we will need to deal with non-array elements. throw new NotImplementedException(); } } // Take care of the single copy case! else if (rows == 1 || (rows == 4 && columns == 4)) Buffer.BlockCopy(data as Array, 0, _buffer, offset, rows*columns*elementSize); else { var source = data as Array; var stride = (columns*elementSize); for (var y = 0; y < rows; y++) Buffer.BlockCopy(source, stride*y, _buffer, offset + (rowSize*y), columns*elementSize); } } 

Is this some kind of marshaling problem? Thank you for your time!

Edit: PS: The exception is an InvalidCastException , not a NotImplementedException .

+7
c # xna monogame
source share
2 answers

Not sure if this will help you or not, but the only casting that, as I see it, is being done is the data as an array. I would argue that it collapses on the line:

 Buffer.BlockCopy(data as Array, 0, _buffer, offset, rows*columns*elementSize); 

or

 var source = data as Array; 

Because they do not perform any type checks before distinguishing them. If this is the line on which it crashes, it is because they do not seem to support data values ​​other than an array. I do not know this structure well enough to give you a solid answer on how to get around this. I'll probably talk about this as a bug for the creators here

+1
source share

Try the 2MGFX tool, which optimizes shaders for monogame. tool tips MGFX

+1
source share

All Articles