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;
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.
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
I created this simple rectangle model in Blender that is textured (1024 x 1024). I loaded the model in XNA and it does not display on the screen. I breakpointed on the model and the debug screen says it contains zero meshes which is not true, because I opened the model in Blender and it shows the mesh. There is a total of 1 meshes. What could be wrong? Is it the code? Or is it Blender? I am new to 3D modeling. Here is the source code below:
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
paddelloader1.World = Matrix.CreateTranslation(ballpos);
paddelloader1.View = Matrix.CreateLookAt(new Vector3(0, 0, 10), new Vector3(0, 0, 0), Vector3.UnitY);
paddelloader1.Projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(45), 800f / 480f, 0.1f, 100f);
paddelloader1.Load();
base.Draw(gameTime);
}
I solved it by re-exporting the model in Blender and it fixed the problem.
I am using both primitives and sprites in an XNA project. I draw my primitives using this code (a summary, not verbatim from my project):
transmatrix = Matrix.CreateTranslation(v23(-pos)) * Matrix.CreateScale(scale, -scale, 1f) * Matrix.CreateTranslation(v23(offset));
basicEffect.World = transmatrix;
basicEffect.View = Matrix.CreateLookAt(new Vector3(0.0f, 0.0f, 1.0f), Vector3.Zero, Vector3.Up);
basicEffect.Projection = Matrix.CreateOrthographicOffCenter(0, (float)GraphicsDevice.Viewport.Width, (float)GraphicsDevice.Viewport.Height, 0, 1.0f, 1000.0f);
basicEffect.Begin();
//draw primitives blah blah
basicEffect.End();
spritebatch.Begin(SpriteBlendMode.None, SpriteSortMode.Immediate, SaveStateMode.None, transmatrix);
//draw sprites blah blah
spritebatch.end()
if I have
transmatrix = Matrix.CreateTranslation(v23(-pos)) * Matrix.CreateScale(scale, scale, 1f) * Matrix.CreateTranslation(v23(offset));
both the primitives and the sprites draw (but y is the inverse of what I want).
if I have
transmatrix = Matrix.CreateTranslation(v23(-pos)) * Matrix.CreateScale(scale, -scale, 1f) * Matrix.CreateTranslation(v23(offset));
The primitives draw correctly, but the sprites don't draw at all. What am I missing? I have tried messing around with lots of different things but nothing seems to work.
It turns it was another problem that was causing the issue. I have to scale all the sprites with negative y to get them to draw correctly as mentioned in a msdn community content "Something that is not obvious when using this form of the method to map SpriteBatch to a desired coordinate system is the effect of negative scaling on the results. If you scale by a single negative number in the X or Y axes (if, for instance, you want to flip the Y-axis to match your game coordinates) the polygon that the sprite gets drawn on gets flipped in the process and gets backface-culled. It is necessary to also scale the texture by a negative in the same direction to get the results you expect."
http://msdn.microsoft.com/en-us/library/ff433701.aspx
SpriteBatch sets up its own "camera" using its own parameters. To scale your camera, do this:
basicEffect.View = Matrix.CreateScale(1.0f, -1.0, 1.0f) * Matrix.CreateLookAt(new Vector3(0.0f, 0.0f, 1.0f), Vector3.Zero, Vector3.Up);
Or you could just create a different matrix for the spritebatch.
Alternatively, you could pass in your BasicEffect to SpriteBatch:
http://msdn.microsoft.com/en-us/library/ff433700.aspx