Monogame OpenGL - FatalExecutionEngineError для GraphicsDevice.DrawInstancedPrimitives () - PullRequest
0 голосов
/ 26 сентября 2019

Я портирую одноигровую игру DirectX на DesktopGL.Я использую аппаратное создание экземпляров для рисования тысяч блоков (например, minecraft)

Это отлично работает в DirectX, но в DesktopGL эта строка вылетает, показывая следующую ошибку

GraphicsDevice.DrawInstancedPrimitives(PrimitiveType.TriangleList, 0, meshPart.StartIndex, meshPart.PrimitiveCount, this.CountForBT[i]);

Managed Debugging Assistant'FatalExecutionEngineError' Message = Помощник по управляемой отладке. 'FatalExecutionEngineError': 'Во время выполнения обнаружена фатальная ошибка.Адрес ошибки был 0x34fbe02b в потоке 0x2ac4.Код ошибки 0xc0000005.Эта ошибка может быть ошибкой в ​​CLR или в небезопасных или не поддающихся проверке частях пользовательского кода.Распространенные источники этой ошибки включают в себя ошибки пользовательского маршалинга для COM-взаимодействия или PInvoke, которые могут повредить стек. '

Полная пустота:

private void DrawBlocksFromArrays()
    {
        int i = 1;

        int view, proj, sun, cam, sunDir;
        if (Main.platform == Main.Platform.DirectX)
        {
            view = 0; proj = 1; sun = 2; cam = 3; sunDir = 4;
        }
        else
        {
            //This is just because OpenGL shader compiler changes the order of vars in HLSL
            view = 1; proj = 2; sun = 3; cam = 4; sunDir = 0;
        }


        do
        {
            BlockType BT = BlockType.BTList[i];
            int InstancesCount = this.CountForBT[i];
            bool flag = InstancesCount != 0;
            if (flag)
            {
                Vector4[] BlockInstances = this.ArraysForBT[i];
                DynamicVertexBuffer instanceVertexBuffer = this.IVBsForBT[i];
                instanceVertexBuffer.SetData<Vector4>(BlockInstances, 0, this.CountForBT[i], SetDataOptions.Discard);
                VertexBufferBinding[] MeshVertexBufferBinding = new VertexBufferBinding[]
                {
                        default,
                        new VertexBufferBinding(instanceVertexBuffer, 0, 1)
                };

                foreach (ModelMeshPart meshPart in BT.Mesh.MeshParts)
                {
                    MeshVertexBufferBinding[0] = new VertexBufferBinding(meshPart.VertexBuffer, meshPart.VertexOffset, 0);
                    base.GraphicsDevice.SetVertexBuffers(MeshVertexBufferBinding);
                    base.GraphicsDevice.Indices = meshPart.IndexBuffer;
                    Effect effect = meshPart.Effect;

                    effect.Parameters[view].SetValue(Main.viewMatrix);
                    effect.Parameters[proj].SetValue(Main.projectionMatrix);
                    effect.Parameters[sun].SetValue(Main.SunLightIntencity);
                    effect.Parameters[cam].SetValue(Main.cameraPosition);
                    effect.Parameters[sunDir].SetValue(Main.SunlightDirection);


                    foreach (EffectPass pass in effect.CurrentTechnique.Passes)
                    {
                        pass.Apply();
                         // ---- Crash at this Line --- //
                        base.GraphicsDevice.DrawInstancedPrimitives(PrimitiveType.TriangleList, 0, meshPart.StartIndex, meshPart.PrimitiveCount, this.CountForBT[i]);

                    }

                }

            }
            i++;
        }
        while (i <= 10);

    }

Шейдер HLSL:

#if OPENGL
#define SV_POSITION POSITION
#define VS_SHADERMODEL vs_3_0
#define PS_SHADERMODEL ps_3_0
#else
#define SV_POSITION POSITION0
#define VS_SHADERMODEL vs_4_0_level_9_1
#define PS_SHADERMODEL ps_4_0_level_9_1
#endif

//DX

// Camera settings.
//matrix World;
matrix View;
matrix Projection;
float DiffuseLight = 1.0;
float3 CamPos = float3(0, 0, 1);
float3 LightDir = float3(0, -1, 0);



float ShadeX = 0.8;
float ShadeY = 1.0;
float ShadeZ = 0.6;

float4 IMC1 = float4(1, 0, 0, 0);
float4 IMC2 = float4(0, 1, 0, 0);
float4 IMC3 = float4(0, 0, 1, 0);



sampler Sampler = sampler_state
{
    Texture = (Texture);
};


struct VertexShaderInput
{
    float4 Position : SV_POSITION;
    float3 Normal : NORMAL0;
    float2 TextureCoordinate : TEXCOORD0;
};


struct VertexShaderOutput
{
    float4 Position : SV_POSITION;
    float3 Color : COLOR0;
    float2 TextureCoordinate : TEXCOORD0;
    float3 Normal : NORMAL0;
    float3 CamDir : NORMAL1;

};


VertexShaderOutput MainVS(in VertexShaderInput input, float4 instancePos:BLENDWEIGHT0)
{
    VertexShaderOutput output = ( VertexShaderOutput) 0;


    matrix instanceTransform = matrix(IMC1, IMC2, IMC3, instancePos);

    float4 worldPosition = mul(input.Position, instanceTransform);
    float4 viewPosition = mul(worldPosition, View);
    output.Position = mul(viewPosition, Projection);

    float diffuseAmount = (abs(input.Normal.x) * ShadeX) + (abs(input.Normal.y) * ShadeY) + (abs(input.Normal.z) * ShadeZ);



    output.Color = saturate(diffuseAmount) * DiffuseLight;

    output.Normal = input.Normal;
    output.CamDir = normalize(input.Position.xyz - CamPos);


    output.TextureCoordinate = input.TextureCoordinate;

    return output;
}



float4 MainPS(VertexShaderOutput input) : COLOR
{


    float4 pix = tex2D(Sampler, input.TextureCoordinate);
    //float4 pix = float4(1, 1, 1,1);

    float i = (dot(LightDir, input.Normal));
    float r = (dot(input.CamDir, input.Normal));
    float theta = clamp(1 - abs(i - r), 0, 0.8) * 0.4;

    float spec = pow(theta, 2);

    return  float4(pix.x * input.Color.x + spec, pix.y * input.Color.y + spec, pix.z * input.Color.z + spec, pix.w);


}


// Hardware instancing technique.
technique HardwareInstancing
{
    pass Pass1
    {
        VertexShader = compile VS_SHADERMODEL MainVS();
        PixelShader = compile PS_SHADERMODEL MainPS();
    }
}

Game.cs @ https://github.com/HasinduLanka/BlockEngine/blob/master/BlockEngine.core/Game1.cs

Полный источник @ https://github.com/HasinduLanka/BlockEngine

...