I am attempting to get instancing with models to play nicely with Android/OpenGL ES. The shader and the code do work when I only draw the instanced objects and it renders correctly. However, if I try to render any other 3d models after or before that then everything shows up in “artifacts” and is stretched out and distorted. When I try to draw anything 2D to the game screen it will not show up at all if I have just the 2d things and the instanced models being drawn. However, if I also draw a 3d model, the instanced models, and anything in 2d, then they will all show up but the 3d stuff is still distorted.
I also run into an error with switching render targets when using the instanced code when I do this, nothing shows up in game at all.
I’m a bit confused by this behavior and can’t figure out what is going on. Everything is working fine with windows OpenGL but this is delaying my release for Android so I really hope someone might have an idea of what to do to resolve this issue.
I’ve also included the relevant source code for how I am doing this.
public void Draw(GraphicsDevice graphicsDevice)
{
foreach (ModelMesh mesh in cube.Meshes)
{
foreach (ModelMeshPart meshPart in mesh.MeshParts)
{
graphicsDevice.Indices = meshPart.IndexBuffer;
effect.CurrentTechnique = effect.Techniques["Instancing"];
effect.Parameters["World"].SetValue(Matrix.CreateScale(1f) * Matrix.Identity);
effect.Parameters["View"].SetValue(view);
effect.Parameters["Projection"].SetValue(projection);
effect.Parameters["LightDirection"].SetValue(new Vector3(.5f, 1f, -1f));
effect.Parameters["Ambient"].SetValue(1f);
effect.Parameters["Color"].SetValue(new Vector4(0.15f, .15f, 0.35f, 1f));
effect.Parameters["ModelTexture"].SetValue(texture);
effect.CurrentTechnique.Passes[0].Apply();
graphicsDevice.SetVertexBuffers(
new VertexBufferBinding(meshPart.VertexBuffer, meshPart.VertexOffset, 0),
new VertexBufferBinding(instanceVertexBuffer, 0, 1)
);
graphicsDevice.DrawInstancedPrimitives(PrimitiveType.TriangleList, 0, meshPart.StartIndex, meshPart.PrimitiveCount, positions.Length);
}
}
public void Load(GraphicsDevice graphicsDevice, ContentManager content)
{
Vector3 lookat = new Vector3(0, 0, 100);
view = Matrix.CreateLookAt(lookat, Vector3.Zero, Vector3.Up);
projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, graphicsDevice.Viewport.AspectRatio, 1, 3000);
viewVector = Vector3.Transform(Vector3.Zero - lookat, Matrix.CreateRotationY(0));
viewVector.Normalize();
instanceVertexDeclaration = new VertexDeclaration
(
new VertexElement(0, VertexElementFormat.Vector4, VertexElementUsage.BlendWeight, 0),
new VertexElement(16, VertexElementFormat.Vector4, VertexElementUsage.BlendWeight, 1),
new VertexElement(32, VertexElementFormat.Vector4, VertexElementUsage.BlendWeight, 2),
new VertexElement(48, VertexElementFormat.Vector4, VertexElementUsage.BlendWeight, 3)
);
instanceVertexBuffer = new DynamicVertexBuffer(graphicsDevice, instanceVertexDeclaration, width * height, BufferUsage.WriteOnly);
instanceVertexBuffer.SetData(positions, 0, width * height, SetDataOptions.Discard);
texture = content.Load<Texture2D>("BackDrop/squareOutline");
effect = content.Load<Effect>("BackDrop/instancing");
cube = content.Load<Model>("BackDrop/cube");
for (int x = 0; x < width; x++)
{
for (int y = 0; y < height; y++)
{
positions[x + width * y] = Matrix.CreateTranslation(new Vector3(x * gridSpace - (width * gridSpace / 2), y * gridSpace - (height * gridSpace / 2), 0));
}
}
midpointCircle = new MidPointCircle(31);
//This is a hackish way to do it. I should determine the size of the cubes by
//using the perspective and distance and camera but this is quick and will work for a one off
EstimatedSquareSize = (Math.Abs(Game1.LeftBoundary - Game1.RightBoundary) / width);
Console.WriteLine("Estimated Square Size: " + EstimatedSquareSize);
}