- Main Page
- Namespaces
- Classes
- Files

- File List

# Image.cpp

    00001
    00002 //
    00003 // SFML - Simple and Fast Multimedia Library
    00004 // Copyright (C) 2007-2009 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/Graphics/Image.hpp>
    00029 #include <SFML/Graphics/ImageLoader.hpp>
    00030 #include <SFML/Graphics/RenderWindow.hpp>
    00031 #include <SFML/Graphics/GraphicsContext.hpp>
    00032 #include <algorithm>
    00033 #include <iostream>
    00034 #include <vector>
    00035 #include <string.h>
    00036
    00037
    00038 namespace sf
    00039 {
    00043 Image::Image() :
    00044 myWidth            (0),
    00045 myHeight           (0),
    00046 myTextureWidth     (0),
    00047 myTextureHeight    (0),
    00048 myTexture          (0),
    00049 myIsSmooth         (true),
    00050 myNeedTextureUpdate(false),
    00051 myNeedArrayUpdate  (false)
    00052 {
    00053
    00054 }
    00055
    00056
    00060 Image::Image(const Image& Copy) :
    00061 Resource<Image>    (Copy),
    00062 myWidth            (Copy.myWidth),
    00063 myHeight           (Copy.myHeight),
    00064 myTextureWidth     (Copy.myTextureWidth),
    00065 myTextureHeight    (Copy.myTextureHeight),
    00066 myTexture          (0),
    00067 myIsSmooth         (Copy.myIsSmooth),
    00068 myPixels           (Copy.myPixels),
    00069 myNeedTextureUpdate(false),
    00070 myNeedArrayUpdate  (false)
    00071 {
    00072     CreateTexture();
    00073 }
    00074
    00075
    00079 Image::Image(unsigned int Width, unsigned int Height, const Color& Col) :
    00080 myWidth            (0),
    00081 myHeight           (0),
    00082 myTextureWidth     (0),
    00083 myTextureHeight    (0),
    00084 myTexture          (0),
    00085 myIsSmooth         (true),
    00086 myNeedTextureUpdate(false),
    00087 myNeedArrayUpdate  (false)
    00088 {
    00089     Create(Width, Height, Col);
    00090 }
    00091
    00092
    00096 Image::Image(unsigned int Width, unsigned int Height, const Uint8* Data) :
    00097 myWidth            (0),
    00098 myHeight           (0),
    00099 myTextureWidth     (0),
    00100 myTextureHeight    (0),
    00101 myTexture          (0),
    00102 myIsSmooth         (true),
    00103 myNeedTextureUpdate(false),
    00104 myNeedArrayUpdate  (false)
    00105 {
    00106     LoadFromPixels(Width, Height, Data);
    00107 }
    00108
    00109
    00113 Image::~Image()
    00114 {
    00115     // Destroy the OpenGL texture
    00116     DestroyTexture();
    00117 }
    00118
    00119
    00123 bool Image::LoadFromFile(const std::string& Filename)
    00124 {
    00125     // Let the image loader load the image into our pixel array
    00126     bool Success = priv::ImageLoader::GetInstance().LoadImageFromFile(Filename, myPixels, myWidth, myHeight);
    00127
    00128     if (Success)
    00129     {
    00130         // Loading succeeded : we can create the texture
    00131         if (CreateTexture())
    00132             return true;
    00133     }
    00134
    00135     // Oops... something failed
    00136     Reset();
    00137
    00138     return false;
    00139 }
    00140
    00141
    00145 bool Image::LoadFromMemory(const char* Data, std::size_t SizeInBytes)
    00146 {
    00147     // Check parameters
    00148     if (!Data || (SizeInBytes == 0))
    00149     {
    00150         std::cerr << "Failed to image font from memory, no data provided" << std::endl;
    00151         return false;
    00152     }
    00153
    00154     // Let the image loader load the image into our pixel array
    00155     bool Success = priv::ImageLoader::GetInstance().LoadImageFromMemory(Data, SizeInBytes, myPixels, myWidth, myHeight);
    00156
    00157     if (Success)
    00158     {
    00159         // Loading succeeded : we can create the texture
    00160         if (CreateTexture())
    00161             return true;
    00162     }
    00163
    00164     // Oops... something failed
    00165     Reset();
    00166
    00167     return false;
    00168 }
    00169
    00170
    00174 bool Image::LoadFromPixels(unsigned int Width, unsigned int Height, const Uint8* Data)
    00175 {
    00176     if (Data)
    00177     {
    00178         // Store the texture dimensions
    00179         myWidth  = Width;
    00180         myHeight = Height;
    00181
    00182         // Fill the pixel buffer with the specified raw data
    00183         const Color* Ptr = reinterpret_cast<const Color*>(Data);
    00184         myPixels.assign(Ptr, Ptr + Width * Height);
    00185
    00186         // We can create the texture
    00187         if (CreateTexture())
    00188         {
    00189             return true;
    00190         }
    00191         else
    00192         {
    00193             // Oops... something failed
    00194             Reset();
    00195             return false;
    00196         }
    00197     }
    00198     else
    00199     {
    00200         // No data provided : create a white image
    00201         return Create(Width, Height, Color(255, 255, 255, 255));
    00202     }
    00203 }
    00204
    00205
    00209 bool Image::SaveToFile(const std::string& Filename) const
    00210 {
    00211     // Check if the array of pixels needs to be updated
    00212     EnsureArrayUpdate();
    00213
    00214     // Let the image loader save our pixel array into the image
    00215     return priv::ImageLoader::GetInstance().SaveImageToFile(Filename, myPixels, myWidth, myHeight);
    00216 }
    00217
    00218
    00222 bool Image::Create(unsigned int Width, unsigned int Height, Color Col)
    00223 {
    00224     // Store the texture dimensions
    00225     myWidth  = Width;
    00226     myHeight = Height;
    00227
    00228     // Recreate the pixel buffer and fill it with the specified color
    00229     myPixels.clear();
    00230     myPixels.resize(Width * Height, Col);
    00231
    00232     // We can create the texture
    00233     if (CreateTexture())
    00234     {
    00235         return true;
    00236     }
    00237     else
    00238     {
    00239         // Oops... something failed
    00240         Reset();
    00241         return false;
    00242     }
    00243 }
    00244
    00245
    00249 void Image::CreateMaskFromColor(Color ColorKey, Uint8 Alpha)
    00250 {
    00251     // Check if the array of pixels needs to be updated
    00252     EnsureArrayUpdate();
    00253
    00254     // Calculate the new color (old color with no alpha)
    00255     Color NewColor(ColorKey.r, ColorKey.g, ColorKey.b, Alpha);
    00256
    00257     // Replace the old color by the new one
    00258     std::replace(myPixels.begin(), myPixels.end(), ColorKey, NewColor);
    00259
    00260     // The texture will need to be updated
    00261     myNeedTextureUpdate = true;
    00262 }
    00263
    00264
    00270 void Image::Copy(const Image& Source, unsigned int DestX, unsigned int DestY, const IntRect& SourceRect, bool ApplyAlpha)
    00271 {
    00272     // Make sure both images are valid
    00273     if ((Source.myWidth == 0) || (Source.myHeight == 0) || (myWidth == 0) || (myHeight == 0))
    00274         return;
    00275
    00276     // Make sure both images have up-to-date arrays
    00277     EnsureArrayUpdate();
    00278     Source.EnsureArrayUpdate();
    00279
    00280     // Adjust the source rectangle
    00281     IntRect SrcRect = SourceRect;
    00282     if (SrcRect.GetWidth() == 0 || (SrcRect.GetHeight() == 0))
    00283     {
    00284         SrcRect.Left   = 0;
    00285         SrcRect.Top    = 0;
    00286         SrcRect.Right  = Source.myWidth;
    00287         SrcRect.Bottom = Source.myHeight;
    00288     }
    00289     else
    00290     {
    00291         if (SrcRect.Left   < 0) SrcRect.Left = 0;
    00292         if (SrcRect.Top    < 0) SrcRect.Top  = 0;
    00293         if (SrcRect.Right  > static_cast<int>(Source.myWidth))  SrcRect.Right  = Source.myWidth;
    00294         if (SrcRect.Bottom > static_cast<int>(Source.myHeight)) SrcRect.Bottom = Source.myHeight;
    00295     }
    00296
    00297     // Then find the valid bounds of the destination rectangle
    00298     int Width  = SrcRect.GetWidth();
    00299     int Height = SrcRect.GetHeight();
    00300     if (DestX + Width  > myWidth)  Width  = myWidth  - DestX;
    00301     if (DestY + Height > myHeight) Height = myHeight - DestY;
    00302
    00303     // Make sure the destination area is valid
    00304     if ((Width <= 0) || (Height <= 0))
    00305         return;
    00306
    00307     // Precompute as much as possible
    00308     int          Pitch     = Width * 4;
    00309     int          Rows      = Height;
    00310     int          SrcStride = Source.myWidth * 4;
    00311     int          DstStride = myWidth * 4;
    00312     const Uint8* SrcPixels = Source.GetPixelsPtr() + (SrcRect.Left + SrcRect.Top * Source.myWidth) * 4;
    00313     Uint8*       DstPixels = reinterpret_cast<Uint8*>(&myPixels[0]) + (DestX + DestY * myWidth) * 4;
    00314
    00315     // Copy the pixels
    00316     if (ApplyAlpha)
    00317     {
    00318         // Interpolation using alpha values, pixel by pixel (slower)
    00319         for (int i = 0; i < Rows; ++i)
    00320         {
    00321             for (int j = 0; j < Width; ++j)
    00322             {
    00323                 // Get a direct pointer to the components of the current pixel
    00324                 const Uint8* Src   = SrcPixels + j * 4;
    00325                 Uint8*       Dst   = DstPixels + j * 4;
    00326
    00327                 // Interpolate RGB components using the alpha value of the source pixel
    00328                 Uint8 Alpha = Src[3];
    00329                 Dst[0] = (Src[0] * Alpha + Dst[0] * (255 - Alpha)) / 255;
    00330                 Dst[1] = (Src[1] * Alpha + Dst[1] * (255 - Alpha)) / 255;
    00331                 Dst[2] = (Src[2] * Alpha + Dst[2] * (255 - Alpha)) / 255;
    00332             }
    00333
    00334             SrcPixels += SrcStride;
    00335             DstPixels += DstStride;
    00336         }
    00337     }
    00338     else
    00339     {
    00340         // Optimized copy ignoring alpha values, row by row (faster)
    00341         for (int i = 0; i < Rows; ++i)
    00342         {
    00343             memcpy(DstPixels, SrcPixels, Pitch);
    00344             SrcPixels += SrcStride;
    00345             DstPixels += DstStride;
    00346         }
    00347     }
    00348
    00349     // The texture will need an update
    00350     myNeedTextureUpdate = true;
    00351 }
    00352
    00353
    00358 bool Image::CopyScreen(RenderWindow& Window, const IntRect& SourceRect)
    00359 {
    00360     // Adjust the source rectangle
    00361     IntRect SrcRect = SourceRect;
    00362     if (SrcRect.GetWidth() == 0 || (SrcRect.GetHeight() == 0))
    00363     {
    00364         SrcRect.Left   = 0;
    00365         SrcRect.Top    = 0;
    00366         SrcRect.Right  = Window.GetWidth();
    00367         SrcRect.Bottom = Window.GetHeight();
    00368     }
    00369     else
    00370     {
    00371         if (SrcRect.Left   < 0) SrcRect.Left = 0;
    00372         if (SrcRect.Top    < 0) SrcRect.Top  = 0;
    00373         if (SrcRect.Right  > static_cast<int>(Window.GetWidth()))  SrcRect.Right  = Window.GetWidth();
    00374         if (SrcRect.Bottom > static_cast<int>(Window.GetHeight())) SrcRect.Bottom = Window.GetHeight();
    00375     }
    00376
    00377     // Store the texture dimensions
    00378     myWidth  = SrcRect.GetWidth();
    00379     myHeight = SrcRect.GetHeight();
    00380
    00381     // We can then create the texture
    00382     if (Window.SetActive() && CreateTexture())
    00383     {
    00384         GLint PreviousTexture;
    00385         GLCheck(glGetIntegerv(GL_TEXTURE_BINDING_2D, &PreviousTexture));
    00386
    00387         GLCheck(glBindTexture(GL_TEXTURE_2D, myTexture));
    00388         GLCheck(glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, SrcRect.Left, SrcRect.Top, myWidth, myHeight));
    00389
    00390         GLCheck(glBindTexture(GL_TEXTURE_2D, PreviousTexture));
    00391
    00392         myNeedTextureUpdate = false;
    00393         myNeedArrayUpdate = true;
    00394
    00395         return true;
    00396     }
    00397     else
    00398     {
    00399         Reset();
    00400         return false;
    00401     }
    00402 }
    00403
    00404
    00408 void Image::SetPixel(unsigned int X, unsigned int Y, const Color& Col)
    00409 {
    00410     // First check if the array of pixels needs to be updated
    00411     EnsureArrayUpdate();
    00412
    00413     // Check if pixel is whithin the image bounds
    00414     if ((X >= myWidth) || (Y >= myHeight))
    00415     {
    00416         std::cerr << "Cannot set pixel (" << X << "," << Y << ") for image "
    00417                   << "(width = " << myWidth << ", height = " << myHeight << ")" << std::endl;
    00418         return;
    00419     }
    00420
    00421     myPixels[X + Y * myWidth] = Col;
    00422
    00423     // The texture will need to be updated
    00424     myNeedTextureUpdate = true;
    00425 }
    00426
    00427
    00431 const Color& Image::GetPixel(unsigned int X, unsigned int Y) const
    00432 {
    00433     // First check if the array of pixels needs to be updated
    00434     EnsureArrayUpdate();
    00435
    00436     // Check if pixel is whithin the image bounds
    00437     if ((X >= myWidth) || (Y >= myHeight))
    00438     {
    00439         std::cerr << "Cannot get pixel (" << X << "," << Y << ") for image "
    00440                   << "(width = " << myWidth << ", height = " << myHeight << ")" << std::endl;
    00441         return Color::Black;
    00442     }
    00443
    00444     return myPixels[X + Y * myWidth];
    00445 }
    00446
    00447
    00453 const Uint8* Image::GetPixelsPtr() const
    00454 {
    00455     // First check if the array of pixels needs to be updated
    00456     EnsureArrayUpdate();
    00457
    00458     if (!myPixels.empty())
    00459     {
    00460         return reinterpret_cast<const Uint8*>(&myPixels[0]);
    00461     }
    00462     else
    00463     {
    00464         std::cerr << "Trying to access the pixels of an empty image" << std::endl;
    00465         return NULL;
    00466     }
    00467 }
    00468
    00469
    00473 void Image::Bind() const
    00474 {
    00475     // First check if the texture needs to be updated
    00476     EnsureTextureUpdate();
    00477
    00478     // Bind it
    00479     if (myTexture)
    00480     {
    00481         GLCheck(glEnable(GL_TEXTURE_2D));
    00482         GLCheck(glBindTexture(GL_TEXTURE_2D, myTexture));
    00483     }
    00484 }
    00485
    00486
    00490 void Image::SetSmooth(bool Smooth)
    00491 {
    00492     if (Smooth != myIsSmooth)
    00493     {
    00494         myIsSmooth = Smooth;
    00495
    00496         if (myTexture)
    00497         {
    00498             // Make sure we have a valid context
    00499             priv::GraphicsContext Ctx;
    00500
    00501             GLint PreviousTexture;
    00502             GLCheck(glGetIntegerv(GL_TEXTURE_BINDING_2D, &PreviousTexture));
    00503
    00504             GLCheck(glBindTexture(GL_TEXTURE_2D, myTexture));
    00505             GLCheck(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, myIsSmooth ? GL_LINEAR : GL_NEAREST));
    00506             GLCheck(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, myIsSmooth ? GL_LINEAR : GL_NEAREST));
    00507
    00508             GLCheck(glBindTexture(GL_TEXTURE_2D, PreviousTexture));
    00509         }
    00510     }
    00511 }
    00512
    00513
    00517 unsigned int Image::GetWidth() const
    00518 {
    00519     return myWidth;
    00520 }
    00521
    00522
    00526 unsigned int Image::GetHeight() const
    00527 {
    00528     return myHeight;
    00529 }
    00530
    00531
    00535 bool Image::IsSmooth() const
    00536 {
    00537     return myIsSmooth;
    00538 }
    00539
    00540
    00545 FloatRect Image::GetTexCoords(const IntRect& Rect, bool Adjust) const
    00546 {
    00547     float Width  = static_cast<float>(myTextureWidth);
    00548     float Height = static_cast<float>(myTextureHeight);
    00549
    00550     if (Adjust && myIsSmooth)
    00551     {
    00552         return FloatRect((Rect.Left   + 0.5f) / Width,
    00553                          (Rect.Top    + 0.5f) / Height,
    00554                          (Rect.Right  - 0.5f) / Width,
    00555                          (Rect.Bottom - 0.5f) / Height);
    00556     }
    00557     else
    00558     {
    00559         return FloatRect(Rect.Left   / Width,
    00560                          Rect.Top    / Height,
    00561                          Rect.Right  / Width,
    00562                          Rect.Bottom / Height);
    00563     }
    00564 }
    00565
    00566
    00570 unsigned int Image::GetValidTextureSize(unsigned int Size)
    00571 {
    00572     // Make sure we have a valid context
    00573     priv::GraphicsContext Ctx;
    00574
    00575     if (glewIsSupported("GL_ARB_texture_non_power_of_two") != 0)
    00576     {
    00577         // If hardware supports NPOT textures, then just return the unmodified size
    00578         return Size;
    00579     }
    00580     else
    00581     {
    00582         // If hardware doesn't support NPOT textures, we calculate the nearest power of two
    00583         unsigned int PowerOfTwo = 1;
    00584         while (PowerOfTwo < Size)
    00585             PowerOfTwo *= 2;
    00586
    00587         return PowerOfTwo;
    00588     }
    00589 }
    00590
    00591
    00595 Image& Image::operator =(const Image& Other)
    00596 {
    00597     Image Temp(Other);
    00598
    00599     std::swap(myWidth,             Temp.myWidth);
    00600     std::swap(myHeight,            Temp.myHeight);
    00601     std::swap(myTextureWidth,      Temp.myTextureWidth);
    00602     std::swap(myTextureHeight,     Temp.myTextureHeight);
    00603     std::swap(myTexture,           Temp.myTexture);
    00604     std::swap(myIsSmooth,          Temp.myIsSmooth);
    00605     std::swap(myNeedArrayUpdate,   Temp.myNeedArrayUpdate);
    00606     std::swap(myNeedTextureUpdate, Temp.myNeedTextureUpdate);
    00607     myPixels.swap(Temp.myPixels);
    00608
    00609     return *this;
    00610 }
    00611
    00612
    00616 bool Image::CreateTexture()
    00617 {
    00618     // Check if texture parameters are valid before creating it
    00619     if (!myWidth || !myHeight)
    00620         return false;
    00621
    00622     // Make sure we have a valid context
    00623     priv::GraphicsContext Ctx;
    00624
    00625     // Adjust internal texture dimensions depending on NPOT textures support
    00626     unsigned int TextureWidth  = GetValidTextureSize(myWidth);
    00627     unsigned int TextureHeight = GetValidTextureSize(myHeight);
    00628
    00629     // Check the maximum texture size
    00630     GLint MaxSize;
    00631     GLCheck(glGetIntegerv(GL_MAX_TEXTURE_SIZE, &MaxSize));
    00632     if ((TextureWidth > static_cast<unsigned int>(MaxSize)) || (TextureHeight > static_cast<unsigned int>(MaxSize)))
    00633     {
    00634         std::cerr << "Failed to create image, its internal size is too high (" << TextureWidth << "x" << TextureHeight << ")" << std::endl;
    00635         return false;
    00636     }
    00637
    00638     // Destroy the previous OpenGL texture if it already exists with another size
    00639     if ((TextureWidth != myTextureWidth) || (TextureHeight != myTextureHeight))
    00640     {
    00641         DestroyTexture();
    00642         myTextureWidth  = TextureWidth;
    00643         myTextureHeight = TextureHeight;
    00644     }
    00645
    00646     // Create the OpenGL texture
    00647     if (!myTexture)
    00648     {
    00649         GLint PreviousTexture;
    00650         GLCheck(glGetIntegerv(GL_TEXTURE_BINDING_2D, &PreviousTexture));
    00651
    00652         GLuint Texture = 0;
    00653         GLCheck(glGenTextures(1, &Texture));
    00654         GLCheck(glBindTexture(GL_TEXTURE_2D, Texture));
    00655         GLCheck(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, myTextureWidth, myTextureHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL));
    00656         GLCheck(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP));
    00657         GLCheck(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP));
    00658         GLCheck(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, myIsSmooth ? GL_LINEAR : GL_NEAREST));
    00659         GLCheck(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, myIsSmooth ? GL_LINEAR : GL_NEAREST));
    00660         myTexture = static_cast<unsigned int>(Texture);
    00661
    00662         GLCheck(glBindTexture(GL_TEXTURE_2D, PreviousTexture));
    00663     }
    00664
    00665     myNeedTextureUpdate = true;
    00666
    00667     return true;
    00668 }
    00669
    00670
    00675 void Image::EnsureTextureUpdate() const
    00676 {
    00677     if (myNeedTextureUpdate)
    00678     {
    00679         // Copy the pixels
    00680         if (myTexture && !myPixels.empty())
    00681         {
    00682             GLint PreviousTexture;
    00683             GLCheck(glGetIntegerv(GL_TEXTURE_BINDING_2D, &PreviousTexture));
    00684
    00685             // Update the texture with the pixels array in RAM
    00686             GLCheck(glBindTexture(GL_TEXTURE_2D, myTexture));
    00687             GLCheck(glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, myWidth, myHeight, GL_RGBA, GL_UNSIGNED_BYTE, &myPixels[0]));
    00688
    00689             GLCheck(glBindTexture(GL_TEXTURE_2D, PreviousTexture));
    00690         }
    00691
    00692         myNeedTextureUpdate = false;
    00693     }
    00694 }
    00695
    00696
    00701 void Image::EnsureArrayUpdate() const
    00702 {
    00703     if (myNeedArrayUpdate)
    00704     {
    00705         // Save the previous texture
    00706         GLint PreviousTexture;
    00707         GLCheck(glGetIntegerv(GL_TEXTURE_BINDING_2D, &PreviousTexture));
    00708
    00709         // Resize the destination array of pixels
    00710         myPixels.resize(myWidth * myHeight);
    00711
    00712         if ((myWidth == myTextureWidth) && (myHeight == myTextureHeight))
    00713         {
    00714             // Texture and array have the same size, we can use a direct copy
    00715
    00716             // Copy pixels from texture to array
    00717             GLCheck(glBindTexture(GL_TEXTURE_2D, myTexture));
    00718             GLCheck(glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, &myPixels[0]));
    00719         }
    00720         else
    00721         {
    00722             // Texture and array don't have the same size, we have to use a slower algorithm
    00723
    00724             // All the pixels will first be copied to a temporary array
    00725             std::vector<Color> AllPixels(myTextureWidth * myTextureHeight);
    00726             GLCheck(glBindTexture(GL_TEXTURE_2D, myTexture));
    00727             GLCheck(glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, &AllPixels[0]));
    00728
    00729             // The we copy the useful pixels from the temporary array to the final one
    00730             const Color* Src = &AllPixels[0];
    00731             Color* Dst = &myPixels[0];
    00732             for (unsigned int i = 0; i < myHeight; ++i)
    00733             {
    00734                 std::copy(Src, Src + myWidth, Dst);
    00735                 Src += myTextureWidth;
    00736                 Dst += myWidth;
    00737             }
    00738         }
    00739
    00740         // Restore the previous texture
    00741         GLCheck(glBindTexture(GL_TEXTURE_2D, PreviousTexture));
    00742
    00743         myNeedArrayUpdate = false;
    00744     }
    00745 }
    00746
    00747
    00751 void Image::Reset()
    00752 {
    00753     DestroyTexture();
    00754
    00755     myWidth             = 0;
    00756     myHeight            = 0;
    00757     myTextureWidth      = 0;
    00758     myTextureHeight     = 0;
    00759     myTexture           = 0;
    00760     myIsSmooth          = true;
    00761     myNeedTextureUpdate = false;
    00762     myNeedArrayUpdate   = false;
    00763     myPixels.clear();
    00764 }
    00765
    00766
    00770 void Image::DestroyTexture()
    00771 {
    00772     // Destroy the internal texture
    00773     if (myTexture)
    00774     {
    00775         // Make sure we have a valid context
    00776         priv::GraphicsContext Ctx;
    00777
    00778         GLuint Texture = static_cast<GLuint>(myTexture);
    00779         GLCheck(glDeleteTextures(1, &Texture));
    00780         myTexture           = 0;
    00781         myNeedTextureUpdate = false;
    00782         myNeedArrayUpdate   = false;
    00783     }
    00784 }
    00785
    00786 } // namespace sf

:: Copyright © 2007-2008 Laurent Gomila, all rights reserved :: Documentation generated by doxygen 1.5.2 ::