TiledBackground.cpp

00001 
00002 //
00003 // SFML - Simple and Fast Multimedia Library
00004 // Copyright (C) 2007 Laurent Gomila (laurent.gom@gmail.com)
00005 //
00006 // This software is provided 'as-is', without any express or implied warranty.
00007 // In no event will the authors be held liable for any damages arising from the use of this software.
00008 //
00009 // Permission is granted to anyone to use this software for any purpose,
00010 // including commercial applications, and to alter it and redistribute it freely,
00011 // subject to the following restrictions:
00012 //
00013 // 1. The origin of this software must not be misrepresented;
00014 //    you must not claim that you wrote the original software.
00015 //    If you use this software in a product, an acknowledgment
00016 //    in the product documentation would be appreciated but is not required.
00017 //
00018 // 2. Altered source versions must be plainly marked as such,
00019 //    and must not be misrepresented as being the original software.
00020 //
00021 // 3. This notice may not be removed or altered from any source distribution.
00022 //
00024 
00026 // Headers
00028 #include <SFML/AdvancedGraphics/TiledBackground.hpp>
00029 #include <SFML/Graphics/Image.hpp>
00030 #include <SFML/Graphics/OpenGL.hpp>
00031 #include <SFML/Graphics/RenderWindow.hpp>
00032 
00033 
00037 sfTiledBackground::sfTiledBackground() :
00038 myTileset   (NULL),
00039 myTileSize  (32),
00040 myNbTilesX  (1),
00041 myNbTilesY  (1),
00042 myTiles     (1),
00043 myIsCompiled(false),
00044 myGLList    (0)
00045 {
00046     // Create the display list
00047     myGLList = glGenLists(1);
00048 }
00049 
00050 
00054 sfTiledBackground::sfTiledBackground(const sfImage& Image, unsigned int TileSize, unsigned int NbTilesX, unsigned int NbTilesY) :
00055 myTileset   (&Image),
00056 myTileSize  (TileSize),
00057 myNbTilesX  (NbTilesX),
00058 myNbTilesY  (NbTilesY),
00059 myTiles     (NbTilesX * NbTilesY),
00060 myIsCompiled(false),
00061 myGLList    (0)
00062 {
00063     // Create the display list
00064     myGLList = glGenLists(1);
00065 
00066     Initialize(Image, TileSize, NbTilesX, NbTilesY);
00067 }
00068 
00069 
00073 sfTiledBackground::sfTiledBackground(const sfTiledBackground& Copy) :
00074 myTileset   (Copy.myTileset),
00075 myTileSize  (Copy.myTileSize),
00076 myNbTilesX  (Copy.myNbTilesX),
00077 myNbTilesY  (Copy.myNbTilesY),
00078 myTiles     (Copy.myTiles),
00079 myIsCompiled(false),
00080 myGLList    (0)
00081 {
00082     // Create the display list
00083     myGLList = glGenLists(1);
00084 }
00085 
00086 
00090 sfTiledBackground::~sfTiledBackground()
00091 {
00092     // Destroy the video resources
00093     DestroyVideoResources();
00094 }
00095 
00096 
00100 void sfTiledBackground::Render(sfRenderWindow&)
00101 {
00102     // Check if rendering commands are compiled before rendering the background
00103     if (!myIsCompiled)
00104         Compile();
00105 
00106     // Just call compiled list
00107     sfGLCheck(glCallList(myGLList));
00108 }
00109 
00110 
00114 void sfTiledBackground::Initialize(const sfImage& Image, unsigned int TileSize, unsigned int NbTilesX, unsigned int NbTilesY)
00115 {
00116     myTileset    = &Image;
00117     myTileSize   = TileSize;
00118     myNbTilesX   = NbTilesX;
00119     myNbTilesY   = NbTilesY;
00120     myIsCompiled = false;
00121     myTiles.resize(NbTilesX * NbTilesY);
00122 }
00123 
00124 
00128 void sfTiledBackground::SetTile(unsigned int Left, unsigned int Top, unsigned int IndexX, unsigned int IndexY)
00129 {
00130     if ((Left < myNbTilesX) && (Top < myNbTilesY))
00131     {
00132         myTiles[Left + Top * myNbTilesX].X = IndexX;
00133         myTiles[Left + Top * myNbTilesX].Y = IndexY;
00134         myIsCompiled = false;
00135     }
00136     else
00137     {
00138         std::cerr << "Trying to access an invalid position in tiled background "
00139                   << "(position = (" << Left << ", " << Top << ", size = (" << myNbTilesX << ", " << myNbTilesY << ")"
00140                   << std::endl;
00141     }
00142 }
00143 
00144 
00148 sfTiledBackground& sfTiledBackground::operator =(const sfTiledBackground& Other)
00149 {
00150     sfTiledBackground Temp(Other);
00151 
00152     std::swap(myTileset,    Temp.myTileset);
00153     std::swap(myTileSize,   Temp.myTileSize);
00154     std::swap(myNbTilesX,   Temp.myNbTilesX);
00155     std::swap(myNbTilesY,   Temp.myNbTilesY);
00156     std::swap(myTiles,      Temp.myTiles);
00157     std::swap(myIsCompiled, Temp.myIsCompiled);
00158     std::swap(myGLList,     Temp.myGLList);
00159 
00160     return *this;
00161 }
00162 
00163 
00167 void sfTiledBackground::Compile()
00168 {
00169     // If the background is already compiled, we don't do anything
00170     if (myIsCompiled)
00171         return;
00172 
00173     // Check if the tileset is valid
00174     if (myTileset == NULL)
00175         return;
00176 
00177     // Start capturing OpenGL commands
00178     sfGLCheck(glNewList(myGLList, GL_COMPILE));
00179     float Size = static_cast<float>(myTileSize);
00180 
00181     // Bind the tileset texture
00182     myTileset->Bind();
00183 
00184     // Render tiles
00185     glBegin(GL_QUADS);
00186     for (unsigned int i = 0; i < myNbTilesX; ++i)
00187         for (unsigned int j = 0; j < myNbTilesY; ++j)
00188         {
00189             // Calculate texture coordinates
00190             int X = myTiles[i + j * myNbTilesX].X * myTileSize;
00191             int Y = myTiles[i + j * myNbTilesX].Y * myTileSize;
00192             sfFloatRect TexCoords = myTileset->GetTexCoords(sfIntRect(X, Y, X + myTileSize, Y + myTileSize));
00193 
00194             // Create quad corresponding to current tile
00195             glTexCoord2f(TexCoords.Left,  TexCoords.Top);    glVertex2f((i + 0) * Size, (j + 0) * Size);
00196             glTexCoord2f(TexCoords.Left,  TexCoords.Bottom); glVertex2f((i + 0) * Size, (j + 1) * Size);
00197             glTexCoord2f(TexCoords.Right, TexCoords.Bottom); glVertex2f((i + 1) * Size, (j + 1) * Size);
00198             glTexCoord2f(TexCoords.Right, TexCoords.Top);    glVertex2f((i + 1) * Size, (j + 0) * Size);
00199         }
00200     glEnd();
00201 
00202     // End capturing OpenGL commands
00203     sfGLCheck(glEndList());
00204 
00205     // Set the "compiled" flag
00206     myIsCompiled = true;
00207 }
00208 
00209 
00213 void sfTiledBackground::DestroyVideoResources()
00214 {
00215     // Destroy the display list
00216     if (myGLList)
00217     {
00218         sfGLCheck(glDeleteLists(myGLList, 1));
00219         myGLList = 0;
00220     }
00221 }