Sign in to follow this  
NickGravelyn

Reversing Mesh Normals

Recommended Posts

NickGravelyn    855
Is there a function or way to invert the normals of an ID3DXMesh* object? I have a box enclosing my scene and wish to invert the normals to make it act like a room.

Share this post


Link to post
Share on other sites
hplus0603    11356
Culling doesn't care about the normals, it only cares about the winding order.

Thus, you should (ideally) build the box with inverted faces in your modeler, before you export it. However, if that's not an option, then you can change the culling mode render state, to cull away CW faces (such that CCW faces get rendered).

Of course, this means that the normals will point the wrong way if you want to actually do lighting, so in that case, you ALSO need to invert the normals. Typically, you do that by locking the vertex buffer, and walking the buffer, multiplying each normal vector by -1. This is easy if you know C++ and pointers; it's harder if you want to use Managed DirectX; you pretty much have to use unsafe code.

If that's all too cumbersome (manage winding order and updating normals), you can also lock the index buffer, and swap the two first indices of each triangle -- if the triangle index list is 0,1,2, 2,3,0 (for two triangles making a quad), you can swap the first two of each triangle to make it 1,0,2 3,2,0. Then call CalculateNormals to re-calculate the new normals if you want lighting to work right.

Share this post


Link to post
Share on other sites
NickGravelyn    855
Oh, I already took care of culling by simply turning it off (a temporary fix, really). I just want to try my hand at shadows and needed a quick way to get an area to project onto so I used the D3DXCreateBox() function to get my box. I'll try the pointers and reverse the normals. I don't need to change any vertices or indices at all.

Share this post


Link to post
Share on other sites
NickGravelyn    855
So after a few minutes of trying various things with both the vertex and index buffers, I can't figure out how to do this. Can anyone explain how to manipulate the buffers?

Share this post


Link to post
Share on other sites
DonnieDarko    251
One way of doing this is using the CD3DXCrackDecl class which can read and write arbitrary elements from a vertex stream in a very flexible way. The class can be found in the UVAtlas sample directory.

Here's an example that uses it to invert all the normals in the vertex buffer:


void *pVertexData;
mesh->LockVertexBuffer(D3DLOCK_NOSYSLOCK, &pVertexData);
D3DVERTEXELEMENT9 decl[MAX_FVF_DECL_SIZE];
mesh->GetDeclaration(decl);
CD3DXCrackDecl cd;
cd.SetDeclaration(decl);
cd.SetStreamSource(0, pVertexData, 0);

for (int i=0; i<mesh->GetNumVertices(); i++)
{
D3DXVECTOR3 norm;
cd.DecodeSemantic(D3DDECLUSAGE_NORMAL, 0, i, (float*)&norm, 3);
norm *= -1.0f;
cd.EncodeSemantic(D3DDECLUSAGE_NORMAL, 0, i, (float*)&norm, 3);
}
mesh->UnlockVertexBuffer();

Share this post


Link to post
Share on other sites
BornToCode    1185
from your post you said that you are using D3DXCreateBox. So the easiest way to do what you are trying to do is.

First of all D3DXCreateBox will give you a mesh wchich has this attribute

D3DXVECTOR3 position;
D3DXVECTOR3 normal;

so basically the normal will be the second coordinate.

The next step you want to do is lock the vertexbuffer and modify each normal like so.

PBYTE p=NULL;
mesh->LockVertexBuffer(0,(LPVOID*)&p);
for(int i=0;i<mesh->GetNumVertices();i++)
{
//Skip the position
p+=sizeof(float)*3;
//Modify the Normal.
(*(float*)&*p)=(*(float*)&*p)*-1;p+=4;
(*(float*)&*p)=(*(float*)&*p)*-1;p+=4;
(*(float*)&*p)=(*(float*)&*p)*-1;p+=4;
//Go to the next vertex
p+=D3DXGetFVFVertexSize(mesh->GetFVF())-24;
}
mesh->UnlockVertexBuffer();

Share this post


Link to post
Share on other sites

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