XNA Creators Club Online
Page 1 of 1 (6 items)
Sort Posts: Previous Next

Combining Models and Primitives in winforms

Last post 11/4/2009 6:54 PM by BShields. 5 replies.
  • 10/17/2009 12:58 AM

    Combining Models and Primitives in winforms

    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).
  • 11/3/2009 10:52 PM In reply to

    Re: Combining Models and Primitives in winforms

    Could it possibly be that once the 3D model is in the scene, the GraphicsDevice has a pixel/vertex shader set to it? It's the only real change I can find that occurs when the model is in the scene versus just containing primitives, but even if I set both the pixel and vertex shader on the GraphicsDevice to null before drawing, I'm getting the same result, so it seems unlikely. Is anyone else able to shed some light on the subject for me?
  • 11/3/2009 11:22 PM In reply to

    Re: Combining Models and Primitives in winforms

    Looks like you forgot to set the vertex declaration?
    XNA Framework Developer - blog - homepage
  • 11/4/2009 4:26 AM In reply to

    Re: Combining Models and Primitives in winforms

    I've got the following in my Initialize() for my LevelEditorControl:
    GraphicsDevice.VertexDeclaration = new VertexDeclaration(GraphicsDevice, VertexPositionColor.VertexElements); 

    The interesting thing I've just noticed is that different models seem to have different effects on my pixel colors. A cube (either the gray cube I'd been using, or a textured one) turns all of them blue. If I use a right triangular prism, the Z and Y axis points all turn black, but the X axis points vary in color (it looks like pink, green, red, black, and purple, in no discernible pattern).

    And since my list of VertexPositionColors is still storing the correct information, I'm not really sure what's going on.
  • 11/4/2009 3:34 PM In reply to

    Re: Combining Models and Primitives in winforms

    Answer
    Reply Quote
    You have to set it before the draw call, or else something else may replace it.
  • 11/4/2009 6:54 PM In reply to

    Re: Combining Models and Primitives in winforms

    That's the ticket! Thanks!
Page 1 of 1 (6 items) Previous Next