D:/Programmation/Cpp/SFML/src/SFML/Graphics/ImageImpl.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/Graphics/ImageImpl.hpp>
00029 #include <SFML/Graphics/GraphicsDevice.hpp>
00030 #include <SFML/Graphics/OpenGL.hpp>
00031 #include <algorithm>
00032 
00033 
00034 namespace sf_private
00035 {
00039 sfImageImpl::sfImageImpl(unsigned int Width, unsigned int Height, const std::vector<sfUint32>& Pixels) :
00040 myWidth        (Width),
00041 myHeight       (Height),
00042 myTextureWidth (0),
00043 myTextureHeight(0),
00044 myPixels       (Pixels),
00045 myGLTexture    (0)
00046 {
00047     // If we have a valid render context, we can create video resources
00048     if (sfGraphicsDevice::GetInstance())
00049         InitVideoResources();
00050 }
00051 
00052 
00056 sfImageImpl::~sfImageImpl()
00057 {
00058     // Destroy video resources
00059     DestroyVideoResources();
00060 }
00061 
00062 
00066 void sfImageImpl::CreateMaskFromColor(sfUint32 ColorKey)
00067 {
00068     // Calculate new color (old color with no alpha)
00069     sfUint32 NewColor = ColorKey & 0x00FFFFFF;
00070 
00071     // Replace old color by new one
00072     std::replace(myPixels.begin(), myPixels.end(), ColorKey, NewColor);
00073 
00074     // Update internal texture
00075     Update();
00076 }
00077 
00078 
00082 void sfImageImpl::SetPixel(unsigned int X, unsigned int Y, sfUint32 Color)
00083 {
00084     // Set new color in pixel buffer
00085     myPixels[X + Y * myWidth] = Color;
00086 }
00087 
00088 
00094 const std::vector<sfUint32>& sfImageImpl::GetPixels() const
00095 {
00096     return myPixels;
00097 }
00098 
00099 
00103 void sfImageImpl::Update()
00104 {
00105     if (myGLTexture && myWidth && myHeight && !myPixels.empty())
00106     {
00107         // Update texture pixels
00108         sfGLCheck(glBindTexture(GL_TEXTURE_2D, myGLTexture));
00109         sfGLCheck(glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, myWidth, myHeight, GL_RGBA, GL_UNSIGNED_BYTE, &myPixels[0]));
00110         sfGLCheck(glBindTexture(GL_TEXTURE_2D, 0));
00111     }
00112 }
00113 
00114 
00118 void sfImageImpl::Bind() const
00119 {
00120     // Bind OpenGL texture
00121     if (myGLTexture)
00122         sfGLCheck(glBindTexture(GL_TEXTURE_2D, myGLTexture));
00123 }
00124 
00125 
00129 void sfImageImpl::SetSmooth(bool Smooth) const
00130 {
00131     if (myGLTexture)
00132     {
00133         // Change OpenGL texture filter
00134         sfGLCheck(glBindTexture(GL_TEXTURE_2D, myGLTexture));
00135         sfGLCheck(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, Smooth ? GL_LINEAR : GL_NEAREST));
00136         sfGLCheck(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, Smooth ? GL_LINEAR : GL_NEAREST));
00137         sfGLCheck(glBindTexture(GL_TEXTURE_2D, 0));
00138     }
00139 }
00140 
00141 
00146 void sfImageImpl::SetRepeat(bool Repeat) const
00147 {
00148     if (myGLTexture)
00149     {
00150         // Change OpenGL texture wrap mode
00151         sfGLCheck(glBindTexture(GL_TEXTURE_2D, myGLTexture));
00152         sfGLCheck(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, Repeat ? GL_REPEAT : GL_CLAMP));
00153         sfGLCheck(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, Repeat ? GL_REPEAT : GL_CLAMP));
00154         sfGLCheck(glBindTexture(GL_TEXTURE_2D, 0));
00155     }
00156 }
00157 
00158 
00162 unsigned int sfImageImpl::GetWidth() const
00163 {
00164     return myWidth;
00165 }
00166 
00167 
00171 unsigned int sfImageImpl::GetHeight() const
00172 {
00173     return myHeight;
00174 }
00175 
00176 
00181 sfFloatRect sfImageImpl::GetTexCoords(const sfIntRect& Rect) const
00182 {
00183     return sfFloatRect((Rect.Left   + 0.5f) / myTextureWidth,
00184                        (Rect.Top    + 0.5f) / myTextureHeight,
00185                        (Rect.Right  - 0.5f) / myTextureWidth,
00186                        (Rect.Bottom - 0.5f) / myTextureHeight);
00187 }
00188 
00189 
00193 unsigned int sfImageImpl::GetValidTextureSize(unsigned int Size)
00194 {
00195     if (sfGraphicsDevice::GetInstance()->GetCapabilities().NonPowerOfTwoTextures)
00196     {
00197         // If hardware supports NPOT textures, then just return the unmodified size
00198         return Size;
00199     }
00200     else
00201     {
00202         // If hardware doesn't support NPOT textures, we calculate the nearest power of two
00203         unsigned int PowerOfTwo = 1;
00204         while (PowerOfTwo < Size)
00205             PowerOfTwo *= 2;
00206 
00207         return PowerOfTwo;
00208     }
00209 }
00210 
00214 void sfImageImpl::InitVideoResources()
00215 {
00216     // Check if texture parameters are valid before creating it
00217     if (!myWidth || !myHeight || myPixels.empty())
00218         return;
00219 
00220     // Destroy previous OpenGL texture if it was loaded
00221     if (myGLTexture)
00222     {
00223         sfGLCheck(glDeleteTextures(1, &myGLTexture));
00224         myGLTexture = 0;
00225     }
00226 
00227     // Adjust internal texture dimensions depending on NPOT textures support
00228     myTextureWidth  = GetValidTextureSize(myWidth);
00229     myTextureHeight = GetValidTextureSize(myHeight);
00230 
00231     // Create the OpenGL texture
00232     sfGLCheck(glGenTextures(1, &myGLTexture));
00233     sfGLCheck(glBindTexture(GL_TEXTURE_2D, myGLTexture));
00234     sfGLCheck(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, myTextureWidth, myTextureHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL));
00235 
00236     // Set texture parameters for 2D rendering
00237     sfGLCheck(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,     GL_REPEAT));
00238     sfGLCheck(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,     GL_REPEAT));
00239     sfGLCheck(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
00240     sfGLCheck(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
00241 
00242     // Copy pixel buffer to OpenGL texture
00243     Update();
00244 }
00245 
00246 
00250 void sfImageImpl::DestroyVideoResources()
00251 {
00252     // Destroy textures
00253     if (myGLTexture)
00254     {
00255         sfGLCheck(glDeleteTextures(1, &myGLTexture));
00256         myGLTexture = 0;
00257     }
00258 }
00259 
00260 } // namespace sf_private

Generated for SFML by  doxygen 1.5.2