void MulticoreLauncher::popAll(const String& progressMessage) { Timer timer; F32 progress = 0.0f; while (getNumTasks()) { if (timer.getElapsed() > 0.1f) { printf("\r%s %d%%", progressMessage.getPtr(), (int)progress); timer.start(); } pop(); progress += (100.0f - progress) / (F32)(getNumTasks() + 1); } printf("\r%s 100%%\n", progressMessage.getPtr()); }
S32 FW::keyToUnicode(const String& key) { const char* ptr = key.getPtr(); S32 cp = 0; if (*ptr != 'U' || *++ptr != '+') return 0; while (*++ptr) { cp <<= 4; if (*ptr >= '0' && *ptr <= '9') cp += *ptr - '0'; else if (*ptr >= 'A' && *ptr <= 'F') cp += *ptr - ('A' - 10); else return 0; if (cp > 0x10FFFF) return 0; } return cp; }
File::File(const String& name, Mode mode, bool disableCache) : m_name(name), m_file(name.getPtr()) { const char* modeName; QFile::OpenMode openMode; switch (mode) { case Read: modeName = "read"; openMode = QFile::ReadOnly; break; case Create: modeName = "create"; openMode = QFile::ReadWrite | QFile::Truncate; break; case Modify: modeName = "modify"; openMode = QFile::ReadWrite; break; default: FW_ASSERT(false); return; } if (!m_file.open(disableCache ? openMode | QFile::Unbuffered : openMode)) { setError("Cannot open file '%s' for %s!", m_name.getPtr(), modeName); } }
CudaKernel CudaModule::getKernel(const String& name) { CUfunction kernel = findKernel(name); if (!kernel) fail("CudaModule: Kernel not found '%s'!", name.getPtr()); return CudaKernel(this, kernel); }
void GLContext::setFont(const String& name, int size, U32 style) { FW_ASSERT(size > 0); LOGFONT lf; lf.lfHeight = size; lf.lfWidth = 0; lf.lfEscapement = 0; lf.lfOrientation = 0; lf.lfWeight = ((style & FontStyle_Bold) != 0) ? FW_BOLD : FW_NORMAL; lf.lfItalic = ((style & FontStyle_Italic) != 0); lf.lfUnderline = false; lf.lfStrikeOut = false; lf.lfCharSet = ANSI_CHARSET; lf.lfOutPrecision = OUT_DEFAULT_PRECIS; lf.lfClipPrecision = CLIP_DEFAULT_PRECIS; lf.lfQuality = PROOF_QUALITY; lf.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE; memcpy(lf.lfFaceName, name.getPtr(), name.getLength() + 1); HFONT font = CreateFontIndirect(&lf); if (!font) failWin32Error("CreateFontIndirect"); setFont(font); }
Array<String> Window::showDirLoadDialog(const String& title, const String& initialDir) { char rawPath[MAX_PATH]; rawPath[0] = '\0'; Array<String> names; LPITEMIDLIST pidl = NULL; BROWSEINFO bi = { 0 }; bi.hwndOwner = m_hwnd; bi.pszDisplayName = rawPath; bi.pidlRoot = NULL; bi.lpszTitle = title.getPtr(); bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_USENEWUI; bool old = setDiscardEvents(true); if((pidl = SHBrowseForFolder(&bi)) != NULL) { SHGetPathFromIDList(pidl, rawPath); CoTaskMemFree(pidl); names.add(String(rawPath)); traverseDirectory(rawPath, names); } setDiscardEvents(old); getGL()->swapBuffers(); return names; }
void CudaCompiler::initLogFile(const String& name, const String& firstLine) { File file(name, File::Create); BufferedOutputStream out(file); out.writef("%s\n", firstLine.getPtr()); out.flush(); }
bool String::endsWith(const String& str) const { int a = getLength(); int b = str.getLength(); if (a < b) return false; return (strcmp(getPtr() + a - b, str.getPtr()) == 0); }
String& String::append(const String& other) { if (&other != this) return append(other.getPtr()); String tmp = other; return append(tmp.getPtr()); }
void Window::setTitle(const String& title) { if (m_title != title) { m_title = title; SetWindowText(m_hwnd, title.getPtr()); } }
bool String::startsWith(const String& str) const { const char* a = getPtr(); const char* b = str.getPtr(); for (int ofs = 0; b[ofs]; ofs++) if (a[ofs] != b[ofs]) return false; return true; }
CUfunction CudaModule::getKernel(const String& name, int paramSize) { CUfunction kernel = NULL; cuModuleGetFunction(&kernel, m_module, name.getPtr()); if (!kernel) cuModuleGetFunction(&kernel, m_module, (String("__globfunc_") + name).getPtr()); if (kernel) checkError("cuParamSetSize", cuParamSetSize(kernel, paramSize)); return kernel; }
String CudaCompiler::queryEnv(const String& name) { // Query buffer size. DWORD bufferSize = GetEnvironmentVariable(name.getPtr(), NULL, 0); if (!bufferSize) return ""; // Query value. char* buffer = new char[bufferSize]; buffer[0] = '\0'; GetEnvironmentVariable(name.getPtr(), buffer, bufferSize); // Convert to String. String res = buffer; delete[] buffer; return res; }
UString::UString( const String & _STRING ) : UStringBase( Converter( _STRING.getPtr() , _STRING.getSize() ).getString() ) { }
CUsurfref CudaModule::getSurfRef(const String& name) { #if (CUDA_VERSION >= 3010) CUsurfref surfRef; checkError("cuModuleGetSurfRef", cuModuleGetSurfRef(&surfRef, m_module, name.getPtr())); return surfRef; #else FW_UNREF(name); fail("CudaModule: getSurfRef() requires CUDA 3.1 or later!"); return NULL; #endif }
void CudaCompiler::runCompiler(const String& cubinFile, const String& finalOpts) { String logFile = m_cachePath + "\\compile.log"; String cmd = sprintf("%s -o \"%s\" -include \"%s\\defines.inl\" %s \"%s\" 2>>\"%s\"", s_nvccCommand.getPtr(), cubinFile.getPtr(), m_cachePath.getPtr(), finalOpts.getPtr(), saveSource().getPtr(), logFile.getPtr()); initLogFile(logFile, cmd); if (system(cmd.getPtr()) != 0 || !fileExists(cubinFile)) setLoggedError("CudaCompiler: Compilation failed!", logFile); #if SHOW_NVCC_OUTPUT setLoggedError("", logFile); printf("%s\n", getError().getPtr()); clearError(); #endif }
void App::saveMesh(const String& fileName) { if (!m_mesh) { m_commonCtrl.message("No mesh to save!"); return; } m_window.showModalMessage(sprintf("Saving mesh to '%s'...", fileName.getPtr())); String oldError = clearError(); exportMesh(fileName, m_mesh); String newError = getError(); if (restoreError(oldError)) { m_commonCtrl.message(sprintf("Error while saving '%s': %s", fileName.getPtr(), newError.getPtr())); return; } m_meshFileName = fileName; m_commonCtrl.message(sprintf("Saved mesh to '%s'", fileName.getPtr())); }
CUtexref CudaModule::getTexRef(const String& name) { S32* found = m_texRefHash.search(name); if (found) return m_texRefs[*found]; CUtexref texRef; checkError("cuModuleGetTexRef", cuModuleGetTexRef(&texRef, m_module, name.getPtr())); m_texRefHash.add(name, m_texRefs.getSize()); m_texRefs.add(texRef); return texRef; }
GLuint GLContext::Program::createGLShader(GLenum type, const String& typeStr, const String& source, bool bThrow) { GLuint shader = glCreateShader(type); const char* sourcePtr = source.getPtr(); int sourceLen = source.getLength(); glShaderSource(shader, 1, &sourcePtr, &sourceLen); glCompileShader(shader); GLint status = 0; glGetShaderiv(shader, GL_COMPILE_STATUS, &status); if (!status) { GLint infoLen = 0; glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen); if (!infoLen) if ( !bThrow ) fail("glCompileShader(%s) failed!", typeStr.getPtr()); else { glDeleteShader(shader); throw ShaderCompilationException( sprintf( "glCompileShader(%s) failed!", typeStr.getPtr() ) ); } Array<char> info(NULL, infoLen); info[0] = '\0'; glGetShaderInfoLog(shader, infoLen, &infoLen, info.getPtr()); if ( !bThrow ) fail("glCompileShader(%s) failed!\n\n%s", typeStr.getPtr(), info.getPtr()); else { glDeleteShader(shader); throw ShaderCompilationException( sprintf( "glCompileShader(%s) failed!\n\n%s", typeStr.getPtr(), info.getPtr() ) ); } } GLContext::checkErrors(); return shader; }
void FW::fail(const char* fmt, ...) { // Fail only once. s_lock.enter(); bool alreadyFailed = s_hasFailed; s_hasFailed = true; s_lock.leave(); if (alreadyFailed) return; // Print message. String tmp; va_list args; va_start(args, fmt); tmp.setfv(fmt, args); va_end(args); printf("\n%s\n", tmp.getPtr()); // Try to prevent any user code from being executed. Thread::suspendAll(); setDiscardEvents(true); // Display modal dialog. MessageBox(NULL, tmp.getPtr(), "Fatal error", MB_OK); // Running under a debugger => break here. if (IsDebuggerPresent()) __debugbreak(); // Kill the app. FatalExit(1); }
void CudaCompiler::setLoggedError(const String& description, const String& logFile) { String message = description; File file(logFile, File::Read); BufferedInputStream in(file); in.readLine(); for (;;) { const char* linePtr = in.readLine(); if (!linePtr) break; if (*linePtr) message += '\n'; message += linePtr; } setError("%s", message.getPtr()); }
String SQLite::escape(const String &str) const { #ifndef HAVE_SQLITE3 throw UnsupportedFeatureException("SQLite"); #else // SQLite hat keine Escape-Funktion, daher müssen wir das selbst machen String n; const char *tmp=str.getPtr(); int c; while ((c=tmp[0])) { if (c=='\'') n+="'"; n+=c; tmp++; } return n; #endif }
// Load in objects from standard input into the global variables: // gCtrlPoints, gCurves, gCurveNames, gSurfaces, gSurfaceNames. If // loading fails, this will exit the program. void App::loadModel(const String& fileName) { int end = fileName.lastIndexOf('.'); String prefix = (end > 0) ? fileName.substring(0, end) : fileName; String skeletonFile = prefix + ".skel"; String meshFile = prefix + ".obj"; String attachmentsFile = prefix + ".attach"; cout << "skeleton: " << skeletonFile.getPtr() << endl; cout << "mesh: " << meshFile.getPtr() << endl; cout << "attachment: " << attachmentsFile.getPtr() << endl; m_model.load(skeletonFile.getPtr(), meshFile.getPtr(), attachmentsFile.getPtr()); }
String CudaCompiler::saveSource(void) { // Inline code specified => write to a temporary file. String path = m_sourceFile; if (m_inlineSource.getLength()) { path = m_cachePath + "\\inline.cu"; File file(path, File::Create); file.write(m_inlineSource.getPtr(), m_inlineSource.getLength()); } // Convert to an absolute path. // (Required by Nsight for breakpoints to work properly) char absolutePath[MAX_PATH]; if (GetFullPathName(path.getPtr(), FW_ARRAY_SIZE(absolutePath), absolutePath, NULL) != 0) path = absolutePath; return path; }
void App::screenshot (const String& name) { // Capture image. const Vec2i& size = window_.getGL()->getViewSize(); Image image(size, ImageFormat::R8_G8_B8_A8); glUseProgram(0); glWindowPos2i(0, 0); glReadPixels(0, 0, size.x, size.y, GL_RGBA, GL_UNSIGNED_BYTE, image.getMutablePtr()); // Display the captured image immediately. for (int i = 0; i < 3; ++i) { glDrawPixels(size.x, size.y, GL_RGBA, GL_UNSIGNED_BYTE, image.getPtr()); window_.getGL()->swapBuffers(); } glDrawPixels(size.x, size.y, GL_RGBA, GL_UNSIGNED_BYTE, image.getPtr()); // Export. image.flipY(); exportImage(name, &image); printf("Saved screenshot to '%s'", name.getPtr()); }
CUfunction CudaModule::findKernel(const String& name) { // Search from hash. CUfunction* found = m_kernels.search(name); if (found) return *found; // Search from module. CUfunction kernel = NULL; cuModuleGetFunction(&kernel, m_module, name.getPtr()); if (!kernel) cuModuleGetFunction(&kernel, m_module, (String("__globfunc_") + name).getPtr()); if (!kernel) return NULL; // Add to hash. m_kernels.add(name, kernel); return kernel; }
void Window::showFileDialog(Array<String>& names, const String& title, bool save, bool multi, const String& filters, const String& initialDir, bool forceInitialDir) { // Form the filter string. String filterStr; Array<String> extensions; int numFilters = 0; int start = 0; while (start < filters.getLength()) { int colon = filters.indexOf(':', start); FW_ASSERT(colon != -1); int comma = filters.indexOf(',', colon); if (comma == -1) comma = filters.getLength(); FW_ASSERT(colon < comma); String all; while (start < colon) { int semi = filters.indexOf(';', start); if (semi == -1 || semi > colon) semi = colon; String ext = filters.substring(start, semi); extensions.add(ext); start = semi + 1; if (all.getLength()) all += ';'; all += "*."; all += ext; } String title = filters.substring(colon + 1, comma); filterStr.appendf("%s Files (%s)\n%s\n", title.getPtr(), all.getPtr(), all.getPtr()); numFilters++; start = comma + 1; } // Add "All Supported Formats" and "All Files". if (numFilters > 1 && !save) { String all; for (int i = 0; i < extensions.getSize(); i++) { if (all.getLength()) all += ';'; all += "*."; all += extensions[i]; } filterStr = sprintf("All Supported Formats (%s)\n%s\n", all.getPtr(), all.getPtr()) + filterStr; } filterStr += "All Files (*.*)\n*.*\n"; // Convert linefeeds to null characters. Array<char> filterChars(filterStr.getPtr(), filterStr.getLength() + 1); for (int i = 0; i < filterChars.getSize(); i++) if (filterChars[i] == '\n') filterChars[i] = '\0'; // Setup OPENFILENAME struct. char rawPath[MAX_PATH * 256]; // Allow plenty of space for multiple filenames rawPath[0] = '\0'; U32 flags; if (save) flags = OFN_CREATEPROMPT | OFN_NOCHANGEDIR | OFN_OVERWRITEPROMPT | OFN_PATHMUSTEXIST; else flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY | OFN_NOCHANGEDIR; if (save) multi = false; if (multi) flags |= OFN_ALLOWMULTISELECT | OFN_EXPLORER; OPENFILENAME ofn; ofn.lStructSize = sizeof(ofn); ofn.hwndOwner = m_hwnd; ofn.hInstance = NULL; ofn.lpstrFilter = filterChars.getPtr(); ofn.lpstrCustomFilter = NULL; ofn.nMaxCustFilter = 0; ofn.nFilterIndex = 0; ofn.lpstrFile = rawPath; ofn.nMaxFile = FW_ARRAY_SIZE(rawPath); ofn.lpstrFileTitle = NULL; ofn.nMaxFileTitle = 0; ofn.lpstrInitialDir = (initialDir.getLength() && forceInitialDir) ? initialDir.getPtr() : NULL; ofn.lpstrTitle = title.getPtr(); ofn.Flags = flags; ofn.nFileOffset = 0; ofn.nFileExtension = 0; ofn.lpstrDefExt = (extensions.getSize()) ? extensions[0].getPtr() : NULL; ofn.lCustData = NULL; ofn.lpfnHook = NULL; ofn.lpTemplateName = NULL; ofn.pvReserved = NULL; ofn.dwReserved = 0; ofn.FlagsEx = 0; // Backup current working directory and set it to initialDir. char oldCwd[MAX_PATH]; bool oldCwdValid = (GetCurrentDirectory(FW_ARRAY_SIZE(oldCwd), oldCwd) != 0); if (oldCwdValid && initialDir.getLength() && !forceInitialDir) SetCurrentDirectory(initialDir.getPtr()); // Show modal dialog. bool old = setDiscardEvents(true); bool rawPathValid = (((save) ? GetSaveFileName(&ofn) : GetOpenFileName(&ofn)) != 0); setDiscardEvents(old); getGL()->swapBuffers(); // Terminate here if raw path was not valid. if (!rawPathValid) { names.reset(1); names[0] = ""; return; } // Construct array of raw paths. Array<String> rawPaths; if (!multi) { rawPaths.reset(1); rawPaths[0] = rawPath; } else { int ofs = ofn.nFileOffset; if (ofs <= (int)strlen(rawPath)) { rawPaths.reset(1); rawPaths[0] = rawPath; } else { while (rawPath[ofs] != '\0') { String name = rawPath; name += "\\"; name += (rawPath + ofs); rawPaths.add(name); ofs += (int)strlen(rawPath + ofs) + 1; } } } int numFiles = rawPaths.getSize(); // Convert paths to absolute and restore current working directory. Array<String> absolutePaths(0, numFiles); for (int i=0; i < numFiles; i++) { char absolutePath[MAX_PATH]; bool absolutePathValid = (GetFullPathName(rawPaths[i].getPtr(), FW_ARRAY_SIZE(absolutePath), absolutePath, NULL) != 0); absolutePaths[i] = (absolutePathValid ? absolutePath : ""); } if (oldCwdValid) SetCurrentDirectory(oldCwd); // Convert paths to relative and place in result array. names.reset(numFiles); for (int i=0; i < numFiles; i++) { char relativePath[MAX_PATH]; bool absolutePathValid = absolutePaths[i].getLength() > 0; bool relativePathValid = (oldCwdValid && absolutePathValid && PathRelativePathTo(relativePath, oldCwd, FILE_ATTRIBUTE_DIRECTORY, (absolutePathValid) ? absolutePaths[i].getPtr() : rawPaths[i].getPtr(), 0)); // Return the best path that we have. names[i] = (relativePathValid) ? relativePath : (absolutePathValid) ? absolutePaths[i] : rawPaths[i]; } }
void Window::showMessageDialog(const String& title, const String& text) { bool old = setDiscardEvents(true); MessageBox(m_hwnd, text.getPtr(), title.getPtr(), MB_OK); setDiscardEvents(old); }
bool operator== (const String& other) const { return (strcmp(getPtr(), other.getPtr()) == 0); }
// This function iterates over all the "submeshes" (parts of the object with different materials), // heaps all the vertices and triangles together, and calls the BVH constructor. // It is the responsibility of the tree to free the data when deleted. // This functionality is _not_ part of the RayTracer class in order to keep it separate // from the specifics of the Mesh class. void App::constructTracer() { // if we had a hierarchy, delete it. if ( m_rt != 0 ) delete m_rt; // fetch vertex and triangle data -----> m_rtVertices.clear(); m_rtVertices.reserve( m_mesh->numVertices() ); m_rtTriangles.clear(); m_rtTriangles.reserve( m_mesh->numTriangles() ); m_rtMap.clear(); m_rtMap.reserve( m_mesh->numTriangles() ); for ( int i = 0; i < m_mesh->numVertices(); ++i ) { Vec3f p = m_mesh->getVertexAttrib( i, FW::MeshBase::AttribType_Position ).getXYZ(); m_rtVertices.push_back( p ); } for ( int i = 0; i < m_mesh->numSubmeshes(); ++i ) { const Array<Vec3i>& idx = m_mesh->indices( i ); for ( int j = 0; j < idx.getSize(); ++j ) { RTToMesh m; m.submesh = i; m.tri_idx = j; m_rtMap.push_back( m ); RTTriangle t(&m_rtVertices[0] + idx[j][0], &m_rtVertices[0] + idx[j][1], &m_rtVertices[0] + idx[j][2]); m_rtTriangles.push_back( t ); } } FW_ASSERT( m_rtMap.size() == m_rtTriangles.size() ); // fix the user pointers to point to the array that tells // which (submesh,tri) combination each linearly-indexed triangle corresponds to. for ( size_t i = 0; i < m_rtTriangles.size(); ++i ) { m_rtTriangles[ i ].m_userPointer = &m_rtMap[ i ]; // Store the vertex normals to RTTriangle Vec3i vindices = m_mesh->indices(m_rtMap[ i ].submesh)[ m_rtMap[i].tri_idx ]; for (int j = 0; j < 3; ++j) { m_rtTriangles[ i ].m_vertexNormals[ j ] = &(m_mesh->getVertexPtr(vindices[j])->n); } } // <------- // compute checksum String md5 = RayTracer::computeMD5( m_rtVertices ); FW::printf( "Mesh MD5: %s\n", md5.getPtr() ); // .. m_rt = new RayTracer(); const bool tryLoadHieararchy = true; if ( tryLoadHieararchy ) { // check if saved hierarchy exists String hierarchyCacheFile = String("Hierarchy-") + md5 + String(".bin"); if ( fileExists( hierarchyCacheFile.getPtr() ) ) { // yes, load! m_rt->loadHierarchy( hierarchyCacheFile.getPtr(), m_rtTriangles ); ::printf( "Loaded hierarchy from %s\n", hierarchyCacheFile.getPtr() ); } else { // no, construct... m_rt->constructHierarchy( m_rtTriangles ); // .. and save! m_rt->saveHierarchy( hierarchyCacheFile.getPtr(), m_rtTriangles ); ::printf( "Saved hierarchy to %s\n", hierarchyCacheFile.getPtr() ); } } else { // nope, bite the bullet and construct it m_rt->constructHierarchy( m_rtTriangles ); } }