void TextureFilterHandler::init() { if (isInited()) return; m_inited = config.textureFilter.txFilterMode | config.textureFilter.txEnhancementMode | config.textureFilter.txHiresEnable; if (m_inited == 0) return; m_options = _getConfigOptions(); s32 maxTextureSize = gfxContext.getMaxTextureSize(); wchar_t wRomName[32]; ::mbstowcs(wRomName, RSP.romname, 32); wchar_t txPath[PLUGIN_PATH_SIZE + 16]; wchar_t * pTexPackPath = config.textureFilter.txPath; if (::wcslen(config.textureFilter.txPath) == 0) { api().GetUserDataPath(txPath); gln_wcscat(txPath, wst("/hires_texture")); pTexPackPath = txPath; } wchar_t txCachePath[PLUGIN_PATH_SIZE]; api().GetUserCachePath(txCachePath); m_inited = txfilter_init(maxTextureSize, // max texture width supported by hardware maxTextureSize, // max texture height supported by hardware 32, // max texture bpp supported by hardware m_options, config.textureFilter.txCacheSize, // cache texture to system memory txCachePath, // path to store cache files pTexPackPath, // path to texture packs folder wRomName, // name of ROM. must be no longer than 256 characters displayLoadProgress); }
boolean TxCache::get(uint64 checksum, GHQTexInfo *info) { if (!checksum || _cache.empty()) return 0; /* find a match in cache */ std::map<uint64, TXCACHE*>::iterator itMap = _cache.find(checksum); if (itMap != _cache.end()) { /* yep, we've got it. */ memcpy(info, &(((*itMap).second)->info), sizeof(GHQTexInfo)); /* push it to the back of the list */ if (_cacheSize > 0) { _cachelist.erase(((*itMap).second)->it); _cachelist.push_back(checksum); ((*itMap).second)->it = --(_cachelist.end()); } /* zlib decompress it */ if (info->format & GL_TEXFMT_GZ) { uLongf destLen = _gzdestLen; uint8 *dest = (_gzdest0 == info->data) ? _gzdest1 : _gzdest0; if (uncompress(dest, &destLen, info->data, ((*itMap).second)->size) != Z_OK) { DBG_INFO(80, wst("Error: zlib decompression failed!\n")); return 0; } info->data = dest; info->format &= ~GL_TEXFMT_GZ; DBG_INFO(80, wst("zlib decompressed: %.02fkb->%.02fkb\n"), (float)(((*itMap).second)->size)/1000, (float)destLen/1000); } return 1; } return 0; }
void TxDbg::output(const int level, const wchar_t *format, ...) { if (level > _level) return; va_list args; wchar_t newformat[4095]; va_start(args, format); tx_swprintf(newformat, 4095, wst("%d:\t"), level); wcscat(newformat, format); vfwprintf(_dbgfile, newformat, args); fflush(_dbgfile); #ifdef GHQCHK //vwprintf(newformat, args); vwprintf(newformat.c_str(), args); #endif va_end(args); }
boolean TxCache::del(uint64 checksum) { if (!checksum || _cache.empty()) return 0; std::map<uint64, TXCACHE*>::iterator itMap = _cache.find(checksum); if (itMap != _cache.end()) { /* for texture cache (not hi-res cache) */ if (!_cachelist.empty()) _cachelist.erase(((*itMap).second)->it); /* remove from cache */ free((*itMap).second->info.data); _totalSize -= (*itMap).second->size; delete (*itMap).second; _cache.erase(itMap); DBG_INFO(80, wst("removed from cache: checksum = %08X %08X\n"), (uint32)(checksum & 0xffffffff), (uint32)(checksum >> 32)); return 1; } return 0; }
void Config::resetToDefaults() { version = CONFIG_VERSION_CURRENT; #if defined(PANDORA) || defined(VC) video.fullscreen = 1; video.fullscreenWidth = video.windowedWidth = 800; #else video.fullscreen = 0; video.fullscreenWidth = video.windowedWidth = 640; #endif video.fullscreenHeight = video.windowedHeight = 480; video.fullscreenRefresh = 60; video.multisampling = 0; video.verticalSync = 0; video.cropMode = cmDisable; video.cropWidth = video.cropHeight = 0; video.rotate = 0; texture.maxAnisotropy = 0; texture.bilinearMode = BILINEAR_STANDARD; texture.maxBytes = 500 * gc_uMegabyte; texture.screenShotFormat = 0; generalEmulation.enableLOD = 1; generalEmulation.enableNoise = 1; generalEmulation.enableHWLighting = 0; generalEmulation.enableCustomSettings = 1; generalEmulation.enableShadersStorage = 1; generalEmulation.correctTexrectCoords = tcDisable; generalEmulation.enableNativeResTexrects = 0; generalEmulation.enableLegacyBlending = 0; generalEmulation.hacks = 0; #ifdef GLES2 generalEmulation.enableFragmentDepthWrite = 0; #else generalEmulation.enableFragmentDepthWrite = 1; #endif generalEmulation.enableBlitScreenWorkaround = 0; #ifdef ANDROID generalEmulation.forcePolygonOffset = 0; generalEmulation.polygonOffsetFactor = 0.0f; generalEmulation.polygonOffsetUnits = 0.0f; #endif frameBufferEmulation.enable = 1; frameBufferEmulation.copyDepthToRDRAM = cdSoftwareRender; frameBufferEmulation.copyFromRDRAM = 0; frameBufferEmulation.copyAuxToRDRAM = 0; frameBufferEmulation.copyToRDRAM = ctAsync; frameBufferEmulation.N64DepthCompare = 0; frameBufferEmulation.aspect = a43; frameBufferEmulation.bufferSwapMode = bsOnVerticalInterrupt; frameBufferEmulation.nativeResFactor = 0; frameBufferEmulation.fbInfoReadColorChunk = 0; frameBufferEmulation.fbInfoReadDepthChunk = 1; #ifndef MUPENPLUSAPI frameBufferEmulation.fbInfoDisabled = 0; #else frameBufferEmulation.fbInfoDisabled = 1; #endif textureFilter.txFilterMode = 0; textureFilter.txEnhancementMode = 0; textureFilter.txDeposterize = 0; textureFilter.txFilterIgnoreBG = 0; textureFilter.txCacheSize = 100 * gc_uMegabyte; textureFilter.txHiresEnable = 0; textureFilter.txHiresFullAlphaChannel = 0; textureFilter.txHresAltCRC = 0; textureFilter.txDump = 0; textureFilter.txForce16bpp = 0; textureFilter.txCacheCompression = 1; textureFilter.txSaveCache = 1; api().GetUserDataPath(textureFilter.txPath); gln_wcscat(textureFilter.txPath, wst("/hires_texture")); #ifdef OS_WINDOWS font.name.assign("arial.ttf"); #elif defined (ANDROID) font.name.assign("DroidSans.ttf"); #elif defined (PANDORA) font.name.assign("LiberationMono-Regular.ttf"); #else font.name = "FreeSans.ttf"; #endif font.size = 18; font.color[0] = 0xB5; font.color[1] = 0xE6; font.color[2] = 0x1D; font.color[3] = 0xFF; for (int i = 0; i < 4; ++i) font.colorf[i] = font.color[i] / 255.0f; bloomFilter.enable = 0; bloomFilter.thresholdLevel = 4; bloomFilter.blendMode = 0; bloomFilter.blurAmount = 10; bloomFilter.blurStrength = 20; gammaCorrection.force = 0; gammaCorrection.level = 2.0f; onScreenDisplay.vis = 0; onScreenDisplay.fps = 0; onScreenDisplay.percent = 0; onScreenDisplay.pos = posBottomLeft; }
void Config::resetToDefaults() { version = CONFIG_VERSION_CURRENT; #if defined(PANDORA) || defined(VC) video.fullscreen = 1; video.fullscreenWidth = video.windowedWidth = 800; #else video.fullscreen = 0; video.fullscreenWidth = video.windowedWidth = 640; #endif video.fullscreenHeight = video.windowedHeight = 480; video.fullscreenRefresh = 60; video.multisampling = 0; video.verticalSync = 0; texture.maxAnisotropy = 0; texture.bilinearMode = BILINEAR_STANDARD; texture.maxBytes = 500 * gc_uMegabyte; texture.screenShotFormat = 0; generalEmulation.enableFog = 1; generalEmulation.enableLOD = 1; generalEmulation.enableNoise = 1; generalEmulation.enableHWLighting = 0; generalEmulation.enableCustomSettings = 1; generalEmulation.enableShadersStorage = 1; generalEmulation.hacks = 0; #ifdef ANDROID generalEmulation.forcePolygonOffset = 0; generalEmulation.polygonOffsetFactor = 0.0f; generalEmulation.polygonOffsetUnits = 0.0f; #endif #ifdef VC frameBufferEmulation.enable = 0; #else frameBufferEmulation.enable = 1; #endif frameBufferEmulation.copyDepthToRDRAM = ctDisable; frameBufferEmulation.copyFromRDRAM = 0; frameBufferEmulation.copyToRDRAM = ctSync; frameBufferEmulation.detectCFB = 0; frameBufferEmulation.N64DepthCompare = 0; frameBufferEmulation.aspect = 1; textureFilter.txCacheSize = 100 * gc_uMegabyte; textureFilter.txDump = 0; textureFilter.txEnhancementMode = 0; textureFilter.txFilterIgnoreBG = 0; textureFilter.txFilterMode = 0; textureFilter.txHiresEnable = 0; textureFilter.txHiresFullAlphaChannel = 0; textureFilter.txHresAltCRC = 0; textureFilter.txCacheCompression = 1; textureFilter.txForce16bpp = 0; textureFilter.txSaveCache = 1; api().GetUserDataPath(textureFilter.txPath); gln_wcscat(textureFilter.txPath, wst("/hires_texture")); #ifdef OS_WINDOWS font.name.assign("arial.ttf"); #elif defined (ANDROID) font.name.assign("DroidSans.ttf"); #elif defined (PANDORA) font.name.assign("LiberationMono-Regular.ttf"); #else font.name = "FreeSans.ttf"; #endif font.size = 18; font.color[0] = 0xB5; font.color[1] = 0xE6; font.color[2] = 0x1D; font.color[3] = 0xFF; for (int i = 0; i < 4; ++i) font.colorf[i] = font.color[i] / 255.0f; bloomFilter.enable = 0; bloomFilter.thresholdLevel = 4; bloomFilter.blendMode = 0; bloomFilter.blurAmount = 10; bloomFilter.blurStrength = 20; }
boolean TxCache::add(uint64 checksum, GHQTexInfo *info, int dataSize) { /* NOTE: dataSize must be provided if info->data is zlib compressed. */ if (!checksum || !info->data) return 0; uint8 *dest = info->data; uint32 format = info->format; if (!dataSize) { dataSize = TxUtil::sizeofTx(info->width, info->height, info->format); if (!dataSize) return 0; if (_options & (GZ_TEXCACHE|GZ_HIRESTEXCACHE)) { /* zlib compress it. compression level:1 (best speed) */ uLongf destLen = _gzdestLen; dest = (dest == _gzdest0) ? _gzdest1 : _gzdest0; if (compress2(dest, &destLen, info->data, dataSize, 1) != Z_OK) { dest = info->data; DBG_INFO(80, wst("Error: zlib compression failed!\n")); } else { DBG_INFO(80, wst("zlib compressed: %.02fkb->%.02fkb\n"), (float)dataSize/1000, (float)destLen/1000); dataSize = destLen; format |= GL_TEXFMT_GZ; } } } /* if cache size exceeds limit, remove old cache */ if (_cacheSize > 0) { _totalSize += dataSize; if ((_totalSize > _cacheSize) && !_cachelist.empty()) { /* _cachelist is arranged so that frequently used textures are in the back */ std::list<uint64>::iterator itList = _cachelist.begin(); while (itList != _cachelist.end()) { /* find it in _cache */ std::map<uint64, TXCACHE*>::iterator itMap = _cache.find(*itList); if (itMap != _cache.end()) { /* yep we have it. remove it. */ _totalSize -= (*itMap).second->size; free((*itMap).second->info.data); delete (*itMap).second; _cache.erase(itMap); } itList++; /* check if memory cache has enough space */ if (_totalSize <= _cacheSize) break; } /* remove from _cachelist */ _cachelist.erase(_cachelist.begin(), itList); DBG_INFO(80, wst("+++++++++\n")); } _totalSize -= dataSize; } /* cache it */ uint8 *tmpdata = (uint8*)malloc(dataSize); if (tmpdata) { TXCACHE *txCache = new TXCACHE; if (txCache) { /* we can directly write as we filter, but for now we get away * with doing memcpy after all the filtering is done. */ memcpy(tmpdata, dest, dataSize); /* copy it */ memcpy(&txCache->info, info, sizeof(GHQTexInfo)); txCache->info.data = tmpdata; txCache->info.format = format; txCache->size = dataSize; /* add to cache */ if (_cacheSize > 0) { _cachelist.push_back(checksum); txCache->it = --(_cachelist.end()); } /* _cache[checksum] = txCache; */ _cache.insert(std::map<uint64, TXCACHE*>::value_type(checksum, txCache)); #ifdef DEBUG DBG_INFO(80, wst("[%5d] added!! crc:%08X %08X %d x %d gfmt:%x total:%.02fmb\n"), _cache.size(), (uint32)(checksum >> 32), (uint32)(checksum & 0xffffffff), info->width, info->height, info->format & 0xffff, (float)_totalSize/1000000); if (_cacheSize > 0) { DBG_INFO(80, wst("cache max config:%.02fmb\n"), (float)_cacheSize/1000000); if (_cache.size() != _cachelist.size()) { DBG_INFO(80, wst("Error: cache/cachelist mismatch! (%d/%d)\n"), _cache.size(), _cachelist.size()); } } #endif /* total cache size */ _totalSize += dataSize; return 1; } free(tmpdata); } return 0; }
boolean TxCache::load(const wchar_t *path, const wchar_t *filename, int config) { /* find it on disk */ char cbuf[MAX_PATH]; #ifdef OS_WINDOWS wchar_t curpath[MAX_PATH]; GETCWD(MAX_PATH, curpath); CHDIR(path); #else char curpath[MAX_PATH]; GETCWD(MAX_PATH, curpath); wcstombs(cbuf, path, MAX_PATH); CHDIR(cbuf); #endif wcstombs(cbuf, filename, MAX_PATH); gzFile gzfp = gzopen(cbuf, "rb"); DBG_INFO(80, wst("gzfp:%x file:%ls\n"), gzfp, filename); if (gzfp) { /* yep, we have it. load it into memory cache. */ int dataSize; uint64 checksum; int tmpconfig; /* read header to determine config match */ gzread(gzfp, &tmpconfig, 4); if (tmpconfig == config) { do { GHQTexInfo tmpInfo; gzread(gzfp, &checksum, 8); gzread(gzfp, &tmpInfo.width, 4); gzread(gzfp, &tmpInfo.height, 4); gzread(gzfp, &tmpInfo.format, 4); gzread(gzfp, &tmpInfo.texture_format, 2); gzread(gzfp, &tmpInfo.pixel_type, 2); gzread(gzfp, &tmpInfo.is_hires_tex, 1); gzread(gzfp, &dataSize, 4); tmpInfo.data = (uint8*)malloc(dataSize); if (tmpInfo.data) { gzread(gzfp, tmpInfo.data, dataSize); /* add to memory cache */ add(checksum, &tmpInfo, (tmpInfo.format & GL_TEXFMT_GZ) ? dataSize : 0); free(tmpInfo.data); } else { gzseek(gzfp, dataSize, SEEK_CUR); } /* skip in between to prevent the loop from being tied down to vsync */ if (_callback && (!(_cache.size() % 100) || gzeof(gzfp))) (*_callback)(wst("[%d] total mem:%.02fmb - %ls\n"), _cache.size(), (float)_totalSize/1000000, filename); } while (!gzeof(gzfp)); gzclose(gzfp); } } CHDIR(curpath); return !_cache.empty(); }
boolean TxCache::save(const wchar_t *path, const wchar_t *filename, int config) { if (_cache.empty()) return true; /* dump cache to disk */ char cbuf[MAX_PATH]; osal_mkdirp(path); /* Ugly hack to enable fopen/gzopen in Win9x */ #ifdef OS_WINDOWS wchar_t curpath[MAX_PATH]; GETCWD(MAX_PATH, curpath); CHDIR(path); #else char curpath[MAX_PATH]; GETCWD(MAX_PATH, curpath); wcstombs(cbuf, path, MAX_PATH); CHDIR(cbuf); #endif wcstombs(cbuf, filename, MAX_PATH); gzFile gzfp = gzopen(cbuf, "wb1"); DBG_INFO(80, wst("gzfp:%x file:%ls\n"), gzfp, filename); if (gzfp) { /* write header to determine config match */ gzwrite(gzfp, &config, 4); std::map<uint64, TXCACHE*>::iterator itMap = _cache.begin(); int total = 0; while (itMap != _cache.end()) { uint8 *dest = (*itMap).second->info.data; uint32 destLen = (*itMap).second->size; uint32 format = (*itMap).second->info.format; /* to keep things simple, we save the texture data in a zlib uncompressed state. */ /* sigh... for those who cannot wait the extra few seconds. changed to keep * texture data in a zlib compressed state. if the GZ_TEXCACHE or GZ_HIRESTEXCACHE * option is toggled, the cache will need to be rebuilt. */ /*if (format & GL_TEXFMT_GZ) { dest = _gzdest0; destLen = _gzdestLen; if (dest && destLen) { if (uncompress(dest, &destLen, (*itMap).second->info.data, (*itMap).second->size) != Z_OK) { dest = nullptr; destLen = 0; } format &= ~GL_TEXFMT_GZ; } }*/ if (dest && destLen) { /* texture checksum */ gzwrite(gzfp, &((*itMap).first), 8); /* other texture info */ gzwrite(gzfp, &((*itMap).second->info.width), 4); gzwrite(gzfp, &((*itMap).second->info.height), 4); gzwrite(gzfp, &format, 4); gzwrite(gzfp, &((*itMap).second->info.texture_format), 2); gzwrite(gzfp, &((*itMap).second->info.pixel_type), 2); gzwrite(gzfp, &((*itMap).second->info.is_hires_tex), 1); gzwrite(gzfp, &destLen, 4); gzwrite(gzfp, dest, destLen); } itMap++; if (_callback) (*_callback)(wst("Total textures saved to HDD: %d\n"), ++total); } gzclose(gzfp); } CHDIR(curpath); return _cache.empty(); }
void ASE_Loader::Write(SE_BufferOutput& output, SE_BufferOutput& outScene, const char* shaderPath) { int materialNum = mSceneObject->mMats.size(); int numWhichHasSubmaterial = 0; int materialRealNum = materialNum; int i; for(i = 0 ; i < materialNum ; i++) { ASE_Material* srcm = &mSceneObject->mMats[i]; materialRealNum += srcm->numsubmaterials; if(srcm->numsubmaterials > 0) { numWhichHasSubmaterial++; } } std::vector<_MaterialData> materialVector(materialRealNum); std::vector<int> indexWhichHasSubmaterial(numWhichHasSubmaterial); int l = 0; int mi = 0; for(i = 0 ; i < materialNum ; i++) { ASE_Material* srcm = &mSceneObject->mMats[i]; _MaterialData md; md.subMaterialNum = srcm->numsubmaterials; md.md = srcm->materialData; materialVector[mi++] = md; if(srcm->numsubmaterials > 0) { indexWhichHasSubmaterial[l++] = i; } } std::vector<int>::iterator it; for(it = indexWhichHasSubmaterial.begin() ; it != indexWhichHasSubmaterial.end() ; it++) { int index = *it; ASE_Material* m = &mSceneObject->mMats[index]; for(int j = 0 ; j < m->numsubmaterials ; j++) { _MaterialData md; md.subMaterialNum = 0; md.md = m->submaterials[j]; materialVector[mi++] = md; } } std::vector<_MaterialData>::iterator itMaterial; output.writeShort(SE_MATERIALDATA_ID); output.writeInt(materialVector.size()); int mmm = materialVector.size(); //for(itMaterial = materialVector.begin() ; itMaterial != materialVector.end() ; itMaterial++) for(i = 0 ; i < materialVector.size() ; i++) { SE_MaterialDataID mid = SE_Application::getInstance()->createCommonID(); mid.print(); SE_Util::sleep(SLEEP_COUNT); materialVector[i].mid = mid; mid.write(output); output.writeVector3f(materialVector[i].md.ambient); output.writeVector3f(materialVector[i].md.diffuse); output.writeVector3f(materialVector[i].md.specular); output.writeVector3f(SE_Vector3f(0, 0, 0)); } /////////////////////////////write texture data /////////////// output.writeShort(SE_IMAGEDATA_ID); int imageDataNum = 0; for(itMaterial = materialVector.begin() ; itMaterial != materialVector.end() ; itMaterial++) { std::string texStr(itMaterial->md.texName); if(texStr != "") { imageDataNum++; } } output.writeInt(imageDataNum); for(itMaterial = materialVector.begin() ; itMaterial != materialVector.end() ; itMaterial++) { std::string texStr(itMaterial->md.texName); if(texStr != "") { size_t pos = texStr.find('.'); std::string name = texStr.substr(0, pos); name = name + ".raw"; SE_ImageDataID tid = texStr.c_str(); itMaterial->tid = tid; tid.write(output); output.writeInt(0); // image data type output.writeString(name.c_str()); } } /////////////////////////////write geom data ///////////////////////////////////////////// output.writeShort(SE_GEOMETRYDATA_ID); int geomDataNum = mSceneObject->mGeomObjects.size(); output.writeInt(geomDataNum); std::vector<_GeomTexCoordData> geomTexCoordData(geomDataNum); std::list<ASE_GeometryObject*>::iterator itGeomObj; int n = 0; SE_Matrix4f modelToWorldM, worldToModelM; SE_Matrix3f rotateM; SE_Quat rotateQ; SE_Vector3f rotateAxis, scale, translate; for(itGeomObj = mSceneObject->mGeomObjects.begin(); itGeomObj != mSceneObject->mGeomObjects.end(); itGeomObj++) { ASE_GeometryObject* go = *itGeomObj; ASE_Mesh* mesh = go->mesh; SE_GeometryDataID gid = SE_Application::getInstance()->createCommonID(); SE_Util::sleep(SLEEP_COUNT); rotateAxis.x = go->rotateAxis[0]; rotateAxis.y = go->rotateAxis[1]; rotateAxis.z = go->rotateAxis[2]; scale.x = go->scale[0]; scale.y = go->scale[1]; scale.z = go->scale[2]; translate.x = go->translate[0]; translate.y = go->translate[1]; translate.z = go->translate[2]; rotateQ.set(go->rotateAngle, rotateAxis); rotateM = rotateQ.toMatrix3f();//.setRotateFromAxis(go->rotateAngle, rotateAxis); modelToWorldM.set(rotateM, scale, translate); worldToModelM = modelToWorldM.inverse(); geomTexCoordData[n++].geomID = gid; gid.write(output); output.writeInt(mesh->numVertexes); output.writeInt(mesh->numFaces); output.writeInt(0); int i; for(i = 0 ; i < mesh->numVertexes ; i++) { SE_Vector4f p(mesh->vertexes[i].x, mesh->vertexes[i].y, mesh->vertexes[i].z, 1.0f); p = worldToModelM.map(p); output.writeFloat(p.x); output.writeFloat(p.y); output.writeFloat(p.z); } for(i = 0 ; i < mesh->numFaces ; i++) { output.writeInt(mesh->faces[i].vi[0]); output.writeInt(mesh->faces[i].vi[1]); output.writeInt(mesh->faces[i].vi[2]); } } ////////////////////////write texture coordinate/////////////////////////////////////////////// output.writeShort(SE_TEXCOORDDATA_ID); output.writeInt(geomDataNum); n = 0; for(itGeomObj = mSceneObject->mGeomObjects.begin(); itGeomObj != mSceneObject->mGeomObjects.end(); itGeomObj++) { ASE_GeometryObject* go = *itGeomObj; ASE_Mesh* mesh = go->mesh; SE_TextureCoordDataID tcid = SE_Application::getInstance()->createCommonID(); SE_Util::sleep(SLEEP_COUNT); tcid.write(output); geomTexCoordData[n++].texCoordID = tcid; output.writeInt(mesh->numTVertexes); output.writeInt(mesh->numFaces); int i; for(i = 0 ; i < mesh->numTVertexes ; i++) { output.writeFloat(mesh->tvertexes[i].s); output.writeFloat(mesh->tvertexes[i].t); } for(i = 0 ; i < mesh->numFaces ; i++) { output.writeInt(mesh->tfaces[i].vi[0]); output.writeInt(mesh->tfaces[i].vi[1]); output.writeInt(mesh->tfaces[i].vi[2]); } } ///////////////////// write shader program //// output.writeShort(SE_SHADERPROGRAMDATA_ID); int spNum = 1; output.writeInt(spNum);// shader program num; std::vector<SE_ProgramDataID> programDataVector(spNum); for(i = 0 ; i < spNum ; i++) { SE_ProgramDataID proID = "main_vertex_shader"; programDataVector[i] = proID; SE_Util::sleep(SLEEP_COUNT); proID.write(output); std::string str(shaderPath); std::string vertexShaderPath = str + SE_SEP + "main_vertex_shader.glsl"; std::string fragmentShaderPath = str + SE_SEP + "main_fragment_shader.glsl"; char* vertexShader = NULL; int vertexShaderLen = 0; char* fragmentShader = NULL; int fragmentShaderLen = 0; SE_IO::readFileAll(vertexShaderPath.c_str(), vertexShader, vertexShaderLen); SE_IO::readFileAll(fragmentShaderPath.c_str(), fragmentShader, fragmentShaderLen); output.writeInt(vertexShaderLen); output.writeInt(fragmentShaderLen); output.writeBytes(vertexShader, vertexShaderLen); output.writeBytes(fragmentShader, fragmentShaderLen); delete[] vertexShader; delete[] fragmentShader; } ///////////////////// write mesh //////////////// std::vector<SE_MeshID> meshIDVector(geomDataNum); output.writeShort(SE_MESHDATA_ID); output.writeInt(geomDataNum); n = 0; for(itGeomObj = mSceneObject->mGeomObjects.begin(); itGeomObj != mSceneObject->mGeomObjects.end(); itGeomObj++) { ASE_GeometryObject* go = *itGeomObj; ASE_Mesh* mesh = go->mesh; SE_MeshID meshID = SE_Application::getInstance()->createCommonID(); SE_Util::sleep(SLEEP_COUNT); meshID.write(output); meshIDVector[n] = meshID; SE_GeometryDataID geomID = geomTexCoordData[n].geomID; SE_TextureCoordDataID texCoordID = geomTexCoordData[n].texCoordID; n++; geomID.write(output); output.writeFloat(go->wireframeColor[0]); output.writeFloat(go->wireframeColor[1]); output.writeFloat(go->wireframeColor[2]); int texNum = 0; int materialref = go->materialref; int startpos = 0; int subMaterialStartPos = 0; _MaterialData mdData; if(materialref == -1) { output.writeInt(texNum); goto WRIET_SURFACE; } mdData = materialVector[materialref]; if(mdData.subMaterialNum > 0) { int j; for(j = 0 ; j < (materialref - 1) ; j++) { _MaterialData d = materialVector[j]; startpos += d.subMaterialNum; } int k = startpos; for(int j = 0 ; j < mdData.subMaterialNum ; j++) { _MaterialData subMaterialData = materialVector[materialNum + k]; k++; std::string texStr(subMaterialData.md.texName); if(texStr != "") { texNum++; } } } else { std::string texStr(mdData.md.texName); if(texStr != "") { texNum = 1; } } output.writeInt(texNum); for(i = 0 ; i < texNum ; i++) { if(mdData.subMaterialNum > 0) { int j; for(j = 0 ; j < (materialref - 1) ; j++) { _MaterialData d = materialVector[j]; subMaterialStartPos += d.subMaterialNum; } for(int j = 0 ; j < mdData.subMaterialNum ; j++) { _MaterialData subMaterialData = materialVector[materialNum + subMaterialStartPos]; subMaterialStartPos++; std::string texStr(subMaterialData.md.texName); if(texStr != "") { output.writeInt(1);//current we just has one texture unit; output.writeInt(0);//texture unit type is TEXTURE0 texCoordID.write(output); output.writeInt(1);//image num use in the texture unit. current it is not mipmap. so the num is 1 subMaterialData.tid.write(output); } } } else { std::string texStr(mdData.md.texName); if(texStr != "") { output.writeInt(1);//current we just has one texture unit; output.writeInt(0);//texture unit type is TEXTURE0 texCoordID.write(output); output.writeInt(1);//image num use in the texture unit. current it is not mipmap. so the num is 1 mdData.tid.write(output); } } } ///write surface WRIET_SURFACE: if(mesh->numFaceGroup > 0) { SE_ASSERT(mesh->numFaceGroup == mesh->faceGroup.size()); output.writeInt(mesh->numFaceGroup); std::vector<std::list<int> >::iterator itFaceGroup; int indexM = startpos; int texIndex = 0; for(itFaceGroup = mesh->faceGroup.begin() ; itFaceGroup != mesh->faceGroup.end(); itFaceGroup++) { _MaterialData md = materialVector[materialNum + indexM]; std::string texStr(md.md.texName); md.mid.write(output); output.writeInt(itFaceGroup->size()); std::list<int>::iterator itFace; for(itFace = itFaceGroup->begin() ; itFace != itFaceGroup->end() ; itFace++) { output.writeInt(*itFace); } programDataVector[0].write(output); if(texStr != "") { output.writeInt(texIndex); } else { output.writeInt(-1); } indexM++; texIndex++; } } else { output.writeInt(1); //just has one surface std::string texStr(mdData.md.texName); mdData.mid.write(output); output.writeInt(mesh->numFaces); // facets num; for(int f = 0 ; f < mesh->numFaces ; f++) output.writeInt(f); programDataVector[0].write(output); if(texStr != "") { output.writeInt(0); // the texture index is 0; } else { output.writeInt(-1); } } } /////// create scene ////////// SE_SpatialID spatialID = SE_Application::getInstance()->createCommonID(); SE_Util::sleep(SLEEP_COUNT); SE_CommonNode* rootNode = new SE_CommonNode(spatialID, NULL); rootNode->setBVType(SE_BoundingVolume::AABB); n = 0; for(itGeomObj = mSceneObject->mGeomObjects.begin(); itGeomObj != mSceneObject->mGeomObjects.end(); itGeomObj++) { ASE_GeometryObject* go = *itGeomObj; ASE_Mesh* mesh = go->mesh; SE_MeshID meshID = meshIDVector[n++]; SE_SpatialID childID = SE_Application::getInstance()->createCommonID(); SE_Util::sleep(SLEEP_COUNT); SE_Geometry* child = new SE_Geometry(childID, rootNode); rootNode->addChild(child); SE_Vector3f translate, scale, rotateAxis; translate.x = go->translate[0]; translate.y = go->translate[1]; translate.z = go->translate[2]; scale.x = go->scale[0]; scale.y = go->scale[1]; scale.z = go->scale[2]; rotateAxis.x = go->rotateAxis[0]; rotateAxis.y = go->rotateAxis[1]; rotateAxis.z = go->rotateAxis[2]; child->setLocalTranslate(translate); //child->setLocalTranslate(SE_Vector3f(0, 0, 0)); child->setLocalScale(scale); //child->setLocalScale(SE_Vector3f(1.0, 1.0, 1.0)); SE_Quat q; q.set(go->rotateAngle, rotateAxis); child->setLocalRotate(q); //q.set(0, SE_Vector3f(0, 0, 0)); child->setBVType(SE_BoundingVolume::AABB); SE_MeshSimObject* meshObj = new SE_MeshSimObject(meshID); meshObj->setName(go->name); child->attachSimObject(meshObj); } SE_SceneID sceneID = SE_Application::getInstance()->createCommonID(); SE_Util::sleep(SLEEP_COUNT); sceneID.write(outScene); _WriteSceneTravel wst(outScene); rootNode->travel(&wst, true); LOGI("write end\n"); }