Recently I have posted the same question that my FBX model was not showing correctly in XNA. I got a answer to the question and the model was displayed slightly better, but it is still not displaying correctly.
What it should look like is this:
https://docs.google.com/open?id=0B54ow8GRluDUYTBubTQ4bjBramM
But it shows as:
https://docs.google.com/open?id=0B54ow8GRluDUNXR5bmJUMVJFTUk
My drawing code is:
public void Draw(Matrix projection, Matrix view)
{
Matrix[] transforms = new Matrix[model.Bones.Count];
model.CopyAbsoluteBoneTransformsTo(transforms);
foreach (ModelMesh mesh in model.Meshes)
{
foreach (BasicEffect effect in mesh.Effects)
{
effect.EnableDefaultLighting();
effect.View = view;
effect.Projection = projection;
effect.World = Matrix.CreateRotationX(-270) *
transforms[mesh.ParentBone.Index] *
Matrix.CreateTranslation(Position);
}
mesh.Draw();
}
}
Can someone please help!
Thanks.
This is my solution:
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
#region ResetGraphic
ResetGraphic();
#endregion
#region render 3D
BeginRender3D();
//Render 3D here
#endregion
#region render 2D
//Render 2D here
#endregion
}
public void ResetGraphic()
{
GraphicsDevice.BlendState = BlendState.AlphaBlend;
GraphicsDevice.DepthStencilState = DepthStencilState.None;
GraphicsDevice.RasterizerState = RasterizerState.CullCounterClockwise;
GraphicsDevice.SamplerStates[0] = SamplerState.AnisotropicWrap;
}
public void BeginRender3D()
{
GraphicsDevice.BlendState = BlendState.Opaque;
GraphicsDevice.DepthStencilState = DepthStencilState.Default;
}
Based on your previous question where the Xna rendered image showed that you were rendering 2d and 3d items, it is important to reset some graphics states between 2d & 3d.
Specifically, after rendering the 2d stuff, add these lines:
GraphicsDevice.BlendState = BlendState.Opaque;
GraphicsDevice.DepthStencilState = DepthStencilState.Default;
These settings are necessary for 3d but they get changed when calling SpriteBatch.Begin() so it is necessary to change them back before the 3d stuff.
Here is the blog post explaining it:
http://blogs.msdn.com/b/shawnhar/archive/2010/06/18/spritebatch-and-renderstates-in-xna-game-studio-4-0.aspx
Related
I have a window form with xna included in a control, right now I have two models in one area of the screen. The thing is I need to rotate both models at the same time, I can rotate one object wich is a tank and the other is the skybox(landscape) rendered in a box.
The tank move with data provided by a serial port which is in real time, the tanks move perfectly, but I can't rotate the map.
(the ground should be moving along with the tank).
http://i61.tinypic.com/2efqrvc.jpg
I use this code to render the landscape:
private void SkyBoxRender()
{
RasterizerState originalRasterizerState = GraphicsDevice.RasterizerState;
RasterizerState rasterizerState = new RasterizerState();
rasterizerState.CullMode = CullMode.None;
GraphicsDevice.RasterizerState = rasterizerState;
aspectRatio = GraphicsDevice.Viewport.AspectRatio;
orientacion = Matrix.CreateFromYawPitchRoll(MathHelper.ToRadians(-85.0f), MathHelper.ToRadians(TiempoReal.rollPitch[1]), MathHelper.ToRadians(TiempoReal.rollPitch[0]));
cameraPositionSkyBox = distance * new Vector3((float)Math.Sin(angle), 0, (float)Math.Cos(angle));
foreach (EffectPass pass in skyBoxEffect.CurrentTechnique.Passes)
{
pass.Apply();
foreach (ModelMesh mesh in skyBox.Meshes)
{
foreach (ModelMeshPart part in mesh.MeshParts)
{
part.Effect = skyBoxEffect;
part.Effect.Parameters["World"].SetValue(Matrix.CreateScale(50.0f) * Matrix.CreateTranslation(cameraPositionSkyBox));
part.Effect.Parameters["View"].SetValue(view);
part.Effect.Parameters["Projection"].SetValue(Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(45.0f), aspectRatio, 1.0f, 10000.0f));
part.Effect.Parameters["SkyBoxTexture"].SetValue(skyBoxTexture);
part.Effect.Parameters["CameraPosition"].SetValue(cameraPositionSkyBox);
}
mesh.Draw();
}
}
GraphicsDevice.RasterizerState = originalRasterizerState;
}
I think the problem is in the line part.Effect.Parameters["World"].SetValue.....
I don't know what to put there to make the map rotate using all the axis.
I rotate the tank using this code:
orientacion = Matrix.CreateFromYawPitchRoll(MathHelper.ToRadians(-85.0f),
MathHelper.ToRadians(floatAngle1), MathHelper.ToRadians(floatAngle2));
If you look at the second line you can notice that I use angles to rotate the tank (it have to be in that way...), so any idea or suggestion?
Update:
Solved, how?
in the SkyBoxRender Method I added the following:
orientacionCamara = Matrix.CreateFromYawPitchRoll(MathHelper.ToRadians(0.0f), MathHelper.ToRadians(floatAngle1), MathHelper.ToRadians(floatAngle2));
then I archived to move the camera in the map using this:
part.Effect.Parameters["View"].SetValue(Matrix.CreateLookAt(yourCameraPosition) * orientacionCamara);
Now to move the camera at the same time with the same angles like the model I rotate the model, not the camera in this time.
private void BeginRender3D()
{
GraphicsDevice.BlendState = BlendState.Opaque;
GraphicsDevice.DepthStencilState = DepthStencilState.Default;
Matrix[] transforms = new Matrix[modelo.Bones.Count];
modelo.CopyAbsoluteBoneTransformsTo(transforms);
**orientacion** = Matrix.CreateFromYawPitchRoll(MathHelper.ToRadians(-85.0f), MathHelper.ToRadians(floatAngle1), MathHelper.ToRadians(floatAngle2);
foreach (ModelMesh mesh in modelo.Meshes)
{
foreach (BasicEffect effect in mesh.Effects)
{
effect.EnableDefaultLighting();
effect.PreferPerPixelLighting = true;
effect.World = transforms[mesh.ParentBone.Index] * **orientacion**; //* orientacion
effect.View = Matrix.CreateLookAt(camaraPosicion, Vector3.Zero, Vector3.Up);
effect.Projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(45.0f), aspectRatio, 1.0f, 10000.0f);
}
mesh.Draw();
}
fps++;
}
I hope It can help to anyone, thanks for the suggestion guys.
You could rotate the map by the orientation by multiplying the world parameter in the skyboxeffect by "orientacion". Still, you would have to make sure it rotates around the tanks position, by changing the whole line to this:
part.Effect.Parameters["World"].SetValue(Matrix.CreateScale(50.0f) * matrix.createtranslation(TankPosition) * orientacion * Matrix.CreateTranslation(cameraPositionSkyBox - TankPosition));
assuming "TankPosition" would be the position of your tank.
I'm not sure what you're trying to achieve, but if you're trying to simulate rotating a camera round the tank, I would just rotate the camera around the tank, by setting
view = matrix.CreatePerspectiveFieldOfView()
Read up on it here: http://msdn.microsoft.com/en-us/library/bb195667.aspx
I have a 3D FBX model that i want to draw it in XNA 4.0 windows game. Here is the Model in FBX viewer:
But when I run the project, it display like this
this is my drawing method:
private void DrawModel(Model model, Matrix worldMatrix, string name)
{
Matrix[] modelTransforms = new Matrix[model.Bones.Count];
model.CopyAbsoluteBoneTransformsTo(modelTransforms);
foreach (ModelMesh mesh in model.Meshes)
{
foreach (BasicEffect effect in mesh.Effects)
{
effect.EnableDefaultLighting();
effect.World = Matrix.CreateWorld(position, new Vector3(0, 0, 1), Vector3.Up) * worldMatrix;
effect.View = viewMat;
effect.Projection = projectionMat;
}
mesh.Draw();
}
}
And this is base draw method:
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.White);
graphics.GraphicsDevice.BlendState = BlendState.Opaque;
graphics.GraphicsDevice.DepthStencilState = DepthStencilState.Default;
graphics.GraphicsDevice.SamplerStates[0] = SamplerState.LinearWrap;
DrawModel(house, houseWorld, "house");
base.Draw(gameTime);
}
Thanks for your help
Most likely, the problem is with your effect.World property. You are doing something odd by creating a matrix, and then combining it with worldMatrix. What makes it even odder is that you create the set of absolute transforms (modelTransforms), but you don't use them.
Typically, it would look like this:
effect.World = modelTransforms[mesh.ParentBone.Index] * worldMatrix;
Your Matrix.CreateWorld(position, Vector3.Backward, Vector3.Up) looks like a way that you are simply adding some translation (position) to the mix. Usually, you would add position to worldMatrix before bringing it into the draw(). But, the following might work for you:
effect.World = modelTransforms[mesh.ParentBone.Index] * worldMatrix * Matrix.CreateWorld(position, Vector3.Backward, Vector3.Up);
I put the CreateWorld() last because it appears to hold translation info only and with row majore matricies, you translate last.
I am trying to import in XNA an .fbx model exported with blender.
Here is my drawing code
public void Draw()
{
Matrix[] modelTransforms = new Matrix[Model.Bones.Count];
Model.CopyAbsoluteBoneTransformsTo(modelTransforms);
foreach (ModelMesh mesh in Model.Meshes)
{
foreach (BasicEffect be in mesh.Effects)
{
be.EnableDefaultLighting();
be.World = GameCamera.World * Translation * modelTransforms[mesh.ParentBone.Index];
be.View = GameCamera.View;
be.Projection = GameCamera.Projection;
}
mesh.Draw();
}
}
The problem is that when I start the game some model parts are overlying others instead of being behind. I've tried to download other models from internet but they have the same problem.
This line:
be.World = GameCamera.World * Translation * modelTransforms[mesh.ParentBone.Index];
is usually arrainged the other way around, and the order that you multiply matrices in will make the results different. Try this:
be.World = modelTransforms[mesh.ParentBone.Index] * GameCamera.World * Translation;
I am using the background scrolling tutorial on xnadevelopment.com (modified to suit my requirement) to create a vertical scrolling loop for a game on windows phone 7.1. It seems like the background is flickering whenever the next image is drawn. Though I am using a single image for the loop, the flickering occurs even if multiple images are used. I have posted a youtube video showing the flicker that occurs at the top of the screen.
http://youtu.be/Ajdiw2zILq0
Below is the code used to create the loop:
Background class:
private List<string> _road;
private VericalBackgroundLoop _roadLoop;
private readonly Vector2 _roadSpeed = new Vector2(0, 300);
public void LoadContent(ContentManager contentManager)
{
_road = new List<string>
{
"Test\\Road_Bgnd",
"Test\\Road_Bgnd"
};
_roadLoop = new VericalBackgroundLoop();
_roadLoop.Initialize(_road, contentManager, Vector2.Zero, true);
}
public void Update(TimeSpan elapsedTime)
{
_roadLoop.Update(_roadSpeed, elapsedTime);
}
public void Draw(SpriteBatch spriteBatch)
{
_roadLoop.Draw(spriteBatch);
}
Background loop class:
private List<Sprite> _sprites;
private bool _isLoopDirectionTopToBottom;
private Vector2 _loopDirection;
public void Initialize(List<string> spriteNames, ContentManager contentManager, Vector2 loopStartPosition, bool isLoopDirectionTopToBottom)
{
_sprites = new List<Sprite>();
_isLoopDirectionTopToBottom = isLoopDirectionTopToBottom;
_loopDirection = new Vector2(0, -1);
// Build the sprite object's list
foreach (string spriteName in spriteNames)
{
Sprite sprite = new Sprite();
sprite.LoadContent(contentManager, spriteName);
_sprites.Add(sprite);
}
if (_isLoopDirectionTopToBottom)
{
// Set the initial position for the sprite objects
foreach (Sprite currentSprite in _sprites)
{
if (currentSprite == _sprites.First())
{
currentSprite.Position = loopStartPosition;
}
else
{
Sprite prevSprite = GetSpriteAtIndex(_sprites.IndexOf(currentSprite) - 1);
currentSprite.Position = new Vector2(0, prevSprite.Position.Y - prevSprite.Size.Height);
}
}
}
}
public void Update(Vector2 loopSpeed, TimeSpan elapsedTime)
{
if (_isLoopDirectionTopToBottom)
{
foreach (Sprite currentSprite in _sprites)
{
if (currentSprite == _sprites.First())
{
Sprite lastSprite = _sprites.Last();
if (currentSprite.Position.Y > (currentSprite.Size.Height))
{
currentSprite.Position.Y = lastSprite.Position.Y - lastSprite.Size.Height;
}
}
else
{
Sprite prevSprite = GetSpriteAtIndex(_sprites.IndexOf(currentSprite) - 1);
if (currentSprite.Position.Y > (currentSprite.Size.Height))
{
currentSprite.Position.Y = prevSprite.Position.Y - prevSprite.Size.Height;
}
}
// Update the sprite X position with the speed and time
currentSprite.Position -= _loopDirection * loopSpeed * (float)elapsedTime.TotalSeconds;
}
}
}
public void Draw(SpriteBatch spriteBatch)
{
foreach (Sprite sprite in _sprites)
{
sprite.Draw(spriteBatch);
}
}
private Sprite GetSpriteAtIndex(int index)
{
return _sprites[index];
}
I need help in figuring out why the flicker is occurring and why motion seems to be jerky and not smooth (it is a bit better on the device, but jerky nevertheless). IsFixedTimeStep is set to true in the game.cs class. Thank you.
EDIT : Seems like the flicker is not occuring if 3 or more images are used. This could be due to the first image not being placed back into the start position quickly enough. But am still trying to figure out whey the animation is still so jerky :(
You wouldn't be the first to report seeing flickers or stutters. Lots of posts on the App Hub forums about that. (glad you're finding luck using my tutorials/samples by the way!)
Here's an example of someone reporting what you're seeing -> http://forums.create.msdn.com/forums/t/30500.aspx
And here's the best answer I've seen to date from one of the XNA Framework developers ->
http://forums.create.msdn.com/forums/p/9934/53561.aspx#53561
Basically you've stumbled onto "a" solution, but as Shawn's post points out there's a variety of ways to fix the problem, it just depends on what's right for your game.
i just try draw a simple 3d model(many model (.fbx) tested) with basicEffect in xna 4.0 , and there is no other object like 2d spritebatchs or text or ...
but it does not shown correctly , i searched it and did some solution but no one work
like set
graphics.GraphicsDevice.BlendState = BlendState.Opaque;
graphics.GraphicsDevice.DepthStencilState = DepthStencilState.Default;
although i did not draw anything else ! and what is funny i already work with 3d model without problem !
here is my draw code and a result screenshot
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.White);
graphics.GraphicsDevice.BlendState = BlendState.Opaque;
graphics.GraphicsDevice.DepthStencilState = DepthStencilState.Default;
foreach (ModelMesh mesh in m_Model.Meshes)
{
foreach (ModelMeshPart meshPart in mesh.MeshParts)
{
BasicEffect effect = (BasicEffect)meshPart.Effect;
effect.View = Matrix.CreateLookAt(new Vector3(0, 100, 1000), Vector3.Zero, Vector3.Up);
effect.World = bones[mesh.ParentBone.Index] * (Matrix.CreateWorld(Vector3.Zero, Vector3.Right, Vector3.Up));
effect.Projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, GraphicsDevice.Viewport.AspectRatio, 0.0001f, 1000000f);
effect.EnableDefaultLighting();
}
mesh.Draw();
}
base.Draw(gameTime);
}
ty for your time
The near clip value in your projection Matrix is most likely causing this. Try setting it to 1.0f instead of 0.0001f. If that doesn't solve the problem completely, bring the far clip down to something like 10000f.
edit - noticing that your camera is over 1000 units away from your model, you can even set the near clip to 5f or 10f to gain depth read precision if needed.
Its the problem of depth buffer, you are using the spritebrite to draw something which changes your default depth buffer off.
Make it on before drawing 3d model mesh.
After calling SpriteBatch.End(), add this code:
device.DepthStencilState = DepthStencilState.Default;