void QuadTreeNode::loadLayers(const LayerCollection& collection) { assert (!mMaterialGenerator->hasLayers()); std::vector<Ogre::TexturePtr> blendTextures; for (std::vector<Ogre::PixelBox>::const_iterator it = collection.mBlendmaps.begin(); it != collection.mBlendmaps.end(); ++it) { // TODO: clean up blend textures on destruction static int count=0; Ogre::TexturePtr map = Ogre::TextureManager::getSingleton().createManual("terrain/blend/" + Ogre::StringConverter::toString(count++), Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, Ogre::TEX_TYPE_2D, it->getWidth(), it->getHeight(), 0, it->format); Ogre::DataStreamPtr stream(new Ogre::MemoryDataStream(it->data, it->getWidth()*it->getHeight()*Ogre::PixelUtil::getNumElemBytes(it->format), true)); map->loadRawData(stream, it->getWidth(), it->getHeight(), it->format); blendTextures.push_back(map); } mMaterialGenerator->setLayerList(collection.mLayers); mMaterialGenerator->setBlendmapList(blendTextures); }
void GlobalMap::render (Loading::Listener* loadingListener) { Ogre::TexturePtr tex; const MWWorld::ESMStore &esmStore = MWBase::Environment::get().getWorld()->getStore(); // get the size of the world MWWorld::Store<ESM::Cell>::iterator it = esmStore.get<ESM::Cell>().extBegin(); for (; it != esmStore.get<ESM::Cell>().extEnd(); ++it) { if (it->getGridX() < mMinX) mMinX = it->getGridX(); if (it->getGridX() > mMaxX) mMaxX = it->getGridX(); if (it->getGridY() < mMinY) mMinY = it->getGridY(); if (it->getGridY() > mMaxY) mMaxY = it->getGridY(); } mWidth = mCellSize*(mMaxX-mMinX+1); mHeight = mCellSize*(mMaxY-mMinY+1); loadingListener->loadingOn(); loadingListener->setLabel("Creating map"); loadingListener->setProgressRange((mMaxX-mMinX+1) * (mMaxY-mMinY+1)); loadingListener->setProgress(0); std::vector<Ogre::uchar> data (mWidth * mHeight * 3); for (int x = mMinX; x <= mMaxX; ++x) { for (int y = mMinY; y <= mMaxY; ++y) { ESM::Land* land = esmStore.get<ESM::Land>().search (x,y); if (land) { int mask = ESM::Land::DATA_WNAM; if (!land->isDataLoaded(mask)) land->loadData(mask); } for (int cellY=0; cellY<mCellSize; ++cellY) { for (int cellX=0; cellX<mCellSize; ++cellX) { int vertexX = static_cast<int>(float(cellX)/float(mCellSize) * 9); int vertexY = static_cast<int>(float(cellY) / float(mCellSize) * 9); int texelX = (x-mMinX) * mCellSize + cellX; int texelY = (mHeight-1) - ((y-mMinY) * mCellSize + cellY); unsigned char r,g,b; float y = 0; if (land && land->mDataTypes & ESM::Land::DATA_WNAM) y = (land->mLandData->mWnam[vertexY * 9 + vertexX] << 4) / 2048.f; else y = (SCHAR_MIN << 4) / 2048.f; if (y < 0) { r = static_cast<unsigned char>(14 * y + 38); g = static_cast<unsigned char>(20 * y + 56); b = static_cast<unsigned char>(18 * y + 51); } else if (y < 0.3f) { if (y < 0.1f) y *= 8.f; else { y -= 0.1f; y += 0.8f; } r = static_cast<unsigned char>(66 - 32 * y); g = static_cast<unsigned char>(48 - 23 * y); b = static_cast<unsigned char>(33 - 16 * y); } else { y -= 0.3f; y *= 1.428f; r = static_cast<unsigned char>(34 - 29 * y); g = static_cast<unsigned char>(25 - 20 * y); b = static_cast<unsigned char>(17 - 12 * y); } data[texelY * mWidth * 3 + texelX * 3] = r; data[texelY * mWidth * 3 + texelX * 3+1] = g; data[texelY * mWidth * 3 + texelX * 3+2] = b; } } loadingListener->increaseProgress(); if (land) land->unloadData(); } } Ogre::DataStreamPtr stream(new Ogre::MemoryDataStream(&data[0], data.size())); tex = Ogre::TextureManager::getSingleton ().createManual ("GlobalMap.png", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, Ogre::TEX_TYPE_2D, mWidth, mHeight, 0, Ogre::PF_B8G8R8, Ogre::TU_STATIC); tex->loadRawData(stream, mWidth, mHeight, Ogre::PF_B8G8R8); tex->load(); mOverlayTexture = Ogre::TextureManager::getSingleton().createManual("GlobalMapOverlay", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, Ogre::TEX_TYPE_2D, mWidth, mHeight, 0, Ogre::PF_A8B8G8R8, Ogre::TU_DYNAMIC, this); clear(); loadingListener->loadingOff(); }