From: <vo...@us...> - 2009-02-23 11:21:26
|
Revision: 1145 http://opde.svn.sourceforge.net/opde/?rev=1145&view=rev Author: volca Date: 2009-02-23 11:21:16 +0000 (Mon, 23 Feb 2009) Log Message: ----------- * Changed the DrawQuad to not contain duplicities * Font's Glyphs sorting, and atlas draw source sorting in general, was fixed Modified Paths: -------------- trunk/src/services/draw/DrawBuffer.cpp trunk/src/services/draw/DrawCommon.cpp trunk/src/services/draw/DrawCommon.h trunk/src/services/draw/DrawService.cpp trunk/src/services/draw/DrawService.h trunk/src/services/draw/FontDrawSource.cpp trunk/src/services/draw/RenderedImage.cpp trunk/src/services/draw/RenderedLabel.cpp trunk/src/services/draw/TextureAtlas.cpp Modified: trunk/src/services/draw/DrawBuffer.cpp =================================================================== --- trunk/src/services/draw/DrawBuffer.cpp 2009-02-19 20:08:19 UTC (rev 1144) +++ trunk/src/services/draw/DrawBuffer.cpp 2009-02-23 11:21:16 UTC (rev 1145) @@ -256,54 +256,54 @@ const DrawQuad* dq = *it; /// Top Left corner - *buf++ = dq->positions.topleft.x; - *buf++ = dq->positions.topleft.y; - *buf++ = dq->positions.topleft.z; + *buf++ = dq->positions.left; + *buf++ = dq->positions.top; + *buf++ = dq->depth; - *buf++ = dq->texCoords.topleft.x; - *buf++ = dq->texCoords.topleft.y; + *buf++ = dq->texCoords.left; + *buf++ = dq->texCoords.top; colptr = reinterpret_cast<Ogre::RGBA*>(buf); - Ogre::Root::getSingleton().convertColourValue(dq->colors.topleft, colptr); + Ogre::Root::getSingleton().convertColourValue(dq->color, colptr); colptr++; buf = reinterpret_cast<float*>(colptr); /// Top right corner - *buf++ = dq->positions.topright.x; - *buf++ = dq->positions.topright.y; - *buf++ = dq->positions.topright.z; + *buf++ = dq->positions.right; + *buf++ = dq->positions.top; + *buf++ = dq->depth; - *buf++ = dq->texCoords.topright.x; - *buf++ = dq->texCoords.topright.y; + *buf++ = dq->texCoords.right; + *buf++ = dq->texCoords.top; colptr = reinterpret_cast<Ogre::RGBA*>(buf); - Ogre::Root::getSingleton().convertColourValue(dq->colors.topright, colptr); + Ogre::Root::getSingleton().convertColourValue(dq->color, colptr); colptr++; buf = reinterpret_cast<float*>(colptr); /// Bottom left corner - *buf++ = dq->positions.bottomleft.x; - *buf++ = dq->positions.bottomleft.y; - *buf++ = dq->positions.bottomleft.z; + *buf++ = dq->positions.left; + *buf++ = dq->positions.bottom; + *buf++ = dq->depth; - *buf++ = dq->texCoords.bottomleft.x; - *buf++ = dq->texCoords.bottomleft.y; + *buf++ = dq->texCoords.left; + *buf++ = dq->texCoords.bottom; colptr = reinterpret_cast<Ogre::RGBA*>(buf); - Ogre::Root::getSingleton().convertColourValue(dq->colors.bottomleft, colptr); + Ogre::Root::getSingleton().convertColourValue(dq->color, colptr); colptr++; buf = reinterpret_cast<float*>(colptr); /// Bottom right corner - *buf++ = dq->positions.bottomright.x; - *buf++ = dq->positions.bottomright.y; - *buf++ = dq->positions.bottomright.z; + *buf++ = dq->positions.right; + *buf++ = dq->positions.bottom; + *buf++ = dq->depth; - *buf++ = dq->texCoords.bottomright.x; - *buf++ = dq->texCoords.bottomright.y; + *buf++ = dq->texCoords.right; + *buf++ = dq->texCoords.bottom; colptr = reinterpret_cast<Ogre::RGBA*>(buf); - Ogre::Root::getSingleton().convertColourValue(dq->colors.bottomright, colptr); + Ogre::Root::getSingleton().convertColourValue(dq->color, colptr); colptr++; buf = reinterpret_cast<float*>(colptr); } Modified: trunk/src/services/draw/DrawCommon.cpp =================================================================== --- trunk/src/services/draw/DrawCommon.cpp 2009-02-19 20:08:19 UTC (rev 1144) +++ trunk/src/services/draw/DrawCommon.cpp 2009-02-23 11:21:16 UTC (rev 1145) @@ -42,7 +42,7 @@ //------------------------------------------------------ bool QuadLess::operator()(const DrawQuad* a, const DrawQuad* b) const { - return a->positions.topleft.z < b->positions.topleft.z; + return a->depth < b->depth; }; //------------------------------------------------------ @@ -69,6 +69,16 @@ return tran; }; + + //------------------------------------------------------ + Ogre::Real DrawSource::transformX(Ogre::Real x) { + return x*mSize.x + mDisplacement.x; + } + + //------------------------------------------------------ + Ogre::Real DrawSource::transformY(Ogre::Real y) { + return y*mSize.y + mDisplacement.y; + } //------------------------------------------------------ void DrawSource::atlas(const Ogre::MaterialPtr& mat, size_t x, size_t y, size_t width, size_t height) { @@ -85,11 +95,11 @@ } //------------------------------------------------------ - void DrawSource::fillTexCoords(DrawRect<Ogre::Vector2>& tc) { - tc.topleft = mDisplacement; - tc.topright = mDisplacement + Vector2(mSize.x, 0); - tc.bottomleft = mDisplacement + Vector2(0, mSize.y); - tc.bottomright = mDisplacement + Vector2(mSize.x, mSize.y); + void DrawSource::fillTexCoords(DrawRect<Ogre::Real>& tc) { + tc.left = mDisplacement.x; + tc.right = mDisplacement.x + mSize.x; + tc.top = mDisplacement.y; + tc.bottom = mDisplacement.y + mSize.y; } //------------------------------------------------------ Modified: trunk/src/services/draw/DrawCommon.h =================================================================== --- trunk/src/services/draw/DrawCommon.h 2009-02-19 20:08:19 UTC (rev 1144) +++ trunk/src/services/draw/DrawCommon.h 2009-02-23 11:21:16 UTC (rev 1145) @@ -37,12 +37,12 @@ namespace Opde { - /// Universal rect. (Idea cloned after Canvas'es quad) + /// Universal rect. Specifies left, right, top and bottom coordinates template<typename T> struct DrawRect { - T topleft; - T topright; - T bottomleft; - T bottomright; + T left; + T right; + T top; + T bottom; }; /// A pixel coordinates type @@ -67,12 +67,16 @@ size_t height; }; - /// Draw quad - a single Rectangle that can be stored for rendering + /// Draw quad - a single Rectangle that can be stored for rendering. All coordinates are already transformed as needed struct OPDELIB_EXPORT DrawQuad { - DrawRect<Ogre::Vector3> positions; - DrawRect<Ogre::Vector2> texCoords; - DrawRect<Ogre::ColourValue> colors; - + /// Positions of the rect + DrawRect<Ogre::Real> positions; + /// Positions in the texture space + DrawRect<Ogre::Real> texCoords; + /// Color of the rect + Ogre::ColourValue color; + /// The Z value to use (after transform) + Ogre::Real depth; // TODO: IBO and VBO position markers (mutable) (That means current position specifier) }; @@ -108,18 +112,18 @@ // first we gather the txt coordinates of the corners (the same manner we use here) Ogre::Real tleft, tright, ttop, tbottom; - tleft = quad.texCoords.topleft.x; - tright = quad.texCoords.topright.x; - ttop = quad.texCoords.topleft.y; - tbottom = quad.texCoords.bottomleft.y; + tleft = quad.texCoords.left; + tright = quad.texCoords.right; + ttop = quad.texCoords.top; + tbottom = quad.texCoords.bottom; // Then we gather the screen positions Ogre::Real pleft, pright, ptop, pbottom; - pleft = quad.positions.topleft.x; - pright = quad.positions.topright.x; - ptop = quad.positions.topleft.y; - pbottom = quad.positions.bottomleft.y; + pleft = quad.positions.left; + pright = quad.positions.right; + ptop = quad.positions.top; + pbottom = quad.positions.bottom; // No intersection? if ((pleft > right) || (pright < left) || (ptop < bottom) || (pbottom > top)) @@ -136,43 +140,31 @@ Ogre::Real tnleft = tleft + (left-pleft)*hconv; // move the txt - quad.texCoords.topleft.x = tnleft; - quad.texCoords.bottomleft.x = tnleft; + quad.texCoords.left = tnleft; // move the position - quad.positions.topleft.x = left; - quad.positions.bottomleft.x = left; + quad.positions.left = left; } if (pright > right) { Ogre::Real tnright = tright - (right - pright) * hconv; - quad.texCoords.topright.x = tnright; - quad.texCoords.bottomright.x = tnright; - - - quad.positions.bottomright.x = right; - quad.positions.topright.x = right; + quad.texCoords.right = tnright; + quad.positions.right = right; } if (pbottom < bottom) { Ogre::Real tnbottom = tbottom + (bottom - pbottom) * vconv; - quad.texCoords.bottomleft.y = tnbottom; - quad.texCoords.bottomright.y = tnbottom; - - quad.positions.bottomleft.y = bottom; - quad.positions.bottomright.y = bottom; + quad.texCoords.bottom = tnbottom; + quad.positions.bottom = bottom; } if (ptop > top) { Ogre::Real tntop = ttop - (top - ptop) * vconv; - quad.texCoords.topleft.y = tntop; - quad.texCoords.topright.y = tntop; - - quad.positions.topleft.y = top; - quad.positions.topright.y = top; + quad.texCoords.top = tntop; + quad.positions.top = top; } return true; @@ -246,6 +238,12 @@ /// Will transform the Texture coordinates to those usable for rendering Ogre::Vector2 transform(const Ogre::Vector2& input); + + /// Transforms the X part of the texture coordinate + Ogre::Real transformX(Ogre::Real x); + + /// Transforms the Y part of the texture coordinate + Ogre::Real transformY(Ogre::Real y); inline void* getPlacementPtr() const { return mPlacement; }; @@ -263,8 +261,8 @@ /// Updates the pixel size from the supplied image. Do NOT forget to call this after loading the image by hand. void updatePixelSizeFromImage(); - /// Fills the specified DrawRect of vector2 elements to represent the full image of this draw source - void fillTexCoords(DrawRect<Ogre::Vector2>& tc); + /// Fills the specified DrawRect to represent the full image of this draw source + void fillTexCoords(DrawRect<Ogre::Real>& tc); protected: /** Source image of this draw source - may be lost after atlassing this, internal */ @@ -284,11 +282,11 @@ }; - struct DrawSourceLess { + struct OPDELIB_EXPORT DrawSourceLess { bool operator() (const DrawSource* a, const DrawSource* b) { size_t sa = a->getPixelArea(); size_t sb = b->getPixelArea(); - return sa < sb; + return sa > sb; } }; Modified: trunk/src/services/draw/DrawService.cpp =================================================================== --- trunk/src/services/draw/DrawService.cpp 2009-02-19 20:08:19 UTC (rev 1144) +++ trunk/src/services/draw/DrawService.cpp 2009-02-23 11:21:16 UTC (rev 1145) @@ -537,17 +537,26 @@ } //------------------------------------------------------ - Ogre::Vector3 DrawService::convertToScreenSpace(int x, int y, int z) { - Ogre::Vector3 res(x,y,getConvertedDepth(z)); - // Portions inspired by/taken from ajs's Canvas code - res.x = ((res.x + mXTextelOffset) / mViewport->getActualWidth()) * 2.0f - 1.0f; - res.y = ((res.y + mYTextelOffset) / mViewport->getActualHeight()) * -2.0f + 1.0f; + Ogre::Real DrawService::convertToScreenSpaceX(int x) { + Ogre::Real res = x; + res = ((res + mXTextelOffset) / mViewport->getActualWidth()) * 2.0f - 1.0f; + return res; } + + + //------------------------------------------------------ + Ogre::Real DrawService::convertToScreenSpaceY(int y) { + Ogre::Real res = y; + + res = ((res + mYTextelOffset) / mViewport->getActualHeight()) * -2.0f + 1.0f; + return res; + } + //------------------------------------------------------ - Ogre::Real DrawService::getConvertedDepth(int z) { + Ogre::Real DrawService::convertToScreenSpaceZ(int z) { Ogre::Real depth = mRenderSystem->getMaximumDepthInputValue() - mRenderSystem->getMinimumDepthInputValue(); if (z < 0) @@ -558,6 +567,7 @@ return mRenderSystem->getMaximumDepthInputValue() - (z * depth / MAX_Z_VALUE); } + //------------------------------------------------------ void DrawService::_queueAtlasForRebuild(TextureAtlas* atlas) { Modified: trunk/src/services/draw/DrawService.h =================================================================== --- trunk/src/services/draw/DrawService.h 2009-02-19 20:08:19 UTC (rev 1144) +++ trunk/src/services/draw/DrawService.h 2009-02-23 11:21:16 UTC (rev 1145) @@ -113,15 +113,19 @@ */ void destroyAtlas(TextureAtlas* atlas); - /** Converts the given coordinates to the screen space x,y,z coordinates + /** Converts the given coordinate to the screen space x coordinate */ - Ogre::Vector3 convertToScreenSpace(int x, int y, int z); - - /** Converts the given depth to screen-space + Ogre::Real convertToScreenSpaceX(int x); + + /** Converts the given coordinate to the screen space y coordinates + */ + Ogre::Real convertToScreenSpaceY(int y); + + /** Converts the given coordinate to the screen space y coordinates * @param z the depth in 0 - MAX_Z_VALUE range * @return Real number describing the depth */ - Ogre::Real getConvertedDepth(int z); + Ogre::Real convertToScreenSpaceZ(int z); /// Queues an atlas for rebuilding (on render queue started event) void _queueAtlasForRebuild(TextureAtlas* atlas); Modified: trunk/src/services/draw/FontDrawSource.cpp =================================================================== --- trunk/src/services/draw/FontDrawSource.cpp 2009-02-19 20:08:19 UTC (rev 1144) +++ trunk/src/services/draw/FontDrawSource.cpp 2009-02-23 11:21:16 UTC (rev 1145) @@ -121,7 +121,7 @@ } // we have the image data ready, now we'll populate image with it - dsp->getImage().loadDynamicImage(reinterpret_cast<Ogre::uchar*>(pixels), dimensions.width, dimensions.height, 1, Ogre::PF_BYTE_BGRA, true); + dsp->getImage().loadDynamicImage(reinterpret_cast<Ogre::uchar*>(pixels), dimensions.width, dimensions.height, 1, Ogre::PF_A8R8G8B8, true); } //------------------------------------------------------ @@ -151,7 +151,7 @@ } // we have the image data ready, now we'll populate image with it - dsp->getImage().loadDynamicImage(reinterpret_cast<Ogre::uchar*>(pixels), dimensions.width, dimensions.height, 1, Ogre::PF_BYTE_BGRA, true); + dsp->getImage().loadDynamicImage(reinterpret_cast<Ogre::uchar*>(pixels), dimensions.width, dimensions.height, 1, Ogre::PF_A8R8G8B8, true); } }; Modified: trunk/src/services/draw/RenderedImage.cpp =================================================================== --- trunk/src/services/draw/RenderedImage.cpp 2009-02-19 20:08:19 UTC (rev 1144) +++ trunk/src/services/draw/RenderedImage.cpp 2009-02-23 11:21:16 UTC (rev 1145) @@ -35,15 +35,13 @@ /*----------------------------------------------------*/ RenderedImage::RenderedImage(DrawService* owner, DrawOperation::ID id, DrawSource* ds) : DrawOperation(owner, id), mDrawSource(ds) { - mDrawQuad.texCoords.topleft = ds->transform(Vector2(0,0)); - mDrawQuad.texCoords.topright = ds->transform(Vector2(1.0f,0)); - mDrawQuad.texCoords.bottomleft = ds->transform(Vector2(0,1.0f)); - mDrawQuad.texCoords.bottomright = ds->transform(Vector2(1.0f,1.0f)); + mDrawQuad.texCoords.left = ds->transformX(0); + mDrawQuad.texCoords.right = ds->transformX(1.0f); + mDrawQuad.texCoords.top = ds->transformY(0); + mDrawQuad.texCoords.bottom = ds->transformY(1.0f); + - mDrawQuad.colors.topleft = ColourValue(1.0f, 1.0f, 1.0f); - mDrawQuad.colors.topright = ColourValue(1.0f, 1.0f, 1.0f); - mDrawQuad.colors.bottomleft = ColourValue(1.0f, 1.0f, 1.0f); - mDrawQuad.colors.bottomright = ColourValue(1.0f, 1.0f, 1.0f); + mDrawQuad.color = ColourValue(1.0f, 1.0f, 1.0f); mInClip = true; @@ -66,10 +64,12 @@ //------------------------------------------------------ void RenderedImage::_rebuild() { const PixelSize& ps = mDrawSource->getPixelSize(); - mDrawQuad.positions.topleft = mOwner->convertToScreenSpace(mPosition.first, mPosition.second, mZOrder); - mDrawQuad.positions.topright = mOwner->convertToScreenSpace(mPosition.first + ps.width, mPosition.second, mZOrder); - mDrawQuad.positions.bottomleft = mOwner->convertToScreenSpace(mPosition.first, mPosition.second + ps.height, mZOrder); - mDrawQuad.positions.bottomright = mOwner->convertToScreenSpace(mPosition.first + ps.width, mPosition.second + ps.height, mZOrder); + + mDrawQuad.positions.left = mOwner->convertToScreenSpaceX(mPosition.first); + mDrawQuad.positions.right = mOwner->convertToScreenSpaceX(mPosition.first + ps.width); + mDrawQuad.positions.top = mOwner->convertToScreenSpaceY(mPosition.second); + mDrawQuad.positions.bottom = mOwner->convertToScreenSpaceY(mPosition.second + ps.height); + mDrawQuad.depth = mOwner->convertToScreenSpaceZ(mZOrder); mInClip = mClipRect.clip(mDrawQuad); _markDirty(); Modified: trunk/src/services/draw/RenderedLabel.cpp =================================================================== --- trunk/src/services/draw/RenderedLabel.cpp 2009-02-19 20:08:19 UTC (rev 1144) +++ trunk/src/services/draw/RenderedLabel.cpp 2009-02-23 11:21:16 UTC (rev 1145) @@ -105,10 +105,11 @@ void RenderedLabel::fillQuad(int x, int y, const unsigned char chr, DrawSource* ds, DrawQuad& dq) { const PixelSize& ps = ds->getPixelSize(); - dq.positions.topleft = mOwner->convertToScreenSpace(mPosition.first + x, mPosition.second + y, mZOrder); - dq.positions.topright = mOwner->convertToScreenSpace(mPosition.first + x + ps.width, mPosition.second + y, mZOrder); - dq.positions.bottomleft = mOwner->convertToScreenSpace(mPosition.first + x, mPosition.second + y + ps.height, mZOrder); - dq.positions.bottomright = mOwner->convertToScreenSpace(mPosition.first + x + ps.width, mPosition.second + y + ps.height, mZOrder); + dq.positions.left = mOwner->convertToScreenSpaceX(mPosition.first + x); + dq.positions.right = mOwner->convertToScreenSpaceX(mPosition.first + x + ps.width); + dq.positions.top = mOwner->convertToScreenSpaceY(mPosition.second + y); + dq.positions.bottom = mOwner->convertToScreenSpaceY(mPosition.second + y + ps.height); + dq.depth = mOwner->convertToScreenSpaceZ(mZOrder); ds->fillTexCoords(dq.texCoords); } Modified: trunk/src/services/draw/TextureAtlas.cpp =================================================================== --- trunk/src/services/draw/TextureAtlas.cpp 2009-02-19 20:08:19 UTC (rev 1144) +++ trunk/src/services/draw/TextureAtlas.cpp 2009-02-23 11:21:16 UTC (rev 1145) @@ -26,6 +26,7 @@ #include "TextureAtlas.h" #include "DrawService.h" #include "FontDrawSource.h" +#include "logger.h" #include <OgreTextureManager.h> #include <OgreStringConverter.h> @@ -121,9 +122,6 @@ size_t area = 0; - // First, we sort by size of the DrawSource - mMyDrawSources.sort(DrawSourceLess()); - // 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(); @@ -135,6 +133,9 @@ 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; @@ -144,16 +145,19 @@ DrawSourceSet::iterator it = mMyDrawSources.begin(); while (it != mMyDrawSources.end()) { + DrawSource* ds = *it++; const PixelSize& ps = ds->getPixelSize(); area += ps.getPixelArea(); + + LOG_DEBUG("TextureAtlas: Trying to place %d x %d (%d -> %d)", ps.width, ps.height, ps.getPixelArea(), area); // try to allocate - FreeSpaceInfo* area = mAtlasAllocation->allocate(ps.width, ps.height); + FreeSpaceInfo* fsi = mAtlasAllocation->allocate(ps.width, ps.height); - if (area) { - ds->setPlacementPtr(area); + if (fsi) { + ds->setPlacementPtr(fsi); } else { fitted = false; break; @@ -164,6 +168,8 @@ if (!fitted) // nope - Enlarge! enlarge(area); } while (!fitted); + + LOG_INFO("TextureAtlas: Creating atlas '%s' with dimensions %d x %d", mAtlasName.c_str(), mAtlasSize.width, mAtlasSize.height); // it seems we're here because we fitted! Lets paint the textures into the atlas mTexture = Ogre::TextureManager::getSingleton().createManual(mAtlasName, @@ -236,7 +242,17 @@ ds->atlas(mMaterial, fsi->x, fsi->y, mAtlasSize.width, mAtlasSize.height); } - pixelBuffer->unlock(); + + // 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"); + + pixelBuffer->unlock(); } //------------------------------------------------------ @@ -246,6 +262,8 @@ // mark dirty the atlas markDirty(); + + LOG_DEBUG("TextureAtlas: Enlarging atlas from %d x %d", mAtlasSize.width, mAtlasSize.height); size_t size; @@ -260,6 +278,9 @@ size = mAtlasSize.width * mAtlasSize.height; } while (size < area); + + LOG_DEBUG("TextureAtlas: Enlarged atlas to %d x %d", mAtlasSize.width, mAtlasSize.height); + delete mAtlasAllocation; mAtlasAllocation = new FreeSpaceInfo(0,0,mAtlasSize.width, mAtlasSize.height); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |