00001 #include <iostream>
00002 #include <fstream>
00003 #include <iomanip>
00004 #include <algorithm>
00005 #include <cstdio>
00006 #include <cassert>
00007 #include <cstring>
00008 #include <d3dx9.h>
00009
00010 using namespace std;
00011
00012 static IDirect3D9* g_d3d = NULL;
00013 static IDirect3DDevice9* g_d3dDev = NULL;
00014 static HWND g_mainWindow = NULL;
00015
00016 char* D3DErrorString(HRESULT);
00017 void ShowD3DErrorMessage(char* info, HRESULT hr);
00018
00019
00020 struct VertexAttribute
00021 {
00022 enum {
00023 Position = 0,
00024 Color0 = 1,
00025 Color1 = 2,
00026 Normal = 3,
00027 Tangent = 4,
00028 Texture0 = 5,
00029 Texture1 = 6,
00030 Texture2 = 7,
00031 Texture3 = 8,
00032 MaxAttribute = 9,
00033 InvalidAttribute = -1,
00034 };
00035
00036 enum Format
00037 {
00038 Float1 = 0,
00039 Float2 = 1,
00040 Float3 = 2,
00041 Float4 = 3,
00042 UByte4 = 4,
00043 InvalidFormat = -1,
00044 };
00045
00046 unsigned int offset;
00047 Format format;
00048 };
00049
00050 char* AttribFormatNames[] =
00051 { "f1", "f2", "f3", "f4", "ub4" };
00052
00053 char* AttribNames[] = {
00054 "position",
00055 "color0",
00056 "color1",
00057 "normal",
00058 "tangent",
00059 "texcoord0",
00060 "texcoord1",
00061 "texcoord2",
00062 "texcoord3"
00063 };
00064
00065
00066 bool operator==(const D3DCOLORVALUE& c0, const D3DCOLORVALUE& c1)
00067 {
00068 return (c0.r == c1.r && c0.g == c1.g && c0.b == c1.b && c0.a == c1.a);
00069 }
00070
00071
00072 bool operator<(const D3DCOLORVALUE& c0, const D3DCOLORVALUE& c1)
00073 {
00074 if (c0.r == c1.r)
00075 {
00076 if (c0.g == c1.g)
00077 {
00078 if (c0.b == c1.b)
00079 return c0.a < c1.a;
00080 else
00081 return c0.b < c1.b;
00082 }
00083 else
00084 {
00085 return c0.g < c1.g;
00086 }
00087 }
00088 else
00089 {
00090 return c0.r < c1.r;
00091 }
00092 }
00093
00094
00095 bool operator==(const D3DXMATERIAL& mat0, const D3DXMATERIAL& mat1)
00096 {
00097
00098
00099 bool sameTex;
00100 if (mat0.pTextureFilename == NULL)
00101 {
00102 sameTex = (mat1.pTextureFilename == NULL);
00103 }
00104 else if (mat1.pTextureFilename == NULL)
00105 {
00106 sameTex = false;
00107 }
00108 else
00109 {
00110 sameTex = (strcmp(mat0.pTextureFilename, mat1.pTextureFilename) == 0);
00111 }
00112
00113 return (mat0.MatD3D.Diffuse == mat1.MatD3D.Diffuse &&
00114 mat0.MatD3D.Ambient == mat1.MatD3D.Ambient &&
00115 mat0.MatD3D.Specular == mat1.MatD3D.Specular &&
00116 mat0.MatD3D.Emissive == mat1.MatD3D.Emissive &&
00117 mat0.MatD3D.Power == mat1.MatD3D.Power &&
00118 sameTex);
00119 }
00120
00121
00122 ostream& operator<<(ostream& o, const D3DCOLORVALUE& c)
00123 {
00124 return (o << c.r << ' ' << c.g << ' ' << c.b);
00125 }
00126
00127
00128 static void render()
00129 {
00130 g_d3dDev->Clear(0, NULL,
00131 D3DCLEAR_TARGET,
00132 D3DCOLOR_ARGB(255, 0, 0, 192),
00133 0.0f,
00134 0);
00135 }
00136
00137
00138 template<class T> int checkForFan(DWORD nTris, T* indices)
00139 {
00140
00141
00142 if (nTris % 2 == 1 || nTris <= 2)
00143 return -1;
00144
00145 DWORD i;
00146 T anchor = indices[0];
00147 bool isFan = true;
00148 for (i = 1; i < nTris / 2 && isFan; i++)
00149 {
00150 if (indices[i * 2] != anchor)
00151 isFan = false;
00152 }
00153
00154 if (isFan)
00155 return 0;
00156
00157 isFan = true;
00158 anchor = indices[1];
00159 for (i = 1; i < nTris / 2 && isFan; i++)
00160 {
00161 if (indices[i * 2 + 1] != anchor)
00162 isFan = false;
00163 }
00164
00165 if (isFan)
00166 cout << "fan: nTris=" << nTris << ", anchor=" << anchor << '\n';
00167
00168 return isFan ? 1 : -1;
00169 }
00170
00171
00172 template<class T> int DumpTriStrip(DWORD nTris,
00173 T* indices,
00174 int materialIndex,
00175 ostream& meshfile)
00176 {
00177 meshfile << "tristrip ";
00178 meshfile << materialIndex << ' ' << (nTris + 2) << '\n';
00179
00180 DWORD indexCount = nTris + 2;
00181
00182 for (DWORD j = 0; j < indexCount; j++)
00183 {
00184 meshfile << indices[j] << ' ';
00185 if (j == indexCount - 1 || j % 12 == 11)
00186 meshfile << '\n';
00187 }
00188 }
00189
00190
00191
00192
00193
00194
00195
00196 template<class T> void DumpTriStripAsFan(DWORD nTris,
00197 T* indices,
00198 int materialIndex,
00199 DWORD anchorOffset,
00200 ostream& meshfile)
00201 {
00202 meshfile << "trifan ";
00203 meshfile << materialIndex << ' ' << (nTris / 2 + 3) << '\n';
00204
00205 DWORD indexCount = nTris + 2;
00206
00207 T anchor = indices[anchorOffset];
00208 meshfile << anchor << ' ';
00209
00210 if (anchorOffset == 1)
00211 {
00212 for (int j = (int) indexCount - 1; j >= 0; j--)
00213 {
00214 if (indices[j] != anchor)
00215 meshfile << indices[j] << ' ';
00216 if (j == 0 || j % 12 == 11)
00217 meshfile << '\n';
00218 }
00219 }
00220 else if (anchorOffset == 0)
00221 {
00222
00223
00224 for (int j = 1; j < (int) indexCount; j++)
00225 {
00226 if (indices[j] != anchor)
00227 meshfile << indices[j] << ' ';
00228 if (j == indexCount - 1 || j % 12 == 11)
00229 meshfile << '\n';
00230 }
00231 }
00232 }
00233
00234
00235 bool StripifyMeshSubset(ID3DXMesh* mesh,
00236 DWORD attribId,
00237 ostream& meshfile)
00238 {
00239
00240
00241
00242
00243 IDirect3DIndexBuffer9* indices = NULL;
00244 DWORD numIndices = 0;
00245 ID3DXBuffer* strips = NULL;
00246 DWORD numStrips = 0;
00247 HRESULT hr;
00248 hr = D3DXConvertMeshSubsetToStrips(mesh,
00249 attribId,
00250 0,
00251 &indices,
00252 &numIndices,
00253 &strips,
00254 &numStrips);
00255 if (FAILED(hr))
00256 {
00257 cout << "Stripify failed\n";
00258 return false;
00259 }
00260
00261 cout << "Converted to " << numStrips << " strips\n";
00262 cout << "Strip buffer size: " << strips->GetBufferSize() << '\n';
00263 if (numStrips != strips->GetBufferSize() / 4)
00264 {
00265 cout << "Strip count is incorrect!\n";
00266 return false;
00267 }
00268
00269 bool index32 = false;
00270 {
00271 D3DINDEXBUFFER_DESC desc;
00272 indices->GetDesc(&desc);
00273 if (desc.Format == D3DFMT_INDEX32)
00274 {
00275 index32 = true;
00276 }
00277 else if (desc.Format == D3DFMT_INDEX16)
00278 {
00279 index32 = false;
00280 }
00281 else
00282 {
00283 cout << "Bad index format. Strange.\n";
00284 return false;
00285 }
00286 }
00287
00288 void* indexData = NULL;
00289 hr = indices->Lock(0, 0, &indexData, D3DLOCK_READONLY);
00290 if (FAILED(hr))
00291 {
00292 cout << "Failed to lock index buffer: " << D3DErrorString(hr) << '\n';
00293 return false;
00294 }
00295
00296 {
00297 DWORD* stripLengths = reinterpret_cast<DWORD*>(strips->GetBufferPointer());
00298 int k = 0;
00299 for (int i = 0; i < numStrips; i++)
00300 {
00301 if (stripLengths[i] == 0)
00302 {
00303 cout << "Bad triangle strip (length == 0) in mesh!\n";
00304 return false;
00305 }
00306
00307 if (index32)
00308 {
00309 DWORD* indices = reinterpret_cast<DWORD*>(indexData) + k;
00310 int fanStart = checkForFan(stripLengths[i], indices);
00311 if (fanStart != 1)
00312 {
00313 DumpTriStrip(stripLengths[i], indices, (int) attribId,
00314 meshfile);
00315 }
00316 else
00317 {
00318 DumpTriStripAsFan(stripLengths[i], indices, (int) attribId,
00319 fanStart, meshfile);
00320 }
00321 }
00322 else
00323 {
00324 WORD* indices = reinterpret_cast<WORD*>(indexData) + k;
00325 int fanStart = checkForFan(stripLengths[i], indices);
00326 if (fanStart != 1)
00327 {
00328 DumpTriStrip(stripLengths[i], indices, (int) attribId,
00329 meshfile);
00330 }
00331 else
00332 {
00333 DumpTriStripAsFan(stripLengths[i], indices, (int) attribId,
00334 fanStart, meshfile);
00335 }
00336 }
00337
00338 k += stripLengths[i] + 2;
00339 }
00340
00341 cout << "k=" << k << ", numIndices=" << numIndices;
00342 if (index32)
00343 cout << ", 32-bit indices\n";
00344 else
00345 cout << ", 16-bit indices\n";
00346 }
00347
00348 return true;
00349 }
00350
00351
00352 void DumpVertexDescription(VertexAttribute vertexMap[],
00353 ostream& meshfile)
00354 {
00355 meshfile << "vertexdesc\n";
00356 for (int i = 0; i < VertexAttribute::MaxAttribute; i++)
00357 {
00358 if (vertexMap[i].format != VertexAttribute::InvalidFormat)
00359 {
00360 meshfile << AttribNames[i] << " " <<
00361 AttribFormatNames[vertexMap[i].format] << " " << '\n';
00362 }
00363 }
00364 meshfile << "end_vertexdesc\n\n";
00365 }
00366
00367
00368 bool DumpMeshVertices(ID3DXMesh* mesh,
00369 VertexAttribute vertexMap[],
00370 DWORD stride,
00371 ostream& meshfile)
00372 {
00373 IDirect3DVertexBuffer9* vb = NULL;
00374 HRESULT hr = mesh->GetVertexBuffer(&vb);
00375 if (FAILED(hr))
00376 {
00377 ShowD3DErrorMessage("Getting vertex buffer", hr);
00378 return false;
00379 }
00380
00381 char* vertexData = NULL;
00382 hr = vb->Lock(0, 0, reinterpret_cast<void**>(&vertexData), D3DLOCK_READONLY);
00383 if (FAILED(hr) || vertexData == NULL)
00384 {
00385 ShowD3DErrorMessage("Locking vertex buffer", hr);
00386 return false;
00387 }
00388
00389 DWORD numVertices = mesh->GetNumVertices();
00390
00391 meshfile << "vertices " << numVertices << '\n';
00392
00393 for (DWORD i = 0; i < numVertices; i++)
00394 {
00395 for (int attr = 0; attr < VertexAttribute::MaxAttribute; attr++)
00396 {
00397 if (vertexMap[attr].format != VertexAttribute::InvalidFormat)
00398 {
00399 char* chardata = vertexData + i * stride + vertexMap[attr].offset;
00400 float* floatdata = reinterpret_cast<float*>(chardata);
00401
00402 switch (vertexMap[attr].format)
00403 {
00404 case VertexAttribute::Float1:
00405 meshfile << floatdata[0] << ' ';
00406 break;
00407 case VertexAttribute::Float2:
00408 meshfile << floatdata[0] << ' ' << floatdata[1] << ' ';
00409 break;
00410 case VertexAttribute::Float3:
00411 meshfile << floatdata[0] << ' ' << floatdata[1] << ' ';
00412 meshfile << floatdata[2] << ' ';
00413 break;
00414 case VertexAttribute::Float4:
00415 meshfile << floatdata[0] << ' ' << floatdata[1] << ' ';
00416 meshfile << floatdata[2] << ' ' << floatdata[3];
00417 break;
00418 case VertexAttribute::UByte4:
00419 meshfile << (unsigned int) chardata[0] << ' ' <<
00420 (unsigned int) chardata[1] << ' ' <<
00421 (unsigned int) chardata[2] << ' ' <<
00422 (unsigned int) chardata[3] << ' ';
00423 break;
00424 default:
00425 break;
00426 }
00427 }
00428 }
00429
00430 meshfile << '\n';
00431 }
00432
00433 vb->Unlock();
00434
00435 meshfile << '\n';
00436
00437 return true;
00438 }
00439
00440
00441 bool CreateVertexAttributeMap(D3DVERTEXELEMENT9 declElements[],
00442 VertexAttribute vertexMap[])
00443 {
00444 int i = 0;
00445 for (i = 0; i < VertexAttribute::MaxAttribute; i++)
00446 {
00447 vertexMap[i].offset = 0;
00448 vertexMap[i].format = VertexAttribute::InvalidFormat;
00449 }
00450
00451 unsigned int outputOffset = 0;
00452 for (i = 0; i < MAX_FVF_DECL_SIZE && declElements[i].Stream != 255; i++)
00453 {
00454 int attr = VertexAttribute::InvalidAttribute;
00455 VertexAttribute::Format format = VertexAttribute::InvalidFormat;
00456 unsigned int formatSize = 0;
00457
00458 if (declElements[i].Stream == 0)
00459 {
00460 switch (declElements[i].Type)
00461 {
00462 case D3DDECLTYPE_FLOAT1:
00463 format = VertexAttribute::Float1;
00464 formatSize = 4;
00465 break;
00466 case D3DDECLTYPE_FLOAT2:
00467 format = VertexAttribute::Float2;
00468 formatSize = 8;
00469 break;
00470 case D3DDECLTYPE_FLOAT3:
00471 format = VertexAttribute::Float3;
00472 formatSize = 12;
00473 break;
00474 case D3DDECLTYPE_FLOAT4:
00475 format = VertexAttribute::Float4;
00476 formatSize = 16;
00477 break;
00478 case D3DDECLTYPE_UBYTE4:
00479 case D3DDECLTYPE_UBYTE4N:
00480 format = VertexAttribute::UByte4;
00481 formatSize = 4;
00482 break;
00483 }
00484
00485 switch (declElements[i].Usage)
00486 {
00487 case D3DDECLUSAGE_POSITION:
00488 if (declElements[i].UsageIndex == 0)
00489 {
00490 attr = VertexAttribute::Position;
00491 }
00492 break;
00493 case D3DDECLUSAGE_NORMAL:
00494 if (declElements[i].UsageIndex == 0)
00495 {
00496 attr = VertexAttribute::Normal;
00497 }
00498 break;
00499 case D3DDECLUSAGE_TEXCOORD:
00500 if (declElements[i].UsageIndex < 4)
00501 {
00502 if (declElements[i].UsageIndex == 0)
00503 attr = VertexAttribute::Texture0;
00504 else if (declElements[i].UsageIndex == 1)
00505 attr = VertexAttribute::Texture1;
00506 else if (declElements[i].UsageIndex == 2)
00507 attr = VertexAttribute::Texture2;
00508 else
00509 attr = VertexAttribute::Texture3;
00510 }
00511 break;
00512 case D3DDECLUSAGE_COLOR:
00513 if (declElements[i].UsageIndex < 2)
00514 {
00515 if (declElements[i].UsageIndex == 0)
00516 attr = VertexAttribute::Color0;
00517 else
00518 attr = VertexAttribute::Color1;
00519 }
00520 break;
00521 case D3DDECLUSAGE_TANGENT:
00522 if (declElements[i].UsageIndex == 0)
00523 {
00524 attr = VertexAttribute::Tangent;
00525 }
00526 break;
00527 }
00528
00529 if (attr != VertexAttribute::InvalidAttribute)
00530 {
00531 vertexMap[attr].offset = declElements[i].Offset;
00532 vertexMap[attr].format = format;
00533 }
00534 }
00535 }
00536
00537 return true;
00538 }
00539
00540
00541 static LRESULT CALLBACK MainWindowProc(HWND hWnd,
00542 UINT uMsg,
00543 WPARAM wParam,
00544 LPARAM lParam)
00545 {
00546 switch (uMsg)
00547 {
00548 case WM_CREATE:
00549 break;
00550
00551 case WM_DESTROY:
00552 PostQuitMessage(0);
00553 break;
00554
00555 case WM_PAINT:
00556 if (g_d3dDev != NULL)
00557 {
00558
00559
00560 }
00561 break;
00562
00563 default:
00564 return DefWindowProc(hWnd, uMsg, wParam, lParam);
00565 }
00566
00567 return 0;
00568 }
00569
00570
00571 int APIENTRY WinMain(HINSTANCE hInstance,
00572 HINSTANCE hPrevInstance,
00573 LPSTR lpCmdLine,
00574 int nCmdShow)
00575 {
00576 WNDCLASS wc;
00577
00578 wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
00579 wc.lpfnWndProc = (WNDPROC) MainWindowProc;
00580 wc.cbClsExtra = 0;
00581 wc.cbWndExtra = 0;
00582 wc.hInstance = hInstance;
00583 wc.hIcon = NULL;
00584 wc.hCursor = LoadCursor(NULL, MAKEINTRESOURCE(IDC_ARROW));
00585 wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
00586 wc.lpszMenuName = NULL;
00587 wc.lpszClassName = "xtocmod";
00588 if (RegisterClass(&wc) == 0)
00589 {
00590 MessageBox(NULL,
00591 "Failed to register the window class.", "Fatal Error",
00592 MB_OK | MB_ICONERROR);
00593 return NULL;
00594 }
00595
00596 DWORD windowStyle = (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU |
00597 WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX);
00598 g_mainWindow = CreateWindow("xtocmod",
00599 "xtocmod",
00600 windowStyle,
00601 CW_USEDEFAULT,
00602 CW_USEDEFAULT,
00603 300, 300,
00604 NULL,
00605 NULL,
00606 hInstance,
00607 NULL);
00608 if (g_mainWindow == NULL)
00609 {
00610 MessageBox(NULL,
00611 "Error creating application window.", "Fatal Error",
00612 MB_OK | MB_ICONERROR);
00613 }
00614
00615
00616 SetForegroundWindow(g_mainWindow);
00617 SetFocus(g_mainWindow);
00618
00619
00620 g_d3d = Direct3DCreate9(D3D_SDK_VERSION);
00621 if (g_d3d == NULL)
00622 {
00623 ShowD3DErrorMessage("Initializing D3D", 0);
00624 return 1;
00625 }
00626
00627 D3DPRESENT_PARAMETERS presentParams;
00628 ZeroMemory(&presentParams, sizeof(presentParams));
00629 presentParams.Windowed = TRUE;
00630 presentParams.SwapEffect = D3DSWAPEFFECT_COPY;
00631 #if 0
00632 presentParams.BackBufferWidth = 300;
00633 presentParams.BackBufferHeight = 300;
00634 presentParams.BackBufferCount = 1;
00635 presentParams.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
00636 presentParams.Windowed = TRUE;
00637 #endif
00638
00639 HRESULT hr = g_d3d->CreateDevice(D3DADAPTER_DEFAULT,
00640 D3DDEVTYPE_HAL,
00641 g_mainWindow,
00642 D3DCREATE_HARDWARE_VERTEXPROCESSING,
00643 &presentParams,
00644 &g_d3dDev);
00645 if (FAILED(hr))
00646 {
00647 ShowD3DErrorMessage("Creating D3D device", hr);
00648
00649 }
00650
00651 string inputFilename(lpCmdLine);
00652 string outputFilename(inputFilename, 0, inputFilename.rfind('.'));
00653 outputFilename += ".cmod";
00654
00655 ID3DXMesh* mesh = NULL;
00656 ID3DXBuffer* adjacency = NULL;
00657 ID3DXBuffer* materialBuf = NULL;
00658 ID3DXBuffer* effects = NULL;
00659 DWORD numMaterials;
00660
00661 hr = D3DXLoadMeshFromX(inputFilename.c_str(),
00662 0,
00663 g_d3dDev,
00664 &adjacency,
00665 &materialBuf,
00666 &effects,
00667 &numMaterials,
00668 &mesh);
00669 if (FAILED(hr))
00670 {
00671 ShowD3DErrorMessage("Loading mesh from X file", hr);
00672 return 1;
00673 }
00674
00675
00676 DWORD numVertices = mesh->GetNumVertices();
00677 DWORD numFaces = mesh->GetNumFaces();
00678
00679 cout << "vertices: " << numVertices << '\n';
00680 cout << "faces: " << numFaces << '\n';
00681
00682 cout << "adjacency buffer size: " << adjacency->GetBufferSize() << '\n';
00683
00684 ofstream meshfile(outputFilename.c_str());
00685
00686
00687 meshfile << "#celmodel__ascii\n\n";
00688
00689 cout << "numMaterials=" << numMaterials << '\n';
00690 D3DXMATERIAL* materials = reinterpret_cast<D3DXMATERIAL*>(materialBuf->GetBufferPointer());
00691 for (DWORD mat = 0; mat < numMaterials; mat++)
00692 {
00693 meshfile << "material\n";
00694 meshfile << "diffuse " << materials[mat].MatD3D.Diffuse << '\n';
00695
00696 meshfile << "specular " << materials[mat].MatD3D.Specular << '\n';
00697 meshfile << "specpower " << materials[mat].MatD3D.Power << '\n';
00698 meshfile << "opacity " << materials[mat].MatD3D.Diffuse.a << '\n';
00699 meshfile << "end_material\n\n";
00700 }
00701
00702
00703 D3DVERTEXELEMENT9 declElements[MAX_FVF_DECL_SIZE];
00704 hr = mesh->GetDeclaration(declElements);
00705 if (FAILED(hr))
00706 {
00707 ShowD3DErrorMessage("Checking vertex declaration", hr);
00708 return 1;
00709 }
00710
00711 DWORD stride = D3DXGetDeclVertexSize(declElements, 0);
00712
00713 VertexAttribute vertexMap[VertexAttribute::MaxAttribute];
00714 CreateVertexAttributeMap(declElements, vertexMap);
00715
00716 meshfile << "mesh\n\n";
00717
00718 DumpVertexDescription(vertexMap, meshfile);
00719
00720 ID3DXMesh* optMesh = NULL;
00721 ID3DXBuffer* vertexRemap = NULL;
00722 DWORD* faceRemap = new DWORD[numFaces];
00723 DWORD* optAdjacency = new DWORD[numFaces * 3];
00724 hr = mesh->Optimize(D3DXMESHOPT_COMPACT | D3DXMESHOPT_STRIPREORDER,
00725
00726 reinterpret_cast<DWORD*>(adjacency->GetBufferPointer()),
00727 optAdjacency,
00728 faceRemap,
00729 &vertexRemap,
00730 &optMesh);
00731 if (FAILED(hr))
00732 {
00733 ShowD3DErrorMessage("Optimize failed: ", hr);
00734 return 1;
00735 }
00736
00737
00738 DWORD attribTableSize = 0;
00739 hr = optMesh->GetAttributeTable(NULL, &attribTableSize);
00740 if (FAILED(hr))
00741 {
00742 ShowD3DErrorMessage("Querying attribute table size", hr);
00743 return 1;
00744 }
00745
00746 D3DXATTRIBUTERANGE* attribTable = NULL;
00747 if (attribTableSize > 0)
00748 {
00749 attribTable = new D3DXATTRIBUTERANGE[attribTableSize];
00750 hr = optMesh->GetAttributeTable(attribTable, &attribTableSize);
00751 if (FAILED(hr))
00752 {
00753 ShowD3DErrorMessage("Getting attribute table", hr);
00754 return 1;
00755 }
00756 }
00757
00758 cout << "Attribute table size: " << attribTableSize << '\n';
00759 if (attribTableSize == 1)
00760 {
00761 cout << "Attribute id: " << attribTable[0].AttribId << '\n';
00762 }
00763
00764 if (!DumpMeshVertices(optMesh, vertexMap, stride, meshfile))
00765 return 1;
00766
00767
00768 for (DWORD attr = 0; attr < attribTableSize; attr++)
00769 {
00770 StripifyMeshSubset(optMesh, attr, meshfile);
00771 }
00772 meshfile << "\nend_mesh\n";
00773
00774 #if 0
00775 IDirect3DIndexBuffer9* indices = NULL;
00776 hr = mesh->GetIndexBuffer(&indices);
00777 #endif
00778
00779 #if 0
00780
00781 MSG msg;
00782 GetMessage(&msg, NULL, 0u, 0u);
00783 while (msg.message != WM_QUIT)
00784 {
00785 GetMessage(&msg, NULL, 0u, 0u);
00786 TranslateMessage(&msg);
00787 DispatchMessage(&msg);
00788 }
00789 #endif
00790
00791 return 0;
00792 }
00793
00794
00795 int main(int argc, char* argv[])
00796 {
00797 if (argc != 2)
00798 {
00799 cerr << "Usage: xtocmod <meshfile.x>\n";
00800 return 1;
00801 }
00802
00803 ID3DXMesh* mesh = NULL;
00804 ID3DXBuffer* adjacency = NULL;
00805 ID3DXBuffer* materials = NULL;
00806 ID3DXBuffer* effects = NULL;
00807
00808 return 0;
00809 }
00810
00811
00812 char* D3DErrorString(HRESULT hr)
00813 {
00814 switch (hr)
00815 {
00816 case D3DERR_WRONGTEXTUREFORMAT:
00817 return "D3DERR_WRONGTEXTUREFORMAT";
00818 case D3DERR_UNSUPPORTEDCOLOROPERATION:
00819 return "D3DERR_UNSUPPORTEDCOLOROPERATION";
00820 case D3DERR_UNSUPPORTEDCOLORARG:
00821 return "D3DERR_UNSUPPORTEDCOLORARG";
00822 case D3DERR_UNSUPPORTEDALPHAOPERATION:
00823 return "D3DERR_UNSUPPORTEDALPHAOPERATION";
00824 case D3DERR_UNSUPPORTEDALPHAARG:
00825 return "D3DERR_UNSUPPORTEDALPHAARG";
00826 case D3DERR_TOOMANYOPERATIONS:
00827 return "D3DERR_TOOMANYOPERATIONS";
00828 case D3DERR_CONFLICTINGTEXTUREFILTER:
00829 return "D3DERR_CONFLICTINGTEXTUREFILTER";
00830 case D3DERR_UNSUPPORTEDFACTORVALUE:
00831 return "D3DERR_UNSUPPORTEDFACTORVALUE";
00832 case D3DERR_CONFLICTINGRENDERSTATE:
00833 return "D3DERR_CONFLICTINGRENDERSTATE";
00834 case D3DERR_UNSUPPORTEDTEXTUREFILTER:
00835 return "D3DERR_UNSUPPORTEDTEXTUREFILTER";
00836 case D3DERR_CONFLICTINGTEXTUREPALETTE:
00837 return "D3DERR_CONFLICTINGTEXTUREPALETTE";
00838 case D3DERR_DRIVERINTERNALERROR:
00839 return "D3DERR_DRIVERINTERNALERROR";
00840 case D3DERR_NOTFOUND:
00841 return "D3DERR_NOTFOUND";
00842 case D3DERR_MOREDATA:
00843 return "D3DERR_MOREDATA";
00844 case D3DERR_DEVICELOST:
00845 return "D3DERR_DEVICELOST";
00846 case D3DERR_DEVICENOTRESET:
00847 return "D3DERR_DEVICENOTRESET";
00848 case D3DERR_NOTAVAILABLE:
00849 return "D3DERR_NOTAVAILABLE";
00850 case D3DERR_OUTOFVIDEOMEMORY:
00851 return "D3DERR_OUTOFVIDEOMEMORY";
00852 case D3DERR_INVALIDDEVICE:
00853 return "D3DERR_INVALIDDEVICE";
00854 case D3DERR_INVALIDCALL:
00855 return "D3DERR_INVALIDCALL";
00856 case D3DERR_DRIVERINVALIDCALL:
00857 return "D3DERR_DRIVERINVALIDCALL";
00858 case D3DERR_WASSTILLDRAWING:
00859 return "D3DERR_WASSTILLDRAWING";
00860 case D3DOK_NOAUTOGEN:
00861 return "D3DOK_NOAUTOGEN";
00862
00863 case D3DXERR_CANNOTMODIFYINDEXBUFFER:
00864 return "D3DXERR_CANNOTMODIFYINDEXBUFFER";
00865 case D3DXERR_INVALIDMESH:
00866 return "D3DXERR_INVALIDMESH";
00867 case D3DXERR_CANNOTATTRSORT:
00868 return "D3DXERR_CANNOTATTRSORT";
00869 case D3DXERR_SKINNINGNOTSUPPORTED:
00870 return "D3DXERR_SKINNINGNOTSUPPORTED";
00871 case D3DXERR_TOOMANYINFLUENCES:
00872 return "D3DXERR_TOOMANYINFLUENCES";
00873 case D3DXERR_INVALIDDATA:
00874 return "D3DXERR_INVALIDDATA";
00875 case D3DXERR_LOADEDMESHASNODATA:
00876 return "D3DXERR_LOADEDMESHASNODATA";
00877 case D3DXERR_DUPLICATENAMEDFRAGMENT:
00878 return "D3DXERR_DUPLICATENAMEDFRAGMENT";
00879
00880 default:
00881 return "Unkown D3D Error";
00882 }
00883 }
00884
00885
00886 void ShowD3DErrorMessage(char* info, HRESULT hr)
00887 {
00888 char buf[1024];
00889
00890 sprintf(buf, "%s - %s", info, D3DErrorString(hr));
00891 MessageBox(g_mainWindow,
00892 buf, "Fatal Error",
00893 MB_OK | MB_ICONERROR);
00894 }
00895