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

problem mixing 2d and 3d graphics

Last post 11/5/2009 3:59 PM by David Hunt. 13 replies.
  • 11/5/2009 1:39 AM

    problem mixing 2d and 3d graphics

    hello, i'm having the common issues with the drawing of 2d and 3d in the same project, i have search over the forum and over the web and i'm not able to find the solution, i put here my screen shoot




    the thing is that i'm using the spritebatch to show my menu, load and save screen, when i try to run the game, after reading the change made by spritebatch to the render states i put this code to reset the renderstate:

                GraphicsDevice.RenderState.DepthBufferEnable = true;
                GraphicsDevice.RenderState.AlphaBlendEnable = false;
                GraphicsDevice.RenderState.AlphaTestEnable = false;
                GraphicsDevice.RenderState.DepthBufferWriteEnable = true;
                GraphicsDevice.RenderState.StencilEnable = false;
                GraphicsDevice.RenderState.CullMode = CullMode.CullCounterClockwiseFace;
                GraphicsDevice.SamplerStates[0].AddressU = TextureAddressMode.Wrap;
                GraphicsDevice.SamplerStates[0].AddressV = TextureAddressMode.Wrap;

    but nothing happend, the image is still black, the model that i'm trying to draw is a brick with a normal map shader effect, i don't know if the shader modifies something, but the real thing is i have 2 days searching to solve this and i still stuck on this issue, can somebody help me ?

    thank you in advance.
    www.vrs.com.ve
  • 11/5/2009 1:51 AM In reply to

    Re: problem mixing 2d and 3d graphics

    I assume your model does not draw black if you draw it alone without the 2D stuff?

    It would be helpful if we could see the code you use to draw the model.
    XNA Framework Developer - blog - homepage
  • 11/5/2009 2:08 AM In reply to

    Re: problem mixing 2d and 3d graphics

    you are right, the model draw perfect if i draw it only in a 3d project, here i put my entire brick class

    using System; 
    using System.Collections.Generic; 
    using System.Linq; 
    using Microsoft.Xna.Framework; 
    using Microsoft.Xna.Framework.Audio; 
    using Microsoft.Xna.Framework.Content; 
    using Microsoft.Xna.Framework.GamerServices; 
    using Microsoft.Xna.Framework.Graphics; 
    using Microsoft.Xna.Framework.Input; 
    using Microsoft.Xna.Framework.Media; 
    using Microsoft.Xna.Framework.Net; 
    using Microsoft.Xna.Framework.Storage; 
     
    namespace loderunner3d 
        public class ladrillo 
        { 
            //variables pricipales 
            Model brick; 
            Vector3 posicion_brick; 
            Effect efecto; 
            Texture2D color_difuse, normal_map; 
            float aspectratio = 0.0f; 
            //variables para el render 
            Matrix renderMatrix, worldMatrix, viewMatrix, projMatrix; 
            Matrix[] bones; 
     
            public ladrillo(ContentManager content, GraphicsDeviceManager graphics) 
            { 
                brick = content.Load<Model>("inanimados/brick"); 
                efecto = content.Load<Effect>("normal_map"); 
                color_difuse = content.Load<Texture2D>("inanimados/normal2"); 
                normal_map = content.Load<Texture2D>("inanimados/bumped_normal"); 
                bones = new Matrix[brick.Bones.Count]; 
                brick.CopyAbsoluteBoneTransformsTo(bones); 
     
                aspectratio = graphics.GraphicsDevice.Viewport.Width / graphics.GraphicsDevice.Viewport.Height; 
                posicion_brick = new Vector3(0.0f, 0.0f, 0.0f); 
     
                worldMatrix = Matrix.Identity; 
     
                float FieldOfView = MathHelper.ToRadians(45.0f), NearPlane = 1.0f, FarPlane = 10000.0f; 
     
                projMatrix = Matrix.CreatePerspectiveFieldOfView(FieldOfView, aspectratio, NearPlane, FarPlane); 
     
                graphics.GraphicsDevice.VertexDeclaration = new VertexDeclaration(graphics.GraphicsDevice, VertexPositionNormalTexture.VertexElements); 
            } 
     
            public void SetPosition(Vector3 posicion) 
            { 
                posicion_brick = posicion; 
            } 
     
            public void SetPosition(float x, float y, float z) 
            { 
                posicion_brick.X = x; 
                posicion_brick.Y = y; 
                posicion_brick.Z = z; 
            } 
     
            public void render(GraphicsDeviceManager graphics) 
            { 
                renderMatrix = Matrix.CreateScale(8.0f); 
                viewMatrix = Matrix.CreateLookAt(new Vector3(0.0f, 1500.0f, 5000.0f), new Vector3(5.0f, 10.0f, 10.0f), Vector3.Up); 
     
     
     
                efecto.CurrentTechnique = efecto.Techniques["NormalMapping"]; 
     
                efecto.Begin(); 
     
     
                foreach (EffectPass pass in efecto.CurrentTechnique.Passes) 
                { 
                    pass.Begin(); 
     
                    foreach (ModelMesh mesh in brick.Meshes) 
                    { 
                        foreach (ModelMeshPart part in mesh.MeshParts) 
                        { 
                            worldMatrix = bones[mesh.ParentBone.Index] * renderMatrix; 
     
                            Vector4 vecEye = new Vector4(0.0f, 1500.0f, 5000.0f, 0); 
                            Matrix worldInverse = Matrix.Invert(worldMatrix); 
                            Vector4 vLightDirection = new Vector4(1.0f, 1.0f, 1.0f, 0.0f); 
                            efecto.Parameters["matWorldViewProj"].SetValue(worldMatrix * viewMatrix * projMatrix); 
                            efecto.Parameters["matWorld"].SetValue(worldMatrix); 
                            efecto.Parameters["vecEye"].SetValue(vecEye); 
                            efecto.Parameters["vecLightDir"].SetValue(vLightDirection); 
                            efecto.Parameters["ColorMap"].SetValue(color_difuse); 
                            efecto.Parameters["NormalMap"].SetValue(normal_map); 
                             
                            graphics.GraphicsDevice.Vertices[0].SetSource(mesh.VertexBuffer, part.StreamOffset, part.VertexStride); 
                            graphics.GraphicsDevice.Indices = mesh.IndexBuffer; 
                            graphics.GraphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, 
                                                                          part.BaseVertex, 0, part.NumVertices, 
                                                                          part.StartIndex, part.PrimitiveCount); 
                        } 
                    } 
     
                    pass.End(); 
                } 
                efecto.End(); 
     
            } 
     
        } 

    in my game play screen draw function i put this to draw the brick:

                     GraphicsDevice.RenderState.DepthBufferEnable = true
                GraphicsDevice.RenderState.AlphaBlendEnable = false
                GraphicsDevice.RenderState.AlphaTestEnable = false
                GraphicsDevice.RenderState.DepthBufferWriteEnable = true
                GraphicsDevice.RenderState.StencilEnable = false
                GraphicsDevice.RenderState.CullMode = CullMode.CullCounterClockwiseFace; 
                GraphicsDevice.SamplerStates[0].AddressU = TextureAddressMode.Wrap; 
                GraphicsDevice.SamplerStates[0].AddressV = TextureAddressMode.Wrap; 
     
                             
                ladrillos.SetPosition(5.0f, 10.0f, 10.0f); 
                ladrillos.render(loderunner.graphics); 

    i have readed your article about mixing the 2d and 3d graphics and i put the code to restore the renderstate, but nothing happend.

    www.vrs.com.ve
  • 11/5/2009 2:10 AM In reply to

    Re: problem mixing 2d and 3d graphics

    I have no idea.  I do remember when i put my sprites in that my code would do some funky stuff like parts would become transparent and the model would seem to be turned inside out  but you ahve the three lines of code that I added.  only lilne I dont see is the device.Clear but I assume you have it but it isnt part of the relevant code.  I have no idea man.  Post more info.
  • 11/5/2009 2:39 AM In reply to

    Re: problem mixing 2d and 3d graphics

    i have used renderstate.reset() and the brick just draw perfect, but i have read that the "reset" has a pitfall in the performance and i don't want that, i know there is something about the vertex or the pixel shader that the spritebatch modifies when i used it, but i don't know what setting i need to change.
    www.vrs.com.ve
  • 11/5/2009 2:58 AM In reply to

    Re: problem mixing 2d and 3d graphics

    Answer
    Reply Quote
    You are not setting the VertexDeclaration on the device before drawing the brick...

  • 11/5/2009 2:59 AM In reply to

    Re: problem mixing 2d and 3d graphics

    When you say you're using the SpriteBatch to draw your menus and stuff, do you mean you're doing it at the same time as when you're drawing your model? I mean, does your code draw the model before SpriteBatch.End() is called?  You might want to try changing the parameters you pass to SpriteBatch.Begin(), especially the second parameter, sortMode.  I was having similar problems drawing a 3d scene after text had been drawn, and what fixed it for me was changing sortMode from SpriteSortMode.Immediate (what I usually use for text on a texture, as in menus) to SpriteSortMode.BackToFront. My suggestion is that you just play around with the SpriteBatch.Begin() parameters until you find something that works for you.


    Hope this helps :) [Mod Edited: Removed colored text and white foreground.]
    "It's pure sawesome!"
    http://hr.michaelgh.com/
  • 11/5/2009 3:13 AM In reply to

    Re: problem mixing 2d and 3d graphics

    Answer
    Reply Quote
    You're not setting the vertex declaration.

    In your constructor you do this
    graphics.GraphicsDevice.VertexDeclaration = new VertexDeclaration(graphics.GraphicsDevice, VertexPositionNormalTexture.VertexElements);  

    But that's meaningless, since you're simply setting the current vertex descriptor to the new one (which you never use).  Just remove that.

    You need set the vertex declaration each time you draw, so the GPU know what type of vertices you're sending.  XNA's Model class already has them, each part has a VertexDeclaration, so add this to your loop:
    graphics.GraphicsDevice.VertexDeclaration = part.VertexDeclaration; 

  • 11/5/2009 3:15 AM In reply to

    Re: problem mixing 2d and 3d graphics

    fr3shme4t:
    You're not setting the vertex declaration.
    I believe I said that. ;-)
  • 11/5/2009 3:33 AM In reply to

    Re: problem mixing 2d and 3d graphics

    thank you fr3shme4t, i solved the issue with your solution, thank you again ...
    www.vrs.com.ve
  • 11/5/2009 3:41 AM In reply to

    Re: problem mixing 2d and 3d graphics

    kainvampire:
    thank you fr3shme4t, i solved the issue with your solution, thank you again ...
    And what am I? Chopped liver? ;-)
  • 11/5/2009 4:55 AM In reply to

    Re: problem mixing 2d and 3d graphics

    David Hunt:
    fr3shme4t:
    You're not setting the vertex declaration.
    I believe I said that. ;-)


    Heh, I totally didn't see that response...  I guess it's all about the code snippits ;-)
  • 11/5/2009 3:00 PM In reply to

    Re: problem mixing 2d and 3d graphics

    sorry David Hunt, thank you for your response, and yes you have say it too.
    www.vrs.com.ve
  • 11/5/2009 3:59 PM In reply to

    Re: problem mixing 2d and 3d graphics

    No worries and thanks for the recognition!
Page 1 of 1 (14 items) Previous Next