c# - XNA/Mono 效果抛出运行时转换异常

标签 c# xna monogame

作为前言,完全相同的代码在 XNA 中工作得很好,但 Monogame 抛出异常。这可能需要熟悉 Monogame 渲染管道的人员。

在我的游戏的绘制部分,有一个 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, RenderTarget2D destination, String techniqueName, Texture2D shadowMap) in C:\Users\[snip]\dropbox\Projects\JASG2\JASG\JASG\Rendering\ShadowmapResolver.cs:line 253

因此,我试图设置的着色器参数之一似乎以某种方式混淆了 monogame,但我不明白它可能是什么。我推 float ,而不是 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, 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);
    }
}

这是某种编码问题吗?感谢您的宝贵时间!

编辑:附言:异常是 InvalidCastException 而不是 NotImplementedException

最佳答案

不确定这是否对您有帮助,但我看到的唯一转换是将数据转换为数组。我敢打赌它在线上崩溃了:

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

var source = data as Array;

因为他们在转换之前不做任何类型检查。如果那是它崩溃的那一行,那是因为它们似乎不支持非数组数据值。我不太了解这个框架,无法就如何解决这个问题给你一个可靠的答案。我可能会将此作为错误报告给制造商 here

关于c# - XNA/Mono 效果抛出运行时转换异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22306072/

相关文章:

c# - C# 标准库是否有用于存储可变值的泛型类?

c# - 在 Xamarin Forms UWP 中突出显示选定的选项卡

c# - 创建具有频率的汽车声音

input - 如何为 monogame metro 应用程序创建输入文本框

visual-studio-2012 - 如何启动适用于 Windows 桌面(以及 future 端口)的 MonoGame 项目?

c# - 无法在 VS2012 中添加新的 monogame 内容项目到解决方案

c# - 比赛收集超时

C#内存不足的困惑

c# - 在 Unity 中使用 Shells 技术实现 Fur

c# - 在 XNA 中重用游戏对象是否有意义?