作为前言,完全相同的代码在XNA中工作得很好,但是Monogame会引发异常.这可能需要熟悉Monogame渲染管道的人.
在我的游戏的Draw部分中,有一个ShadowmapResolver渲染出一个纹理,它是给定光源的最终计算光模式.当从基本上是EffectPass.Apply()的渲染中收到异常时,抱怨从Mono中的某个地方尝试从int32 []转换为Single [].这是我调用它的代码:
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); }
这是堆栈跟踪:
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,String techniqueName,Texture2D shadowMap) in C:\Users\[snip]\dropBox\Projects\JASG2\JASG\JASG\Rendering\ShadowmapResolver.cs:line 253
因此,我试图设置的着色器的一个参数似乎是以某种方式混淆了monogame,但我不知道它可能是什么.我正在推动浮动,而不是int数组.我甚至尝试将RenderTarget2D.SurfaceFormat从Color更改为Single以用于我的所有目标和纹理,仍然提供完全相同的错误.
在我给出的函数之外,在更广泛的范围内,自另一个EffectPass.Apply以来没有设置其他参数.在此之前还有其他多种效果可以无错误地呈现.
如果它有帮助,这里是关于ConstantBuffer.SetData()的MonoGame框架的源代码
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,_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,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,offset + (rowSize*y),columns*elementSize); } }
这是某种编组问题吗?谢谢你的时间!
编辑:P.S.:异常是InvalidCastException而不是NotImplementedException.