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(); }
void GlobalMap::render (Loading::Listener* loadingListener) { 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); osg::ref_ptr<osg::Image> image = new osg::Image; image->allocateImage(mWidth, mHeight, 1, GL_RGB, GL_UNSIGNED_BYTE); unsigned char* data = image->data(); 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); } const ESM::Land::LandData *landData = land ? land->getLandData (ESM::Land::DATA_WNAM) : 0; 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 = (y-mMinY) * mCellSize + cellY; unsigned char r,g,b; float y = 0; if (landData) y = (landData->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(); } } mBaseTexture = new osg::Texture2D; mBaseTexture->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_EDGE); mBaseTexture->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_EDGE); mBaseTexture->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR); mBaseTexture->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR); mBaseTexture->setImage(image); mBaseTexture->setResizeNonPowerOfTwoHint(false); clear(); loadingListener->loadingOff(); }