C# XNA Normals, Diffuse, and Specular for a Model? - c#

I'm a beginner in XNA, trying my luck at a basic 3D game.
I have some very talented 3D modellers backing me, and while I have on issue importing the .fbx files (the models themselves) into my basic 3D universe in XNA, I have no idea how include the normal maps, diffuse, and specular that they've included with their models.
The normal, diffuse and specular are all in .tga image file format, and I don't know how I can add those to the drawing of my model.
Right now my code for drawing the 3D object is as follows:
private void DrawObject(Model spaceStation, Matrix world, Matrix view, Matrix projection)
{
foreach (ModelMesh mesh in spaceStation.Meshes)
{
foreach (BasicEffect effect in mesh.Effects)
{
effect.World = world;
effect.View = view;
effect.Projection = projection;
}
mesh.Draw();
}
}

Related

Draw 3D model at coordinates in C# xna?

i'm drawing several primitives with a camera class that supplies with view, world and projection. With these i can move the camera and see all 3 of my primitives. The problem is that i now wan't to add a 3d model in the project, but the ways i know of to draw a 3d model won't work with the camera class. I have tried using:
Matrix[] transforms = new Matrix[mymodel.Bones.Count];
mymodel.CopyAbsoluteBoneTransformsTo(transforms);
foreach (ModelMesh mesh in mymodel.Meshes)
{
foreach (BasicEffect effect in mesh.Effects)
{
effect.EnableDefaultLighting();
effect.World = transforms[mesh.ParentBone.Index] *
Matrix.CreateRotationY(0.0f)
* Matrix.CreateTranslation(modelposistion);
effect.View = Matrix.CreateLookAt(cameraPosistion, Vector3.Zero, Vector3.Up);
effect.Projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, aspectRatio, 1.0f, 10000.0f);
}
mesh.Draw();
}
But this draws the model in the center of the screen, while i want it stationary, so i can view other models in the same project.
Any help to how this can be achieved?
If I understand your problem: "as you move your camera, the model follows".
Most likely, it isn't following, you are just moving the camera without changing where the camera is "looking at". Your view matrix calls for it to look at (camera to be pointed at) Vector3.Zero no matter what position the camera is altered to. This means that if your model position does not change, and your view matrix is always looking at the same world location, then the model will not appear to change position. It may get bigger or smaller or you might see it from different angles, but it will always be in the same spot on your screen. It's because your telling the camera to always look at the same position in your world.
Changing the camera position isn't enough to freely look around your world, you must also change where the camera is looking at ( the 2nd param of the View matrix).
Also, it is best to think of the camera as having just a view and projection matrices. The world matrix should be thought of as part of (or supplied by) the model.

Odd geometry with 3D models XNA + Blender

Ok, this is hard to explain without pictures. I made a very limited model of a glock in Blender with an extruded cube making up the base and a scaled cube making up the barrel.
In Blender, It looks fine:
However, after exporting the model to .fbx and loading it into the compiler, it comes out like this:
I don't know exactly what is going on. Everything on the model is properly UV Mapped and the coordinates are correct, It just seems the translation is.. off..
Here is my drawModel code:
private void DrawModel(Model model, Matrix world, Matrix view, Matrix projection)
{
foreach (ModelMesh mesh in model.Meshes)
{
foreach (BasicEffect effect in mesh.Effects)
{
effect.EnableDefaultLighting();
effect.World = world;
effect.View = view;
effect.Projection = projection;
}
mesh.Draw();
}
}
Any pointers will be helpful!
EDIT: After Applying rotation, location, and scale, I was able to get them in the right position, but why does it look transparent?
Thank you for all the help!
As Nikola mentioned, in the later versions of Blender, they have proper XNA support.
Here's a screenshot of the settings I chose when exporting a model:
Why this happens:
Your Depth Buffer is not enabled, so when your GPU draws the barrel first, then the stock/handle, the handle is drawn on top of the barrel, even though some parts of it are supposed to be invisible because they would be hidden by the barrel.
How to fix:
Enable Depth Buffer as other answer suggests. And/Or order meshes in your model based on distance from camera, and draw tehm in order from the nearset to the farthest. This may not seem usefull now, but when you start working with transparent objects, you will see why this is a good thing to learn.
Enable depth buffer:
GraphicsDevice.DepthStencilState = DepthStencilStates.Default;
And to Draw a model in Xna you can follow this tutorial, that shows how the bone transforms have to be applied to get the meshes in right position.

Mesh.Effects input XNA

I didnt quite understand whats is the effect.World and effect.View etc. and why we put the matricies in them?
foreach (ModelMesh mesh in model1.Meshes)
{
foreach (BasicEffect effect in mesh.Effects)
{
effect.World = Matrix.CreateWorld(Vector3.Zero, Vector3.Forward, Vector3.Up);
effect.View = Matrix.CreateLookAt(Vector3.Zero, Vector3.Zero, Vector3.Up);
}
}
effect.World is not a matrix representing the world. It is a matrix representing a 3d object's (mesh, model) position and orientation relative to the 3d game world. Each object will have a different effect.World matrix if they are positioned differently &/or pointed differently.
effect.View is a matrix that represents (in an inverted form) the position & orientation of the camera relative to that same 3d game world. Most of the time, there is only one camera, but there can be more (say, a rear view mirror will have it's own view matrix as opposed to the main screen showing the view out the windshield of a car racing game).
a model's vertices are hard valued to model local space.
Then the effect.World transforms them to game world space.
then the effect.View transforms them to camera space.
Then the effect.Projection transforms them to 2d screen space and 'volia', your pixel shader knows where to draw what.
From MSDN;
BasicEffect.World
Gets or sets the world matrix. Use this matrix to change the position
of the model, using world coordinates.
BasicEffect.View
Gets or sets the view matrix. Use this matrix to change the position
and direction of the camera.
I think bold lines explain what is exactly their difference. Also I found some helpful articles;
How to: Use BasicEffect
Does every Entity in an XNA game need it's own BasicEffect instance?
Understanding Half-Pixel and Half-Texel Offsets
http://blogs.msdn.com/b/shawnhar/archive/2010/04/05/spritebatch-and-custom-shaders-in-xna-game-studio-4-0.aspx
http://msdn.microsoft.com/en-us/library/bb219690(VS.85).aspx

What is the best way to configure the position of a model / texture in xna project

I wanted to know if my method used below is the correct way to determine the position of my model before drawing on the screen.
Because when I want to create a floor duplicating my model. I find myself faced with the "Z-fighting" problem ^ ^.
thank you very much
Code sample to st position on my model before drawing :
model_Position.X = (float) 1.0;
model_Position.Z = (float) 3.0;
model_Position.Y = (float) 5.0;
// Draw the model. A model can have multiple meshes, so loop.
foreach (ModelMesh mesh in model_ground_land1.Meshes)
{
// This is where the mesh orientation is set, as well
// as our camera and projection.
foreach (BasicEffect effect in mesh.Effects)
{
effect.EnableDefaultLighting();
effect.World = transforms[mesh.ParentBone.Index] *
Matrix.CreateRotationY(model_Rotation) * Matrix.CreateTranslation(model_Position);
effect.View = View;
effect.Projection = Projection;
}
// Draw the mesh, using the effects set above.
mesh.Draw();
}
As far as I can see, your method is correct for positioning the model. What comes to the Z fighting problem, it happens when two 3D faces are drawn in the same plane overlapping each other. As you say that you "duplicate your model" it sounds like this is the problem, not the model positioning itself. To resolve the fighting, you can set some nonzero value to GraphicsDevice.RasterizerState.DepthBias before drawing the second copy of the model. From the documentation:
"Polygons with a high z-bias value appear in front of polygons with a
low value, without requiring sorting for drawing order. For example,
polygons with a value of 1 appear in front of polygons with a value of
0."

XNA not loading model textures automatically

I have a very n00b like question here .. I have this small XNA game in which I tried importing a 3D model already made and provided by Microsoft. The problem is XNA isn't loading the textures associated with this model, even though it makes sure that the associated with the model are present in the project directory (compiler gives an error if it can't find these textures), .. So basically I just see a big clay model :P ..
This picture shows the result I'm getting:
This is what it should be like:
Is there anything which I'm missing here ? Shouldn't XNA automatically apply all textures associated with a specific model ?
When you are rendering your dude.fbx model, make sure that in the loop for drawing the model that you have something like the following:
foreach (ModelMesh mesh in model.Meshes)
{
foreach (BasicEffect effect in mesh.Effects)
{
effect.EnableDefaultLighting();
}
}
This is off the top of my head, so the method calls might not be correct.
Xna does not automatically load the textures for the model.
The exception you're getting when the texture is not present is thrown by the Xna's resource compiler and is not related to actually importing anything.
The way you would solve this is by loading the texture manually in LoadContent() or anywhere else where you have a ContentManager using:
modelTexture = Content.Load<Texture2D>("mytexture");
and then add the texture either as a parameter if you have a custom effect or put it in the Texture property on your BasicEffect instance when you draw it:
foreach (ModelMesh mesh in model.Meshes)
{
foreach (BasicEffect eff in mesh.Effects)
{
eff.TextureEnabled = true;
eff.Texture = modelTexture;
}
mesh.Draw();
}
(drawing should obviously not be done in LoadContent() though)
Notice the eff.TextureEnabled = true; which is required to activate textures when using BasicEffect.

Categories

Resources