Monogame OpenGL - FatalExecutionEngineError on GraphicsDevice.DrawInstancedPrimitives()

0

I am porting a DirectX monogame game to DesktopGL. I use hardware instancing to draw thousands of blocks (like minecraft)

This works fine in DirectX, but on DesktopGL this line crashes showing the following error

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

Managed Debugging Assistant 'FatalExecutionEngineError' Message=Managed Debugging Assistant 'FatalExecutionEngineError' : 'The runtime has encountered a fatal error. The address of the error was at 0x34fbe02b, on thread 0x2ac4. The error code is 0xc0000005. This error may be a bug in the CLR or in the unsafe or non-verifiable portions of user code. Common sources of this bug include user marshaling errors for COM-interop or PInvoke, which may corrupt the stack.'

Full void :

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 shader :

#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

Full source @ https://github.com/HasinduLanka/BlockEngine

c#
opengl
directx
monogame
executionengineexception
asked on Stack Overflow Sep 26, 2019 by Hasindu Lanka

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0