Sign in to follow this  
Duncanf

Increasing mesh surface tesselation help

Recommended Posts

Ello all, My cel shading technique relies on high-poly models to look great, so what I'd like to be able to do when loading meshes into my engine is to increase the number of triangles in them (without changing the shape of the mesh) arbitrarily. I thought up and wrote my own simple algorithm to do it, which, unsurprisingly, isn't working. All it does is, for every face in a mesh, divide it into 4 faces by generating new vertices inbetween the actual vertices, and wind up 4 new triangles. However, when I do this, I get crashes later on when I'm asking DX to compute adjacency information and normal information (D3DX: Assertion failure! (d:\bt\130\private\multimedia\directx\dxg\d3dx9\mesh\tri3mesh.inl 1985): (pwFace[0] == iVertex1) || (pwFace[1] == iVertex1) || (pwFace[2] == iVertex1)). Here's my algorithm, if anyone has any idea what I'm doing wrong it'd be useful because I've looked at the actual mesh data produced and it all seems to make sense to me.
ID3DXMesh* newMesh = 0;
DuncEngineMesh::Vertex* vertices = 0;
WORD* indices = 0;
	
DuncEngineMesh::Vertex* newVertices = 0;
WORD* newIndices = 0;
int newIndex = 0; //index of where we write new index data
int newVertex = 0; //index of where we write new vertex data

oldMesh->LockVertexBuffer(D3DLOCK_READONLY,(void**)&vertices);
oldMesh->LockIndexBuffer(D3DLOCK_READONLY,(void**)&indices);
	
D3DXCreateMesh((oldMeshNumIndices/3)*4,oldMeshNumVertices*2,D3DXMESH_DYNAMIC,generalVertexDeclarationStruct,device,&newMesh);
newMesh->LockVertexBuffer(D3DLOCK_DISCARD,(void**)&newVertices);
newMesh->LockIndexBuffer(D3DLOCK_DISCARD,(void**)&newIndices);

//for each face
for (int i = 0; i < oldMeshNumIndices/3; i++)
{
//get vertices using face data
        Vertex zero = vertices[indices[i*3]];
	Vertex one = vertices[indices[i*3+1]];
	Vertex two = vertices[indices[i*3+2]];

	//calculate vertices in between zero, one and two
	Vertex zeroA((zero._x+one._x)/2,(zero._y+one._y)/2,(zero._z+one._z)/2);
	Vertex oneA((one._x+two._x)/2,(one._y+two._y)/2,(one._z+two._z)/2);
	Vertex twoA((two._x+zero._x)/2,(two._y+zero._y)/2,(two._z+zero._z)/2);

	//allocate them into new mesh vertex data
	newVertices[newVertex] = zero;
	newVertices[newVertex+1] = zeroA;
	newVertices[newVertex+2] = one;
	newVertices[newVertex+3] = oneA;
	newVertices[newVertex+4] = two;
	newVertices[newVertex+5] = twoA;

	//build 4 new triangles from new vertices
	newIndices[newIndex] = newVertex;
	newIndices[newIndex+1] = newVertex+1;
	newIndices[newIndex+2] = newVertex+5;

	newIndices[newIndex+3] = newVertex+1;
	newIndices[newIndex+4] = newVertex+2;
	newIndices[newIndex+5] = newVertex+3;

	newIndices[newIndex+6] = newVertex+3;
	newIndices[newIndex+7] = newVertex+4;
	newIndices[newIndex+8] = newVertex+5;

	newIndices[newIndex+9] = newVertex+5;
	newIndices[newIndex+10] = newVertex;
	newIndices[newIndex+11] = newVertex+1;

	//increment where we are in generating new data
	newVertex += 6; //we add 6 vertices to our new mesh each step
	newIndex += 12; //and 4 triangles
}

newMesh->UnlockIndexBuffer();
newMesh->UnlockVertexBuffer();

oldMesh->UnlockIndexBuffer();
oldMesh->UnlockVertexBuffer();

Thanks for any help, Duncan

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