//----------------------------------------------------------------------------// Texture* OgreImageCodec::load(const RawDataContainer& data, Texture* result) { using namespace Ogre; // wrap the buffer of the RawDataContainer with an Ogre::MemoryDataStream. DataStreamPtr stream( new MemoryDataStream( const_cast<void*>(static_cast<const void*>(data.getDataPtr())), data.getSize(), false)); // load the image Ogre::Image image; image.load(stream); // discover the pixel format and number of pixel components Texture::PixelFormat format; int components; switch (image.getFormat()) { case PF_R8G8B8: format = Texture::PF_RGB; components = 3; break; case PF_A8R8G8B8: format = Texture::PF_RGBA; components = 4; break; default: throw FileIOException("OgreImageCodec::load: File data was of an " "unsupported format."); break; } // do the old switcharoo on R and B... // (we could 'fix' this in the CEGUI::OgreTexture, but that would break all // the other ImageCodecs when used with the Ogre renderer, hence we don't) uchar* dat = image.getData(); for (uint j = 0; j < image.getHeight(); ++j) { for (uint i = 0; i < image.getWidth(); ++i) { uchar tmp = dat[i * components + 0]; dat[i * components + 0] = dat[i * components + 2]; dat[i * components + 2] = tmp; } dat += image.getRowSpan(); } // load the resulting image into the texture result->loadFromMemory(image.getData(), Size(image.getWidth(), image.getHeight()), format); return result; }
//----------------------------------------------------------------------------------------- void CTerrainGroupEditor::importFullTerrainFromHeightMap() { UTFStringVector extlist; extlist.push_back(OTR("PNG Grayscale")); extlist.push_back("*.png"); extlist.push_back(OTR("Raw 32bit Float File")); extlist.push_back("*.raw;*.ohm;*.f32;*.r32"); Ogre::UTFString defaultPath = mSystem->GetSetting("system", "ExportTerrainPath", ""); Ogre::String filename = mSystem->DisplayOpenDialog(OTR("Import Heightmap"), extlist, defaultPath); if(filename == "") return; mSystem->SetSetting("system", "ExportTerrainPath", OgitorsUtils::ExtractFilePath(filename)); Ogre::NameValuePairList params; if(!mSystem->DisplayImportHeightMapDialog(params)) return; Ogre::Real fScale = Ogre::StringConverter::parseReal(params["scale"]); Ogre::Real fBias = Ogre::StringConverter::parseReal(params["bias"]); Ogre::String normal = params["normal"]; Ogre::String diffuse = params["diffuse"]; bool flipV = Ogre::StringConverter::parseBool(params["inverted"]); float *data = 0; float *flipBV = 0; Ogre::String namePart = OgitorsUtils::ExtractFileName(filename); namePart.erase(0, namePart.find(".")); int imgW = 0; int imgH = 0; if(namePart == ".png") { std::fstream fstr(filename.c_str(), std::ios::in|std::ios::binary); Ogre::DataStreamPtr stream = Ogre::DataStreamPtr(OGRE_NEW Ogre::FileStreamDataStream(&fstr, false)); Ogre::Image img; img.load(stream); data = OGRE_ALLOC_T(float, img.getWidth() * img.getHeight(), Ogre::MEMCATEGORY_GEOMETRY); Ogre::PixelBox pb(img.getWidth(), img.getHeight(), 1, Ogre::PF_FLOAT32_R, data); Ogre::PixelUtil::bulkPixelConversion(img.getPixelBox(), pb); imgW = img.getWidth(); imgH = img.getHeight(); img.freeMemory(); stream.setNull(); }
void SnowTerrain::initBlendMaps(Terrain* terrain) { TextureLayerFileList blendImages = mSnowConfig->terrainSettings.textureBlendFileList; // load those blendmaps into the layers for(int j = 0;j < terrain->getLayerCount();j++) { // skip first layer if(j==0) continue; // no blend map for this layer if(blendImages.size() >= j && blendImages[j].length() == 0) continue; Ogre::TerrainLayerBlendMap *blendmap = terrain->getLayerBlendMap(j); Ogre::Image img; img.load(blendImages[j],"General"); int blendmapsize = terrain->getLayerBlendMapSize(); if(img.getWidth() != blendmapsize) img.resize(blendmapsize, blendmapsize); float *ptr = blendmap->getBlendPointer(); Ogre::uint8 *data = static_cast<Ogre::uint8*>(img.getPixelBox().data); for(int bp = 0;bp < blendmapsize * blendmapsize;bp++) ptr[bp] = static_cast<float>(data[bp]) / 255.0f; blendmap->dirty(); blendmap->update(); } }
void gkTextureLoader::loadResource(Ogre::Resource* resource) { Ogre::Texture* texture = static_cast<Ogre::Texture*>(resource); if (!m_stream) { gkPrintf("Warning: Skipping image %s no packed file information is present!", texture->getName().c_str()); return; } Ogre::DataStreamPtr stream(OGRE_NEW Ogre::MemoryDataStream(m_stream->ptr(), m_stream->size())); Ogre::Image ima; ima.load(stream); texture->setUsage(Ogre::TU_DEFAULT); texture->setTextureType(Ogre::TEX_TYPE_2D); texture->setNumMipmaps(gkEngine::getSingleton().getUserDefs().defaultMipMap); texture->setWidth(ima.getWidth()); texture->setHeight(ima.getHeight()); texture->setDepth(ima.getDepth()); texture->setFormat(ima.getFormat()); Ogre::ConstImagePtrList ptrs; ptrs.push_back(&ima); texture->_loadImages(ptrs); }
//----------------------------------------------------------------------------------------- void CTerrainGroupEditor::setBrushName(const std::string& brush) { mBrushName = brush; if(!mDecalTexture.isNull()) { Ogre::Image img; img.load(brush,"Brushes"); unsigned char *dataptr = OGRE_ALLOC_T(unsigned char, img.getWidth() * img.getHeight() * 3, Ogre::MEMCATEGORY_GEOMETRY); Ogre::PixelBox resultbox(img.getWidth(),img.getHeight(),1,Ogre::PF_B8G8R8,dataptr); Ogre::PixelUtil::bulkPixelConversion(img.getPixelBox(), resultbox); resultbox.setConsecutive(); int pos = 0; Ogre::ColourValue colval; for(unsigned int x = 0;x < img.getHeight() * img.getWidth();x++) { dataptr[pos] = 0; dataptr[pos + 1] = 0; dataptr[pos + 2] *= 0.8f; pos += 3; } mDecalTexture->setHeight(img.getHeight()); mDecalTexture->setWidth(img.getWidth()); Ogre::HardwarePixelBufferSharedPtr ptr = mDecalTexture->getBuffer(); ptr->blitFromMemory(resultbox); OGRE_FREE(dataptr, Ogre::MEMCATEGORY_GEOMETRY); img.resize(mBrushSize, mBrushSize); img.resize(BRUSH_DATA_SIZE, BRUSH_DATA_SIZE); pos = 0; Ogre::ColourValue cval; for(unsigned int y = 0;y < BRUSH_DATA_SIZE ;y++) { pos = ((BRUSH_DATA_SIZE - 1) - y) * BRUSH_DATA_SIZE; for(unsigned int x = 0;x < BRUSH_DATA_SIZE ;x++) { cval = img.getColourAt(x,y,0); mBrushData[pos] = cval.r; pos++; } } }
void AppDemarrage::createTerrain() { // options globales mTerrainOptions = OGRE_NEW Ogre::TerrainGlobalOptions(); mTerrainOptions->setMaxPixelError(8); mTerrainOptions->setLightMapDirection(mLight->getDerivedDirection()); mTerrainOptions->setCompositeMapDistance(3000); mTerrainOptions->setCompositeMapAmbient(mSceneMgr->getAmbientLight()); mTerrainOptions->setCompositeMapDiffuse(mLight->getDiffuseColour()); mTerrain = OGRE_NEW Ogre::Terrain(mSceneMgr); Ogre::Image img; img.load("terrain.png", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); // informations géométriques Ogre::Terrain::ImportData imp; imp.inputImage = &img; imp.terrainSize = img.getWidth(); imp.worldSize = 8000; imp.inputScale = 600; imp.minBatchSize = 33; imp.maxBatchSize = 65; // textures imp.layerList.resize(3); imp.layerList[0].worldSize = 100; imp.layerList[0].textureNames.push_back("grass_green-01_diffusespecular.dds"); imp.layerList[0].textureNames.push_back("grass_green-01_normalheight.dds"); imp.layerList[1].worldSize = 30; imp.layerList[1].textureNames.push_back("growth_weirdfungus-03_diffusespecular.dds"); imp.layerList[1].textureNames.push_back("growth_weirdfungus-03_normalheight.dds"); imp.layerList[2].worldSize = 200; imp.layerList[2].textureNames.push_back("dirt_grayrocky_diffusespecular.dds"); imp.layerList[2].textureNames.push_back("dirt_grayrocky_normalheight.dds"); mTerrain->prepare(imp); mTerrain->load(); // plaquage de texture Ogre::TerrainLayerBlendMap* blendMap1 = mTerrain->getLayerBlendMap(1); float* pBlend1 = blendMap1->getBlendPointer(); for (Ogre::uint16 y = 0; y < mTerrain->getLayerBlendMapSize(); ++y) { for (Ogre::uint16 x = 0; x < mTerrain->getLayerBlendMapSize(); ++x) { *pBlend1++ = 150; } } blendMap1->dirty(); blendMap1->update(); mTerrain->freeTemporaryResources(); }
void MouseCursor::_setSkinType(const Ogre::String type) { if(mSkinType == type) return; mSkinType = type; Ogre::Image i; i.load(mSkinTypeManager->getSkinType("MouseCursor",mSkinType)->getSkinElement(TEXTURE)->getTextureName(),Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); // update cursor size to match texture used setSize(i.getWidth(),i.getHeight()); }
//----------------------------------------------------------------------------------------- QPixmap GenericImageEditorCodec::onBeforeDisplay(Ogre::DataStreamPtr stream) { Ogre::Image image; image.load(stream); ImageConverter imageConverter(image.getWidth(), image.getHeight()); if (mPixmap.convertFromImage(imageConverter.fromOgreImage(image))) return mPixmap; mPixmap = 0; return mPixmap; }
//----------------------------------------------------------------------- void AtlasImageTool::correctAlpha (Ogre::Image& image, Ogre::Real alphaCorrection) { size_t numPixels = image.getWidth() * image.getHeight(); size_t pointer = 0; for (size_t i = 0; i < numPixels; ++i) { Ogre::ColourValue colour; Ogre::PixelUtil::unpackColour(&colour, image.getFormat(), (image.getData() + pointer)); colour.a *= alphaCorrection; Ogre::PixelUtil::packColour(colour, image.getFormat(), (image.getData() + pointer)); pointer += Ogre::PixelUtil::getNumElemBytes(image.getFormat()); } }
void MouseCursor::setSkinType(const Ogre::String type) { mSkinType = type; mDefaultSkinType = type; Ogre::Image i; i.load(mSkinTypeManager->getSkinType("MouseCursor",mSkinType)->getSkinElement(TEXTURE)->getTextureName(),Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); // update cursor size to match texture used setSize(i.getWidth(),i.getHeight()); Sheet* sheet = mMouseCursorDesc.guiManager->getActiveSheet(); if(sheet != NULL) { MouseEventArgs args(sheet); args.position = getPosition(); sheet->fireSheetEvent(SHEET_EVENT_MOUSE_CURSOR_SKIN_CHANGED,args); } }
MouseCursor::MouseCursor(const MouseCursorDesc& d) : mSkinType("default"), mDefaultSkinType("default") { mMouseCursorDesc.guiManager = d.guiManager; mSkinTypeManager = SkinTypeManager::getSingletonPtr(); for(int i = 0; i < 4; ++i) mEnteredBorders[i] = false; // Update Size of Cursor to match Skin Texture Ogre::Image i; i.load(mSkinTypeManager->getSkinType("MouseCursor",mSkinType)->getSkinElement(TEXTURE)->getTextureName(),Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); // update cursor size to match texture used setSize(i.getWidth(),i.getHeight()); // Set default position setPosition(0,0); }
//----------------------------------------------------------------------- void AtlasImageTool::interpolate (Ogre::Image& interpolatedImage, Ogre::Image& firstImage, Ogre::Image& nextImage, Ogre::Real fraction) { size_t numPixels = interpolatedImage.getWidth() * interpolatedImage.getHeight(); size_t pointer = 0; for (size_t i = 0; i < numPixels; ++i) { Ogre::ColourValue firstColour; Ogre::ColourValue nextColour; Ogre::ColourValue interpolatedColour; Ogre::PixelUtil::unpackColour(&firstColour, firstImage.getFormat(), (firstImage.getData() + pointer)); Ogre::PixelUtil::unpackColour(&nextColour, nextImage.getFormat(), (nextImage.getData() + pointer)); interpolatedColour = firstColour + fraction * (nextColour - firstColour); Ogre::PixelUtil::packColour(interpolatedColour, interpolatedImage.getFormat(), (interpolatedImage.getData() + pointer)); pointer += Ogre::PixelUtil::getNumElemBytes(interpolatedImage.getFormat()); } }
void DotSceneLoader::processBlendmaps(rapidxml::xml_node<>* XMLNode) { int pageX = Ogre::StringConverter::parseInt(XMLNode->first_attribute("pageX")->value()); int pageY = Ogre::StringConverter::parseInt(XMLNode->first_attribute("pageY")->value()); Ogre::String filename = mTerrainGroup->generateFilename(pageX, pageY); // skip this is terrain page has been saved already if (!Ogre::ResourceGroupManager::getSingleton().resourceExists(mTerrainGroup->getResourceGroup(), filename)) { rapidxml::xml_node<>* pElement; // Process blendmaps (*) std::vector<Ogre::String> blendMaps; rapidxml::xml_node<>* pBlendmap; pElement = XMLNode->first_node("blendMaps"); pBlendmap = pElement->first_node("blendMap"); while(pBlendmap) { blendMaps.push_back(getAttrib(pBlendmap, "texture","")); pBlendmap = pBlendmap->next_sibling("blendMap"); } for(int j = 1;j < mTerrainGroup->getTerrain(pageX, pageY)->getLayerCount();j++) { Ogre::TerrainLayerBlendMap *blendmap = mTerrainGroup->getTerrain(pageX, pageY)->getLayerBlendMap(j); Ogre::Image img; img.load(blendMaps[j-1],"General"); int blendmapsize = mTerrainGroup->getTerrain(pageX, pageY)->getLayerBlendMapSize(); if(img.getWidth() != blendmapsize) img.resize(blendmapsize, blendmapsize); float *ptr = blendmap->getBlendPointer(); Ogre::uint8 *data = static_cast<Ogre::uint8*>(img.getPixelBox().data); for(int bp = 0;bp < blendmapsize * blendmapsize;bp++) ptr[bp] = static_cast<float>(data[bp]) / 255.0f; blendmap->dirty(); blendmap->update(); } } }
void GlobalMap::exploreCell(int cellX, int cellY) { float originX = static_cast<float>((cellX - mMinX) * mCellSize); // NB y + 1, because we want the top left corner, not bottom left where the origin of the cell is float originY = static_cast<float>(mHeight - (cellY + 1 - mMinY) * mCellSize); if (cellX > mMaxX || cellX < mMinX || cellY > mMaxY || cellY < mMinY) return; Ogre::TexturePtr localMapTexture = Ogre::TextureManager::getSingleton().getByName("Cell_" + boost::lexical_cast<std::string>(cellX) + "_" + boost::lexical_cast<std::string>(cellY)); if (!localMapTexture.isNull()) { int mapWidth = localMapTexture->getWidth(); int mapHeight = localMapTexture->getHeight(); mOverlayTexture->load(); mOverlayTexture->getBuffer()->blit(localMapTexture->getBuffer(), Ogre::Image::Box(0,0,mapWidth,mapHeight), Ogre::Image::Box(static_cast<Ogre::uint32>(originX), static_cast<Ogre::uint32>(originY), static_cast<Ogre::uint32>(originX + mCellSize), static_cast<Ogre::uint32>(originY + mCellSize))); Ogre::Image backup; std::vector<Ogre::uchar> data; data.resize(mCellSize*mCellSize*4, 0); backup.loadDynamicImage(&data[0], mCellSize, mCellSize, Ogre::PF_A8B8G8R8); localMapTexture->getBuffer()->blitToMemory(Ogre::Image::Box(0,0,mapWidth,mapHeight), backup.getPixelBox()); for (int x=0; x<mCellSize; ++x) for (int y=0; y<mCellSize; ++y) { assert (originX+x < mOverlayImage.getWidth()); assert (originY+y < mOverlayImage.getHeight()); assert (x < int(backup.getWidth())); assert (y < int(backup.getHeight())); mOverlayImage.setColourAt(backup.getColourAt(x, y, 0), static_cast<size_t>(originX + x), static_cast<size_t>(originY + y), 0); } } }
//------------------------------------------------------ void TextureAtlas::build() { if (!mIsDirty) return; bool fitted; size_t area = 0; // build the fonts (if this didn't happen already) // so we'll be sure the glyphs are there to be atlassed FontSet::iterator fit = mMyFonts.begin(); while (fit != mMyFonts.end()) { FontDrawSource* fdsp = *fit++; if (!fdsp->isBuilt()) fdsp->build(); } // First, we sort by size of the DrawSource mMyDrawSources.sort(DrawSourceLess()); // now try to allocate all the draw sources. If we fail, grow and try again do { fitted = true; area = 0; // try to fit DrawSourceList::iterator it = mMyDrawSources.begin(); while (it != mMyDrawSources.end()) { const DrawSourcePtr& ds = *it++; const PixelSize& ps = ds->getPixelSize(); area += ps.getPixelArea(); LOG_VERBOSE("TextureAtlas: (%s) Trying to place %d x %d (%d -> %d)", mAtlasName.c_str(), ps.width, ps.height, ps.getPixelArea(), area); // try to allocate FreeSpaceInfo* fsi = mAtlasAllocation->allocate(ps.width, ps.height); if (fsi) { ds->setPlacementPtr(fsi); } else { fitted = false; break; } } // fitted? if (!fitted) // nope - Enlarge! enlarge(area); } while (!fitted); LOG_INFO("TextureAtlas: (%s) Creating atlas with dimensions %d x %d", mAtlasName.c_str(), mAtlasSize.width, mAtlasSize.height); if (mTexture.isNull()) prepareResources(); // TODO: Reallocate the texture here if needed! Ogre::HardwarePixelBufferSharedPtr pixelBuffer = mTexture->getBuffer(); pixelBuffer->lock(Ogre::HardwareBuffer::HBL_DISCARD); const Ogre::PixelBox& targetBox = pixelBuffer->getCurrentLock(); size_t pixelsize = Ogre::PixelUtil::getNumElemBytes(targetBox.format); size_t rowsize = targetBox.rowPitch * pixelsize; Ogre::uint8* dstData = static_cast<Ogre::uint8*>(targetBox.data); // We'll iterate over all draw sources, painting the pixels onto the allocated space DrawSourceList::iterator it = mMyDrawSources.begin(); while (it != mMyDrawSources.end()) { const DrawSourcePtr& ds = *it++; // render all pixels into the right place FreeSpaceInfo* fsi = reinterpret_cast<FreeSpaceInfo*>(ds->getPlacementPtr()); assert(fsi); // render into the specified place unsigned char* conversionBuf = NULL; const PixelSize& dps = ds->getPixelSize(); Ogre::Image* img = ds->getImage(); Ogre::PixelBox srcPixels = img->getPixelBox(); // convert if the source data don't match if(img->getFormat() != Ogre::PF_BYTE_BGRA) { conversionBuf = new unsigned char[img->getWidth() * img->getHeight() * pixelsize]; Ogre::PixelBox convPixels(Ogre::Box(0, 0, dps.width, dps.height), Ogre::PF_BYTE_BGRA, conversionBuf); Ogre::PixelUtil::bulkPixelConversion(srcPixels, convPixels); srcPixels = convPixels; } size_t srcrowsize = srcPixels.rowPitch * pixelsize; Ogre::uint8* srcData = static_cast<Ogre::uint8*>(srcPixels.data); // TODO: we're always handling 32bit data, so we could as well transfer 4 bytes each iteration instead of one (speedup) for(size_t row = 0; row < dps.height; row++) { for(size_t col = 0; col < srcrowsize; col++) { dstData[((row + fsi->y) * rowsize) + (fsi->x * pixelsize) + col] = srcData[(row * srcrowsize) + col]; } } delete[] conversionBuf; // Convert the full draw source pixel coordinates to the atlas contained ones (initializes the texturing coordinates transform) ds->atlas(mMaterial, fsi->x, fsi->y, mAtlasSize.width, mAtlasSize.height); } // for debug, write the texture to a file /*unsigned char *readrefdata = static_cast<unsigned char*>(targetBox.data); Ogre::Image img; img = img.loadDynamicImage (readrefdata, mTexture->getWidth(), mTexture->getHeight(), mTexture->getFormat()); img.save(mAtlasName + ".png");*/ // and close the pixel buffer of the atlas at the end pixelBuffer->unlock(); mIsDirty = false; }
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); } } }
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; }
Vector4* SnowTerrain::getTerrainNormalData() { PixelBox* terrainNormals; // load from normals file if(mSnowConfig->terrainSettings.normalsDataFile.length() > 0) { // get terrain normal data using image Ogre::Image img; img.load(mSnowConfig->terrainSettings.normalsDataFile, "General"); //img.flipAroundY(); //img.flipAroundX(); size_t size = img.getWidth(); assert(img.getWidth() == img.getHeight()); if (img.getWidth() != mTerrainSize || img.getHeight() != mTerrainSize) img.resize(mTerrainSize, mTerrainSize); terrainNormals = &img.getPixelBox(); Vector4* floats = convertNormalsToFloats(terrainNormals, true); //OGRE_FREE(terrainNormals->data, Ogre::MEMCATEGORY_GENERAL); // need to swap z and y vector due to different vertical axis in normal map and world space! for(size_t i = 0;i<mTerrainSize*mTerrainSize;i++) { Vector4 v = floats[i]; floats[i].z = v.y; floats[i].y = v.z; } return floats; } else { // need to wait until terrain is loaded while (getTerrain()->isDerivedDataUpdateInProgress()) { // we need to wait for this to finish OGRE_THREAD_SLEEP(50); Root::getSingleton().getWorkQueue()->processResponses(); } // Get terrain normal data using official method //terrainNormals = getTerrain()->calculateNormals(Ogre::Rect(0,0,mTerrainSize,mTerrainSize),Rect(0,0,mTerrainSize,mTerrainSize)); Ogre::Image img; getTerrain()->getTerrainNormalMap()->convertToImage(img); //img.flipAroundY(); img.flipAroundX(); //img.save("test_normals.bmp"); terrainNormals = &img.getPixelBox(); Vector4* floats = convertNormalsToFloats(terrainNormals, true); //OGRE_FREE(terrainNormals->data, Ogre::MEMCATEGORY_GENERAL); return floats; } }
void MaterialPreviewDialog::buildPreviewBitmap( const Ogre::String &texName ) { const Ogre::uchar BytePerPixel = 8; // 读取原始image Ogre::Image *oriImage = getPreviewImage(texName); // 源大纹理的大小 size_t oriImageHeight = oriImage->getHeight(); size_t oriImageWidth = oriImage->getWidth(); Ogre::uchar *oriImageData = oriImage->getData(); // 分配一个足够大的空间来保存新建的image的数据 size_t newImagegetRowSpan = oriImageWidth*oriImage->getBPP()/BytePerPixel; // 新建的image的行宽(单位为字节) Ogre::uchar *newImageData = OGRE_ALLOC_T(Ogre::uchar, oriImageHeight*newImagegetRowSpan, Ogre::MEMCATEGORY_GENERAL);//new Ogre::uchar[oriImageHeight*newImagegetRowSpan]; Ogre::uchar *newImageDataPointer = newImageData; Ogre::uchar *oriImagedataPointer = oriImageData; // 把所选的纹理的数据提取出来,并创建一个新的image for ( Ogre::uint i=0; i<oriImageHeight; ++i ) { memcpy(newImageDataPointer, oriImagedataPointer, newImagegetRowSpan); newImageDataPointer += newImagegetRowSpan; oriImagedataPointer += oriImage->getRowSpan(); } Ogre::Image newImage; newImage.loadDynamicImage(newImageData,oriImageWidth,oriImageHeight,1,oriImage->getFormat(),true); // 如果所选纹理大于64*64,就先resize if ( oriImageWidth > mPreviewImageWidth || oriImageHeight > mPreviewImageHeight ) newImage.resize(mPreviewImageWidth, mPreviewImageHeight); // 如果有alpha,要与黑白图进行混合 if ( newImage.getHasAlpha() ) { Ogre::ColourValue col; for ( int i=0; i<mPreviewImageWidth; ++i ) { for ( int j=0; j<mPreviewImageWidth; ++j ) { col = newImage.getColourAt(j,i,0); float alphaValue = col.a; unsigned char r = col.r*255 * alphaValue; unsigned char g = col.g*255 * alphaValue; unsigned char b = col.b*255 * alphaValue; // 设置到image中 mCurrentPreviewImage.SetRGB(j,i,r,g,b); } } } // 没有alpha,就直接拷贝数据 else { Ogre::ColourValue col; for ( int i=0; i<mPreviewImageWidth; ++i ) { for ( int j=0; j<mPreviewImageWidth; ++j ) { col = newImage.getColourAt(j,i,0); unsigned char r = col.r*255; unsigned char g = col.g*255; unsigned char b = col.b*255; // 设置到image中 mCurrentPreviewImage.SetRGB(j,i,r,g,b); } } } }
void Terrain::_createAtlasPixmap(size_t pixmapId) { const TerrainData::Pixmap& pixmap = mData->mPixmaps[pixmapId]; size_t textureId = pixmap.textureId; assert(textureId < mData->mTextures.size()); const Ogre::String& textureName = mData->mTextures[textureId]; // If the atlas texture already exist, use it. AtlasArray::const_iterator it; for (it = mAtlases.begin(); it != mAtlases.end(); ++it) { if (it->texture->getName() == textureName) break; } if (it != mAtlases.end()) { // Fill up atlas pixmap info size_t atlasId = it - mAtlases.begin() + 1; mAtlasPixmaps[pixmapId].atlasId = atlasId; mAtlasPixmaps[pixmapId].left = pixmap.left; mAtlasPixmaps[pixmapId].top = pixmap.top; mAtlasPixmaps[pixmapId].right = pixmap.right; mAtlasPixmaps[pixmapId].bottom = pixmap.bottom; return; } // If texture already loaded and is composited, use it without any modify. Ogre::TexturePtr texture = Ogre::TextureManager::getSingleton().getByName(textureName); if (!texture.isNull() && (texture->getWidth() > mAtlasPixmapSize || texture->getHeight() > mAtlasPixmapSize)) { mAtlases.push_back(Atlas()); Atlas& atlas = mAtlases.back(); atlas.texture = texture; // Fill up atlas pixmap info size_t atlasId = mAtlases.size(); mAtlasPixmaps[pixmapId].atlasId = atlasId; mAtlasPixmaps[pixmapId].left = pixmap.left; mAtlasPixmaps[pixmapId].top = pixmap.top; mAtlasPixmaps[pixmapId].right = pixmap.right; mAtlasPixmaps[pixmapId].bottom = pixmap.bottom; return; } // Load the image Ogre::Image image; image.load(textureName, BRUSH_RESOURCE_GROUP_NAME); // If the image is composited, use it without any modify. if (image.getWidth() > mAtlasPixmapSize || image.getHeight() > mAtlasPixmapSize) { mAtlases.push_back(Atlas()); Atlas& atlas = mAtlases.back(); // re-use the loaded image avoid load it again atlas.texture = Ogre::TextureManager::getSingleton() .loadImage(textureName, BRUSH_RESOURCE_GROUP_NAME, image); // Fill up atlas pixmap info size_t atlasId = mAtlases.size(); mAtlasPixmaps[pixmapId].atlasId = atlasId; mAtlasPixmaps[pixmapId].left = pixmap.left; mAtlasPixmaps[pixmapId].top = pixmap.top; mAtlasPixmaps[pixmapId].right = pixmap.right; mAtlasPixmaps[pixmapId].bottom = pixmap.bottom; return; } // Composite into the atlas texture. bool isTransparent = image.getHasAlpha(); AtlasAllocInfo& allocInfo = isTransparent ? mTransparentAtlasAllocInfo : mSolidAtlasAllocInfo; if (allocInfo.blockId >= mMaxAtlasBlockId) { // Use special name to avoid confuse with other reference with this texture Ogre::String atlasName = "<Terrain/Atlas>:" + Ogre::StringConverter::toString(mAtlases.size()); mAtlases.push_back(Atlas()); Atlas& atlas = mAtlases.back(); Ogre::PixelFormat pixelFormat = isTransparent ? Ogre::PF_A8R8G8B8 : Ogre::PF_X8R8G8B8; atlas.image.bind(new Ogre::Image); atlas.image->loadDynamicImage(0, mAtlasTextureSize, mAtlasTextureSize, 1, pixelFormat, true, 1, mAtlasNumMipMaps); memset(atlas.image->getData(), 0, atlas.image->getSize()); atlas.texture = Ogre::TextureManager::getSingleton().createManual(atlasName, BRUSH_RESOURCE_GROUP_NAME, Ogre::TEX_TYPE_2D, atlas.image->getWidth(), atlas.image->getHeight(), mAtlasNumMipMaps, atlas.image->getFormat(), Ogre::TU_DYNAMIC_WRITE_ONLY_DISCARDABLE, this); allocInfo.atlasId = mAtlases.size(); allocInfo.blockId = 0; } // Copy origin pixmap to atlas image Atlas& atlas = mAtlases[allocInfo.atlasId - 1]; int blockX = allocInfo.blockId % mAtlasBlockSize; int blockY = allocInfo.blockId / mAtlasBlockSize; Ogre::PixelBox dst = atlas.image->getPixelBox().getSubVolume(Ogre::Box( blockX * mAtlasPixmapSize, blockY * mAtlasPixmapSize, blockX * mAtlasPixmapSize + mAtlasPixmapSize, blockY * mAtlasPixmapSize + mAtlasPixmapSize)); Ogre::PixelBox src = image.getPixelBox().getSubVolume(Ogre::Box( fast_ifloor(pixmap.left * image.getWidth() + 0.5f), fast_ifloor(pixmap.top * image.getHeight() + 0.5f), fast_ifloor(pixmap.right * image.getWidth() + 0.5f), fast_ifloor(pixmap.bottom * image.getHeight() + 0.5f))); if (src.getWidth() == mAtlasPixmapSize && src.getHeight() == mAtlasPixmapSize) Ogre::PixelUtil::bulkPixelConversion(src, dst); else Ogre::Image::scale(src, dst); // Generate mipmaps manual for (size_t mipmap = 1; mipmap <= mAtlasNumMipMaps; ++mipmap) { src = dst; size_t pixmapSize = mAtlasPixmapSize >> mipmap; dst = atlas.image->getPixelBox(0, mipmap).getSubVolume(Ogre::Box( blockX * pixmapSize, blockY * pixmapSize, blockX * pixmapSize + pixmapSize, blockY * pixmapSize + pixmapSize)); Ogre::Image::scale(src, dst); } // Notify that the atlas texture need to reload if (atlas.texture->isLoaded()) atlas.texture->unload(); ++allocInfo.blockId; // Fill up atlas pixmap info mAtlasPixmaps[pixmapId].atlasId = allocInfo.atlasId; mAtlasPixmaps[pixmapId].left = blockX * mAtlasBlockTexCoordInc + 0.5f / mAtlasTextureSize; mAtlasPixmaps[pixmapId].top = blockY * mAtlasBlockTexCoordInc + 0.5f / mAtlasTextureSize; mAtlasPixmaps[pixmapId].right = mAtlasPixmaps[pixmapId].left + mAtlasBlockTexCoordInc - 1.0f / mAtlasTextureSize; mAtlasPixmaps[pixmapId].bottom = mAtlasPixmaps[pixmapId].top + mAtlasBlockTexCoordInc - 1.0f / mAtlasTextureSize; }
AssetLoadState TextureAsset::DeserializeFromData(const u8 *data, size_t numBytes) { if (!data) return ASSET_LOAD_FAILED; ///\todo Log out error. if (numBytes == 0) return ASSET_LOAD_FAILED; ///\todo Log out error. // Don't load textures to memory in headless mode if (assetAPI->IsHeadless()) { return ASSET_LOAD_FAILED; } if (OGRE_THREAD_SUPPORT != 0) { // We can only do threaded loading from disk, and not any disk location but only from asset cache. // local:// refs will return empty string here and those will fall back to the non-threaded loading. // Do not change this to do DiskCache() as that directory for local:// refs will not be a known resource location for ogre. QString cacheDiskSource = assetAPI->GetAssetCache()->GetDiskSource(QUrl(Name())); if (!cacheDiskSource.isEmpty()) { QFileInfo fileInfo(cacheDiskSource); std::string sanitatedAssetRef = fileInfo.fileName().toStdString(); loadTicket_ = Ogre::ResourceBackgroundQueue::getSingleton().load(Ogre::TextureManager::getSingleton().getResourceType(), sanitatedAssetRef, OgreRenderer::OgreRenderingModule::CACHE_RESOURCE_GROUP, false, 0, 0, this); return ASSET_LOAD_PROCESSING; } } try { // Convert the data into Ogre's own DataStream format. std::vector<u8> tempData(data, data + numBytes); #include "DisableMemoryLeakCheck.h" Ogre::DataStreamPtr stream(new Ogre::MemoryDataStream(&tempData[0], tempData.size(), false)); #include "EnableMemoryLeakCheck.h" // Load up the image as an Ogre CPU image object. Ogre::Image image; image.load(stream); if (ogreTexture.isNull()) // If we are creating this texture for the first time, create a new Ogre::Texture object. { ogreAssetName = OgreRenderer::SanitateAssetIdForOgre(this->Name().toStdString()).c_str(); ogreTexture = Ogre::TextureManager::getSingleton().loadImage(ogreAssetName.toStdString(), Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, image); } else // If we're loading on top of an Ogre::Texture we've created before, don't lose the old Ogre::Texture object, but reuse the old. { // This will allow all existing materials to keep referring to this texture, and they'll get the updated texture image immediately. ogreTexture->freeInternalResources(); if (image.getWidth() != ogreTexture->getWidth() || image.getHeight() != ogreTexture->getHeight() || image.getFormat() != ogreTexture->getFormat()) { ogreTexture->setWidth(image.getWidth()); ogreTexture->setHeight(image.getHeight()); ogreTexture->setFormat(image.getFormat()); } if (ogreTexture->getBuffer().isNull()) { LogError("DeserializeFromData: Failed to create texture " + this->Name().toStdString() + ": OgreTexture::getBuffer() was null!"); return ASSET_LOAD_FAILED; } Ogre::PixelBox pixelBox(Ogre::Box(0,0, image.getWidth(), image.getHeight()), image.getFormat(), (void*)image.getData()); ogreTexture->getBuffer()->blitFromMemory(pixelBox); ogreTexture->createInternalResources(); } return ASSET_LOAD_SUCCESFULL; } catch (Ogre::Exception &e) { LogError("DeserializeFromData: Failed to create texture " + this->Name().toStdString() + ": " + std::string(e.what())); return ASSET_LOAD_FAILED; } }
int _tmain(int argc, _TCHAR* argv[]) { // ------------------------- Check for command line argument ------------------------------------------- if (! argv[1]) { printf("\n"); printf("Missing argument.\nExample: \"Converter.exe job1.cfg\""); return 0; } // ------------------------- Basic Ogre Engine initialization ------------------------------------------- Ogre::Root* root = new Ogre::Root; Ogre::RenderSystem* rendersys = root->getRenderSystemByName("Direct3D9 Rendering Subsystem"); rendersys->setConfigOption("Full Screen", "No"); rendersys->setConfigOption("Video Mode", "800 x 600 @ 32-bit colour"); root->setRenderSystem(rendersys); Ogre::ResourceGroupManager::getSingleton().addResourceLocation("resource", "FileSystem", "General"); Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups(); root->initialise(false); Ogre::RenderWindow* window = root->createRenderWindow("RAW2OGT", 800, 600, false); Ogre::SceneManager* scenemgr = root->createSceneManager(Ogre::SceneType::ST_GENERIC); Ogre::Camera* camera = scenemgr->createCamera("camera"); Ogre::Viewport* viewport = window->addViewport(camera); /*Ogre::Vector3 lightdir(0, -0.3, 0.75); lightdir.normalise(); Ogre::Light* l = scenemgr->createLight("tstLight"); l->setType(Ogre::Light::LT_DIRECTIONAL); l->setDirection(lightdir); l->setDiffuseColour(Ogre::ColourValue(1.0, 1.0, 1.0)); l->setSpecularColour(Ogre::ColourValue(0.4, 0.4, 0.4));*/ scenemgr->setAmbientLight(Ogre::ColourValue(0.7, 0.7, 0.7)); // --------------------------------- Start convert ---------------------------------------------------- // Load job config Ogre::ConfigFile* terrainconfig = OGRE_NEW Ogre::ConfigFile(); terrainconfig->loadDirect(argv[1]); // Load info from [general] block Ogre::String heightmapfile = terrainconfig->getSetting("heightmap", "general"); Ogre::Real heightmapscale = Ogre::StringConverter::parseReal(terrainconfig->getSetting("heightmapscale", "general")); Ogre::Real heightmapoffset = Ogre::StringConverter::parseReal(terrainconfig->getSetting("heightmapoffset", "general")); Ogre::uint16 terrainsize = Ogre::StringConverter::parseUnsignedInt(terrainconfig->getSetting("terrainsize", "general")); Ogre::Real worldsize = Ogre::StringConverter::parseReal(terrainconfig->getSetting("worldsize", "general")); Ogre::uint16 layercount = Ogre::StringConverter::parseUnsignedInt(terrainconfig->getSetting("layercount", "general")); // initialise stream to heightmapfile Ogre::DataStreamPtr stream = Ogre::ResourceGroupManager::getSingleton().openResource(heightmapfile, "General"); size_t size = stream.get()->size(); // verify size if(size != terrainsize * terrainsize * 4) OGRE_EXCEPT( Ogre::Exception::ERR_INTERNAL_ERROR, "Size of stream does not match terrainsize!", "TerrainPage" ); // load to buffer float* buffer = OGRE_ALLOC_T(float, size, Ogre::MEMCATEGORY_GENERAL); stream->read(buffer, size); // apply scale and offset for(int i=0;i<terrainsize*terrainsize;i++) { buffer[i] = (buffer[i] + heightmapoffset) * heightmapscale; } // Terrain initialization Ogre::TerrainGlobalOptions* terrainglobals = OGRE_NEW Ogre::TerrainGlobalOptions(); terrainglobals->setMaxPixelError(1); //terrainglobals->setCompositeMapDistance(30000); //terrainglobals->setLightMapDirection(lightdir); //terrainglobals->setCompositeMapAmbient(scenemgr->getAmbientLight()); //terrainglobals->setCompositeMapDiffuse(l->getDiffuseColour()); Ogre::TerrainMaterialGeneratorA::SM2Profile* pMatProfile = static_cast<Ogre::TerrainMaterialGeneratorA::SM2Profile*>(terrainglobals->getDefaultMaterialGenerator()->getActiveProfile()); pMatProfile->setLightmapEnabled(false); pMatProfile->setCompositeMapEnabled(false); Ogre::TerrainGroup* terraingroup = OGRE_NEW Ogre::TerrainGroup(scenemgr, Ogre::Terrain::ALIGN_X_Z, terrainsize, worldsize); terraingroup->setFilenameConvention(Ogre::String("terrain"), Ogre::String("ogt")); terraingroup->setOrigin(Ogre::Vector3::ZERO); Ogre::Terrain* terrain = OGRE_NEW Ogre::Terrain(scenemgr); // terrainsettings Ogre::Terrain::ImportData& imp = terraingroup->getDefaultImportSettings(); imp.terrainSize = terrainsize; imp.worldSize = worldsize; imp.minBatchSize = 33; imp.maxBatchSize = 65; // use float RAW heightmap as input imp.inputFloat = buffer; // process texture layers imp.layerList.resize(layercount); Ogre::StringVector blendmaps(layercount); for(int i=0;i<layercount;i++) { // load layer info Ogre::String sectionStr = Ogre::StringConverter::toString(i); Ogre::Real layerworldsize = Ogre::StringConverter::parseReal(terrainconfig->getSetting("worldsize", sectionStr)); if (i==0) { // no blendmap at layer 0 (baselayer) Ogre::String specular = terrainconfig->getSetting("specular", sectionStr); Ogre::String normal = terrainconfig->getSetting("normal", sectionStr); // add layer imp.layerList[i].textureNames.push_back(specular); imp.layerList[i].textureNames.push_back(normal); imp.layerList[i].worldSize = layerworldsize; } else { Ogre::String specular = terrainconfig->getSetting("specular", sectionStr); Ogre::String normal = terrainconfig->getSetting("normal", sectionStr); Ogre::String blend = terrainconfig->getSetting("blend", sectionStr); // add layer imp.layerList[i].textureNames.push_back(specular); imp.layerList[i].textureNames.push_back(normal); imp.layerList[i].worldSize = layerworldsize; blendmaps[i] = blend; } } // load the terrain terrain->prepare(imp); terrain->load(); // load those blendmaps into the layers for(int j = 1;j < terrain->getLayerCount();j++) { Ogre::TerrainLayerBlendMap *blendmap = terrain->getLayerBlendMap(j); Ogre::Image img; img.load(blendmaps[j],"General"); int blendmapsize = terrain->getLayerBlendMapSize(); if(img.getWidth() != blendmapsize) img.resize(blendmapsize, blendmapsize); float *ptr = blendmap->getBlendPointer(); Ogre::uint8 *data = static_cast<Ogre::uint8*>(img.getPixelBox().data); for(int bp = 0;bp < blendmapsize * blendmapsize;bp++) ptr[bp] = static_cast<float>(data[bp]) / 255.0f; blendmap->dirty(); blendmap->update(); } // create filename for writing int pos = heightmapfile.find_last_of('.'); if (pos < 0) heightmapfile = heightmapfile + ".ogt"; else heightmapfile = heightmapfile.substr(0, pos) + ".ogt"; // save as Ogre .OGT terrain->save(heightmapfile); Ogre::LogManager::getSingletonPtr()->logMessage(Ogre::LogMessageLevel::LML_NORMAL, heightmapfile + " successfully written."); // debug viewing (exit with CTRL+C) camera->setPosition(-terrainsize, 7000, -terrainsize); camera->lookAt(terrainsize/2,0,terrainsize/2); root->startRendering(); return 0; }
void MaterialPreviewDialog::buildPreviewBitmap( const Ogre::String &texName ) { const Ogre::uchar BytePerPixel = 8; // 读取原始image Ogre::Image *oriImage = getPreviewImage(texName); // 源大纹理的大小 size_t oriImageHeight = oriImage->getHeight(); size_t oriImageWidth = oriImage->getWidth(); Ogre::uchar *oriImageData = oriImage->getData(); // 分配一个足够大的空间来保存新建的image的数据 size_t newImagegetRowSpan = oriImageWidth*oriImage->getBPP()/BytePerPixel; // 新建的image的行宽(单位为字节) Ogre::uchar *newImageData = new Ogre::uchar[oriImageHeight*newImagegetRowSpan]; Ogre::uchar *newImageDataPointer = newImageData; Ogre::uchar *oriImagedataPointer = oriImageData; // 把所选的纹理的数据提取出来,并创建一个新的image for ( Ogre::uint i=0; i<oriImageHeight; ++i ) { memcpy(newImageDataPointer, oriImagedataPointer, newImagegetRowSpan); newImageDataPointer += newImagegetRowSpan; oriImagedataPointer += oriImage->getRowSpan(); } Ogre::Image newImage; newImage.loadDynamicImage(newImageData,oriImageWidth,oriImageHeight,1,oriImage->getFormat(),true); // 如果所选纹理大于64*64,就先resize if ( oriImageWidth > mPreviewImageWidth || oriImageHeight > mPreviewImageHeight ) newImage.resize(mPreviewImageWidth, mPreviewImageHeight); // 如果有alpha,要与黑白图进行混合 if ( newImage.getHasAlpha() ) { Ogre::uchar *tempPtr = newImage.getData(); assert (tempPtr); for ( size_t i=0; i<mPreviewImageHeight; ++i ) for ( size_t j=0; j<mPreviewImageWidth; ++j ) { // 取出alpha值 float alphaValue = (float)tempPtr[3] / 255.0f; // 计算出经过alpha混合后的颜色值 unsigned char r = tempPtr[2] * alphaValue; unsigned char g = tempPtr[1] * alphaValue; unsigned char b = tempPtr[0] * alphaValue; // 设置到image中 mCurrentPreviewImage.SetRGB(j,i,r,g,b); tempPtr += 4; } // 要把指针移回到图片数据的 tempPtr -= mPreviewImageHeight * mPreviewImageWidth * 4; // 设置到缩略图控件中 } // 没有alpha,就直接拷贝数据 else { memcpy ( mCurrentPreviewImage.GetData(), newImage.getData(), newImage.getSize() ); } }
const Fairy::Action * BrushSelector::OnStartAutoTexAction( const wxTreeItemId &itemId, const wxString &brushName ) { // 启动自动纹理拼接action Fairy::Action* action = GetSceneManipulator()->_getAction("AutoTexPaintAction"); // 获取组的名称 wxString groupName = mBrushesTree->GetItemText(itemId); // 设置当前组的名称 action->setParameter( "%GroupName", AS_STRING(brushName) ); // 把之前的路径加上去 wxTreeItemId parentId = mBrushesTree->GetItemParent(itemId); wxTreeItemId rootId = mBrushesTree->GetRootItem(); while ( parentId != rootId ) { wxString parentText = mBrushesTree->GetItemText(parentId); parentText += '/'; groupName.Prepend( parentText ); parentId = mBrushesTree->GetItemParent(parentId); } groupName += "/"; // 获取该目录下的第一个节点 wxTreeItemIdValue dummy; wxTreeItemId childId = mBrushesTree->GetFirstChild(itemId,dummy); while ( childId.IsOk() == true ) { // 遍历每个节点,设置纹理名称 wxString texName = mBrushesTree->GetItemText(childId); childId = mBrushesTree->GetNextChild(itemId,dummy); if ( texName.find('|') == wxString::npos ) continue; action->setParameter( "%TextureName", AS_STRING(texName) ); } // 输入InputFinish表示纹理名称输入完毕 action->setParameter( "%TextureName", "InputFinish" ); // 判断纹理是否正确地进行了初始化 if ( action->getParameter("%IsInit") == "Yes" ) { GetSceneManipulator()->setActiveAction(action); return action; } else { // 启用simplepaintAction action = GetSceneManipulator()->_getAction("SimplePaintAction"); action->setParameter( "%TextureName", "InputBegin" ); // 获取该目录下的第一个节点 wxTreeItemIdValue dummy; wxTreeItemId childId = mBrushesTree->GetFirstChild(itemId,dummy); while ( childId.IsOk() == true ) { // 遍历每个节点,设置纹理名称 wxString texName = mBrushesTree->GetItemText(childId); childId = mBrushesTree->GetNextChild(itemId,dummy); if ( texName.find('|') == wxString::npos ) continue; const Fairy::TextureInfos ¤tPaintInfos = GetSceneManipulator()->getTextureInfos(mCurrentFileName.c_str()); const Fairy::TextureInfo ¤tPaintInfo = GetSceneManipulator()->getTextureInfo(mCurrentFileName.c_str(), texName.c_str()); Ogre::Image *previewImage = GetSceneManipulator()->getPreviewImage(currentPaintInfo.ownerTextureName); // 组成纹理信息字符串 Ogre::String texInfoString; texInfoString += currentPaintInfo.ownerTextureName; texInfoString += "|"; texInfoString += Ogre::StringConverter::toString(currentPaintInfo.height); texInfoString += "|"; texInfoString += Ogre::StringConverter::toString(currentPaintInfo.width); texInfoString += "|"; texInfoString += Ogre::StringConverter::toString(currentPaintInfo.leftCorner); texInfoString += "|"; texInfoString += Ogre::StringConverter::toString(currentPaintInfo.topCorner); texInfoString += "|"; texInfoString += Ogre::StringConverter::toString(previewImage->getHeight()); texInfoString += "|"; texInfoString += Ogre::StringConverter::toString(previewImage->getWidth()); texInfoString += "|"; texInfoString += Ogre::StringConverter::toString(currentPaintInfo.rotateType); action->setParameter( "%TextureName", AS_STRING(texInfoString) ); // 这里有个错误??,因为没有设置该纹理是否为普通纹理大小,所以如果这一个组中有一个大纹理,那么 // 它可能会只缩放到一格 } if ( action->getParameter("%IsInit") == "Yes" ) { GetSceneManipulator()->setActiveAction(action); return action; } else { // 为能成功初始化,先把active action设为NULL GetSceneManipulator()->setActiveAction(NULL); return NULL; } } }
void BrushSelector::buildPreviewBitmap( const Fairy::TextureInfo texInfo ) { const Ogre::uchar BytePerPixel = 8; // 读取原始image Ogre::Image *oriImage = GetSceneManipulator()->getPreviewImage(texInfo.ownerTextureName); // 源大纹理的大小 size_t oriImageHeight = oriImage->getHeight(); size_t oriImageWidth = oriImage->getWidth(); Ogre::uchar *oriImageData = oriImage->getData(); // 所选纹理的大小 size_t newImageWidth = texInfo.width*TexTileSize; size_t newImageHeight = texInfo.height*TexTileSize; // 分配一个足够大的空间来保存新建的image的数据 size_t newImagegetRowSpan = newImageWidth*oriImage->getBPP()/BytePerPixel; // 新建的image的行宽(单位为字节) Ogre::uchar *newImageData = OGRE_ALLOC_T(Ogre::uchar, oriImageHeight*newImagegetRowSpan, Ogre::MEMCATEGORY_GENERAL);//new Ogre::uchar[newImageHeight*newImagegetRowSpan]; Ogre::uchar *newImageDataPointer = newImageData; // 得知起始像素点 size_t startPoint = ( oriImageWidth * texInfo.topCorner + texInfo.leftCorner ) * TexTileSize * oriImage->getBPP()/BytePerPixel; Ogre::uchar *oriImagedataPointer = oriImageData + startPoint; // 把所选的纹理的数据提取出来,并创建一个新的image for ( Ogre::uint i=0; i<newImageHeight; ++i ) { memcpy(newImageDataPointer, oriImagedataPointer, newImagegetRowSpan); newImageDataPointer += newImagegetRowSpan; oriImagedataPointer += oriImage->getRowSpan(); } Ogre::Image newImage; newImage.loadDynamicImage(newImageData,newImageWidth,newImageHeight,1,oriImage->getFormat(),true); // 如果所选纹理大于64*64,就先resize if ( texInfo.width > 1 || texInfo.height > 1 ) newImage.resize(mPreviewImageWidth, mPreviewImageHeight); // 如果有alpha,要与黑白图进行混合 if ( newImage.getHasAlpha() ) { Ogre::ColourValue col; for ( int i=0; i<mPreviewImageWidth; ++i ) { for ( int j=0; j<mPreviewImageWidth; ++j ) { col = newImage.getColourAt(j,i,0); float alphaValue = col.a; unsigned char r = col.r*255 * alphaValue + mBlackWhitePreviewImage.GetRed(i,j) * ( 1.0f - alphaValue); unsigned char g = col.g*255 * alphaValue + mBlackWhitePreviewImage.GetGreen(i,j) * ( 1.0f - alphaValue); unsigned char b = col.b*255 * alphaValue + mBlackWhitePreviewImage.GetBlue(i,j) * ( 1.0f - alphaValue); // 设置到image中 mCurrentPreviewImage.SetRGB(j,i,r,g,b); } } // 设置到缩略图控件中 mBrushesPreview->SetBitmap(mCurrentPreviewImage); } // 没有alpha,就直接拷贝数据 else { Ogre::ColourValue col; for ( int i=0; i<mPreviewImageWidth; ++i ) { for ( int j=0; j<mPreviewImageWidth; ++j ) { col = newImage.getColourAt(j,i,0); unsigned char r = col.r*255; unsigned char g = col.g*255; unsigned char b = col.b*255; // 设置到image中 mCurrentPreviewImage.SetRGB(j,i,r,g,b); } } mBrushesPreview->SetBitmap(mCurrentPreviewImage); } }
void Terrain::resourcesLoaded() { mTerrain = OGRE_NEW Ogre::Terrain( GlobalsBase::mScene ); Ogre::Terrain::ImportData imp; Ogre::Image img; switch( mHeightmapType ) { case HEIGHTMAPTYPE_IMAGE: { Ogre::TexturePtr texture = Ogre::TextureManager::getSingleton().getByName( mHeightmapFile.string(), mResourceManager.getGroup() ); texture->convertToImage( img ); imp.inputImage = &img; imp.terrainSize = img.getWidth(); imp.inputScale = mInputScale; break; } case HEIGHTMAPTYPE_RAW: { Ogre::DataStreamPtr stream = Ogre::ResourceGroupManager::getSingleton().openResource( mHeightmapFile.string(), mResourceManager.getGroup() ); img.loadRawData( stream, 1025, 1025, Ogre::PF_FLOAT32_R ); imp.inputImage = &img; imp.terrainSize = img.getWidth(); imp.inputScale = 1; break; } case HEIGHTMAPTYPE_OGREBINARY: break; } if( mTerrainType != TERRAINTYPE_OGREBINARY ) { // Generic import data imp.worldSize = 1025; imp.minBatchSize = 33; imp.maxBatchSize = 65; imp.pos = toVector3<Ogre::Vector3>( ServerPosition( ClientPlugin::getServer().getGridPosition() ).get3DPosition() ); mTerrain->setPosition( imp.pos ); // Set textures imp.layerList.resize( mLayerInstances.size() ); for( unsigned int i = 0; i < mLayerInstances.size(); ++i ) { imp.layerList[i].worldSize = mLayerInstances[i].mWorldSize; for( std::vector<Path>::iterator j = mLayerInstances[i].mTextureFiles.begin(); j != mLayerInstances[i].mTextureFiles.end(); ++j ) { imp.layerList[i].textureNames.push_back( (*j).string() ); } } // Load the terrain mTerrain->prepare( imp ); mTerrain->load(); } // Set blending switch( mTerrainType ) { case TERRAINTYPE_AUTOBLENDMAP: { Ogre::TerrainLayerBlendMap* blendMap0 = mTerrain->getLayerBlendMap(1); Ogre::TerrainLayerBlendMap* blendMap1 = mTerrain->getLayerBlendMap(2); float* pBlend1 = blendMap1->getBlendPointer(); for (Ogre::uint16 y = 0; y < mTerrain->getLayerBlendMapSize(); ++y) { for (Ogre::uint16 x = 0; x < mTerrain->getLayerBlendMapSize(); ++x) { Ogre::Real tx, ty; blendMap0->convertImageToTerrainSpace(x, y, &tx, &ty); Ogre::Real height = mTerrain->getHeightAtTerrainPosition(tx, ty); Ogre::Real val = (height - mMinHeight0) / mFadeDistance0; val = Ogre::Math::Clamp(val, (Ogre::Real)0, (Ogre::Real)1); val = (height - mMinHeight1) / mFadeDistance1; val = Ogre::Math::Clamp(val, (Ogre::Real)0, (Ogre::Real)1); *pBlend1++ = val; } } blendMap0->dirty(); blendMap1->dirty(); blendMap0->update(); blendMap1->update(); break; } case TERRAINTYPE_OGREBINARY: // Everything is embedded in the binary file. mTerrain->setResourceGroup( mResourceManager.getGroup() ); mTerrain->prepare( mHeightmapFile.string() ); mTerrain->load( mHeightmapFile.string() ); break; } mTerrain->freeTemporaryResources(); ClientPlugin::mLoadingCompletedSignal( *this ); }
void BrushSelector::OnPixmapListSelected(wxTreeEvent& event) { try { // 以下是改成定义文件后的修改 // mPaintInOneGrid = false; // 保存当前选中的纹理的大小 int selectedTexXSize = 0; int selectedTexZSize = 0; // 当画刷被选中时,要进行判断 wxTreeItemId itemId = event.GetItem(); wxTreeItemId rootId = mBrushesTree->GetRootItem(); // 如果选中根,就返回 if ( itemId == rootId ) { // 选中根目录名时,所有选项都变灰 mFlipHorizontal->Enable(false); mFlipVertical->Enable(false); mRotateRightAngle->Enable(false); mMirrorDiagonal->Enable(false); mRandom->Enable(false); mEnablePreview->Enable(false); // 缩略图用黑白图 mBrushesPreview->SetBitmap(mBlackWhitePreviewImage); return; } if (itemId.IsOk()) { mCurrentOrientationType = 0; // 如果选项的父是root,说明该画刷是放在根目录下的,也有可能是根目录下的子目录 if ( mBrushesTree->GetItemParent(itemId) == rootId ) { mCurrentFileName = mBrushesTree->GetItemText(itemId); } else { // 以下处理不是放在根目录下的画刷 wxTreeItemId parentId = mBrushesTree->GetItemParent(itemId); mCurrentFileName = mBrushesTree->GetItemText(itemId); // 以此取出父目录的目录名,组合成相对路径名,并加上文件名 while ( parentId != rootId ) { wxString parentText = mBrushesTree->GetItemText(parentId); parentText += '/'; mCurrentFileName.Prepend( parentText ); parentId = mBrushesTree->GetItemParent(parentId); } } // 如果名字中有.,说明是文件名,不是目录名 if ( mCurrentFileName.find_first_of('|') != wxString::npos ) { mFlipHorizontal->Enable(true); mFlipVertical->Enable(true); mRotateRightAngle->Enable(true); mMirrorDiagonal->Enable(true); mRandom->Enable(true); mEnablePreview->Enable(true); Ogre::String currentFileName(mCurrentFileName.c_str()); size_t pos = currentFileName.find_last_of('/'); // 取出brush名称 Ogre::String brushName = currentFileName.substr(0,pos); Ogre::String textureName = currentFileName.substr(pos+1); const Fairy::TextureInfos ¤tPaintInfos = GetSceneManipulator()->getTextureInfos(brushName); const Fairy::TextureInfo ¤tPaintInfo = GetSceneManipulator()->getTextureInfo(brushName, textureName); Ogre::Image *previewImage = GetSceneManipulator()->getPreviewImage(currentPaintInfo.ownerTextureName); // 组成纹理信息字符串 Ogre::String texInfoString; texInfoString += currentPaintInfo.ownerTextureName; texInfoString += "|"; texInfoString += Ogre::StringConverter::toString(currentPaintInfo.height); texInfoString += "|"; texInfoString += Ogre::StringConverter::toString(currentPaintInfo.width); texInfoString += "|"; texInfoString += Ogre::StringConverter::toString(currentPaintInfo.leftCorner); texInfoString += "|"; texInfoString += Ogre::StringConverter::toString(currentPaintInfo.topCorner); texInfoString += "|"; texInfoString += Ogre::StringConverter::toString(previewImage->getHeight()); texInfoString += "|"; texInfoString += Ogre::StringConverter::toString(previewImage->getWidth()); texInfoString += "|"; texInfoString += Ogre::StringConverter::toString(currentPaintInfo.rotateType); Fairy::Action* action = GetSceneManipulator()->_getAction("SimplePaintAction"); action->setParameter( "%TextureName", "InputBegin" ); action->setParameter( "%TextureName", AS_STRING(texInfoString) ); action->setParameter( "%OrientationType", Ogre::StringConverter::toString(mCurrentOrientationType) ); if ( (currentPaintInfo.width > 1 || currentPaintInfo.height > 1) && !mPaintInOneGrid ) { action->setParameter( "%TexNormalSize", "false" ); mFlipHorizontal->Enable(false); mFlipVertical->Enable(false); mRotateRightAngle->Enable(false); mMirrorDiagonal->Enable(false); mRandom->Enable(false); } else { action->setParameter("%TexNormalSize","true"); } GetSceneManipulator()->setActiveAction(action); buildPreviewBitmap(currentPaintInfo); if ( mEnablePreview->IsChecked() == false ) { // 如果不显示缩略图,就显示默认的黑白图 mBrushesPreview->SetBitmap(mBlackWhitePreviewImage); } } // 如果名字中有.,说明不是文件名,是目录名 else { mFlipHorizontal->Enable(false); mFlipVertical->Enable(false); mRotateRightAngle->Enable(false); mMirrorDiagonal->Enable(false); mRandom->Enable(false); mEnablePreview->Enable(true); // 把整个目录的纹理进行判断,并加入到透明纹理列表 const Fairy::Action* action = OnStartAutoTexAction(itemId, mCurrentFileName); if ( action != 0 ) { // 从该组纹理的实心纹理中随机用一个来做为缩略图 // 读取这张纹理,并缩放到mPreviewImageWidth*mPreviewImageHeight,用于缩略图 // Ogre::String tempTexName = action->getParameter( "%TextureName" ); const Fairy::TextureInfos ¤tPaintInfos = GetSceneManipulator()->getTextureInfos(mCurrentFileName.c_str()); // const Fairy::TextureInfo ¤tPaintInfo = currentPaintInfos[0]; // 构建preview image buildPreviewBitmap(currentPaintInfos[0]); } else { mEnablePreview->Enable(false); mBrushesPreview->SetBitmap(mBlackWhitePreviewImage); } if ( mEnablePreview->IsChecked() == false ) { // 如果不显示缩略图,就显示默认的黑白图 mBrushesPreview->SetBitmap(mBlackWhitePreviewImage); } } } // 让所有的checkbox回复未选择的状态 mFlipHorizontal->SetValue(false); mFlipVertical->SetValue(false); mRotateRightAngle->SetValue(false); mMirrorDiagonal->SetValue(false); mRandom->SetValue(false); } catch (Ogre::Exception &e) { wxMessageBox( e.getDescription().c_str(), /* _("Texture Wrong")*/wxT("纹理定义出错或找不到纹理图片"), wxOK|wxCENTRE|wxICON_ERROR, this); } }
void SaveGameDialog::onSlotSelected(MyGUI::ListBox *sender, size_t pos) { if (pos == MyGUI::ITEM_NONE) { mCurrentSlot = NULL; mInfoText->setCaption(""); mScreenshot->setImageTexture(""); return; } if (mSaving) mSaveNameEdit->setCaption(sender->getItemNameAt(pos)); mCurrentSlot = NULL; unsigned int i=0; for (MWState::Character::SlotIterator it = mCurrentCharacter->begin(); it != mCurrentCharacter->end(); ++it, ++i) { if (i == pos) mCurrentSlot = &*it; } assert(mCurrentSlot && "Can't find selected slot"); std::stringstream text; time_t time = mCurrentSlot->mTimeStamp; struct tm* timeinfo; timeinfo = localtime(&time); // Use system/environment locale settings for datetime formatting setlocale(LC_TIME, ""); const int size=1024; char buffer[size]; if (std::strftime(buffer, size, "%x %X", timeinfo) > 0) text << buffer << "\n"; text << "Level " << mCurrentSlot->mProfile.mPlayerLevel << "\n"; text << mCurrentSlot->mProfile.mPlayerCell << "\n"; // text << "Time played: " << slot->mProfile.mTimePlayed << "\n"; int hour = int(mCurrentSlot->mProfile.mInGameTime.mGameHour); bool pm = hour >= 12; if (hour >= 13) hour -= 12; if (hour == 0) hour = 12; text << mCurrentSlot->mProfile.mInGameTime.mDay << " " << MWBase::Environment::get().getWorld()->getMonthName(mCurrentSlot->mProfile.mInGameTime.mMonth) << " " << hour << " " << (pm ? "#{sSaveMenuHelp05}" : "#{sSaveMenuHelp04}"); mInfoText->setCaptionWithReplacing(text.str()); // Decode screenshot std::vector<char> data = mCurrentSlot->mProfile.mScreenshot; // MemoryDataStream doesn't work with const data :( Ogre::DataStreamPtr stream(new Ogre::MemoryDataStream(&data[0], data.size())); Ogre::Image image; image.load(stream, "jpg"); const std::string textureName = "@savegame_screenshot"; Ogre::TexturePtr texture; texture = Ogre::TextureManager::getSingleton().getByName(textureName); mScreenshot->setImageTexture(""); if (texture.isNull()) { texture = Ogre::TextureManager::getSingleton().createManual(textureName, Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, Ogre::TEX_TYPE_2D, image.getWidth(), image.getHeight(), 0, Ogre::PF_BYTE_RGBA, Ogre::TU_DYNAMIC_WRITE_ONLY); } texture->unload(); texture->setWidth(image.getWidth()); texture->setHeight(image.getHeight()); texture->loadImage(image); mScreenshot->setImageTexture(textureName); }
void GlobalMap::read(ESM::GlobalMap& map) { const ESM::GlobalMap::Bounds& bounds = map.mBounds; if (bounds.mMaxX-bounds.mMinX < 0) return; if (bounds.mMaxY-bounds.mMinY < 0) return; if (bounds.mMinX > bounds.mMaxX || bounds.mMinY > bounds.mMaxY) throw std::runtime_error("invalid map bounds"); Ogre::Image image; Ogre::DataStreamPtr stream(new Ogre::MemoryDataStream(&map.mImageData[0], map.mImageData.size())); image.load(stream, "png"); int xLength = (bounds.mMaxX-bounds.mMinX+1); int yLength = (bounds.mMaxY-bounds.mMinY+1); // Size of one cell in image space int cellImageSizeSrc = image.getWidth() / xLength; if (int(image.getHeight() / yLength) != cellImageSizeSrc) throw std::runtime_error("cell size must be quadratic"); // If cell bounds of the currently loaded content and the loaded savegame do not match, // we need to resize source/dest boxes to accommodate // This means nonexisting cells will be dropped silently int cellImageSizeDst = mCellSize; // Completely off-screen? -> no need to blit anything if (bounds.mMaxX < mMinX || bounds.mMaxY < mMinY || bounds.mMinX > mMaxX || bounds.mMinY > mMaxY) return; int leftDiff = (mMinX - bounds.mMinX); int topDiff = (bounds.mMaxY - mMaxY); int rightDiff = (bounds.mMaxX - mMaxX); int bottomDiff = (mMinY - bounds.mMinY); Ogre::Image::Box srcBox ( std::max(0, leftDiff * cellImageSizeSrc), std::max(0, topDiff * cellImageSizeSrc), std::min(image.getWidth(), image.getWidth() - rightDiff * cellImageSizeSrc), std::min(image.getHeight(), image.getHeight() - bottomDiff * cellImageSizeSrc)); Ogre::Image::Box destBox ( std::max(0, -leftDiff * cellImageSizeDst), std::max(0, -topDiff * cellImageSizeDst), std::min(mOverlayTexture->getWidth(), mOverlayTexture->getWidth() + rightDiff * cellImageSizeDst), std::min(mOverlayTexture->getHeight(), mOverlayTexture->getHeight() + bottomDiff * cellImageSizeDst)); // Looks like there is no interface for blitting from memory with src/dst boxes. // So we create a temporary texture for blitting. Ogre::TexturePtr tex = Ogre::TextureManager::getSingleton().createManual("@temp", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, Ogre::TEX_TYPE_2D, image.getWidth(), image.getHeight(), 0, Ogre::PF_A8B8G8R8); tex->loadImage(image); mOverlayTexture->load(); mOverlayTexture->getBuffer()->blit(tex->getBuffer(), srcBox, destBox); if (srcBox.left == destBox.left && srcBox.right == destBox.right && srcBox.top == destBox.top && srcBox.bottom == destBox.bottom && int(image.getWidth()) == mWidth && int(image.getHeight()) == mHeight) mOverlayImage = image; else mOverlayTexture->convertToImage(mOverlayImage); Ogre::TextureManager::getSingleton().remove("@temp"); }
void OgreWidget::getTerrainImage(bool flipX, bool flipY, Ogre::Image& img) { img.load("terrain.png", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); qDebug() << "OgreWidget::getTerrainImage(): loaded terrain heightmap, width is" << img.getWidth(); if(flipX) img.flipAroundY(); if(flipY) img.flipAroundX(); }