00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00024
00026
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
00048 if (sfGraphicsDevice::GetInstance())
00049 InitVideoResources();
00050 }
00051
00052
00056 sfImageImpl::~sfImageImpl()
00057 {
00058
00059 DestroyVideoResources();
00060 }
00061
00062
00066 void sfImageImpl::CreateMaskFromColor(sfUint32 ColorKey)
00067 {
00068
00069 sfUint32 NewColor = ColorKey & 0x00FFFFFF;
00070
00071
00072 std::replace(myPixels.begin(), myPixels.end(), ColorKey, NewColor);
00073
00074
00075 Update();
00076 }
00077
00078
00082 void sfImageImpl::SetPixel(unsigned int X, unsigned int Y, sfUint32 Color)
00083 {
00084
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
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
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
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
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
00198 return Size;
00199 }
00200 else
00201 {
00202
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
00217 if (!myWidth || !myHeight || myPixels.empty())
00218 return;
00219
00220
00221 if (myGLTexture)
00222 {
00223 sfGLCheck(glDeleteTextures(1, &myGLTexture));
00224 myGLTexture = 0;
00225 }
00226
00227
00228 myTextureWidth = GetValidTextureSize(myWidth);
00229 myTextureHeight = GetValidTextureSize(myHeight);
00230
00231
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
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
00243 Update();
00244 }
00245
00246
00250 void sfImageImpl::DestroyVideoResources()
00251 {
00252
00253 if (myGLTexture)
00254 {
00255 sfGLCheck(glDeleteTextures(1, &myGLTexture));
00256 myGLTexture = 0;
00257 }
00258 }
00259
00260 }