I'm currently working on a winforms application as a level editor for my game. The levels are simple grid-based things, with several types of blocks that can go into the grid. My winforms application has 4 sections: a list of block types, a graphics device control where the level is drawn (blocks from the list of block types can be dragged into the graphics device control to place them), a list of properties for the currently selected block in the level, and a slider to set how many seconds into the level to display (since some of the blocks have time-sensitive components).
In order to better view the 3D world, the graphics device control draw Point primitives along the three axes at intervals corresponding to the grid cells. The X-axis has red points, the Y-axis has green points, and the Z-axis has blue points (X,Y,Z => R,G,B). The origin is noted with a black point.
When I launch my level editor, this looks fine. The axes are correctly colored, and I can rotate the camera around with a set of buttons, and the axes remain correctly colored. On mouseDown of my camera rotation buttons, I set a rotation boolean on the graphics device control to true (and the property also calls Invalidate() so that it will redraw), as well as activating a Timer. The timer simply calls Invalidate() regularly to keep redrawing the scene as I rotate it. On mouseUp for the buttons, the boolean is set to false and the Timer is deactivated.
When I add a Model to the scene, I also call Invalidate() once, so that it will show up immediately. When I first add the model, everything's fine; I've got the model drawing correctly, and the axes remain the correct colors. The problem is that when I mouseDown on one of my camera rotation buttons
after adding a model, all of the axis points turn blue. The same happens if I add a second model without rotating (since the second model also calls Invalidate()).
(Added: If I move the box.Draw call before the DrawUserPrimitives call, the points turn blue immediately upon adding the model, which explains why I had to Invalidate it twice for the bug to appear)
I just don't understand why my DrawUserPrimitives<VertexPositionColor> would change the rendered colors after being invalidated after drawing the model once. The list of vertices still stores the correct colors, they're just being rendered incorrectly. The only thing I can guess is the effect for the model (my only testing so far has used the BasicEffect, but some of the models will be using custom effects) is changing something with the graphics device so it doesn't draw the primitives correctly, but what exactly would cause that?
| // LevelEditorControl.Draw: drawing axis primitives |
| effect.Begin(); |
| effect.CurrentTechnique.Passes[0].Begin(); |
| |
| GraphicsDevice.DrawUserPrimitives<VertexPositionColor>(PrimitiveType.PointList, axes, 0, axes.Length); |
| |
| effect.CurrentTechnique.Passes[0].End(); |
| effect.End(); |
| |
| //========== |
| |
| // ABox.Draw: drawing models |
| Matrix[] bones = new Matrix[Model.Bones.Count]; |
| Model.CopyAbsoluteBoneTransformsTo(bones); |
| foreach (ModelMesh mesh in Model.Meshes) |
| { |
| foreach (Effect effect in mesh.Effects) |
| { |
| if (effect.GetType() == typeof(BasicEffect)) |
| { |
| BasicEffect beffect = effect as BasicEffect; |
| beffect.EnableDefaultLighting(); |
| beffect.SpecularColor = Color.White.ToVector3() * 0.125f; |
| beffect.SpecularPower = 8; |
| beffect.View = View; |
| beffect.Projection = Projection; |
| beffect.World = bones[mesh.ParentBone.Index] * World; |
| } |
| else |
| { |
| effect.Parameters["View"].SetValue(View); |
| effect.Parameters["Projection"].SetValue(Projection); |
| effect.Parameters["World"].SetValue(bones[mesh.ParentBone.Index] * World); |
| } |
| } |
| mesh.Draw(); |
| } |
The points are turning
exactly blue (0,0,255), not something close, and they're doing this regardless of what color the points are supposed to be. The model I've been testing this bug with is gray and black, and as you can see I'm not using a blue light or anything like that. The entirety of the model I've been testing with is a unit cube with a matte gray surface (mesh0), and a 1.05 length cube, with inverted normals and a matte black surface (mesh1).