CShaderLibrary::CShaderLibrary() { s_pShaderLibrary = this; m_bCompiled = false; m_iSamples = -1; FILE* f = tfopen("shaders/functions.si", "r"); if (f) { tstring sLine; while (fgetts(sLine, f)) m_sFunctions += sLine; fclose(f); } f = tfopen("shaders/header.si", "r"); if (f) { tstring sLine; while (fgetts(sLine, f)) m_sHeader += sLine; fclose(f); } }
void CShaderLibrary::WriteLog(const tstring& sFile, const char* pszLog, const char* pszShaderText) { if (!pszLog || strlen(pszLog) == 0) return; tstring sLogFile = GetAppDataDirectory(Application()->AppDirectory(), "shaders.txt"); if (m_bLogNeedsClearing) { // Only clear it if we're actually going to write to it so we don't create the file. FILE* fp = tfopen(sLogFile, "w"); fclose(fp); m_bLogNeedsClearing = false; } char szText[100]; strncpy(szText, pszShaderText, 99); szText[99] = '\0'; FILE* fp = tfopen(sLogFile, "a"); fprintf(fp, ("Shader compile output for file: " + sFile + " timestamp: %d\n").c_str(), (int)time(NULL)); fprintf(fp, "%s\n\n", pszLog); fprintf(fp, "%s...\n\n", szText); fclose(fp); }
void kbopen(VOID) { kbinitmap(); if ((fptty = tfopen("/dev/tty","r")) != (FILE*)NULL) { set_terminal(); screen_lines = get_screen_lines(); } }
void flower( long g, int dd, int mm, int yy ) { FILE *fp; char buf[BUFSIZ], *p = NULL, *q = NULL; long m, d; int found = 0; if ( ( fp = tfopen( flowerTblFile, "r" ) ) == NULL ) return; while ( ( p = fgets( buf, BUFSIZ - 1, fp ) ) != NULL ) { if ( (*p >= '0') && (*p <= '1') ) { q = strchr( p, ' ' ); if ( q && (*(q + 1) >= '0' && (*(q + 1) <= '9')) ) { m = atoi( p ); d = atoi( q + 1 ); if ( (m == mm) && (d == dd) ) { found = 1; break; } } } } tfclose( fp ); if ( (found == 1) && q ) { p = strchr( q + 1, ' ' ); if ( !p ) p = strchr( q + 1, '\t' ); if ( p && *(p + 1) ) { q = strchr( p + 1, ' ' ); if ( !q ) q = strchr( p + 1, '\t' ); if ( q && *(q + 1) ) { *q++ = NUL; while ( (*p == ' ') || (*p == '\t') ) p++; while ( (*q == ' ') || (*q == '\t') ) q++; while ( (q[strlen(q) - 1] == '\n') || (q[strlen(q) - 1] == ' ' ) || (q[strlen(q) - 1] == '\t') ) q[strlen(q) - 1] = NUL; if ( *q ) { putchar( '\n' ); printf( "今月の誕生石: %s\n 誕生花: %s\n", birthStone[mm - 1], birthFlower[mm - 1] ); printf( "今日の誕生花: %s\n 花言葉: 『%s』\n", p, q ); } } } } }
// Initialize Log object void GTLogTextFile::Initialize(void) { FILE* fp = tfopen(GTLogTextFile::g_szLogFileName, CTEXT("w")); if(fp) { OutTimestamp(fp); fprintf(fp, "\n"); tfclose(fp); fp = NULL; } }
void GTLogTextFile::LogOutout(const tchar* szMes, const tchar* szType) { if(szMes && szType) { FILE* fp = tfopen(GTLogTextFile::g_szLogFileName, CTEXT("a+")); if(fp) { tfprintf(fp, CTEXT("[%s]: %s\n"), szType, szMes); tfclose(fp); fp = NULL; } } }
int32 GOS::GetFileSize(const tchar* szFileName) { if(NULL == szFileName) { return -1; } FILE* fp = tfopen(szFileName, CTEXT("rb")); if(NULL == fp) { // The file doesn't exist. return -2; } // Set fp to the end of the file tfseek(fp, 0, SEEK_END); // Get the current fp position to get the size const int32 nFileSize = tftell(fp); // Close the file tfclose(fp); fp = NULL; return nFileSize; }
// Silo ascii void CModelConverter::ReadSIA(const tstring& sFilename) { if (m_pWorkListener) m_pWorkListener->BeginProgress(); CConversionSceneNode* pScene = m_pScene->GetScene(m_pScene->AddScene(GetFilename(sFilename).append(_T(".sia")))); if (m_pWorkListener) m_pWorkListener->SetAction(_T("Reading file into memory..."), 0); FILE* fp = tfopen(sFilename, _T("r")); if (!fp) { printf("No input file. Sorry!\n"); return; } fseek(fp, 0L, SEEK_END); long iOBJSize = ftell(fp); fseek(fp, 0L, SEEK_SET); // Make sure we allocate more than we need just in case. size_t iFileSize = (iOBJSize+1) * (sizeof(tchar)+1); tchar* pszEntireFile = (tchar*)malloc(iFileSize); tchar* pszCurrent = pszEntireFile; // Read the entire file into an array first for faster processing. tstring sLine; while (fgetts(sLine, fp)) { tstrncpy(pszCurrent, iFileSize-(pszCurrent-pszEntireFile), sLine.c_str(), sLine.length()); size_t iLength = sLine.length(); if (pszCurrent[iLength-1] == _T('\n')) { pszCurrent[iLength-1] = _T('\0'); iLength--; } pszCurrent += iLength; pszCurrent++; if (m_pWorkListener) m_pWorkListener->WorkProgress(0); } pszCurrent[0] = _T('\0'); fclose(fp); const tchar* pszLine = pszEntireFile; const tchar* pszNextLine = NULL; while (pszLine < pszCurrent) { if (pszNextLine) pszLine = pszNextLine; pszNextLine = pszLine + tstrlen(pszLine) + 1; // This code used to call StripWhitespace() but that's too slow for very large files w/ millions of lines. // Instead we'll just cut the whitespace off the front and deal with whitespace on the end when we come to it. while (*pszLine && IsWhitespace(*pszLine)) pszLine++; if (tstrlen(pszLine) == 0) continue; eastl::vector<tstring> aTokens; tstrtok(pszLine, aTokens, _T(" ")); const tchar* pszToken = aTokens[0].c_str(); if (tstrncmp(pszToken, _T("-Version"), 8) == 0) { // Warning if version is later than 1.0, we may not support it int iMajor, iMinor; eastl::vector<tstring> asTokens; tstrtok(pszLine, asTokens, _T(" .")); if (asTokens.size() >= 3) { iMajor = stoi(asTokens[1]); iMinor = stoi(asTokens[2]); if (iMajor != 1 && iMinor != 0) printf("WARNING: I was programmed for version 1.0, this file is version %d.%d, so this might not work exactly right!\n", iMajor, iMinor); } } else if (tstrncmp(pszToken, _T("-Mat"), 4) == 0) { pszNextLine = ReadSIAMat(pszNextLine, pszCurrent, pScene, sFilename); } else if (tstrncmp(pszToken, _T("-Shape"), 6) == 0) { pszNextLine = ReadSIAShape(pszNextLine, pszCurrent, pScene); } else if (tstrncmp(pszToken, _T("-Texshape"), 9) == 0) { // This is the 3d UV space of the object, but we only care about its 2d UV space which is contained in rhw -Shape section, so meh. pszNextLine = ReadSIAShape(pszNextLine, pszCurrent, pScene, false); } } free(pszEntireFile); m_pScene->SetWorkListener(m_pWorkListener); for (size_t i = 0; i < m_pScene->GetNumMeshes(); i++) { m_pScene->GetMesh(i)->CalculateEdgeData(); m_pScene->GetMesh(i)->CalculateVertexNormals(); m_pScene->GetMesh(i)->CalculateVertexTangents(); } m_pScene->CalculateExtends(); if (m_pWorkListener) m_pWorkListener->EndProgress(); }
void CModelConverter::ReadOBJ(const tstring& sFilename) { if (m_pWorkListener) m_pWorkListener->BeginProgress(); FILE* fp = tfopen(sFilename, _T("r")); if (!fp) { printf("No input file. Sorry!\n"); return; } CConversionSceneNode* pScene = m_pScene->GetScene(m_pScene->AddScene(GetFilename(sFilename).append(_T(".obj")))); CConversionMesh* pMesh = m_pScene->GetMesh(m_pScene->AddMesh(GetFilename(sFilename))); // Make sure it exists. CConversionSceneNode* pMeshNode = m_pScene->GetDefaultSceneMeshInstance(pScene, pMesh); size_t iCurrentMaterial = ~0; size_t iSmoothingGroup = ~0; bool bSmoothingGroups = false; tstring sLastTask; int iTotalVertices = 0; int iTotalFaces = 0; int iVerticesComplete = 0; int iFacesComplete = 0; if (m_pWorkListener) m_pWorkListener->SetAction(_T("Reading file into memory..."), 0); fseek(fp, 0L, SEEK_END); long iOBJSize = ftell(fp); fseek(fp, 0L, SEEK_SET); // Make sure we allocate more than we need just in case. size_t iFileSize = (iOBJSize+1) * (sizeof(tchar)+1); tchar* pszEntireFile = (tchar*)malloc(iFileSize); tchar* pszCurrent = pszEntireFile; pszCurrent[0] = _T('\0'); // Read the entire file into an array first for faster processing. tstring sLine; while (fgetts(sLine, fp)) { tstrncpy(pszCurrent, iFileSize-(pszCurrent-pszEntireFile), sLine.c_str(), sLine.length()); size_t iLength = sLine.length(); tchar cLastChar = pszCurrent[iLength-1]; while (cLastChar == _T('\n') || cLastChar == _T('\r')) { pszCurrent[iLength-1] = _T('\0'); iLength--; cLastChar = pszCurrent[iLength-1]; } pszCurrent += iLength; pszCurrent++; if (m_pWorkListener) m_pWorkListener->WorkProgress(0); } pszCurrent[0] = _T('\0'); fclose(fp); const tchar* pszLine = pszEntireFile; const tchar* pszNextLine = NULL; while (pszLine < pszCurrent) { if (pszNextLine) pszLine = pszNextLine; pszNextLine = pszLine + tstrlen(pszLine) + 1; // This code used to call StripWhitespace() but that's too slow for very large files w/ millions of lines. // Instead we'll just cut the whitespace off the front and deal with whitespace on the end when we come to it. while (*pszLine && IsWhitespace(*pszLine)) pszLine++; if (tstrlen(pszLine) == 0) continue; if (pszLine[0] == '#') { // ZBrush is kind enough to notate exactly how many vertices and faces we have in the comments at the top of the file. if (tstrncmp(pszLine, _T("#Vertex Count"), 13) == 0) { iTotalVertices = stoi(pszLine+13); pMesh->SetTotalVertices(iTotalVertices); } if (tstrncmp(pszLine, _T("#Face Count"), 11) == 0) { iTotalFaces = stoi(pszLine+11); pMesh->SetTotalFaces(iTotalFaces); // Don't kill the video card while we're loading the faces. if (iTotalFaces > 10000) pMeshNode->GetMeshInstance(0)->SetVisible(false); } continue; } tchar szToken[1024]; tstrncpy(szToken, 1024, pszLine, 1024); tchar* pszState = NULL; tchar* pszToken = strtok<tchar>(szToken, " ", &pszState); if (tstrncmp(pszToken, _T("mtllib"), 6) == 0) { tstring sDirectory = GetDirectory(sFilename); tstring sMaterial = sprintf(tstring("%s/%s"), sDirectory.c_str(), pszLine + 7); ReadMTL(sMaterial); } else if (tstrncmp(pszToken, _T("o"), 1) == 0) { // Dunno what this does. } else if (tstrncmp(pszToken, _T("v"), 2) == 0) { if (m_pWorkListener) { if (tstrncmp(sLastTask.c_str(), pszToken, sLastTask.length()) == 0) m_pWorkListener->WorkProgress(iVerticesComplete++); else { m_pWorkListener->SetAction(_T("Reading vertex data"), iTotalVertices); sLastTask = tstring(pszToken); } } // A vertex. float v[3]; // scanf is pretty slow even for such a short string due to lots of mallocs. const tchar* pszToken = pszLine+1; int iDimension = 0; while (*pszToken) { while (pszToken[0] == _T(' ')) pszToken++; v[iDimension++] = (float)stof(pszToken); if (iDimension >= 3) break; while (pszToken[0] != _T(' ')) pszToken++; } pMesh->AddVertex(v[0], v[1], v[2]); } else if (tstrncmp(pszToken, _T("vn"), 3) == 0) { if (m_pWorkListener) { if (tstrncmp(sLastTask.c_str(), pszToken, sLastTask.length()) == 0) m_pWorkListener->WorkProgress(0); else m_pWorkListener->SetAction(_T("Reading vertex normal data"), 0); } sLastTask = tstring(pszToken); // A vertex normal. float x, y, z; eastl::vector<tstring> asTokens; tstrtok(pszLine, asTokens, _T(" ")); if (asTokens.size() == 4) { x = stof(asTokens[1]); y = stof(asTokens[2]); z = stof(asTokens[3]); pMesh->AddNormal(x, y, z); } } else if (tstrncmp(pszToken, _T("vt"), 3) == 0) { if (m_pWorkListener) { if (tstrncmp(sLastTask.c_str(), pszToken, sLastTask.length()) == 0) m_pWorkListener->WorkProgress(0); else m_pWorkListener->SetAction(_T("Reading texture coordinate data"), 0); } sLastTask = tstring(pszToken); // A UV coordinate for a vertex. float u, v; eastl::vector<tstring> asTokens; tstrtok(pszLine, asTokens, _T(" ")); if (asTokens.size() == 3) { u = stof(asTokens[1]); v = stof(asTokens[2]); pMesh->AddUV(u, v); } } else if (tstrncmp(pszToken, _T("g"), 1) == 0) { // A group of faces. pMesh->AddBone(pszLine+2); } else if (tstrncmp(pszToken, _T("usemtl"), 6) == 0) { // All following faces should use this material. tstring sMaterial = tstring(pszLine+7); size_t iMaterial = pMesh->FindMaterialStub(sMaterial); if (iMaterial == ((size_t)~0)) { size_t iSceneMaterial = m_pScene->FindMaterial(sMaterial); if (iSceneMaterial == ((size_t)~0)) iCurrentMaterial = m_pScene->AddDefaultSceneMaterial(pScene, pMesh, sMaterial); else { size_t iMaterialStub = pMesh->AddMaterialStub(sMaterial); m_pScene->GetDefaultSceneMeshInstance(pScene, pMesh)->GetMeshInstance(0)->AddMappedMaterial(iMaterialStub, iSceneMaterial); iCurrentMaterial = iMaterialStub; } } else iCurrentMaterial = iMaterial; } else if (tstrncmp(pszToken, _T("s"), 1) == 0) { if (tstrncmp(pszLine, _T("s off"), 5) == 0) { iSmoothingGroup = ~0; } else { bSmoothingGroups = true; eastl::vector<tstring> asTokens; tstrtok(pszLine, asTokens, _T(" ")); if (asTokens.size() == 2) iSmoothingGroup = stoi(asTokens[1]); } } else if (tstrncmp(pszToken, _T("f"), 1) == 0) { if (m_pWorkListener) { if (tstrncmp(sLastTask.c_str(), pszToken, sLastTask.length()) == 0) m_pWorkListener->WorkProgress(iFacesComplete++); else { m_pWorkListener->SetAction(_T("Reading polygon data"), iTotalFaces); sLastTask = tstring(pszToken); } } if (iCurrentMaterial == ~0) iCurrentMaterial = m_pScene->AddDefaultSceneMaterial(pScene, pMesh, pMesh->GetName()); // A face. size_t iFace = pMesh->AddFace(iCurrentMaterial); // If we get to 10k faces force the mesh off so it doesn't kill the video card. if (iFace == 10000) pMeshNode->GetMeshInstance(0)->SetVisible(false); pMesh->GetFace(iFace)->m_iSmoothingGroup = iSmoothingGroup; while (pszToken = strtok<tchar>(NULL, _T(" "), &pszState)) { if (tstrlen(pszToken) == 0) continue; // We don't use size_t because SOME EXPORTS put out negative numbers. long f[3]; bool bValues[3]; bValues[0] = false; bValues[1] = false; bValues[2] = false; // scanf is pretty slow even for such a short string due to lots of mallocs. const tchar* pszValues = pszToken; int iValue = 0; do { if (!pszValues) break; if (!bValues[0] || pszValues[0] == _T('/')) { if (pszValues[0] == _T('/')) pszValues++; bValues[iValue] = true; f[iValue++] = (long)stoi(pszValues); if (iValue >= 3) break; } // Don't advance if we're on a slash, because that means empty slashes. ie, 11//12 <-- the 12 would get skipped. if (pszValues[0] != _T('/')) pszValues++; } while (*pszValues); if (bValues[0]) { if (f[0] < 0) f[0] = (long)pMesh->GetNumVertices()+f[0]+1; TAssert ( f[0] >= 1 && f[0] < (long)pMesh->GetNumVertices()+1 ); } if (bValues[1] && pMesh->GetNumUVs()) { if (f[1] < 0) f[1] = (long)pMesh->GetNumUVs()+f[1]+1; TAssert ( f[1] >= 1 && f[1] < (long)pMesh->GetNumUVs()+1 ); } if (bValues[2] && pMesh->GetNumNormals()) { if (f[2] < 0) f[2] = (long)pMesh->GetNumNormals()+f[2]+1; TAssert ( f[2] >= 1 && f[2] < (long)pMesh->GetNumNormals()+1 ); } // OBJ uses 1-based indexing. // Convert to 0-based indexing. f[0]--; f[1]--; f[2]--; if (!pMesh->GetNumUVs()) f[1] = ~0; if (bValues[2] == false || !pMesh->GetNumNormals()) f[2] = ~0; pMesh->AddVertexToFace(iFace, f[0], f[1], f[2]); } } } free(pszEntireFile); m_pScene->SetWorkListener(m_pWorkListener); m_pScene->CalculateExtends(); for (size_t i = 0; i < m_pScene->GetNumMeshes(); i++) { m_pScene->GetMesh(i)->CalculateEdgeData(); if (bSmoothingGroups || m_pScene->GetMesh(i)->GetNumNormals() == 0) m_pScene->GetMesh(i)->CalculateVertexNormals(); m_pScene->GetMesh(i)->CalculateVertexTangents(); } if (m_pWorkListener) m_pWorkListener->EndProgress(); }
void CModelConverter::ReadMTL(const tstring& sFilename) { FILE* fp = tfopen(sFilename, _T("r")); if (!fp) return; if (m_pWorkListener) m_pWorkListener->SetAction(_T("Reading materials"), 0); size_t iCurrentMaterial = ~0; tstring sLine; while (fgetts(sLine, fp)) { sLine = StripWhitespace(sLine); if (sLine.length() == 0) continue; if (sLine[0] == '#') continue; eastl::vector<tstring> asTokens; tstrtok(sLine, asTokens, _T(" ")); const tchar* pszToken = NULL; pszToken = asTokens[0].c_str(); CConversionMaterial* pMaterial = NULL; if (iCurrentMaterial != ~0) pMaterial = m_pScene->GetMaterial(iCurrentMaterial); if (tstrncmp(pszToken, _T("newmtl"), 6) == 0) { pszToken = asTokens[1].c_str(); CConversionMaterial oMaterial(pszToken, Vector(0.2f,0.2f,0.2f), Vector(0.8f,0.8f,0.8f), Vector(1,1,1), Vector(0,0,0), 1.0, 0); iCurrentMaterial = m_pScene->AddMaterial(oMaterial); } else if (tstrncmp(pszToken, _T("Ka"), 2) == 0) { eastl::vector<tstring> asTokens; tstrtok(sLine, asTokens, _T(" ")); if (asTokens.size() == 4) { pMaterial->m_vecAmbient.x = stof(asTokens[1]); pMaterial->m_vecAmbient.y = stof(asTokens[2]); pMaterial->m_vecAmbient.z = stof(asTokens[3]); } } else if (tstrncmp(pszToken, _T("Kd"), 2) == 0) { eastl::vector<tstring> asTokens; tstrtok(sLine, asTokens, _T(" ")); if (asTokens.size() == 4) { pMaterial->m_vecDiffuse.x = stof(asTokens[1]); pMaterial->m_vecDiffuse.y = stof(asTokens[2]); pMaterial->m_vecDiffuse.z = stof(asTokens[3]); } } else if (tstrncmp(pszToken, _T("Ks"), 2) == 0) { eastl::vector<tstring> asTokens; tstrtok(sLine, asTokens, _T(" ")); if (asTokens.size() == 4) { pMaterial->m_vecSpecular.x = stof(asTokens[1]); pMaterial->m_vecSpecular.y = stof(asTokens[2]); pMaterial->m_vecSpecular.z = stof(asTokens[3]); } } else if (tstrncmp(pszToken, _T("d"), 1) == 0 || tstrncmp(pszToken, _T("Tr"), 2) == 0) { pMaterial->m_flTransparency = (float)stof(asTokens[1]); } else if (tstrncmp(pszToken, _T("Ns"), 2) == 0) { pMaterial->m_flShininess = (float)stof(asTokens[1])*128/1000; } else if (tstrncmp(pszToken, _T("illum"), 5) == 0) { pMaterial->m_eIllumType = (IllumType_t)stoi(asTokens[1]); } else if (tstrncmp(pszToken, _T("map_Kd"), 6) == 0) { pszToken = asTokens[1].c_str(); FILE* fpTest = tfopen(pszToken, _T("r")); if (fpTest) { fclose(fpTest); pMaterial->m_sDiffuseTexture = tstring(pszToken); } else { tstring sDirectory = GetDirectory(sFilename); pMaterial->m_sDiffuseTexture = sprintf(tstring("%s/%s"), sDirectory.c_str(), pszToken); } } } fclose(fp); }
/* * Find a file on file_list. Outputs return a FILE*, while inputs return FIN*. */ PTR file_find(STRING * sval, int type) { PTR result = 0; FILE_NODE *p; FILE_NODE *q; char *name = sval->str; TRACE(("file_find(%s, %d)\n", name, type)); for (q = 0, p = file_list; p != 0; q = p, p = p->link) { /* search is by name and type */ if (strcmp(name, p->name->str) == 0 && (p->type == type || /* no distinction between F_APPEND and F_TRUNC here */ (p->type >= F_APPEND && type >= F_APPEND))) { if (q != 0) { /* delete from list for move to front */ q->link = p->link; } break; /* while loop */ } } if (!p) { /* open a new one */ p = alloc_filenode(); switch (p->type = (short) type) { case F_TRUNC: if (!(p->ptr = (PTR) tfopen(name, BinMode2("wb", "w")))) output_failed(name); break; case F_APPEND: if (!(p->ptr = (PTR) tfopen(name, BinMode2("ab", "a")))) output_failed(name); break; case F_IN: p->ptr = (PTR) FINopen(name, 0); break; case PIPE_OUT: case PIPE_IN: #if defined(HAVE_REAL_PIPES) || defined(HAVE_FAKE_PIPES) if (!(p->ptr = get_pipe(name, type, &p->pid))) { if (type == PIPE_OUT) output_failed(name); } #else rt_error("pipes not supported"); #endif break; #ifdef DEBUG default: bozo("bad file type"); #endif } } else if (p->ptr == 0 && type == F_IN) { p->ptr = (PTR) FINopen(name, 0); } /* put p at the front of the list */ if (p->ptr == 0) { free_filenode(p); } else { if (p != file_list) { p->link = file_list; file_list = p; } /* successful open */ p->name = sval; sval->ref_cnt++; TRACE(("-> %p\n", p->ptr)); result = p->ptr; } return result; }
bool CShader::Compile() { tstring sShaderHeader = CShaderLibrary::GetShaderHeader(); if (CShaderLibrary::Get()->m_iSamples) sShaderHeader += "#define USE_MULTISAMPLE_TEXTURES 1\n"; sShaderHeader += CShaderLibrary::GetShaderFunctions(); FILE* f = tfopen("shaders/" + m_sVertexFile + ".vs", "r"); TAssert(f); if (!f) return false; tstring sVertexShader = sShaderHeader; sVertexShader += "uniform mat4x4 mProjection;\n"; sVertexShader += "uniform mat4x4 mView;\n"; sVertexShader += "uniform mat4x4 mGlobal;\n"; tstring sLine; while (fgetts(sLine, f)) sVertexShader += sLine; fclose(f); f = tfopen("shaders/" + m_sFragmentFile + ".fs", "r"); TAssert(f); if (!f) return false; tstring sFragmentShader = sShaderHeader; sFragmentShader += "out vec4 vecOutputColor;\n"; while (fgetts(sLine, f)) sFragmentShader += sLine; fclose(f); size_t iVShader = glCreateShader(GL_VERTEX_SHADER); const char* pszStr = sVertexShader.c_str(); glShaderSource((GLuint)iVShader, 1, &pszStr, NULL); glCompileShader((GLuint)iVShader); int iVertexCompiled; glGetShaderiv((GLuint)iVShader, GL_COMPILE_STATUS, &iVertexCompiled); if (iVertexCompiled != GL_TRUE || Application()->HasCommandLineSwitch("--debug-gl")) { int iLogLength = 0; char szLog[1024]; glGetShaderInfoLog((GLuint)iVShader, 1024, &iLogLength, szLog); CShaderLibrary::Get()->WriteLog(m_sVertexFile + ".vs", szLog, pszStr); } size_t iFShader = glCreateShader(GL_FRAGMENT_SHADER); pszStr = sFragmentShader.c_str(); glShaderSource((GLuint)iFShader, 1, &pszStr, NULL); glCompileShader((GLuint)iFShader); int iFragmentCompiled; glGetShaderiv((GLuint)iFShader, GL_COMPILE_STATUS, &iFragmentCompiled); if (iFragmentCompiled != GL_TRUE || Application()->HasCommandLineSwitch("--debug-gl")) { int iLogLength = 0; char szLog[1024]; glGetShaderInfoLog((GLuint)iFShader, 1024, &iLogLength, szLog); CShaderLibrary::Get()->WriteLog(m_sFragmentFile + ".fs", szLog, pszStr); } size_t iProgram = glCreateProgram(); glBindAttribLocation(iProgram, 0, "vecPosition"); // Force position at location 0. ATI cards won't work without this. glAttachShader((GLuint)iProgram, (GLuint)iVShader); glAttachShader((GLuint)iProgram, (GLuint)iFShader); glLinkProgram((GLuint)iProgram); int iProgramLinked; glGetProgramiv((GLuint)iProgram, GL_LINK_STATUS, &iProgramLinked); if (iProgramLinked != GL_TRUE || Application()->HasCommandLineSwitch("--debug-gl")) { int iLogLength = 0; char szLog[1024]; glGetProgramInfoLog((GLuint)iProgram, 1024, &iLogLength, szLog); CShaderLibrary::Get()->WriteLog("link", szLog, "link"); } if (iVertexCompiled != GL_TRUE || iFragmentCompiled != GL_TRUE || iProgramLinked != GL_TRUE) { TError("Shader compilation failed for shader " + m_sName + ". Check shaders.txt\n"); Destroy(); return false; } m_iProgram = iProgram; m_iVShader = iVShader; m_iFShader = iFShader; m_iPositionAttribute = glGetAttribLocation(m_iProgram, "vecPosition"); m_iNormalAttribute = glGetAttribLocation(m_iProgram, "vecNormal"); m_iTangentAttribute = glGetAttribLocation(m_iProgram, "vecTangent"); m_iBitangentAttribute = glGetAttribLocation(m_iProgram, "vecBitangent"); for (size_t i = 0; i < MAX_TEXTURE_CHANNELS; i++) m_aiTexCoordAttributes[i] = glGetAttribLocation(m_iProgram, sprintf("vecTexCoord%d", i).c_str()); m_iColorAttribute = glGetAttribLocation(m_iProgram, "vecVertexColor"); glBindFragDataLocation(m_iProgram, 0, "vecOutputColor"); TAssert(m_iPositionAttribute != ~0); int iNumUniforms; glGetProgramiv(m_iProgram, GL_ACTIVE_UNIFORMS, &iNumUniforms); char szUniformName[256]; GLsizei iLength; GLint iSize; GLenum iType; for (int i = 0; i < iNumUniforms; i++) { glGetActiveUniform(m_iProgram, i, sizeof(szUniformName), &iLength, &iSize, &iType, szUniformName); tstring sUniformName = szUniformName; if (sUniformName == "mProjection") continue; if (sUniformName == "mView") continue; if (sUniformName == "mGlobal") continue; CShader::CUniform& oUniform = m_asUniforms[sUniformName]; oUniform.m_pDefault = nullptr; switch (iType) { case GL_FLOAT: oUniform.m_sUniformType = "float"; break; case GL_FLOAT_VEC2: oUniform.m_sUniformType = "vec2"; break; case GL_FLOAT_VEC3: oUniform.m_sUniformType = "vec3"; break; case GL_FLOAT_VEC4: oUniform.m_sUniformType = "vec4"; break; case GL_INT: oUniform.m_sUniformType = "int"; break; case GL_BOOL: oUniform.m_sUniformType = "bool"; break; case GL_FLOAT_MAT4: oUniform.m_sUniformType = "mat4"; break; case GL_SAMPLER_2D: oUniform.m_sUniformType = "sampler2D"; break; default: TUnimplemented(); } } for (auto it = m_aParameters.begin(); it != m_aParameters.end(); it++) { for (size_t j = 0; j < it->second.m_aActions.size(); j++) { auto it2 = m_asUniforms.find(it->second.m_aActions[j].m_sName); TAssert(it2 != m_asUniforms.end()); if (it2 == m_asUniforms.end()) { TError("Shader '" + m_sName + "' specifies a uniform '" + it->second.m_aActions[j].m_sName + "' that is not in the linked program.\n"); continue; } CShader::CUniform& oUniform = it2->second; // This is almost cheating CData d; d.SetValue(it->second.m_aActions[j].m_sValue); if (oUniform.m_sUniformType == "float") it->second.m_aActions[j].m_flValue = d.GetValueFloat(); else if (oUniform.m_sUniformType == "vec2") it->second.m_aActions[j].m_vec2Value = d.GetValueVector2D(); else if (oUniform.m_sUniformType == "vec3") it->second.m_aActions[j].m_vecValue = d.GetValueVector(); else if (oUniform.m_sUniformType == "vec4") it->second.m_aActions[j].m_vec4Value = d.GetValueVector4D(); else if (oUniform.m_sUniformType == "int") it->second.m_aActions[j].m_iValue = d.GetValueInt(); else if (oUniform.m_sUniformType == "bool") it->second.m_aActions[j].m_bValue = d.GetValueBool(); else if (oUniform.m_sUniformType == "mat4") { TUnimplemented(); } else if (oUniform.m_sUniformType == "sampler2D") { // No op. } else TUnimplemented(); } } for (auto it = m_aDefaults.begin(); it != m_aDefaults.end(); it++) { auto it2 = m_asUniforms.find(it->first); TAssert(it2 != m_asUniforms.end()); if (it2 == m_asUniforms.end()) { TError("Shader '" + m_sName + "' specifies a default for uniform '" + it->second.m_sName + "' that is not in the linked program.\n"); continue; } CShader::CUniform& oUniform = it2->second; oUniform.m_pDefault = &it->second; // Again with the cheating. CData d; d.SetValue(it->second.m_sValue); if (oUniform.m_sUniformType == "float") it->second.m_flValue = d.GetValueFloat(); else if (oUniform.m_sUniformType == "vec2") it->second.m_vec2Value = d.GetValueVector2D(); else if (oUniform.m_sUniformType == "vec3") it->second.m_vecValue = d.GetValueVector(); else if (oUniform.m_sUniformType == "vec4") it->second.m_vec4Value = d.GetValueVector4D(); else if (oUniform.m_sUniformType == "int") it->second.m_iValue = d.GetValueInt(); else if (oUniform.m_sUniformType == "bool") it->second.m_bValue = d.GetValueBool(); else if (oUniform.m_sUniformType == "mat4") { TUnimplemented(); } else if (oUniform.m_sUniformType == "sampler2D") { TUnimplemented(); // Can't set a default texture... yet. } else TUnimplemented(); } return true; }
void do_ISBN_file(/*@null@*/ const char *pathlist, /*@null@*/ const char *name) { FILE *fp; char *p; if (name == (const char*)NULL) return; if ((ISBN_file = findfile(pathlist,name)) == (char*)NULL) return; /* silently ignore missing files */ if ((fp = tfopen(ISBN_file,"r")) == (FILE*)NULL) return; /* silently ignore missing files */ /* The ISBN file is expected to look like the output of -print-ISBN-table: lines are (1) blank or empty, (2) comments from percent to end-of-line, (3) pairs of whitespace-separated (begin-prefix, end-prefix) values, or (4) triples of whitespace-separated (begin-prefix, end-prefix values, countries). In the latter case, the countries continue to end-of-line or a comment character, whichever comes first, and may include blanks. */ while ((p = get_line(fp)) != (char*)NULL) { const char *the_begin; const char *the_end; const char *the_countries; char *comment; comment = strchr(p, BIBTEX_COMMENT_PREFIX); if (comment != (const char*)NULL) *comment = '\0'; /* then discard comment text */ the_begin = strtok(p, TOKEN_SEPARATORS); if (the_begin == (const char*)NULL) continue; /* ignore blank or empty lines */ if (*the_begin == (char)BIBTEX_COMMENT_PREFIX) continue; /* ignore comment lines */ the_end = strtok((char*)NULL, TOKEN_SEPARATORS); if (the_end == (const char*)NULL) { fprintf(stdlog,"Expected end-prefix after begin-prefix [%s] in ISBN file [%s]\n", the_begin, ISBN_file); continue; } the_countries = strtok((char*)NULL, ""); if (the_countries != (const char*)NULL) { /* skip over leading space */ while (Isspace((int)*the_countries)) ++the_countries; } if ((the_countries != (const char*)NULL) && (*the_countries == '\0')) the_countries = (const char*)NULL; #if defined(DEBUG) fprintf(stdlog, "DEBUG:\t[%s]\t[%s]\t[%s]\t[%s]\n", ISBN_file, the_begin, the_end, ((the_countries == (const char*)NULL) ? "" : the_countries)); #endif add_ISBN_range(the_begin, the_end, the_countries); } (void)fclose(fp); }
bool CToyUtil::Read(const tstring& sFilename, CToy* pToy) { FILE* fp = tfopen(sFilename, "r"); if (!fp) return false; fseek(fp, 0L, SEEK_END); long iToySize = ftell(fp); fseek(fp, 0L, SEEK_SET); char* pBuffer = pToy->AllocateBase(iToySize); fread(pBuffer, iToySize, 1, fp); if (memcmp(pBuffer, g_szBaseHeader, sizeof(g_szBaseHeader)) != 0) return false; fclose(fp); if (pToy->GetNumMaterials()) { fp = tfopen(sFilename.substr(0, sFilename.length()-4) + ".mesh.toy", "r"); fseek(fp, 0L, SEEK_END); iToySize = ftell(fp); fseek(fp, 0L, SEEK_SET); char* pBuffer = pToy->AllocateMesh(iToySize); fread(pBuffer, iToySize, 1, fp); TAssert(memcmp(pBuffer, g_szMeshHeader, sizeof(g_szMeshHeader)) == 0); fclose(fp); } fp = tfopen(sFilename.substr(0, sFilename.length()-4) + ".phys.toy", "r"); if (fp) { fseek(fp, 0L, SEEK_END); iToySize = ftell(fp); fseek(fp, 0L, SEEK_SET); char* pBuffer = pToy->AllocatePhys(iToySize); fread(pBuffer, iToySize, 1, fp); TAssert(memcmp(pBuffer, g_szPhysHeader, sizeof(g_szPhysHeader)) == 0); fclose(fp); } if (pToy->GetNumSceneAreas()) { fp = tfopen(sFilename.substr(0, sFilename.length()-4) + ".area.toy", "r"); fseek(fp, 0L, SEEK_END); iToySize = ftell(fp); fseek(fp, 0L, SEEK_SET); char* pBuffer = pToy->AllocateArea(iToySize); fread(pBuffer, iToySize, 1, fp); TAssert(memcmp(pBuffer, g_szAreaHeader, sizeof(g_szAreaHeader)) == 0); fclose(fp); } return true; }
bool CToyUtil::Write(const tstring& sFilename) { CalculateVisibleAreas(); for (size_t i = m_asMaterials.size()-1; i < m_asMaterials.size(); i--) { // Must have at least one vertex or you get the boot. if (!m_aaflData[i].size()) { m_aaflData.erase(m_aaflData.begin()+i); m_asMaterials.erase(m_asMaterials.begin()+i); //m_asCopyTextures.erase(m_asCopyTextures.begin()+i); } } // Copy textures to the destination folders. /* for (size_t i = 0; i < m_asTextures.size(); i++) { if (!m_asCopyTextures[i].length()) continue; if (!m_asTextures[i].length()) continue; if (!CopyFileTo(m_asCopyTextures[i], m_asTextures[i], true)) TError("Couldn't copy texture '" + m_asCopyTextures[i] + "' to '" + m_asTextures[i] + "'.\n"); }*/ FILE* fp = tfopen(sFilename, "w"); TAssert(fp); if (!fp) return false; fwrite(g_szBaseHeader, sizeof(g_szBaseHeader), 1, fp); TAssert(sizeof(m_aabbVisBounds) == 4*6); fwrite(&m_aabbVisBounds, sizeof(m_aabbVisBounds), 1, fp); TAssert(sizeof(m_aabbPhysBounds) == 4*6); fwrite(&m_aabbPhysBounds, sizeof(m_aabbPhysBounds), 1, fp); uint8_t iMaterials = m_asMaterials.size(); fwrite(&iMaterials, sizeof(iMaterials), 1, fp); uint32_t iFirstMaterial = TOY_HEADER_SIZE; uint32_t iSizeSoFar = iFirstMaterial; for (size_t i = 0; i < m_asMaterials.size(); i++) { fwrite(&iSizeSoFar, sizeof(iSizeSoFar), 1, fp); uint32_t iVerts = (m_aaflData[i].size()/5); fwrite(&iVerts, sizeof(iVerts), 1, fp); uint32_t iSize = 0; iSize += MESH_MATERIAL_TEXNAME_LENGTH_SIZE; iSize += m_asMaterials[i].length()+1; iSize += (m_aaflData[i].size()/5)*MESH_MATERIAL_VERTEX_SIZE; iSizeSoFar += iSize; } uint32_t iSceneAreas = m_asSceneAreas.size(); fwrite(&iSceneAreas, sizeof(iSceneAreas), 1, fp); uint32_t iFirstScene = TOY_HEADER_SIZE; iSizeSoFar = iFirstScene; for (size_t i = 0; i < m_asSceneAreas.size(); i++) { fwrite(&iSizeSoFar, sizeof(iSizeSoFar), 1, fp); size_t iSize = 0; iSize += AREA_AABB_SIZE; iSize += AREA_VISIBLE_AREAS_SIZE; iSize += m_asSceneAreas[i].m_aiVisibleAreas.size()*AREA_VISIBLE_AREAS_STRIDE; iSize += AREA_VISIBLE_AREA_NAME_SIZE; iSize += m_asSceneAreas[i].m_sFileName.length()+1; iSizeSoFar += iSize; } fclose(fp); if (m_aaflData.size()) { fp = tfopen(sFilename.substr(0, sFilename.length()-4) + ".mesh.toy", "w"); TAssert(fp); if (!fp) return false; fwrite(g_szMeshHeader, sizeof(g_szMeshHeader), 1, fp); iMaterials = m_asMaterials.size(); for (size_t i = 0; i < m_asMaterials.size(); i++) { uint16_t iLength = m_asMaterials[i].length()+1; fwrite(&iLength, sizeof(iLength), 1, fp); fwrite(m_asMaterials[i].c_str(), iLength, 1, fp); fwrite(m_aaflData[i].data(), m_aaflData[i].size()*sizeof(float), 1, fp); } fclose(fp); } if (m_avecPhysVerts.size() || m_atrsPhysBoxes.size()) { fp = tfopen(sFilename.substr(0, sFilename.length()-4) + ".phys.toy", "w"); TAssert(fp); if (!fp) return false; fwrite(g_szPhysHeader, sizeof(g_szPhysHeader), 1, fp); uint32_t iVerts = m_avecPhysVerts.size(); fwrite(&iVerts, sizeof(iVerts), 1, fp); uint32_t iTris = m_aiPhysIndices.size()/3; fwrite(&iTris, sizeof(iTris), 1, fp); uint32_t iBoxes = m_atrsPhysBoxes.size(); fwrite(&iBoxes, sizeof(iBoxes), 1, fp); fwrite(m_avecPhysVerts.data(), m_avecPhysVerts.size()*sizeof(Vector), 1, fp); fwrite(m_aiPhysIndices.data(), m_aiPhysIndices.size()*sizeof(uint32_t), 1, fp); fwrite(m_atrsPhysBoxes.data(), m_atrsPhysBoxes.size()*sizeof(TRS), 1, fp); fclose(fp); } if (m_asSceneAreas.size()) { fp = tfopen(sFilename.substr(0, sFilename.length()-4) + ".area.toy", "w"); TAssert(fp); if (!fp) return false; fwrite(g_szAreaHeader, sizeof(g_szAreaHeader), 1, fp); for (size_t i = 0; i < m_asSceneAreas.size(); i++) { fwrite(&m_asSceneAreas[i].m_aabbArea, sizeof(m_asSceneAreas[i].m_aabbArea), 1, fp); uint32_t iAreasVisible = m_asSceneAreas[i].m_aiVisibleAreas.size(); fwrite(&iAreasVisible, sizeof(iAreasVisible), 1, fp); fwrite(m_asSceneAreas[i].m_aiVisibleAreas.data(), m_asSceneAreas[i].m_aiVisibleAreas.size()*sizeof(uint32_t), 1, fp); uint16_t iFileLength = m_asSceneAreas[i].m_sFileName.length()+1; fwrite(&iFileLength, sizeof(iFileLength), 1, fp); fwrite(m_asSceneAreas[i].m_sFileName.c_str(), iFileLength, 1, fp); } fclose(fp); } return true; }
// Load a file data into memory void* GOS::LoadFileIntoMemory(const tchar* szFileName, uint32* pSize) { /* // Windows version HANDLE hFile = INVALID_HANDLE_VALUE; uint32 nFileSize = 0; void* ptr = NULL; hFile = ::CreateFile(szFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS, NULL); if(hFile == INVALID_HANDLE_VALUE) { return NULL; } nFileSize = ::GetFileSize(hFile, NULL); ptr = ::malloc(nFileSize); if(!ptr) { ::CloseHandle(hFile); return NULL; } if(::ReadFile(hFile, ptr, nFileSize, &nFileSize, NULL ) == 0) { ::CloseHandle(hFile); ::free(ptr); return NULL; } ::CloseHandle(hFile); if(pSize) { (*pSize) = nFileSize; } return ptr; */ uint32 nFileSize = 0; FILE* hFile = NULL; void* ptr = NULL; // Get the file size nFileSize = GOS::GetFileSize(szFileName); if(nFileSize <= 0) { return NULL; } hFile = tfopen(szFileName, CTEXT("rb")); if(hFile == NULL) { return NULL; } ptr = malloc(nFileSize); if(!ptr) { fclose(hFile); return NULL; } if(0 == tfread(ptr, nFileSize, 1, hFile)) { tfclose(hFile); free(ptr); return NULL; } tfclose(hFile); if(pSize) { (*pSize) = nFileSize; } return ptr; }
const tchar* CModelConverter::ReadSIAMat(const tchar* pszLine, const tchar* pszEnd, CConversionSceneNode* pScene, const tstring& sFilename) { if (m_pWorkListener) m_pWorkListener->SetAction("Reading materials", 0); size_t iCurrentMaterial = m_pScene->AddMaterial(""); CConversionMaterial* pMaterial = m_pScene->GetMaterial(iCurrentMaterial); const tchar* pszNextLine = NULL; while (pszLine < pszEnd) { if (pszNextLine) pszLine = pszNextLine; pszNextLine = pszLine + tstrlen(pszLine) + 1; // This code used to call StripWhitespace() but that's too slow for very large files w/ millions of lines. // Instead we'll just cut the whitespace off the front and deal with whitespace on the end when we come to it. while (*pszLine && IsWhitespace(*pszLine)) pszLine++; if (tstrlen(pszLine) == 0) continue; tvector<tstring> aTokens; tstrtok(pszLine, aTokens, " "); const tchar* pszToken = aTokens[0].c_str(); if (tstrncmp(pszToken, "-name", 5) == 0) { tstring sName = pszLine+6; tvector<tstring> aName; tstrtok(sName, aName, "\""); // Strip out the quotation marks. pMaterial->m_sName = aName[0]; } else if (tstrncmp(pszToken, "-dif", 4) == 0) { tvector<tstring> asTokens; tstrtok(pszLine, asTokens, " "); if (asTokens.size() == 4) { pMaterial->m_vecDiffuse.x = (float)stof(asTokens[1]); pMaterial->m_vecDiffuse.y = (float)stof(asTokens[2]); pMaterial->m_vecDiffuse.z = (float)stof(asTokens[3]); } } else if (tstrncmp(pszToken, "-amb", 4) == 0) { tvector<tstring> asTokens; tstrtok(pszLine, asTokens, " "); if (asTokens.size() == 4) { pMaterial->m_vecAmbient.x = (float)stof(asTokens[1]); pMaterial->m_vecAmbient.y = (float)stof(asTokens[2]); pMaterial->m_vecAmbient.z = (float)stof(asTokens[3]); } } else if (tstrncmp(pszToken, "-spec", 5) == 0) { tvector<tstring> asTokens; tstrtok(pszLine, asTokens, " "); if (asTokens.size() == 4) { pMaterial->m_vecSpecular.x = (float)stof(asTokens[1]); pMaterial->m_vecSpecular.y = (float)stof(asTokens[2]); pMaterial->m_vecSpecular.z = (float)stof(asTokens[3]); } } else if (tstrncmp(pszToken, "-emis", 5) == 0) { tvector<tstring> asTokens; tstrtok(pszLine, asTokens, " "); if (asTokens.size() == 4) { pMaterial->m_vecEmissive.x = (float)stof(asTokens[1]); pMaterial->m_vecEmissive.y = (float)stof(asTokens[2]); pMaterial->m_vecEmissive.z = (float)stof(asTokens[3]); } } else if (tstrncmp(pszToken, "-shin", 5) == 0) { tvector<tstring> asTokens; tstrtok(pszLine, asTokens, " "); if (asTokens.size() == 2) pMaterial->m_flShininess = (float)stof(asTokens[1]); } else if (tstrncmp(pszToken, "-tex", 4) == 0) { const tchar* pszTexture = pszLine+5; tstring sName = pszTexture; tvector<tstring> aName; tstrtok(sName, aName, "\""); // Strip out the quotation marks. FILE* fpTest = tfopen(aName[0].c_str(), "r"); if (fpTest) { fclose(fpTest); pMaterial->m_sDiffuseTexture = tstring(aName[0].c_str()); } else { if (IsAbsolutePath(aName[0])) pMaterial->m_sDiffuseTexture = aName[0]; else { tstring sDirectory = GetDirectory(sFilename); pMaterial->m_sDiffuseTexture = sprintf(tstring("%s/%s"), sDirectory.c_str(), aName[0].c_str()); } } } else if (tstrncmp(pszToken, "-endMat", 7) == 0) { return pszNextLine; } } return pszNextLine; }
void campaign( long g, int dd, int mm, int yy ) { FILE *fp; char buf[BUFSIZ], *p = NULL, *q = NULL, *r = NULL, *s = NULL; long m1, d1, m2, d2; long g1, g2; long cnt = 0; if ( ( fp = tfopen( campaignTblFile, "r" ) ) == NULL ) return; while ( ( p = fgets( buf, BUFSIZ - 1, fp ) ) != NULL ) { if ( (*p >= '0') && (*p <= '1') ) { q = strchr( p, '/' ); if ( q && (*(q + 1) >= '0' && (*(q + 1) <= '9')) ) { q++; m1 = atoi( p ); d1 = atoi( q ); r = strchr( q, ' ' ); if ( r && (*(r + 1) >= '0' && (*(r + 1) <= '1')) ) { r++; s = strchr( r, '/' ); if ( s && (*(s + 1) >= '0' && (*(s + 1) <= '9')) ) { s++; m2 = atoi( r ); d2 = atoi( s ); g1 = absoluteFromGregorian( d1, m1, yy ); g2 = absoluteFromGregorian( d2, m2, yy ); if ( g2 < g1 ) { if ( (g2 < g) && (g < g1) ) continue; if ( g1 <= g ) g2 = absoluteFromGregorian( d2, m2, yy + 1 ); else if ( g <= g2 ) g1 = absoluteFromGregorian( d1, m1, yy - 1 ); } if ( (m1 == 2) && (d1 == 29) ) { if ( !leapyear( yy ) ) { g1--; d1--; } } if ( (m2 == 2) && (d2 == 29) ) { if ( !leapyear( yy ) ) { g2--; d2--; } } if ( (g1 <= g) && (g <= g2) ) { p = strchr( s + 1, ' ' ); if ( !p ) p = strchr( s + 1, '\t' ); if ( p ) { printCampaign( p, d1, m1, d2, m2 ); cnt++; } } } } } } } tfclose( fp ); printCampaign2( &cnt, g, dd, mm, yy ); return; }
void CModelConverter::WriteSMD(size_t iMesh, const tstring& sFilename) { CConversionMesh* pMesh = m_pScene->GetMesh(iMesh); tstring sFile; if (sFilename.length()) { sFile.append(sFilename); sFile.append(_T("_")); } sFile.append(pMesh->GetBoneName(0)); sFile = GetFilename(sFile.c_str()); sFile.append(_T(".smd")); FILE* fp = tfopen(sFile, _T("w")); // SMD file format: http://developer.valvesoftware.com/wiki/SMD // Header section fprintf(fp, "version 1\n\n"); // Nodes section fprintf(fp, "nodes\n"); // Only bothering with one node, we're only doing static props with this code for now. fprintf(fp, "0 \"%s\" -1\n", convertstring<tchar, char>(pMesh->GetBoneName(0)).c_str()); fprintf(fp, "end\n\n"); // Skeleton section fprintf(fp, "skeleton\n"); fprintf(fp, "time 0\n"); fprintf(fp, "0 0.000000 0.000000 0.000000 1.570796 0.000000 0.0000001\n"); fprintf(fp, "end\n\n"); fprintf(fp, "triangles\n"); for (size_t i = 0; i < pMesh->GetNumFaces(); i++) { CConversionFace* pFace = pMesh->GetFace(i); if (!pFace->GetNumVertices()) { printf("WARNING! Found a face with no vertices.\n"); continue; } CConversionVertex* pV1 = pFace->GetVertex(0); for (size_t j = 0; j < pFace->GetNumVertices()-2; j++) { CConversionVertex* pV2 = pFace->GetVertex(j+1); CConversionVertex* pV3 = pFace->GetVertex(j+2); Vector v1 = pMesh->GetVertex(pV1->v); Vector v2 = pMesh->GetVertex(pV2->v); Vector v3 = pMesh->GetVertex(pV3->v); Vector n1 = pMesh->GetNormal(pV1->vn); Vector n2 = pMesh->GetNormal(pV2->vn); Vector n3 = pMesh->GetNormal(pV3->vn); Vector uv1 = pMesh->GetUV(pV1->vu); Vector uv2 = pMesh->GetUV(pV2->vu); Vector uv3 = pMesh->GetUV(pV3->vu); // Material name size_t iMaterial = pFace->m; if (iMaterial == ((size_t)~0) || !m_pScene->GetMaterial(iMaterial)) { printf("ERROR! Can't find a material for a triangle.\n"); fprintf(fp, "error\n"); } else fprintf(fp, "%s\n", convertstring<tchar, char>(m_pScene->GetMaterial(iMaterial)->GetName()).c_str()); // <int|Parent bone> <float|PosX PosY PosZ> <normal|NormX NormY NormZ> <normal|U V> // Studio coordinates are not the same as game coordinates. Studio (x, y, z) is game (x, -z, y) and vice versa. fprintf(fp, "0 \t %f %f %f \t %f %f %f \t %f %f\n", v1.x, -v1.z, v1.y, n1.x, -n1.z, n1.y, uv1.x, uv1.y); fprintf(fp, "0 \t %f %f %f \t %f %f %f \t %f %f\n", v2.x, -v2.z, v2.y, n2.x, -n2.z, n2.y, uv2.x, uv2.y); fprintf(fp, "0 \t %f %f %f \t %f %f %f \t %f %f\n", v3.x, -v3.z, v3.y, n3.x, -n3.z, n3.y, uv3.x, uv3.y); } } fprintf(fp, "end\n"); fclose(fp); }