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);

}
示例#2
0
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;
}
示例#3
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);
}
示例#4
0
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;
}
示例#5
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;
}
示例#6
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;

    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;
}
示例#7
0
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;
}
示例#8
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();
}
示例#9
0
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();
}
示例#10
0
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");
}