Sign in to follow this  

D3DXMesh.ComputeNormals() causes exception...

This topic is 4491 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm currently loading a few converted models using the D3DXMesh(Mind you, I'm using C# and Managed DirectX, but it's just a layer over the C++ libraries). When I load the X file in the Microsoft X viewer, it works fine, however, when I load it myself and call ComputeNormals() on the model, I get this as result: 18446744071704021100 : D3DERR_INVALIDCALL I looked it up in the error viewer, and well, not much help there. This is my code, but I can't see what's wrong with it:
			ExtendedMaterial[] mtrls = null;

			mesh = Mesh.FromFile(@"c:\klingon.x", MeshFlags.Managed, engine.Device, out adj, out mtrls);

			materials = new Material[mtrls.Length];
			textures = new Texture[mtrls.Length];

			for (int i = 0; i < mtrls.Length; ++i)
			{
				materials[i] = mtrls[i].Material3D;
				textures[i] = null;
			}

			if ((mesh.VertexFormat & VertexFormats.Normal) != VertexFormats.Normal)
			{
				Mesh tmp = mesh.Clone(mesh.Options.Value, mesh.VertexFormat | VertexFormats.Normal, engine.Device);
				tmp.ComputeNormals(adj);

				mesh.Dispose();
				mesh = tmp;
			}

I tried ComputeNormals with and without adjacency information, but in both cases, it just throws an exception. For those interested in the model, you can find it here. It's both the original PRJ model and the converted X model(Exported using the 3ds max X exporter). If I don't compute the normal information, the ship shows up completely white in game, which seems a bit weird to me... Toolmaker

Share this post


Link to post
Share on other sites
The compute normals function uses the index buffer (or at least it did with DX8).
Make sure you don't have any index out of range.

Share this post


Link to post
Share on other sites
I discovered it works without computing the normals. I then experimented with scaling the ship up and down, and discovered it goes white when I scale it down too much.

So, I removed the scaling, and it showed up fine, but still looked WEIRD. Like below:


I added 1 light to the scene, like this:

dev.Lights[0].Type = LightType.Point;
dev.Lights[0].Position = new Vector3(0.0f, 30.0f, 0.0f);
dev.Lights[0].Diffuse = Color.White;
dev.Lights[0].Ambient = Color.White;
dev.Lights[0].Range = 10000.0f;
dev.Lights[0].Attenuation0 = 0.1f;
dev.Lights[0].Update();
dev.Lights[0].Enabled = true;


I removed the light and set dev.Render.Ambient = Color.White, but my entire scene goes black when I do that. And the higher I move my light(But increasing the 30 to 500), the more white the ship ends up.

I have NO IDEA what I did wrong, or how to solve this...

Toolmaker

Share this post


Link to post
Share on other sites
when you tried to call ComputeNormals and had the function throw up an exception, what did the debug spew say? Whenever a DirectX function fails, it always prints the reason why it failed to the debug spew. Make sure you're using the Debug Runtime when developing DirectX applications. If you're not sure what I'm talking about, see the Forum FAQ.

From the screenshot you posted, it looks like there is something wrong with the mesh. Try calling ValidMesh and CleanMesh on the model to spruce things up a bit.

neneboricua

Share this post


Link to post
Share on other sites
Ok, I added calls to Validate() and Clean(), but I still get an exception on calling ComputeNormals.

My new Mesh loading function now looks like this:

public static Mesh LoadMesh(string file, Engine engine, out Material[] materials, out Texture[] textures)
{
GraphicsStream adj = null;
ExtendedMaterial[] mtrls = null;
Mesh mesh = null;

mesh = Mesh.FromFile(file, MeshFlags.Managed, engine.Device, out adj, out mtrls);

materials = new Material[mtrls.Length];
textures = new Texture[mtrls.Length];
for (int i = 0; i < mtrls.Length; ++i)
{
materials[i] = mtrls[i].Material3D;

if (mtrls[i].TextureFilename != null && mtrls[i].TextureFilename != string.Empty)
{
try
{
textures[i] = TextureLoader.FromFile(engine.Device, mtrls[i].TextureFilename);
}
catch (Exception e)
{
Console.WriteLine(string.Format("Failed to load {0}", mtrls[i].TextureFilename));
textures[i] = null;
}
}
}

// Validate our mesh
string errorsAndWarnings = "";
mesh.Validate(adj, out errorsAndWarnings);
System.Console.WriteLine(errorsAndWarnings);

// Let's clean our mesh a bit
mesh = Mesh.Clean(CleanType.Simplification | CleanType.Optimization | CleanType.BackFacing, mesh, adj, adj, out errorsAndWarnings);
System.Console.WriteLine(errorsAndWarnings);

// Add in normal data to our model
if ((mesh.VertexFormat & VertexFormats.Normal) != VertexFormats.Normal)
{
Mesh tmpMesh = mesh.Clone(mesh.Options.Value, mesh.VertexFormat | VertexFormats.Normal, engine.Device);
tmpMesh.ComputeNormals();

mesh.Dispose();
mesh = tmpMesh;
}

return mesh;
}




No idea what's wrong...

EDIT: I haven't found a way to actually obtain the Debug output from the debug runtime. I have set the debug output to maximum and I use the debug runtimes, but MSVS doesn't show any debug output. Perhaps this has to do with Managed DirectX.

Is there a way to enable the debug output under C#?

Toolmaker

Share this post


Link to post
Share on other sites
Make sure you have both Direct3D Debugging and "Enable Unmanaged Debugging" on. The downside of this is that it brings your programs to a screeching halt, in my experience the unmanaged debugging slows down the game to the point that it isn't acceptable for normal development work, only when you know there is an error to catch.

Share this post


Link to post
Share on other sites
Quote:
Original post by Toolmaker
I discovered it works without computing the normals. I then experimented with scaling the ship up and down, and discovered it goes white when I scale it down too much.

The normals get scaled as well and won't be normalized anymore. That's the problem. Set NormalizeNormals in the renderstate to true and the effect should disappear.

Regards,
Andre

Share this post


Link to post
Share on other sites
Quote:
Original post by intrest86
Make sure you have both Direct3D Debugging and "Enable Unmanaged Debugging" on. The downside of this is that it brings your programs to a screeching halt, in my experience the unmanaged debugging slows down the game to the point that it isn't acceptable for normal development work, only when you know there is an error to catch.


It starts up EXTREMELY slow, but it shows the debug output after all. Problem is, it throws an exception on the ComputeNormals, but doesn't output any error.

Thanks for the info on how to get output info, rating++.

Share this post


Link to post
Share on other sites

This topic is 4491 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this