Hi,
I am writing a C++ program to convert an .obj (WaveFront) file to .x so that I can use it elsewhere. I can extract the necessary information and render it. The problem is that it is so huge and I want to reduce the number of vertices and faces to get better frame rate. For that, I have to create a progressive mesh, right? So, I try to do that and I get an error. Neither will the clean or validate functions work either. I tried to weld it and optimize it in place, but it still gives me an error. If it is not a valid mesh, then why does it render? See the code below and notice that I have the LPD3DXBUFFER variable remarked out. I can't use that despite what msdn.microsoft.com says or I get an unhandled exception. I have to keep the third parameter NULL so now I can't retrieve any information about why it failed. Please see my code below and tell me if I'm doing anything wrong. Also, please note that even when I set MAX_VERTICES to a lower number, it still fails. Thanks in advance!
if (FAILED(hr = D3DXCreateMeshFVF( numInd, numVert,
D3DXMESH_MANAGED | D3DXMESH_32BIT, D3DFVF_CUSTOMVERTEX,
m_pd3dDevice, &m_pD3DXMesh)))
MessageBox("Failed to create mesh!", "Failure...", MB_OK);
if (hr == D3D_OK)
{
MessageBox("Mesh created!", "Success...", MB_OK);
_ultoa(m_pD3DXMesh->GetNumFaces(), c, 10);
MessageBox((LPCTSTR)c,"Number of Indices...");
_ultoa(m_pD3DXMesh->GetNumVertices(), c, 10);
MessageBox((LPCTSTR)c,"Number of vertices...");
}
numVert = 0;
if (SUCCEEDED(m_pD3DXMesh->LockVertexBuffer(D3DLOCK_TYPE, (VOID **) &vb)))
{
// Loop through the object file.
while(std::getline(sLoadVert, strMatLine) && numVert < MAX_VERTICES)
{
if (strMatLine.find_first_of("v") == 0) // If the first letter is "v", this line contains a vertex.
{
Tokenize(strMatLine, vStr);
vb->x = (float)strtod(vStr.at(1).c_str(), NULL);
vb->y = (float)strtod(vStr.at(2).c_str(), NULL);
vb->z = (float)strtod(vStr.at(3).c_str(), NULL);
vb->color = 0xc0c0c0c0;
vStr.clear();
vb++;
numVert++;
}
}
m_pD3DXMesh->UnlockVertexBuffer();
}
sLoadVert.close();
std::ifstream sLoadInd("C:/Documents and Settings/Tony E. Shelleman/My Documents/T Shelleman 3D/TT-Obj.obj");
if (SUCCEEDED(m_pD3DXMesh->LockIndexBuffer(D3DLOCK_TYPE, (void**) &ib)))
{
// Loop through the object file.
while(std::getline(sLoadInd, strMatLine))
{
if (strMatLine.find_first_of("f") == 0) // If the first letter is "f", this line contains an indice.
{
Tokenize(strMatLine, vStr);
indTemp1 = (DWORD)strtoul(vStr.at(1).c_str(), NULL, 0) - 1;
indTemp2 = (DWORD)strtoul(vStr.at(2).c_str(), NULL, 0) - 1;
indTemp3 = (DWORD)strtoul(vStr.at(3).c_str(), NULL, 0) - 1;
if ((indTemp1 < MAX_VERTICES) && (indTemp2 < MAX_VERTICES) && (indTemp3 < MAX_VERTICES))
{
*ib = indTemp1;
ib++;
*ib = indTemp2;
ib++;
*ib = indTemp3;
ib++;
}
vStr.clear();
}
}
m_pD3DXMesh->UnlockIndexBuffer();
}
sLoadInd.close();
if (SUCCEEDED(m_pD3DXMesh->LockAttributeBuffer(D3DLOCK_TYPE, &ab)))
{
for (int i = 0; i < m_pD3DXMesh->GetNumVertices(); i++)
{
*ab = 0x00000000;
ab++;
}
m_pD3DXMesh->UnlockAttributeBuffer();
}
D3DXComputeNormals(m_pD3DXMesh, NULL);
DWORD* dwAdj = new DWORD[m_pD3DXMesh->GetNumFaces() * 3];
MessageBox("Generating adjacency...", "Progress...");
m_pD3DXMesh->GenerateAdjacency(0.0f, (DWORD*)dwAdj);
D3DXWELDEPSILONS epsilons;
epsilons.Normal = 0.001f;
epsilons.Position = 0.1f;
MessageBox("Welding vertices...", "Progress...");
if (FAILED(hr = D3DXWeldVertices(m_pD3DXMesh, D3DXWELDEPSILONS_WELDPARTIALMATCHES,
&epsilons, (DWORD*) dwAdj, (DWORD*) dwAdj, 0, 0)))
{
MessageBox("Failed to weld!", "Oh, snap!");
}
MessageBox("Optimizing in place...", "Progress...");
if (FAILED(hr = m_pD3DXMesh->OptimizeInplace(D3DXMESHOPT_ATTRSORT | D3DXMESHOPT_COMPACT | D3DXMESHOPT_VERTEXCACHE,
(DWORD*) dwAdj, 0, 0, 0)))
{
MessageBox("Failed to optimize in place!", "Oh, snap!");
}
// LPD3DXBUFFER *ew;
if (FAILED(hr = D3DXValidMesh(m_pD3DXMesh, (DWORD*)dwAdj, NULL)))
{
if (hr = D3DXERR_INVALIDMESH)
{
MessageBox("Invalid mesh!", "Oh, snap!");
}
if (hr = D3DERR_INVALIDCALL)
{
MessageBox("Invalid call!", "Oh, snap!");
}
if (hr = E_OUTOFMEMORY)
{
MessageBox("Out of memory!", "Oh, snap!");
}
MessageBox("Mesh not valid!", "Oh, snap!");
}
if (FAILED(hr = D3DXCleanMesh(m_pD3DXMesh, (DWORD*)dwAdj, &m_pD3DXMeshTemp,
(DWORD*)dwAdj, NULL)))
{
MessageBox("Failed to clean mesh!", "Oh, snap!");
}
hr = D3DXGeneratePMesh(m_pD3DXMesh, (DWORD*)dwAdj,
NULL, NULL, 3, D3DXMESHSIMP_VERTEX, &m_pD3DXPMesh);
if (FAILED(hr))
{
MessageBox("Failed to create progressive mesh!", "Oh, snap!");
}