Пример #1
0
void OgreWidget::defineTerrain(long x, long y, bool flat)
{
    // First, we ask our TerrainGroup what file name it would use to generate the terrain. Then we check if
    // there is a file by that name in our resource group. If there is, it means that we generated a binary
    // terrain data file already, and thus there is no need to import it from an image. If there isn't a data
    // file present, it means we have to generate our terrain, and we load the image and uses that to define it.

    if(flat)
    {
        qDebug() << "OgreWidget::defineTerrain(): flat";
        mTerrainGroup->defineTerrain(x, y, 0.0f);
    }
    else
    {
        Ogre::String filename = mTerrainGroup->generateFilename(x, y);
        qDebug() << "OgreWidget::defineTerrain(): filename" << QString::fromStdString((std::string)filename) << "resourceGroup" << QString::fromStdString((std::string)mTerrainGroup->getResourceGroup());
        if(Ogre::ResourceGroupManager::getSingleton().resourceExists(mTerrainGroup->getResourceGroup(), filename))
        {
            qDebug() << "OgreWidget::defineTerrain(): resource exists, calling TerrainGroup::defineTerrain with x y" << x << y;
            mTerrainGroup->defineTerrain(x, y);
        }
        else
        {
            qDebug() << "OgreWidget::defineTerrain(): resource absent, calling TerrainGroup::defineTerrain with image for x y" << x << y;
            Ogre::Image img;
            getTerrainImage(x % 2 != 0, y % 2 != 0, img);
            img.save("test2.png");
            mTerrainGroup->defineTerrain(x, y, &img);
            mTerrainGroup->getTerrainDefinition(x, y)->importData->inputImage->save("test3.png");

            mTerrainsImported = true;
        }
    }
}
Пример #2
0
	//-----------------------------------------------------------------------
	void Noise3D::noise2img(Ogre::ushort dimension)
	{
		double x = 0.0;
		double y = 0.0;
		double step = 1.0 / (double)dimension;
		size_t buffSize = 4 * dimension * dimension; // Assume Image of pixelformat 32 bits (i.e. PF_R8G8B8A8)
		Ogre::uchar* buff = new Ogre::uchar[buffSize];
		size_t p = 0;
		while (p < buffSize)
		{
			Ogre::uchar n = (Ogre::uchar)(255 * noise(x, y, 0.5));
			buff[p] = n;
			buff[p+1] = n;
			buff[p+2] = n;
			buff[p+3] = n;
			p += 4;

			x += step;
			if (x >= 1.0)
			{
				x = 0.0;
				y += step;
			}
		}
		Ogre::Image* image = new Ogre::Image();
		image->loadDynamicImage(buff, dimension, dimension, 0, Ogre::PF_R8G8B8A8 , false, 1, 0);
		image->save("noise2img.png");
		delete image;
		delete [] buff;
	}
Пример #3
0
	void OgreTexture::saveToFile(const std::string& _filename)
	{
		Ogre::uchar* readrefdata = (Ogre::uchar*)lock(TextureUsage::Read);

		Ogre::Image img;
		img = img.loadDynamicImage(readrefdata, mTexture->getWidth(), mTexture->getHeight(), mTexture->getFormat());
		img.save(_filename);

		unlock();
	}
Пример #4
0
///  _Tool_ tex ..........................
//  (remove alpha channel for ter tex prv img)
void App::ToolTexAlpha()
{
	Ogre::Image im;
	im.load("jungle_5d.png", "General");

	PixelBox pb = im.getPixelBox();
	int w = pb.getWidth(), h = pb.getHeight();
	for(int j=0; j < h; ++j)
	for(int i=0; i < w; ++i)
	{
		ColourValue c = pb.getColourAt(i,j,0);
		c.a = 1.f;
		pb.setColourAt(c,i,j,0);
	}
	im.save(PATHMANAGER::Data()+"/prv.png");
}
Пример #5
0
void WebView::captureImage(const std::string& filename)
{
#ifdef HAVE_AWESOMIUM
	Ogre::Image result;

	int bpp = isWebViewTransparent? 4 : 3;

	unsigned char* buffer = OGRE_ALLOC_T(unsigned char, viewWidth * viewHeight * bpp, Ogre::MEMCATEGORY_GENERAL);

	webView->render(buffer, viewWidth * bpp, bpp);

	result.loadDynamicImage(buffer, viewWidth, viewHeight, 1, isWebViewTransparent? Ogre::PF_BYTE_BGRA : Ogre::PF_BYTE_BGR, false);
	result.save(Awesomium::WebCore::Get().getBaseDirectory() + "\\" + filename);

	OGRE_FREE(buffer, Ogre::MEMCATEGORY_GENERAL);
#endif
}
Пример #6
0
int _tmain(int argc, _TCHAR* argv[])
{
  // Disable Ogre logging
  new LogManager;
  Log *log = LogManager::getSingleton().createLog("");
  //log->setDebugOutputEnabled(false);

  // Set up Root
  Root *root = new Root("","","");
  //MTGACodec::startup();
  //ArchiveManager::getSingleton().addArchiveFactory( new LODArchiveFactory );
  
  //addResourceLocation("D:/games/mm8bukarus/Data/bitmaps.lod", "Lod");
  ResourceGroupManager::getSingleton().addResourceLocation("D:/games/MMCollection/MM_VI/Data/Icons.lod", "Lod");
  ResourceGroupManager::getSingleton().addResourceLocation("D:/games/MMCollection/MM_VI/Data/BITMAPS.LOD", "Lod");
  ResourceGroupManager::getSingleton().addResourceLocation("D:/games/MMCollection/MM_VI/Data/games.lod", "Lod");
  ResourceGroupManager::getSingleton().addResourceLocation("D:/games/MMCollection/MM_VI/Data/SPRITES.LOD", "Lod");
  /*SaveStreamToFile("d:\\_\\2HAxe1", ResourceGroupManager::getSingleton().openResource("2HAxe1"));
  SaveStreamToFile("d:\\_\\2DEvents.txt", ResourceGroupManager::getSingleton().openResource("2DEvents.txt"));
  SaveStreamToFile("d:\\_\\ZNWC.STR", ResourceGroupManager::getSingleton().openResource("ZNWC.STR"));
  SaveStreamToFile("d:\\_\\armormid", ResourceGroupManager::getSingleton().openResource("armormid"));
  SaveStreamToFile("d:\\_\\WtrdrXNW", ResourceGroupManager::getSingleton().openResource("WtrdrXNW"));
  SaveStreamToFile("d:\\_\\d05.blv", ResourceGroupManager::getSingleton().openResource("d05.blv"));
  SaveStreamToFile("d:\\_\\oute3.ddm", ResourceGroupManager::getSingleton().openResource("oute3.ddm"));
  SaveStreamToFile("d:\\_\\3Gem07", ResourceGroupManager::getSingleton().openResource("3Gem07"));
  SaveStreamToFile("d:\\_\\wwalk1F2", ResourceGroupManager::getSingleton().openResource("wwalk1F2"));*/
  Ogre::Image img;
  img.load(Ogre::String("WtrdrXNW"),"General");
  img.save("d:\\_\\WtrdrXNW.png");
  ODMmap map;
  map.load("oute3.odm");
  /*Ogre::Image img2;
  img2.load(Ogre::String("armormid"),"General");
  img2.save("d:\\_\\armormid.png");*/
  //std::cout <<  ResourceGroupManager::getSingleton().resourceExists("General","alphanum1") << std::endl;
  
  //TestArchive();
  //TestStream();
  //cout << "End TestStream()" << endl;

  return 0;
}
Пример #7
0
//-------------------------------------------------------------------------------------
void ScriptInterpreter::writeEveythingToDisk()
{
	MeshSerializer serializer;
	int meshCounter = 0;
	for (std::vector<Entity*>::iterator it = mEntities.begin(); it != mEntities.end(); ++it)
	{
		meshCounter++;
		std::string fileName;
		if (mEntities.size()>1)
			fileName = mCurrentScriptName.substr(0, mCurrentScriptName.find_last_of(".")) + "_" + StringConverter::toString(meshCounter);
		else
			fileName = mCurrentScriptName.substr(0, mCurrentScriptName.find_last_of("."));
		serializer.exportMesh((*it)->getMesh().getPointer(), fileName + ".mesh", MESH_VERSION_LATEST);
	}
	/*MaterialSerializer matSer;
	int matCounter = 0;
	for (std::vector<MaterialPtr>::iterator it = mMaterials.begin(); it != mMaterials.end(); ++it)
	{
		matCounter++;
		std::string fileName;
		if (mEntities.size()>1)
			fileName = mCurrentScriptName.substr(0, mCurrentScriptName.find_last_of(".")) + "_" + StringConverter::toString(meshCounter);
		else
			fileName = mCurrentScriptName.substr(0, mCurrentScriptName.find_last_of("."));

		matSer.exportMaterial(*it, fileName + ".material");
	}*/
	for (std::vector<TexturePtr>::iterator it = mTextures.begin(); it!=mTextures.end(); ++it)
	{
		Ogre::Image im;
		(*it)->convertToImage(im);
		im.save(mCurrentScriptName.substr(0, mCurrentScriptName.find_last_of(".")) + ".png");
	}
	if (mCurrentDotFile)
		mCurrentDotFile->save(".");
}
Пример #8
0
void MapView::createTerrainFromFile()
{
	if (mMap->getTexture().size())
	{
		mMaterial = (Ogre::MaterialPtr)
			Ogre::MaterialManager::getSingleton().getByName(mMap->getTexture());

		if (mMaterial.isNull())
		{
			mMaterial = (Ogre::MaterialPtr)
				Ogre::MaterialManager::getSingleton().create(mMap->getTexture(), "General");
			mMaterial->getTechnique(0)->getPass(0)->createTextureUnitState(mMap->getTexture());
			mMaterial->getTechnique(0)->getPass(0)->setVertexColourTracking(Ogre::TVC_AMBIENT);
		}
	}
	else
	{
		mMaterial = (Ogre::MaterialPtr)
			Ogre::MaterialManager::getSingleton().getByName("terrain");
	}

	Ogre::Image img;
	Ogre::uchar* data = new Ogre::uchar[mMap->getTerrainData().size()];

	float min = mMap->getTerrainData()[0];
	float max = mMap->getTerrainData()[0];

	for (size_t i = 1; i < mMap->getTerrainData().size(); ++i)
	{
		if (mMap->getTerrainData()[i] < min) min = mMap->getTerrainData()[i];
		else if (mMap->getTerrainData()[i] > max) max = mMap->getTerrainData()[i];
	}

	for (size_t i = 0; i < mMap->getTerrainData().size(); ++i)
	{
		data[i] = mMap->getTerrainData()[i];
	}

	img.loadDynamicImage(
		data,
		mMap->getTerrainSize().x,
		mMap->getTerrainSize().z,
		1, Ogre::PF_L8);

	// Save bitmap file.
	std::string name(Convert::ToString(mMap->getID()));
	img.save("..\\cache\\" + name + ".png");

	// Create config file.
	std::ofstream config(
		("..\\cache\\" + name + ".cfg").c_str(),
		std::ios::out | std::ios::trunc);

	config << "DetailTile=3" << "\n";
	config << "PageSource=Heightmap" << "\n";
	config << "Heightmap.image=" << "..\\cache\\" << name << ".png" << "\n";
	config << "PageSize=" << mMap->getTerrainSize().x << "\n";
	config << "TileSize=33" << "\n";
	config << "MaxPixelError=3" << "\n";
	config << "PageWorldX=" << mMap->getSize().x << "\n";
	config << "PageWorldZ=" << mMap->getSize().z << "\n";
	config << "MaxHeight=255" << "\n";
	config << "MaxMipMapLevel=5" << "\n";
	config << "VertexNormals=yes" << "\n";
	config << "VertexColors=yes" << "\n";
	config << "VertexProgramMorph=yes" << "\n";
	config << "LODMorphStart=0.2" << "\n";
	config << "CustomMaterialName=" << mMaterial->getName() << "\n";

	config.close();

	delete[] data;

	mManager->setWorldGeometry("..\\cache\\" + name + ".cfg");
}
Пример #9
0
void TerrainGeometryManager::initBlendMaps(int x, int z, Ogre::Terrain* terrain )
{
	bool debugBlendMaps = BOPT("DebugBlendMaps", false);

	int layerCount = terrain->getLayerCount();
	for (int i = 1; i < layerCount; i++)
	{
		blendLayerInfo_t &bi = blendInfo[i];

		if(bi.blendMapTextureFilename.empty()) continue;

		Ogre::Image img;
		//std::pair<uint8,uint8> textureIndex = terrain->getLayerBlendTextureIndex(i);
		//uint8 bti = terrain->getBlendTextureIndex(i);
		try
		{
			img.load(bi.blendMapTextureFilename, ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME);
		} catch(Exception &e)
		{
			LOG("Error loading blendmap: " + bi.blendMapTextureFilename + " : " + e.getFullDescription());
			continue;
		}

		TerrainLayerBlendMap *blendmap = terrain->getLayerBlendMap(i);

		// resize that blending map so it will fit
		Ogre::uint32 blendmapSize = terrain->getLayerBlendMapSize();
		if (img.getWidth() != blendmapSize)
			img.resize(blendmapSize, blendmapSize);

		// now to the ugly part
		float* ptr = blendmap->getBlendPointer();
		for (Ogre::uint32 z = 0; z != blendmapSize; z++)
		{
			for (Ogre::uint32 x = 0; x != blendmapSize; x++)
			{
				Ogre::ColourValue c = img.getColourAt(x, z, 0);
				float alpha = bi.alpha;
				if      (bi.blendMode == 'R')
					*ptr++ = c.r * alpha;
				else if (bi.blendMode == 'G')
					*ptr++ = c.g * alpha;
				else if (bi.blendMode == 'B')
					*ptr++ = c.b * alpha;
				else if (bi.blendMode == 'A')
					*ptr++ = c.a * alpha;
			}
		}
		blendmap->dirty();
		blendmap->update();
	}

	if (debugBlendMaps)
	{
		for (int i = 1; i < layerCount; i++)
		{
			Ogre::TerrainLayerBlendMap* blendMap = terrain->getLayerBlendMap(i);
			Ogre::uint32 blendmapSize = terrain->getLayerBlendMapSize();
			Ogre::Image img;
			unsigned short *idata = OGRE_ALLOC_T(unsigned short, blendmapSize * blendmapSize, Ogre::MEMCATEGORY_RESOURCE);
			float scale = 65535.0f;
			for (unsigned int x = 0; x < blendmapSize; x++)
				for (unsigned int z = 0; z < blendmapSize; z++)
					idata[x + z * blendmapSize] = (unsigned short)(blendMap->getBlendValue(x, blendmapSize - z) * scale);
			img.loadDynamicImage((Ogre::uchar*)(idata), blendmapSize, blendmapSize, Ogre::PF_L16);
			std::string fileName = "blendmap_layer_" + Ogre::StringConverter::toString(i) + ".png";
			img.save(fileName);
			OGRE_FREE(idata, Ogre::MEMCATEGORY_RESOURCE);
		}
	}
}
Пример #10
0
    bool MiniMapMaker::outputTextures(void)
    {
        // 如果需要(纹理大小改变了或第一次输出文件时),就重建render texture
        if (mNeedRecreate)
        {
            destroy();
            init();
        }

        mTempOutputFileNames.clear();

        static const String TEMP_GROUP_NAME = "#TEMP#";

        // 创建临时的资源组
        Ogre::ResourceGroupManager& rgm = Ogre::ResourceGroupManager::getSingleton();
        rgm.addResourceLocation(mPath, "FileSystem", TEMP_GROUP_NAME, false);

        // 合并所有物体的包围盒
        Ogre::AxisAlignedBox aabb;
        Ogre::SceneManager::MovableObjectIterator itm =
            mManipulator->getSceneManager()->getMovableObjectIterator(Ogre::EntityFactory::FACTORY_TYPE_NAME);
        while (itm.hasMoreElements())
        {
            Ogre::MovableObject* movable = itm.getNext();
            aabb.merge(movable->getWorldBoundingBox(true));
        }

        mCamera->setFarClipDistance(mCamera->getNearClipDistance() + 2 * (aabb.getMaximum().y - aabb.getMinimum().y ));
        mCamera->setNearClipDistance(mTileSize/2);

        // 设置摄像机的高度
        Real yPos = mCamera->getNearClipDistance() + aabb.getMaximum().y;
        
        TerrainData* terrainData = mManipulator->getTerrainData();
        assert (terrainData);

        float terrainHeight = terrainData->mMaxZ - terrainData->mMinZ;
        float terrainWidth = terrainData->mMaxX - terrainData->mMinX;

        // 投影的真正面积
        Real projectSize = 0.0f;

        // 最终切割成小块纹理的块数
        int xIndex = 0;
        int zIndex = 0;

        Ogre::Vector3 originPoint(Ogre::Vector3::ZERO);

        if (mUseRealCameraAngle)
        {
            float outerSquareWidth = 0.0f;
            float outerSquareHeight = 0.0f;

            Ogre::Radian alphaAngle = Ogre::Math::ATan( Ogre::Math::Abs(mMoveZDir.z / mMoveZDir.x) );

            switch (mCameraDirQuadrant)
            {
            case WestNorth :
                {
                    float leftWidth = Ogre::Math::Sin(alphaAngle) * terrainHeight;
                    float rightWidth = Ogre::Math::Cos(alphaAngle) * terrainWidth;
                    outerSquareWidth = leftWidth + rightWidth;

                    float topHeight = Ogre::Math::Cos(alphaAngle) * terrainHeight;
                    float bottomHeight = Ogre::Math::Sin(alphaAngle) * terrainWidth;

                    outerSquareHeight = topHeight + bottomHeight;

                    originPoint = Ogre::Vector3(terrainData->mMinX,0,terrainData->mMinZ) +
                        (-mMoveZDir * leftWidth);

                    float projectOffset = yPos / Ogre::Math::Tan(mCamDirAngle);

                    originPoint.x += (mInvertCameraDir * projectOffset ).x;
                    originPoint.z += (mInvertCameraDir * projectOffset ).z;

                    break;
                }
            case EastNorth :
                {
                    float leftWidth = Ogre::Math::Cos(alphaAngle) * terrainWidth;
                    float rightWidth = Ogre::Math::Sin(alphaAngle) * terrainHeight;
                    outerSquareWidth = leftWidth + rightWidth;

                    float topHeight = Ogre::Math::Cos(alphaAngle) * terrainHeight;
                    float bottomHeight = Ogre::Math::Sin(alphaAngle) * terrainWidth;

                    outerSquareHeight = topHeight + bottomHeight;

                    originPoint = Ogre::Vector3(terrainData->mMaxX,0,terrainData->mMinZ) +
                        (-mMoveZDir * leftWidth);

                    float projectOffset = yPos / Ogre::Math::Tan(mCamDirAngle);

                    originPoint.x += (mInvertCameraDir * projectOffset ).x;
                    originPoint.z += (mInvertCameraDir * projectOffset ).z;

                    break;
                }
            case EastSouth :
                {
                    float leftWidth = Ogre::Math::Sin(alphaAngle) * terrainHeight;
                    float rightWidth = Ogre::Math::Cos(alphaAngle) * terrainWidth;
                    outerSquareWidth = leftWidth + rightWidth;

                    float topHeight = Ogre::Math::Sin(alphaAngle) * terrainWidth;
                    float bottomHeight = Ogre::Math::Cos(alphaAngle) * terrainHeight;

                    outerSquareHeight = topHeight + bottomHeight;

                    originPoint = Ogre::Vector3(terrainData->mMaxX,0,terrainData->mMaxZ) +
                        (-mMoveZDir * topHeight);

                    float projectOffset = yPos / Ogre::Math::Tan(mCamDirAngle);

                    originPoint.x += (mInvertCameraDir * projectOffset ).x;
                    originPoint.z += (mInvertCameraDir * projectOffset ).z;

                    break;
                }
            case WestSouth :
                {
                    float leftWidth = Ogre::Math::Sin(alphaAngle) * terrainHeight;
                    float rightWidth = Ogre::Math::Cos(alphaAngle) * terrainWidth;
                    outerSquareWidth = leftWidth + rightWidth;

                    float topHeight = Ogre::Math::Sin(alphaAngle) * terrainWidth;
                    float bottomHeight = Ogre::Math::Cos(alphaAngle) * terrainHeight;

                    outerSquareHeight = topHeight + bottomHeight;

                    originPoint = Ogre::Vector3(terrainData->mMinX,0,terrainData->mMaxZ) +
                        (-mMoveZDir * rightWidth);

                    float projectOffset = yPos / Ogre::Math::Tan(mCamDirAngle);

                    originPoint.x += (mInvertCameraDir * projectOffset ).x;
                    originPoint.z += (mInvertCameraDir * projectOffset ).z;

                    break;
                }

            default:
                {
                    OGRE_EXCEPT(Ogre::Exception::ERR_INTERNAL_ERROR,
                        " wrong camera dir " + Ogre::StringConverter::toString(mCameraDir),
                        "MiniMapMaker::outputTextures");

                    break;
                }
            }

            // 计算投影的长度
            Real factor = Ogre::Math::Sin(mCamDirAngle);

            if (factor > 0.0f && factor != 1.0f)
                projectSize = mTileSize / factor;

            // 根据当前场景的大小,计算需要的分块数
            xIndex = Ogre::Math::Ceil( (outerSquareWidth) / mTileSize ) + 1;
            zIndex = Ogre::Math::Ceil( (outerSquareHeight) / projectSize ) + 1;
        }
        else
        {
            xIndex = Ogre::Math::Ceil( (terrainData->mMaxX - terrainData->mMinX) / mTileSize ) + 1;
            zIndex = Ogre::Math::Ceil( (terrainData->mMaxZ - terrainData->mMinZ) / mTileSize ) + 1;

            originPoint.x = terrainData->mMinX;
            originPoint.z = terrainData->mMinZ;
        }

        // 计算最终的mini map的大小
        uint miniMapWidth = xIndex * mTexWidth;
        uint miniMapHeight = zIndex * mTexHeight;

        if ( miniMapWidth > 10000 || miniMapHeight > 10000 )
        {
            mLastErrorString = "texture size is out of range!";
            return false;
        }
        // 创建mini map所需的内存空间
        uchar* miniMapData = new uchar[miniMapWidth * miniMapHeight * Ogre::PixelUtil::getNumElemBytes(mOutPutFormat)];

        //// 初始的摄像机位置
        Real xPos = originPoint.x;
        Real zPos = originPoint.z;

        for ( int i=0; i<xIndex; ++i )
        {
            for ( int j=0; j<zIndex; ++j )
            {
                // 设置摄像机位置,并更新render texture的内容
                mCamera->setPosition(xPos, yPos, zPos);
                mRenderTexture->update();

                String fileName = mPath + mSceneBaseName + Ogre::StringConverter::toString(i)
                    + "_" + Ogre::StringConverter::toString(j) + "." + mTexExtension;

                // 输出小纹理文件
                mRenderTexture->writeContentsToFile(fileName);

                mTempOutputFileNames.push_back(fileName);

                // 读取刚创建的纹理
                Ogre::Image* tempImage = new Ogre::Image;
                
                tempImage->load(mSceneBaseName + Ogre::StringConverter::toString(i)
                    + "_" + Ogre::StringConverter::toString(j) + "." + mTexExtension, TEMP_GROUP_NAME);

                // 获取render texture中的内容
                uchar* tempImageData = tempImage->getData();

                // 定位在mini map中的左上角
                uint miniMapIndex = ( j * mTexHeight * miniMapWidth + i * mTexWidth ) * Ogre::PixelUtil::getNumElemBytes(mOutPutFormat);

                uchar* startData = miniMapData + miniMapIndex;

                for ( size_t height = 0; height < tempImage->getHeight(); ++height )
                {
                    for ( size_t width = 0; width < tempImage->getWidth(); ++width )
                    {
                        memcpy(startData, tempImageData, Ogre::PixelUtil::getNumElemBytes(mOutPutFormat));

                        startData += Ogre::PixelUtil::getNumElemBytes(mOutPutFormat);
                        tempImageData += Ogre::PixelUtil::getNumElemBytes( tempImage->getFormat() );
                    }
                    startData += (miniMapWidth - tempImage->getWidth()) * Ogre::PixelUtil::getNumElemBytes(mOutPutFormat);
                }

                delete tempImage;

                // 移动摄像机的z坐标
                if (mUseRealCameraAngle)
                {
                    zPos += (mInvertCameraDir * (projectSize)).z;
                    xPos += (mInvertCameraDir * (projectSize)).x;
                }
                else
                   zPos += mTileSize;
            }
            
            if (mUseRealCameraAngle)
            {
                xPos = originPoint.x;
                zPos = originPoint.z;

                xPos += (mMoveZDir * (mTileSize) * (i+1)).x;
                zPos += (mMoveZDir * (mTileSize) * (i+1)).z;
            }
            else
            {
                // 操作完每一列之后,重置摄像机的z坐标
                zPos = terrainData->mMinZ;

                // 移动摄像机的x坐标
                xPos += mTileSize;
            }
        } 

        // 保存mini map并输出
        Ogre::Image* miniMapImage = new Ogre::Image;
        miniMapImage->loadDynamicImage(miniMapData, miniMapWidth, miniMapHeight, 1, mOutPutFormat, true);

        miniMapImage->save(mPath + mOutFileName + "." + mTexExtension);

        delete miniMapImage;

        rgm.destroyResourceGroup(TEMP_GROUP_NAME);

        return true;
    }
Пример #11
0
Surface*
FontFile::GetSurface(void)
{
    int width    = 512;
    int height   = 4096;
    int chars    = 0;
    int char_num = 6165;
    Surface* ret = CreateSurface(width, height);

    int x_16 = 0;
    int y_16 = 0;

    struct ClutColor
    {
        u8 r;                 /**< @brief red color in CLUT */
        u8 g;                 /**< @brief green color in CLUT */
        u8 b;                 /**< @brief blue color in CLUT */
        u8 a;                 /**< @brief alpha in CLUT */
    };

    ClutColor color;
    color.r = 0;
    color.g = 0;
    color.b = 0;
    color.a = 255;

    u8 data = 0;


    for (int chars = 0; chars < char_num; ++chars)
    {
        Surface* glyth = CreateSurface(16, 16);

        for (int y = 0; y < 16; ++y)
        {
            data = (y < 11) ? GetU8(0xE + chars * 22 + y * 2 + 0) : 0;
            //LOGGER->Log(LOGGER_INFO, "%x, %02x", y, data);
            int j = 0;
            for (int i = 7; i >= 0; --i)
            {
                color.r = ((data >> i) & 0x01 == 1) ? 0 : 255;
                color.g = ((data >> i) & 0x01 == 1) ? 0 : 255;
                color.b = ((data >> i) & 0x01 == 1) ? 0 : 255;
                color.a = ((data >> i) & 0x01 == 1) ? 255 : 255;
                memcpy(glyth->pixels + 64 * y + j, &color, sizeof(ClutColor));
                j += 4;
            }

            data = (y < 11) ? GetU8(0xE + chars * 22 + y * 2 + 1) : 0;
            //LOGGER->Log(LOGGER_INFO, "%02x", data);
            for (int i = 7; i >= 0; --i)
            {
                color.r = ((data >> i) & 0x01 == 1) ? 0 : 255;
                color.g = ((data >> i) & 0x01 == 1) ? 0 : 255;
                color.b = ((data >> i) & 0x01 == 1) ? 0 : 255;
                color.a = ((data >> i) & 0x01 == 1) ? 255 : 255;
                memcpy(glyth->pixels + 64 * y + j, &color, sizeof(ClutColor));
                j += 4;
            }
        }

        CopyToSurface(ret, x_16, y_16, glyth);
        delete glyth;
        x_16 += 16;
        if (x_16 == ret->width)
        {
            y_16 += 16;
            x_16 = 0;
        }
    }



    Ogre::TexturePtr ptex;
    Ogre::HardwarePixelBufferSharedPtr buffer;
    ptex = Ogre::TextureManager::getSingleton().createManual("DynaTex", "General", Ogre::TEX_TYPE_2D, ret->width, ret->height, 0, Ogre::PF_R8G8B8A8, Ogre::TU_STATIC);
    buffer = ptex->getBuffer(0, 0);
    buffer->lock(Ogre::HardwareBuffer::HBL_DISCARD);
    const Ogre::PixelBox& pb = buffer->getCurrentLock();

    for (Uint32 y = 0; y < ret->height; ++y)
    {
        Uint32* data = static_cast<Uint32*>(pb.data) + y * pb.rowPitch;

        for (Uint32 x = 0; x < ret->width; ++x)
        {
            Uint32 clut = ret->pixels[y * ret->width * 4 + x * 4 + 3] | (ret->pixels[y * ret->width * 4 + x * 4 + 2] << 8) | (ret->pixels[y * ret->width * 4 + x * 4 + 1] << 16) | (ret->pixels[y * ret->width * 4 + x * 4 + 0] << 24);
            data[x] = clut;
        }
    }

    Ogre::Image image;
    image.loadDynamicImage((Ogre::uchar*)pb.data, ret->width, ret->height, Ogre::PF_R8G8B8A8);
    image.save("font.png");
    buffer->unlock();
    Ogre::TextureManager::getSingleton().remove("DynaTex");



    return ret;
}
Пример #12
0
void saveAsDotScene(const QString& path, QFile& file, Ogre::SceneManager* sceneManager)
{
    Ogre::MeshSerializer* mMeshSerializer = new Ogre::MeshSerializer();
    Ogre::MaterialSerializer* mMaterialSerializer = new Ogre::MaterialSerializer();

    int idCounter = 3;
    if (!file.open(QIODevice::WriteOnly))
    {
        /* show wrror message if not able to open file */
        QMessageBox::warning(0, "Read only", "The file is in read only mode");
    }
    else
    {
        Ogre::SceneManager::MovableObjectIterator iterator = sceneManager->getMovableObjectIterator("Entity");
        QXmlStreamWriter* xmlWriter = new QXmlStreamWriter();
        xmlWriter->setAutoFormatting(true);
        xmlWriter->setDevice(&file);
        xmlWriter->writeStartElement("scene");
        xmlWriter->writeAttribute("formatVersion","");

        xmlWriter->writeStartElement("nodes");
        while(iterator.hasMoreElements())
        {
            Ogre::Entity* e = static_cast<Ogre::Entity*>(iterator.getNext());
            Ogre::Any any = e->getParentNode()->getUserAny();
            Ogre::String widgetType("");
            if(!any.isEmpty()){
                widgetType = any_cast<Ogre::String>(any);
            }
            Ogre::String tmp(widgetType + ":" + e->getParentNode()->getName());
            QString nodeName(tmp.c_str());
            xmlWriter->writeStartElement("node");
            xmlWriter->writeAttribute("name", nodeName);
            xmlWriter->writeAttribute("id", QString::number(idCounter++));


            xmlWriter->writeStartElement("position");
            xmlWriter->writeAttribute("x", QString::number(e->getParentNode()->getPosition().x));
            xmlWriter->writeAttribute("y", QString::number(e->getParentNode()->getPosition().y));
            xmlWriter->writeAttribute("z", QString::number(e->getParentNode()->getPosition().z));
            xmlWriter->writeEndElement();

            xmlWriter->writeStartElement("scale");
            xmlWriter->writeAttribute("x", QString::number(e->getParentNode()->getScale().x));
            xmlWriter->writeAttribute("y", QString::number(e->getParentNode()->getScale().y));
            xmlWriter->writeAttribute("z", QString::number(e->getParentNode()->getScale().z));
            xmlWriter->writeEndElement();

            xmlWriter->writeStartElement("entity");
            xmlWriter->writeAttribute("name", nodeName);
            xmlWriter->writeAttribute("meshFile", nodeName.toLower() + QString(".mesh") );
            xmlWriter->writeAttribute("static", QString("false"));
            xmlWriter->writeEndElement();

            const Mesh* mesh = e->getMesh().getPointer();


            mMeshSerializer->exportMesh(mesh,String(path.toStdString() +
                                                    nodeName.toLower().toStdString() +
                                                    ".mesh" ));


            std::cout << "numeber" <<  mesh->getNumSubMeshes() << std::endl;


            for(int i = 0; i < e->getNumSubEntities(); i++){


                Ogre::Material *mat = static_cast<Ogre::Material*>
                        (Ogre::MaterialManager::getSingletonPtr()->getByName(e->getSubEntity(i)->getMaterialName()).getPointer());

                //e->getMesh().get()->getSubMesh()
                if(mat->getTechnique(0)->getPass(0)->getNumTextureUnitStates() !=0){
                Ogre::String str = mat->getTechnique(0)->getPass(0)->getTextureUnitState(0)->getTextureName();

            Ogre::MaterialPtr mMatPtr =e->getSubEntity(i)->getMaterial()    ;

            mMaterialSerializer->exportMaterial(mMatPtr ,
                                                String(path.toStdString() +
                                                       nodeName.toLower().toStdString() +
                                                       QString::number(i).toStdString() + ".material" ));
            Ogre::TexturePtr* mTexPtr = new Ogre::TexturePtr(Ogre::TextureManager::getSingletonPtr()->getByName(str));
            Ogre::Texture* mTex = mTexPtr->getPointer();
            Ogre::PixelFormat pxf = mTex->getFormat();
            Ogre::Image mImage;
            mTex->convertToImage(mImage);
            std::cout << str << std::endl;
            mImage.save(String(path.toStdString() +
                                 str));
                }
}
            //material file merge

            for(int i = 0; i < e->getNumSubEntities(); i++){
                Ogre::Material *mat = static_cast<Ogre::Material*>
                        (Ogre::MaterialManager::getSingletonPtr()->getByName(e->getSubEntity(i)->getMaterialName()).getPointer());


                QString mMatFilePath = QString((path.toStdString() +
                                               nodeName.toLower().toStdString() +
                                                ".material").c_str()) ;


                 QFile mFile(mMatFilePath);
                 if (!mFile.open(QIODevice::Append))
                 {
                     /* show wrror message if not able to open file */
                     QMessageBox::warning(0, "Read only", "The file is in read only mode");
                 }
                 else{
                     QTextStream out(&mFile);

                     QString mTempMatPath = QString((path + nodeName.toLower() + QString::number(i) + ".material"));

                     QFile mTempMatFile(mTempMatPath);
                     mTempMatFile.open(QIODevice::ReadOnly);

                     QTextStream src(&mTempMatFile);

                     mFile.write(src.readAll().toStdString().c_str());
                     mTempMatFile.remove();

                 }



            }


            xmlWriter->writeEndElement();


        }

        xmlWriter->writeEndElement();
        xmlWriter->writeEndDocument();
        delete xmlWriter;
    }

    delete mMeshSerializer;
    delete mMaterialSerializer;
}
Пример #13
0
    void FontLoader::loadFont(const std::string &fileName, bool exportToFile)
    {
        Ogre::DataStreamPtr file = Ogre::ResourceGroupManager::getSingleton().openResource(fileName);

        float fontSize;
        int one;
        file->read(&fontSize, sizeof(fontSize));

        file->read(&one, sizeof(int));
        assert(one == 1);
        file->read(&one, sizeof(int));
        assert(one == 1);

        char name_[284];
        file->read(name_, sizeof(name_));
        std::string name(name_);

        GlyphInfo data[256];
        file->read(data, sizeof(data));
        file->close();

        // Create the font texture
        std::string bitmapFilename = "Fonts/" + std::string(name) + ".tex";
        Ogre::DataStreamPtr bitmapFile = Ogre::ResourceGroupManager::getSingleton().openResource(bitmapFilename);

        int width, height;
        bitmapFile->read(&width, sizeof(int));
        bitmapFile->read(&height, sizeof(int));

        std::vector<Ogre::uchar> textureData;
        textureData.resize(width*height*4);
        bitmapFile->read(&textureData[0], width*height*4);
        bitmapFile->close();

        std::string resourceName;
        if (name.size() >= 5 && Misc::StringUtils::ciEqual(name.substr(0, 5), "magic"))
            resourceName = "Magic Cards";
        else if (name.size() >= 7 && Misc::StringUtils::ciEqual(name.substr(0, 7), "century"))
            resourceName = "Century Gothic";
        else if (name.size() >= 7 && Misc::StringUtils::ciEqual(name.substr(0, 7), "daedric"))
            resourceName = "Daedric";
        else
            return; // no point in loading it, since there is no way of using additional fonts

        std::string textureName = name;
        Ogre::Image image;
        image.loadDynamicImage(&textureData[0], width, height, Ogre::PF_BYTE_RGBA);
        Ogre::TexturePtr texture = Ogre::TextureManager::getSingleton().createManual(textureName,
            Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
            Ogre::TEX_TYPE_2D,
            width, height, 0, Ogre::PF_BYTE_RGBA);
        texture->loadImage(image);

        if (exportToFile)
            image.save(resourceName + ".png");

        // Register the font with MyGUI
        MyGUI::ResourceManualFont* font = static_cast<MyGUI::ResourceManualFont*>(
                    MyGUI::FactoryManager::getInstance().createObject("Resource", "ResourceManualFont"));

        // We need to emulate loading from XML because the data members are private as of mygui 3.2.0
        MyGUI::xml::Document xmlDocument;
        MyGUI::xml::ElementPtr root = xmlDocument.createRoot("ResourceManualFont");
        root->addAttribute("name", resourceName);

        MyGUI::xml::ElementPtr defaultHeight = root->createChild("Property");
        defaultHeight->addAttribute("key", "DefaultHeight");
        defaultHeight->addAttribute("value", fontSize);
        MyGUI::xml::ElementPtr source = root->createChild("Property");
        source->addAttribute("key", "Source");
        source->addAttribute("value", std::string(textureName));
        MyGUI::xml::ElementPtr codes = root->createChild("Codes");

        for(int i = 0; i < 256; i++)
        {
            float x1 = data[i].top_left.x*width;
            float y1 = data[i].top_left.y*height;
            float w  = data[i].top_right.x*width - x1;
            float h  = data[i].bottom_left.y*height - y1;

            ToUTF8::Utf8Encoder encoder(mEncoding);
            unsigned long unicodeVal = utf8ToUnicode(getUtf8(i, encoder, mEncoding));

            MyGUI::xml::ElementPtr code = codes->createChild("Code");
            code->addAttribute("index", unicodeVal);
            code->addAttribute("coord", MyGUI::utility::toString(x1) + " "
                                        + MyGUI::utility::toString(y1) + " "
                                        + MyGUI::utility::toString(w) + " "
                                        + MyGUI::utility::toString(h));
            code->addAttribute("advance", data[i].width);
            code->addAttribute("bearing", MyGUI::utility::toString(data[i].kerning) + " "
                               + MyGUI::utility::toString((fontSize-data[i].ascent)));
            code->addAttribute("size", MyGUI::IntSize(data[i].width, data[i].height));

            // More hacks! The french game uses several win1252 characters that are not included
            // in the cp437 encoding of the font. Fall back to similar available characters.
            if (mEncoding == ToUTF8::CP437)
            {
                std::multimap<int, int> additional; // <cp437, unicode>
                additional.insert(std::make_pair(39, 0x2019)); // apostrophe
                additional.insert(std::make_pair(45, 0x2013)); // dash
                additional.insert(std::make_pair(45, 0x2014)); // dash
                additional.insert(std::make_pair(34, 0x201D)); // right double quotation mark
                additional.insert(std::make_pair(34, 0x201C)); // left double quotation mark
                additional.insert(std::make_pair(44, 0x201A));
                additional.insert(std::make_pair(44, 0x201E));
                additional.insert(std::make_pair(43, 0x2020));
                additional.insert(std::make_pair(94, 0x02C6));
                additional.insert(std::make_pair(37, 0x2030));
                additional.insert(std::make_pair(83, 0x0160));
                additional.insert(std::make_pair(60, 0x2039));
                additional.insert(std::make_pair(79, 0x0152));
                additional.insert(std::make_pair(90, 0x017D));
                additional.insert(std::make_pair(39, 0x2019));
                additional.insert(std::make_pair(126, 0x02DC));
                additional.insert(std::make_pair(84, 0x2122));
                additional.insert(std::make_pair(83, 0x0161));
                additional.insert(std::make_pair(62, 0x203A));
                additional.insert(std::make_pair(111, 0x0153));
                additional.insert(std::make_pair(122, 0x017E));
                additional.insert(std::make_pair(89, 0x0178));
                additional.insert(std::make_pair(156, 0x00A2));
                additional.insert(std::make_pair(46, 0x2026));

                for (std::multimap<int, int>::iterator it = additional.begin(); it != additional.end(); ++it)
                {
                    if (it->first != i)
                        continue;

                    MyGUI::xml::ElementPtr code = codes->createChild("Code");
                    code->addAttribute("index", it->second);
                    code->addAttribute("coord", MyGUI::utility::toString(x1) + " "
                                                + MyGUI::utility::toString(y1) + " "
                                                + MyGUI::utility::toString(w) + " "
                                                + MyGUI::utility::toString(h));
                    code->addAttribute("advance", data[i].width);
                    code->addAttribute("bearing", MyGUI::utility::toString(data[i].kerning) + " "
                                       + MyGUI::utility::toString((fontSize-data[i].ascent)));
                    code->addAttribute("size", MyGUI::IntSize(data[i].width, data[i].height));
                }
            }

            // ASCII vertical bar, use this as text input cursor
            if (i == 124)
            {
                MyGUI::xml::ElementPtr cursorCode = codes->createChild("Code");
                cursorCode->addAttribute("index", MyGUI::FontCodeType::Cursor);
                cursorCode->addAttribute("coord", MyGUI::utility::toString(x1) + " "
                                            + MyGUI::utility::toString(y1) + " "
                                            + MyGUI::utility::toString(w) + " "
                                            + MyGUI::utility::toString(h));
                cursorCode->addAttribute("advance", data[i].width);
                cursorCode->addAttribute("bearing", MyGUI::utility::toString(data[i].kerning) + " "
                                   + MyGUI::utility::toString((fontSize-data[i].ascent)));
                cursorCode->addAttribute("size", MyGUI::IntSize(data[i].width, data[i].height));
            }

            // Question mark, use for NotDefined marker (used for glyphs not existing in the font)
            if (i == 63)
            {
                MyGUI::xml::ElementPtr cursorCode = codes->createChild("Code");
                cursorCode->addAttribute("index", MyGUI::FontCodeType::NotDefined);
                cursorCode->addAttribute("coord", MyGUI::utility::toString(x1) + " "
                                            + MyGUI::utility::toString(y1) + " "
                                            + MyGUI::utility::toString(w) + " "
                                            + MyGUI::utility::toString(h));
                cursorCode->addAttribute("advance", data[i].width);
                cursorCode->addAttribute("bearing", MyGUI::utility::toString(data[i].kerning) + " "
                                   + MyGUI::utility::toString((fontSize-data[i].ascent)));
                cursorCode->addAttribute("size", MyGUI::IntSize(data[i].width, data[i].height));
            }
        }

        // These are required as well, but the fonts don't provide them
        for (int i=0; i<2; ++i)
        {
            MyGUI::FontCodeType::Enum type;
            if(i == 0)
                type = MyGUI::FontCodeType::Selected;
            else if (i == 1)
                type = MyGUI::FontCodeType::SelectedBack;

            MyGUI::xml::ElementPtr cursorCode = codes->createChild("Code");
            cursorCode->addAttribute("index", type);
            cursorCode->addAttribute("coord", "0 0 0 0");
            cursorCode->addAttribute("advance", "0");
            cursorCode->addAttribute("bearing", "0 0");
            cursorCode->addAttribute("size", "0 0");
        }

        if (exportToFile)
        {
            xmlDocument.createDeclaration();
            xmlDocument.save(resourceName + ".xml");
        }

        font->deserialization(root, MyGUI::Version(3,2,0));

        MyGUI::ResourceManager::getInstance().removeByName(font->getResourceName());
        MyGUI::ResourceManager::getInstance().addResource(font);
    }
Пример #14
0
int
main( int argc, char *argv[] )
{
    Ogre::Root*         root;
    Ogre::RenderWindow* window;

    root = new Ogre::Root( "", "" );
#ifndef _DEBUG
    root->loadPlugin( "RenderSystem_GL.dll" );
#else
    root->loadPlugin( "RenderSystem_GL_d.dll" );
#endif
    root->setRenderSystem( root->getAvailableRenderers()[ 0 ] );
    root->initialise( false );
    Ogre::NameValuePairList misc;
    misc[ "title" ] = "FFVII Exporter";
    window = root->createRenderWindow( "QGearsWindow", 800, 600, false, &misc );



    FILESYSTEM = new FileSystem();
    LOGGER = new Logger( "game.log" );

    state = GAME;



    {
        BinGZipFile* file = new BinGZipFile( "data/en/WINDOW.BIN" );
        File* font_graf    = file->ExtractGZip( 1 );
        File* font_padding = file->ExtractGZip( 2 );
        FontFile font( font_padding );
        font.Export( "export_en/ui/fonts/ffvii_en.xml", true );
        //font_graf->WriteFile( "font.tim" );

        Vram* vram = new Vram();
        LoadTimFileToVram( font_graf, 0, vram );
        //vram->Save( "text" );

        Ogre::TexturePtr ptex;
        Ogre::HardwarePixelBufferSharedPtr buffer;
        ptex = Ogre::TextureManager::getSingleton().createManual( "DynaTex", "General", Ogre::TEX_TYPE_2D, 256, 256, 0, Ogre::PF_R8G8B8A8, Ogre::TU_STATIC );
        buffer = ptex->getBuffer( 0, 0 );
        buffer->lock( Ogre::HardwareBuffer::HBL_DISCARD );
        const Ogre::PixelBox& pb = buffer->getCurrentLock();
        CreateTextureFromVram( pb, vram, 0, 0, 0x80, 0x1f7, 0x380, 0x100, BPP_4 , false );
        Ogre::Image image;
        image.loadDynamicImage( ( Ogre::uchar* )pb.data, 256, 256, Ogre::PF_R8G8B8A8 );
        image.save( "export_en/ui/fonts/ffvii_en.png" );
        buffer->unlock();

        delete vram;
        delete file;
    }

    {
        BinGZipFile* file = new BinGZipFile( "data/jp/WINDOW.BIN" );
        File* font_graf    = file->ExtractGZip( 1 );
        File* font_graf2   = file->ExtractGZip( 2 );
        File* font_padding = file->ExtractGZip( 3 );
        font_padding->WriteFile( "font_padding.dat" );
        FontFile font( font_padding );
        font.Export( "export_jp/ui/fonts/ffvii_jp.xml", false );
        font_graf->WriteFile( "font.tim" );
        font_graf2->WriteFile( "font2.tim" );

        Vram* vram = new Vram();
        LoadTimFileToVram( font_graf, 0, vram );
        LoadTimFileToVram( font_graf2, 0, vram );
        //vram->Save( "text" );

        Ogre::TexturePtr ptex;
        Ogre::HardwarePixelBufferSharedPtr buffer;
        ptex = Ogre::TextureManager::getSingleton().createManual( "DynaTex", "General", Ogre::TEX_TYPE_2D, 512, 256, 0, Ogre::PF_R8G8B8A8, Ogre::TU_STATIC );
        buffer = ptex->getBuffer( 0, 0 );
        buffer->lock( Ogre::HardwareBuffer::HBL_DISCARD );
        const Ogre::PixelBox& pb = buffer->getCurrentLock();
        CreateTextureFromVram( pb, vram, 0, 0, 0x80, 0x1f7, 0x380, 0x100, BPP_4 , false );
        CreateTextureFromVram( pb, vram, 256, 0, 0x90, 0x1f7, 0x380, 0x100, BPP_4 , false );
        Ogre::Image image;
        image.loadDynamicImage( ( Ogre::uchar* )pb.data, 512, 256, Ogre::PF_R8G8B8A8 );
        image.save( "export_jp/ui/fonts/ffvii_jp.png" );
        buffer->unlock();

        delete vram;
        delete file;
    }

    {
        File sword( "sword.tim" );

        Vram* vram = new Vram();
        LoadTimFileToVram( &sword, 0, vram );
        //vram->Save( "sword" );

        Ogre::TexturePtr ptex;
        Ogre::HardwarePixelBufferSharedPtr buffer;
        ptex = Ogre::TextureManager::getSingleton().createManual( "DynaTex", "General", Ogre::TEX_TYPE_2D, 256, 256, 0, Ogre::PF_R8G8B8A8, Ogre::TU_STATIC );
        buffer = ptex->getBuffer( 0, 0 );
        buffer->lock( Ogre::HardwareBuffer::HBL_DISCARD );
        const Ogre::PixelBox& pb = buffer->getCurrentLock();
        CreateTextureFromVram( pb, vram, 0, 0, 0x0, 0x1e0, 0x0, 0x0, BPP_8 , false );

        Ogre::Image image;
        image.loadDynamicImage( ( Ogre::uchar* )pb.data, 256, 256, Ogre::PF_R8G8B8A8 );
        image.save( "sword.png" );
        buffer->unlock();

        delete vram;
    }

    LOGGER->Log("===================== Stop the game!!!");



    delete FILESYSTEM;
    delete LOGGER;



    delete root;

    return 0;
}
void CTerrainTextureCombineDialog::OnBnClickedOk()
{
    // TODO: 在此添加控件通知处理程序代码
    UpdateData();
    if ( mDiffuse.IsEmpty() )
    {
        MessageBox( "漫反射贴图信息不完整!" );
        return;
    }

    if ( mSpecular.IsEmpty() )
    {
        MessageBox( "镜面贴图信息不完整!" );
        return;
    }

    if ( mNormal.IsEmpty() )
    {
        MessageBox( "法线贴图信息不完整!" );
        return;
    }

    if ( mDisp.IsEmpty() )
    {
        MessageBox( "位移贴图信息不完整!" );
        return;
    }

    if ( mDiffuseSpecular.IsEmpty() )
    {
        MessageBox( "漫反射镜面合成贴图信息不完整!" );
        return;
    }

    if ( mNormalDisp.IsEmpty() )
    {
        MessageBox( "法线位移合成贴图信息不完整!" );
        return;
    }

    Ogre::Image combined;

    combined.loadTwoImagesAsRGBA( mDiffuse.GetBuffer(), mSpecular.GetBuffer(),
                                  Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, Ogre::PF_BYTE_RGBA);
    combined.save(mDiffuseSpecular.GetBuffer());

    combined.loadTwoImagesAsRGBA( mNormal.GetBuffer(), mDisp.GetBuffer(),
                                  Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, Ogre::PF_BYTE_RGBA);
    combined.save(mNormalDisp.GetBuffer());

    MessageBox( "地表贴图合并完成!" );

    mDiffuse = "";
    mSpecular = "";
    mNormal = "";
    mDisp = "";
    mDiffuseSpecular = "test_diffusespecular.png";
    mNormalDisp = "test_normalheight.png";
    UpdateData(FALSE);

    ShowWindow(SW_HIDE);
    //OnOK();
}