#ifdef GTP_INTERNAL #define USE_QT 1 #else #define USE_QT 0 #endif #define USE_THREADS 1 #ifdef UNICODE #undef UNICODE #endif #include #include #include #include "PreprocessorFactory.h" #include "Parser.h" #include "Environment.h" #include "MeshKdTree.h" #include "Preprocessor.h" #include "common.h" #include "PreprocessorThread.h" #if !USE_QT && USE_THREADS #include "BoostPreprocessorThread.h" #endif #include "ResourceManager.h" #include "GlRenderer.h" #if USE_QT #include "QtPreprocessorThread.h" #include "QtGlRenderer.h" #endif #define USE_EXE_PATH false using namespace GtpVisibilityPreprocessor; Preprocessor *preprocessor = NULL; GlRendererWidget *rendererWidget = NULL; // DLL function signature typedef GlRendererWidget *(*importFunction)(Preprocessor *); void Cleanup() { DEL_PTR(rendererWidget); DEL_PTR(preprocessor); Environment::DelSingleton(); MeshManager::DelSingleton(); MaterialManager::DelSingleton(); } static string ReplaceSuffix(string filename, string a, string b) { string result = filename; int pos = (int)filename.rfind(a, (int)filename.size() - 1); if (pos == filename.size() - a.size()) { result.replace(pos, a.size(), b); } return result; } static int SplitFilenames(const string str, vector &filenames) { int pos = 0; while(1) { int npos = (int)str.find(';', pos); if (npos < 0 || npos - pos < 1) break; filenames.push_back(string(str, pos, npos - pos)); pos = npos + 1; } filenames.push_back(string(str, pos, str.size() - pos)); return (int)filenames.size(); } static string GetInternKdTreeName(const string &filename) { vector filenames; const int files = SplitFilenames(filename, filenames); vector::const_iterator sit, sit_end = filenames.end(); string kdFilename; int i = 0; for (sit = filenames.begin(); sit != sit_end; ++ sit, ++ i) { string currentFile = *sit; //cout << "here6 " << currentFile << endl; string strippedFilename; if (i == 0) { strippedFilename = currentFile; } else { strippedFilename = string(StripPath(currentFile.c_str())); } string suffix("_"); if (i == (int)filenames.size() - 1) { if (preprocessor->mLoadMeshes) { suffix = ".kdm"; } else { suffix = ".kdt"; } } if (strstr(strippedFilename.c_str(), ".x3d")) { kdFilename += ReplaceSuffix(strippedFilename, ".x3d", suffix); } else if (strstr(strippedFilename.c_str(), ".dat")) { kdFilename += ReplaceSuffix(strippedFilename, ".dat", suffix); } else if (strstr(strippedFilename.c_str(), ".obj")) { kdFilename += ReplaceSuffix(strippedFilename, ".dat", suffix); } else { cerr << "Error: Currently unsupported format for kd, filename " << currentFile << endl; } } //cout << "kdfilename: " << kdFilename << endl; return kdFilename; } int main(int argc, char **argv) { //Now just call this function at the start of your program and if you're //compiling in debug mode (F5), any leaks will be displayed in the Output //window when the program shuts down. If you're not in debug mode this will //be ignored. Use it as you will! //note: from GDNet Direct [3.8.04 - 3.14.04] void detectMemoryLeaks() { #if 0 _CrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF|_CRTDBG_ALLOC_MEM_DF); _CrtSetReportMode(_CRT_ASSERT,_CRTDBG_MODE_FILE); _CrtSetReportFile(_CRT_ASSERT,_CRTDBG_FILE_STDERR); #endif int returnCode = 0; InitTiming(); Debug.open("debug.log"); Environment::GetSingleton()->Parse(argc, argv, USE_EXE_PATH); MeshKdTree::ParseEnvironment(); char buff[128]; Environment::GetSingleton()->GetStringValue("Preprocessor.type", buff); string preprocessorType(buff); if (!(preprocessor = PreprocessorFactory::CreatePreprocessor(preprocessorType))) { Environment::DelSingleton(); cerr << "Unknown preprocessor type" << endl; exit(1); } ///////////// //-- load scene Environment::GetSingleton()->GetStringValue("Scene.filename", buff); string filename(buff); const string dummyname = GetInternKdTreeName(filename); if (!preprocessor->LoadScene(filename)) { cout << "loading file " << filename << " failed" << endl; Cleanup(); exit(1); } const string externKdTree = ReplaceSuffix(filename, ".obj", ".kdf"); const string internKdTree = GetInternKdTreeName(filename); //-- initialize external ray casters if (preprocessor->InitRayCast(externKdTree, internKdTree)) { cout << "ray casting initialized!" << endl; } else { cout << "ray casting initialization failed" << endl; Cleanup(); exit(1); } // parse view cells related options if (!preprocessor->PrepareViewCells()) { Cleanup(); exit(1); } if (0) { preprocessor->Export(filename + "-out.x3d", true, false); preprocessor->Export(filename + "-kdtree.x3d", false, true); } // create a preprocessor thread (note: capsulates calls to boost fuctions!) //PreprocessorThread *pt = PreprocessorThreadFactory::Create(preprocessor); PreprocessorThread *pt; #if USE_QT pt = new QtPreprocessorThread(preprocessor); #else #if USE_THREADS pt = new BoostPreprocessorThread(preprocessor); #else pt = new PreprocessorThread(preprocessor); #endif #endif bool guiSupported = false; if (preprocessor->mUseGlRenderer || preprocessor->mUseGlDebugger) { cout << "using gl widget" << endl; // create and run the preprocessor application in a parallel thread #if USE_QT #if USE_THREADS pt->InitThread(); if (!preprocessor->mDelayVisibilityComputation) pt->RunThread(); #endif // display the render widget if (!rendererWidget) { // create a qt application first (must be created before any opengl widget ...) QApplication *app = new QApplication(argc, NULL); if (!QGLFormat::hasOpenGL() || !QGLPixelBuffer::hasOpenGLPbuffers()) { QMessageBox::information(0, "OpenGL pbuffers", "This system does not support OpenGL/pbuffers.", QMessageBox::Ok); return NULL; } rendererWidget = new QtGlRendererWidget(preprocessor->mSceneGraph, preprocessor->mViewCellsManager, preprocessor->mKdTree); ((QtGlRendererWidget *)rendererWidget)->SetThread((QtPreprocessorThread *)pt); rendererWidget->Show(); guiSupported = true; } qApp->exec(); #endif } if (!guiSupported) { preprocessor->mUseGlRenderer = false; preprocessor->mUseGlDebugger = false; } if (!(preprocessor->mUseGlRenderer || preprocessor->mUseGlDebugger)) { // just call the mail method -> will be executed in the main thread pt->Main(); } // release memory Cleanup(); return returnCode; }