atlasbook.h

00001 /***************************************************************************
00002  *   Copyright (C) 2005-2011 by the FIFE team                              *
00003  *   http://www.fifengine.net                                              *
00004  *   This file is part of FIFE.                                            *
00005  *                                                                         *
00006  *   FIFE is free software; you can redistribute it and/or                 *
00007  *   modify it under the terms of the GNU Lesser General Public            *
00008  *   License as published by the Free Software Foundation; either          *
00009  *   version 2.1 of the License, or (at your option) any later version.    *
00010  *                                                                         *
00011  *   This library is distributed in the hope that it will be useful,       *
00012  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00013  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
00014  *   Lesser General Public License for more details.                       *
00015  *                                                                         *
00016  *   You should have received a copy of the GNU Lesser General Public      *
00017  *   License along with this library; if not, write to the                 *
00018  *   Free Software Foundation, Inc.,                                       *
00019  *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA          *
00020  ***************************************************************************/
00021 
00022 #ifndef FIFE_VIDEO_ATLASBOOK_H
00023 #define FIFE_VIDEO_ATLASBOOK_H
00024 
00025 // Standard C++ library includes
00026 #include <vector>
00027 #include <cassert>
00028 #include <cmath>
00029 
00030 // 3rd party library includes
00031 
00032 // FIFE includes
00033 // These includes are split up in two parts, separated by one empty line
00034 // First block: files included from the FIFE root src directory
00035 // Second block: files included from the same folder
00036 #include "util/structures/rect.h"
00037 
00038 namespace FIFE {
00039 
00040     class AtlasBlock {
00041     public:
00042         uint32_t page;
00043         uint32_t left, right, top, bottom;
00044 
00045         AtlasBlock(const Rect& rect, uint32_t page)
00046             : page(page),
00047             left(rect.x), right(rect.right()),
00048             top(rect.y), bottom(rect.bottom()){
00049         }
00050 
00051         AtlasBlock() {
00052         }
00053 
00054         //        (0,0) [left]   [right]
00055         //           +--------------------
00056         //           |
00057         //   [top]   |    +---------+
00058         //           |    |         |
00059         //           |    |         |
00060         //           |    |         |
00061         //           |    |         |
00062         //  [bottom] |    +---------+
00063         //           |
00064 
00065         // bottom > top
00066         // right > left
00067 
00068         void setTrivial() {
00069             left = right = top = bottom = 0;
00070         }
00071 
00072         bool isTrivial() const {
00073             return getWidth() == 0 || getHeight() == 0;
00074         }
00075 
00076         uint32_t getWidth() const { return right - left; }
00077         uint32_t getHeight() const { return bottom - top; }
00078 
00079         AtlasBlock intersects(AtlasBlock const& rect) const;
00080         void merge(AtlasBlock const& rect);
00081     };
00082 
00083     class AtlasPage {
00084     public:
00085         AtlasPage(uint32_t width, uint32_t height,
00086             uint32_t pixelSize, uint32_t page)
00087             : width(width), height(height), pixelSize(pixelSize),
00088             page(page), freePixels(width*height*pixelSize){
00089         }
00090 
00091         AtlasBlock* getBlock(uint32_t width, uint32_t height);
00092         void shrink(bool pot);
00093 
00094         uint32_t getWidth() const {
00095             return width;
00096         }
00097 
00098         uint32_t getHeight() const {
00099             return height;
00100         }
00101 
00102     private:
00103         AtlasBlock const* intersects(AtlasBlock const* block) const;
00104 
00105         uint32_t width, height;
00106         uint32_t pixelSize;
00107         uint32_t page;
00108         int32_t freePixels;
00109 
00110         typedef std::vector<AtlasBlock> Blocks;
00111         Blocks blocks;
00112     };
00113 
00114     class AtlasBook {
00115     public:
00116 
00117         AtlasBook(uint32_t pageWidth, uint32_t pageHeight,
00118             uint32_t pixelSize = 4)
00119             : pageWidth(pageWidth), pageHeight(pageHeight),
00120             pixelSize(pixelSize) {
00121         }
00122 
00123         AtlasBlock* getBlock(uint32_t width, uint32_t height);
00124 
00125         // try to shrink every atlas page
00126         void shrink(bool pot);
00127 
00128         AtlasPage& getPage(size_t index) {
00129             return pages[index];
00130         }
00131 
00132     private:
00133         // add new atlas to atlas container
00134         AtlasPage* extendCache(uint32_t minPageWidth, uint32_t minPageHeight);
00135 
00136         // How big the new atlases should be
00137         uint32_t pageWidth, pageHeight;
00138         uint32_t pixelSize;
00139 
00140         typedef std::vector<AtlasPage> Pages;
00141         Pages pages;
00142     };
00143 }
00144 
00145 #endif
00146 /* vim: set noexpandtab: set shiftwidth=2: set tabstop=2: */