OpenGL.
My code is spread out over several classes, methods, and files, but here is the sequence of events (so I donāt have to send my entire program:
Exhibit A:
public override void Prepare(Level level)
{
Camera.GraphicsDevice.SetRenderTarget(backbuffer);
Camera.GraphicsDevice.Clear(Color.Black);
level.DrawHighlight();
base.Prepare(level);
}
Within level.DrawHighlight:
foreach (IDrawable d in AllObjectsToBeDrawn(0, float.PositiveInfinity))
{
Camera.GraphicsDevice.DepthStencilState = DepthStencilState.None;
Camera.GraphicsDevice.BlendState = BlendState.AlphaBlend;
d.DrawSilhouette(Camera, this);
Camera.GraphicsDevice.DepthStencilState = DepthStencilState.None;
Camera.GraphicsDevice.BlendState = BlendState.Additive;
d.DrawHighlight(Camera, this);
}
Camera.GraphicsDevice.DepthStencilState = DepthStencilState.Default;
In one of the IDrawables to be drawn: (which, mind, is not an XNA IDrawable, but rather an interface of my own):
public override void DrawSilhouette(Camera camera, Level environment)
{
Vector3 backup = DiffuseColour;
DiffuseColour = Vector3.Zero;
ApplyStandardParameters(effect, environment);
effect.World = World;
camera.ApplyParameters(effect);
foreach (EffectPass pass in effect.CurrentTechnique.Passes)
{
pass.Apply();
//This is the line that, if uncommented, prevents vertex data from working later on
//Camera.GraphicsDevice.DrawUserIndexedPrimitives<VertexPositionNormalsTexture>(PrimitiveType.TriangleList, vbuf, 0, vbuf.Length, ibuf, 0, ibuf.Length / 3);
}
DiffuseColour = backup;
}
protected void ApplyStandardParameters(ObjectEffect effect, Level environment)
{
effect.Mode = ObjectEffect.Modes.Standard;
effect.World = World;
effect.Alpha = Alpha;
effect.DiffuseColour = DiffuseColour;
effect.FogColour = environment.FogColour;
effect.FogDistance = environment.FogDistance;
effect.FogEnabled = environment.FogEnabled;
}
In the Camera class:
public void ApplyParameters(ObjectEffect effect)
{
effect.View = View;
effect.Projection = Projection;
}
And later, Exhibit B:
public void PrepareLightMap()
{
Camera.GraphicsDevice.BlendState = BlendState.AlphaBlend;
Camera.GraphicsDevice.SetRenderTarget(Camera.LightMap);
Camera.GraphicsDevice.Clear(new Color(LightColour));
IEnumerable<IDrawable> objects = AllObjectsToBeDrawn(0, float.PositiveInfinity);
foreach (IDrawable d in objects)
d.DrawToLightMap(Camera, this);
}
And in the same IDrawableās DrawToLightMap method:
ApplyLightMapParameters(effect, Level);
effect.NormalMap = normalmap;
effect.LightDirection = new Vector3(0, .5f, .866f);
camera.ApplyParameters(effect);
foreach (EffectPass pass in effect.CurrentTechnique.Passes)
{
pass.Apply();
//This is the call that seems to be lacking its incoming vertex data (apart from Position)
Camera.GraphicsDevice.DrawUserIndexedPrimitives<VertexPositionNormalsTexture>(PrimitiveType.TriangleList, vbuf, 0, vbuf.Length, ibuf, 0, ibuf.Length / 3);
}
And its ApplyLightMapParameters:
protected void ApplyLightMapParameters(ObjectEffect effect, Level environment)
{
effect.Mode = ObjectEffect.Modes.LightMap;
effect.World = World;
effect.Alpha = Alpha;
effect.LightColour = environment.LightColour + EmissiveColour;
effect.ShadowColour = environment.ShadowColour;
effect.ShadowMap = environment.Camera.GetShadowMap(Z);
}
I think thatās all the relevant bits. O.o But as you can see, in between the two draws, Iām setting effect parameters, setting CurrentTechniques (which occurs with the effect.Mode property), setting RenderTarget, and clearing the graphics device; I figured this would be enough to completely separate the two instances, let alone such odd vertex behaviour.
The shader code is effectively the same as in my original posts, but I now have it just returning float4(input.TexCoord, 0, 1), which comes out in many colours when itās working properly, and solid blue when itās not.