From: <vo...@us...> - 2008-05-28 19:52:02
|
Revision: 753 http://opde.svn.sourceforge.net/opde/?rev=753&view=rev Author: volca Date: 2008-05-28 12:52:09 -0700 (Wed, 28 May 2008) Log Message: ----------- Tagged atlases for better batching Modified Paths: -------------- trunk/src/services/worldrep/LightmapAtlas.cpp trunk/src/services/worldrep/LightmapAtlas.h Modified: trunk/src/services/worldrep/LightmapAtlas.cpp =================================================================== --- trunk/src/services/worldrep/LightmapAtlas.cpp 2008-05-28 19:47:06 UTC (rev 752) +++ trunk/src/services/worldrep/LightmapAtlas.cpp 2008-05-28 19:52:09 UTC (rev 753) @@ -43,7 +43,7 @@ /* A single texture, containing many lightmaps. used in the texturelist construction */ - LightAtlas::LightAtlas(int idx) { + LightAtlas::LightAtlas(int idx, int tag) : mTag(tag) { mName << "@lightmap" << idx; // so we can find the atlas by number in the returned AtlasInfo this->mIdx = idx; @@ -57,7 +57,7 @@ mTex = TextureManager::getSingleton().createManual( mName.str(), TEMPTEXTURE_RESOURCE_GROUP, TEX_TYPE_2D, ATLAS_WIDTH, ATLAS_HEIGHT, 0, PF_X8R8G8B8, - TU_DYNAMIC_WRITE_ONLY); + TU_STATIC_WRITE_ONLY); mAtlas = mTex->getBuffer(0, 0); @@ -96,12 +96,38 @@ bool LightAtlas::addLightMap(LightMap *lmap) { std::pair<int, int> dim = lmap->getDimensions(); - // get the origin for our lmap FreeSpaceInfo* area = mFreeSpace->allocate(dim.first, dim.second); - if (area == NULL) // didn't fit + if (area == NULL) return false; + + /* // TODO: Dynamic allocation of lmap atlas size... + bool doStep = true; + // try the fit/enlarge combo till we can + while (doStep) { + // get the origin for our lmap + FreeSpaceInfo* area = mFreeSpace->allocate(dim.first, dim.second); + + if (area == NULL) {// didn't fit + // would we fit in a bottom/right of a 2x bigger lmap? + // and is it legal to construct such? + + // always rectangular... + if (mFreeSpace->w < ATLAS_MAX_WIDTH) { + // construct a 2x bigger lmap atlas info + // TODO: If our freespace is a child and free, don't wrap! + mFreeSpace = new FreeSpaceInfo(mFreeSpace); + } else { + return false; + } + } else { + // ok, we're in! + doStep = false; + } + } + */ + // calculate some important UV conversion data // +0.5? to display only the inner transition of lmap texture, the outer goes to black color lmap->mUV.x = ((float)area->x) / ATLAS_WIDTH; @@ -237,12 +263,15 @@ // iterate through existing Atlases, and see if any of them accepts our lightmap for (int i = 0; i < last; i++) { - if (mList.at(i)->addLightMap(lmap)) - return false; + if (mList.at(i)->getTag() != lmap->getTag()) + continue; + + if (mList.at(i)->addLightMap(lmap)) + return false; } // add new atlas to list if none of them accepted the lmap - LightAtlas* la = new LightAtlas(last); + LightAtlas* la = new LightAtlas(last, lmap->getTag()); mList.push_back(la); la->addLightMap(lmap); @@ -255,7 +284,7 @@ lmpixel *cdata = LightMap::convert(buf, w, h, ver); // construct the lmap - LightMap* lmap = new LightMap(w, h, cdata); + LightMap* lmap = new LightMap(w, h, cdata, texture); // Try to insert, will find existing if already there std::pair<TextureLightMapQueue::iterator, bool> lmm; @@ -308,6 +337,23 @@ OPDE_EXCEPT("Could not render the lightmaps!","LightAtlasList::render()"); + // iterate through existing Atlases, and see if any of them accepts our lightmap + int unused_pixels = 0, total_pixels = 0; + + int last = mList.size(); + + for (int i = 0; i < last; i++) { + unused_pixels += mList.at(i)->getUnusedArea(); + total_pixels += ATLAS_WIDTH * ATLAS_HEIGHT; + } + + float percentage = 0; + + if (total_pixels > 0) + percentage = 100.0f * unused_pixels / total_pixels; + + LOG_INFO("Light Map Atlas: Total unused light map atlasses pixels: %d of %d (%f%%). %d atlases total used. Total splits: %d", unused_pixels, total_pixels, percentage, last, mSplitCount); + return true; } Modified: trunk/src/services/worldrep/LightmapAtlas.h =================================================================== --- trunk/src/services/worldrep/LightmapAtlas.h 2008-05-28 19:47:06 UTC (rev 752) +++ trunk/src/services/worldrep/LightmapAtlas.h 2008-05-28 19:52:09 UTC (rev 753) @@ -83,7 +83,28 @@ int w; int h; - + /* TODO Construct a 2x bigger FreeSpaceInfo, holding the given one as a child + FreeSpaceInfo(FreeSpaceInfo* orig) { + x = 0; + y = 0; + + w = 2 * orig->w; + h = 2 * orig->h; + + // rest + // below our original + mChild[0] = new FreeSpaceInfo(orig->w, 0, orig->w, h); + + mChild[0]->mIsLeaf = false; + + mChild[0]->mChild[0] = orig; + // square one, bottom of the original + mChild[0]->mChild[1] = new FreeSpaceInfo(0, orig->h, orig->w, orig->h); + + // next to our original, rectangular + mChild[1] = new FreeSpaceInfo(orig->w, 0, orig->w, h); + } + */ FreeSpaceInfo(int x, int y, int w, int h) { this->x = x; @@ -268,16 +289,16 @@ /** Size of the lmap in the atlas*/ Ogre::Vector2 mSizeUV; + /** Lightmap's tag value */ + int mTag; + public: /** Constructor - takes the targetting freespaceinfo, size of the lightmap and initializes our buffer with the static lightmap. * This class will manage the unallocation of the lighymap as needed, just pass the pointer, it will deallocate the lmap in the destructor * @note The static_lightmap will be delete[]'d in destructor, together with any switchable lightmaps present */ - LightMap(unsigned int sx, unsigned int sy, lmpixel *static_lightmap) { + LightMap(unsigned int sx, unsigned int sy, lmpixel *static_lightmap, int tag = 0) : mSizeX(sx), mSizeY(sy), mTag(tag) { mStaticLmap = static_lightmap; - mSizeX = sx; - mSizeY = sy; - mPosition = NULL; } @@ -328,6 +349,8 @@ /** Returns the atlas index */ int getAtlasIndex(); + + int getTag() {return mTag; }; }; /** Class holding one set of light maps. Uses a HardwarePixelBufferSharedPtr class for texture storage. @@ -364,9 +387,11 @@ /** return an origin - XY coords for the next free space (for a lightmap sized w*h) */ std::pair<FreeSpaceInfo, bool> getOrigin(int w, int h); - + + /** Tag value of this atlas */ + int mTag; public: - LightAtlas(int idx); + LightAtlas(int idx, int tag = 0); ~LightAtlas(); @@ -397,6 +422,9 @@ /** Returns the pixel count of unmapped area of this atlas */ int getUnusedArea(); + + /** returns the tag number of this atlas */ + int getTag() {return mTag;}; }; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |