# 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.

## 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);

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 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 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 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 on other sites
Ok, I added calls to Validate() and Clean(), but I still get an exception on calling ComputeNormals.

		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

Bumping

##### 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 on other sites
I couldn't get D3D debug info to appear in VC# 2005 Express Edition debugger, but luckily I found DebugView when browsing forum FAQ.

##### Share on other sites
Quote:
 Original post by ToolmakerI 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 on other sites
Quote:
 Original post by intrest86Make 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 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.