我正在将DirectX单机游戏移植到DesktopGL。 我使用硬件实例化绘制了数千个方块(如Minecraft)
这在DirectX中工作正常,但在DesktopGL上,此行崩溃,显示以下错误
GraphicsDevice.DrawInstancedPrimitives(PrimitiveType.TriangleList, 0, meshPart.StartIndex, meshPart.PrimitiveCount, this.CountForBT[i]);
托管的调试助手“ FatalExecutionEngineError” Message =托管调试助手'FatalExecutionEngineError':'运行时遇到致命错误。错误的地址在线程0x2ac4上的0x34fbe02b处。错误代码为0xc0000005。此错误可能是CLR或用户代码中不安全或不可验证部分的错误。该错误的常见来源包括COM-interop或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