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/RenderImage.hpp> 00031 #include <SFML/Graphics/RenderWindow.hpp> 00032 #include <SFML/Graphics/GLCheck.hpp> 00033 #include <SFML/System/Err.hpp> 00034 #include <algorithm> 00035 #include <vector> 00036 #include <string.h> 00037 00038 00039 namespace sf 00040 { 00044 Image::Image() : 00045 myWidth (0), 00046 myHeight (0), 00047 myTextureWidth (0), 00048 myTextureHeight (0), 00049 myTexture (0), 00050 myIsSmooth (true), 00051 myTextureUpdated(true), 00052 myArrayUpdated (true), 00053 myPixelsFlipped (false) 00054 { 00055 00056 } 00057 00058 00062 Image::Image(const Image& copy) 00063 { 00064 // First make sure that the source image is up-to-date 00065 copy.EnsureArrayUpdate(); 00066 00067 // Copy all its members 00068 myWidth = copy.myWidth; 00069 myHeight = copy.myHeight; 00070 myTextureWidth = copy.myTextureWidth; 00071 myTextureHeight = copy.myTextureHeight; 00072 myTexture = 0; 00073 myIsSmooth = copy.myIsSmooth; 00074 myPixels = copy.myPixels; 00075 myTextureUpdated = true; 00076 myArrayUpdated = true; 00077 myPixelsFlipped = copy.myPixelsFlipped; 00078 00079 // Create the texture 00080 CreateTexture(); 00081 } 00082 00083 00087 Image::~Image() 00088 { 00089 // Destroy the OpenGL texture 00090 DestroyTexture(); 00091 } 00092 00093 00097 bool Image::LoadFromFile(const std::string& filename) 00098 { 00099 // Let the image loader load the image into our pixel array 00100 bool success = priv::ImageLoader::GetInstance().LoadImageFromFile(filename, myPixels, myWidth, myHeight); 00101 00102 if (success) 00103 { 00104 // Loading succeeded : we can create the texture 00105 if (CreateTexture()) 00106 return true; 00107 } 00108 00109 // Oops... something failed 00110 Reset(); 00111 00112 return false; 00113 } 00114 00115 00119 bool Image::LoadFromMemory(const void* data, std::size_t sizeInBytes) 00120 { 00121 // Check parameters 00122 if (!data || (sizeInBytes == 0)) 00123 { 00124 Err() << "Failed to image font from memory, no data provided" << std::endl; 00125 return false; 00126 } 00127 00128 // Let the image loader load the image into our pixel array 00129 bool success = priv::ImageLoader::GetInstance().LoadImageFromMemory(data, sizeInBytes, myPixels, myWidth, myHeight); 00130 00131 if (success) 00132 { 00133 // Loading succeeded : we can create the texture 00134 if (CreateTexture()) 00135 return true; 00136 } 00137 00138 // Oops... something failed 00139 Reset(); 00140 00141 return false; 00142 } 00143 00144 00148 bool Image::LoadFromPixels(unsigned int width, unsigned int height, const Uint8* data) 00149 { 00150 if (data) 00151 { 00152 // Store the texture dimensions 00153 myWidth = width; 00154 myHeight = height; 00155 00156 // Fill the pixel buffer with the specified raw data 00157 const Color* ptr = reinterpret_cast<const Color*>(data); 00158 myPixels.assign(ptr, ptr + width * height); 00159 00160 // We can create the texture 00161 if (CreateTexture()) 00162 { 00163 return true; 00164 } 00165 else 00166 { 00167 // Oops... something failed 00168 Reset(); 00169 return false; 00170 } 00171 } 00172 else 00173 { 00174 // No data provided : create a white image 00175 return Create(width, height, Color(255, 255, 255)); 00176 } 00177 } 00178 00179 00183 bool Image::SaveToFile(const std::string& filename) const 00184 { 00185 // Check if the array of pixels needs to be updated 00186 EnsureArrayUpdate(); 00187 00188 // Let the image loader save our pixel array into the image 00189 return priv::ImageLoader::GetInstance().SaveImageToFile(filename, myPixels, myWidth, myHeight); 00190 } 00191 00192 00196 bool Image::Create(unsigned int width, unsigned int height, const Color& color) 00197 { 00198 // Store the texture dimensions 00199 myWidth = width; 00200 myHeight = height; 00201 00202 // Recreate the pixel buffer and fill it with the specified color 00203 myPixels.clear(); 00204 myPixels.resize(width * height, color); 00205 00206 // We can create the texture 00207 if (CreateTexture()) 00208 { 00209 return true; 00210 } 00211 else 00212 { 00213 // Oops... something failed 00214 Reset(); 00215 return false; 00216 } 00217 } 00218 00219 00223 void Image::CreateMaskFromColor(const Color& transparentColor, Uint8 alpha) 00224 { 00225 // Check if the array of pixels needs to be updated 00226 EnsureArrayUpdate(); 00227 00228 // Calculate the new color (old color with no alpha) 00229 Color newColor(transparentColor.r, transparentColor.g, transparentColor.b, alpha); 00230 00231 // Replace the old color with the new one 00232 std::replace(myPixels.begin(), myPixels.end(), transparentColor, newColor); 00233 00234 // The texture will need to be updated 00235 myTextureUpdated = false; 00236 } 00237 00238 00244 void Image::Copy(const Image& source, unsigned int destX, unsigned int destY, const IntRect& sourceRect, bool applyAlpha) 00245 { 00246 // Make sure both images are valid 00247 if ((source.myWidth == 0) || (source.myHeight == 0) || (myWidth == 0) || (myHeight == 0)) 00248 return; 00249 00250 // Make sure both images have up-to-date arrays 00251 EnsureArrayUpdate(); 00252 source.EnsureArrayUpdate(); 00253 00254 // Adjust the source rectangle 00255 IntRect srcRect = sourceRect; 00256 if (srcRect.GetSize().x == 0 || (srcRect.GetSize().y == 0)) 00257 { 00258 srcRect.Left = 0; 00259 srcRect.Top = 0; 00260 srcRect.Right = source.myWidth; 00261 srcRect.Bottom = source.myHeight; 00262 } 00263 else 00264 { 00265 if (srcRect.Left < 0) srcRect.Left = 0; 00266 if (srcRect.Top < 0) srcRect.Top = 0; 00267 if (srcRect.Right > static_cast<int>(source.myWidth)) srcRect.Right = source.myWidth; 00268 if (srcRect.Bottom > static_cast<int>(source.myHeight)) srcRect.Bottom = source.myHeight; 00269 } 00270 00271 // Then find the valid bounds of the destination rectangle 00272 int width = srcRect.GetSize().x; 00273 int height = srcRect.GetSize().y; 00274 if (destX + width > myWidth) width = myWidth - destX; 00275 if (destY + height > myHeight) height = myHeight - destY; 00276 00277 // Make sure the destination area is valid 00278 if ((width <= 0) || (height <= 0)) 00279 return; 00280 00281 // Precompute as much as possible 00282 int pitch = width * 4; 00283 int rows = height; 00284 int srcStride = source.myWidth * 4; 00285 int dstStride = myWidth * 4; 00286 const Uint8* srcPixels = source.GetPixelsPtr() + (srcRect.Left + srcRect.Top * source.myWidth) * 4; 00287 Uint8* dstPixels = reinterpret_cast<Uint8*>(&myPixels[0]) + (destX + destY * myWidth) * 4; 00288 00289 // Copy the pixels 00290 if (applyAlpha) 00291 { 00292 // Interpolation using alpha values, pixel by pixel (slower) 00293 for (int i = 0; i < rows; ++i) 00294 { 00295 for (int j = 0; j < width; ++j) 00296 { 00297 // Get a direct pointer to the components of the current pixel 00298 const Uint8* src = srcPixels + j * 4; 00299 Uint8* dst = dstPixels + j * 4; 00300 00301 // Interpolate RGBA components using the alpha value of the source pixel 00302 Uint8 alpha = src[3]; 00303 dst[0] = (src[0] * alpha + dst[0] * (255 - alpha)) / 255; 00304 dst[1] = (src[1] * alpha + dst[1] * (255 - alpha)) / 255; 00305 dst[2] = (src[2] * alpha + dst[2] * (255 - alpha)) / 255; 00306 dst[3] = alpha + dst[3] * (255 - alpha) / 255; 00307 } 00308 00309 srcPixels += srcStride; 00310 dstPixels += dstStride; 00311 } 00312 } 00313 else 00314 { 00315 // Optimized copy ignoring alpha values, row by row (faster) 00316 for (int i = 0; i < rows; ++i) 00317 { 00318 memcpy(dstPixels, srcPixels, pitch); 00319 srcPixels += srcStride; 00320 dstPixels += dstStride; 00321 } 00322 } 00323 00324 // The texture will need an update 00325 myTextureUpdated = false; 00326 } 00327 00328 00333 bool Image::CopyScreen(RenderWindow& window, const IntRect& sourceRect) 00334 { 00335 // Adjust the source rectangle 00336 IntRect srcRect = sourceRect; 00337 if (srcRect.GetSize().x == 0 || (srcRect.GetSize().y == 0)) 00338 { 00339 srcRect.Left = 0; 00340 srcRect.Top = 0; 00341 srcRect.Right = window.GetWidth(); 00342 srcRect.Bottom = window.GetHeight(); 00343 } 00344 else 00345 { 00346 if (srcRect.Left < 0) srcRect.Left = 0; 00347 if (srcRect.Top < 0) srcRect.Top = 0; 00348 if (srcRect.Right > static_cast<int>(window.GetWidth())) srcRect.Right = window.GetWidth(); 00349 if (srcRect.Bottom > static_cast<int>(window.GetHeight())) srcRect.Bottom = window.GetHeight(); 00350 } 00351 00352 // Store the texture dimensions 00353 myWidth = srcRect.GetSize().x; 00354 myHeight = srcRect.GetSize().y; 00355 00356 // We can then create the texture 00357 if (window.SetActive() && CreateTexture()) 00358 { 00359 GLint previous; 00360 GLCheck(glGetIntegerv(GL_TEXTURE_BINDING_2D, &previous)); 00361 00362 GLCheck(glBindTexture(GL_TEXTURE_2D, myTexture)); 00363 GLCheck(glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, srcRect.Left, srcRect.Top, myWidth, myHeight)); 00364 00365 GLCheck(glBindTexture(GL_TEXTURE_2D, previous)); 00366 00367 myTextureUpdated = true; 00368 myArrayUpdated = false; 00369 myPixelsFlipped = true; 00370 00371 return true; 00372 } 00373 else 00374 { 00375 Reset(); 00376 return false; 00377 } 00378 } 00379 00380 00384 void Image::SetPixel(unsigned int x, unsigned int y, const Color& color) 00385 { 00386 // First check if the array of pixels needs to be updated 00387 EnsureArrayUpdate(); 00388 00389 // Check if pixel is whithin the image bounds 00390 /*if ((x >= myWidth) || (y >= myHeight)) 00391 { 00392 Err() << "Cannot set pixel (" << x << "," << y << ") for image " 00393 << "(width = " << myWidth << ", height = " << myHeight << ")" << std::endl; 00394 return; 00395 }*/ 00396 00397 myPixels[x + y * myWidth] = color; 00398 00399 // The texture will need to be updated 00400 myTextureUpdated = false; 00401 } 00402 00403 00407 const Color& Image::GetPixel(unsigned int x, unsigned int y) const 00408 { 00409 // First check if the array of pixels needs to be updated 00410 EnsureArrayUpdate(); 00411 00412 // Check if pixel is whithin the image bounds 00413 if ((x >= myWidth) || (y >= myHeight)) 00414 { 00415 Err() << "Cannot get pixel (" << x << "," << y << ") for image " 00416 << "(width = " << myWidth << ", height = " << myHeight << ")" << std::endl; 00417 return Color::Black; 00418 } 00419 00420 return myPixels[x + y * myWidth]; 00421 } 00422 00423 00429 const Uint8* Image::GetPixelsPtr() const 00430 { 00431 // First check if the array of pixels needs to be updated 00432 EnsureArrayUpdate(); 00433 00434 if (!myPixels.empty()) 00435 { 00436 return reinterpret_cast<const Uint8*>(&myPixels[0]); 00437 } 00438 else 00439 { 00440 Err() << "Trying to access the pixels of an empty image" << std::endl; 00441 return NULL; 00442 } 00443 } 00444 00445 00449 void Image::UpdatePixels(const Uint8* pixels) 00450 { 00451 GLint previous; 00452 GLCheck(glGetIntegerv(GL_TEXTURE_BINDING_2D, &previous)); 00453 00454 // Update the texture from the array of pixels 00455 GLCheck(glBindTexture(GL_TEXTURE_2D, myTexture)); 00456 GLCheck(glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, myWidth, myHeight, GL_RGBA, GL_UNSIGNED_BYTE, pixels)); 00457 00458 GLCheck(glBindTexture(GL_TEXTURE_2D, previous)); 00459 00460 myArrayUpdated = false; 00461 myTextureUpdated = true; 00462 } 00463 00464 00468 void Image::UpdatePixels(const Uint8* pixels, const IntRect& rectangle) 00469 { 00470 // Make sure that the texture is up-to-date 00471 EnsureTextureUpdate(); 00472 00473 GLint previous; 00474 GLCheck(glGetIntegerv(GL_TEXTURE_BINDING_2D, &previous)); 00475 00476 // Update the texture from the array of pixels 00477 GLCheck(glBindTexture(GL_TEXTURE_2D, myTexture)); 00478 GLCheck(glTexSubImage2D(GL_TEXTURE_2D, 0, rectangle.Left, rectangle.Top, rectangle.GetSize().x, rectangle.GetSize().y, GL_RGBA, GL_UNSIGNED_BYTE, pixels)); 00479 00480 GLCheck(glBindTexture(GL_TEXTURE_2D, previous)); 00481 00482 // The pixel cache is no longer up-to-date 00483 myArrayUpdated = false; 00484 } 00485 00486 00490 void Image::Bind() const 00491 { 00492 // First check if the texture needs to be updated 00493 EnsureTextureUpdate(); 00494 00495 // Bind it 00496 GLCheck(glBindTexture(GL_TEXTURE_2D, myTexture)); 00497 } 00498 00499 00503 void Image::SetSmooth(bool smooth) 00504 { 00505 if (smooth != myIsSmooth) 00506 { 00507 myIsSmooth = smooth; 00508 00509 if (myTexture) 00510 { 00511 GLint previous; 00512 GLCheck(glGetIntegerv(GL_TEXTURE_BINDING_2D, &previous)); 00513 00514 GLCheck(glBindTexture(GL_TEXTURE_2D, myTexture)); 00515 GLCheck(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, myIsSmooth ? GL_LINEAR : GL_NEAREST)); 00516 GLCheck(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, myIsSmooth ? GL_LINEAR : GL_NEAREST)); 00517 00518 GLCheck(glBindTexture(GL_TEXTURE_2D, previous)); 00519 } 00520 } 00521 } 00522 00523 00527 unsigned int Image::GetWidth() const 00528 { 00529 return myWidth; 00530 } 00531 00532 00536 unsigned int Image::GetHeight() const 00537 { 00538 return myHeight; 00539 } 00540 00541 00545 bool Image::IsSmooth() const 00546 { 00547 return myIsSmooth; 00548 } 00549 00550 00555 FloatRect Image::GetTexCoords(const IntRect& rect) const 00556 { 00557 if ((myTextureWidth != 0) && (myTextureHeight != 0)) 00558 { 00559 float width = static_cast<float>(myTextureWidth); 00560 float height = static_cast<float>(myTextureHeight); 00561 00562 if (myPixelsFlipped) 00563 { 00564 return FloatRect(rect.Left / width, 00565 rect.Bottom / height, 00566 rect.Right / width, 00567 rect.Top / height); 00568 } 00569 else 00570 { 00571 return FloatRect(rect.Left / width, 00572 rect.Top / height, 00573 rect.Right / width, 00574 rect.Bottom / height); 00575 } 00576 } 00577 else 00578 { 00579 return FloatRect(0, 0, 0, 0); 00580 } 00581 } 00582 00583 00587 unsigned int Image::GetMaximumSize() 00588 { 00589 GLint size; 00590 GLCheck(glGetIntegerv(GL_MAX_TEXTURE_SIZE, &size)); 00591 00592 return static_cast<unsigned int>(size); 00593 } 00594 00595 00599 unsigned int Image::GetValidSize(unsigned int size) 00600 { 00601 // Make sure that GLEW is initialized 00602 priv::EnsureGlewInit(); 00603 00604 if (GLEW_ARB_texture_non_power_of_two) 00605 { 00606 // If hardware supports NPOT textures, then just return the unmodified size 00607 return size; 00608 } 00609 else 00610 { 00611 // If hardware doesn't support NPOT textures, we calculate the nearest power of two 00612 unsigned int powerOfTwo = 1; 00613 while (powerOfTwo < size) 00614 powerOfTwo *= 2; 00615 00616 return powerOfTwo; 00617 } 00618 } 00619 00620 00624 Image& Image::operator =(const Image& other) 00625 { 00626 Image temp(other); 00627 00628 std::swap(myWidth, temp.myWidth); 00629 std::swap(myHeight, temp.myHeight); 00630 std::swap(myTextureWidth, temp.myTextureWidth); 00631 std::swap(myTextureHeight, temp.myTextureHeight); 00632 std::swap(myTexture, temp.myTexture); 00633 std::swap(myIsSmooth, temp.myIsSmooth); 00634 std::swap(myArrayUpdated, temp.myArrayUpdated); 00635 std::swap(myTextureUpdated, temp.myTextureUpdated); 00636 std::swap(myPixelsFlipped, temp.myPixelsFlipped); 00637 std::swap(myPixels, temp.myPixels); 00638 00639 return *this; 00640 } 00641 00642 00646 bool Image::CreateTexture() 00647 { 00648 // Check if texture parameters are valid before creating it 00649 if (!myWidth || !myHeight) 00650 return false; 00651 00652 // Adjust internal texture dimensions depending on NPOT textures support 00653 myTextureWidth = GetValidSize(myWidth); 00654 myTextureHeight = GetValidSize(myHeight); 00655 00656 // Check the maximum texture size 00657 unsigned int maxSize = GetMaximumSize(); 00658 if ((myTextureWidth > maxSize) || (myTextureHeight > maxSize)) 00659 { 00660 Err() << "Failed to create image, its internal size is too high " 00661 << "(" << myTextureWidth << "x" << myTextureHeight << ", " 00662 << "maximum is " << maxSize << "x" << maxSize << ")" 00663 << std::endl; 00664 return false; 00665 } 00666 00667 // Create the OpenGL texture if it doesn't exist yet 00668 if (!myTexture) 00669 { 00670 GLuint texture; 00671 GLCheck(glGenTextures(1, &texture)); 00672 myTexture = static_cast<unsigned int>(texture); 00673 } 00674 00675 // Initialize the texture 00676 GLint previous; 00677 GLCheck(glGetIntegerv(GL_TEXTURE_BINDING_2D, &previous)); 00678 GLCheck(glBindTexture(GL_TEXTURE_2D, myTexture)); 00679 GLCheck(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, myTextureWidth, myTextureHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL)); 00680 GLCheck(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP)); 00681 GLCheck(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP)); 00682 GLCheck(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, myIsSmooth ? GL_LINEAR : GL_NEAREST)); 00683 GLCheck(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, myIsSmooth ? GL_LINEAR : GL_NEAREST)); 00684 GLCheck(glBindTexture(GL_TEXTURE_2D, previous)); 00685 00686 myTextureUpdated = false; 00687 00688 return true; 00689 } 00690 00691 00696 void Image::EnsureTextureUpdate() const 00697 { 00698 if (!myTextureUpdated) 00699 { 00700 if (myTexture && !myPixels.empty()) 00701 { 00702 GLint previous; 00703 GLCheck(glGetIntegerv(GL_TEXTURE_BINDING_2D, &previous)); 00704 00705 // Update the texture with the pixels array in RAM 00706 GLCheck(glBindTexture(GL_TEXTURE_2D, myTexture)); 00707 GLCheck(glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, myWidth, myHeight, GL_RGBA, GL_UNSIGNED_BYTE, &myPixels[0])); 00708 myPixelsFlipped = false; 00709 00710 GLCheck(glBindTexture(GL_TEXTURE_2D, previous)); 00711 } 00712 00713 myTextureUpdated = true; 00714 } 00715 } 00716 00717 00722 void Image::EnsureArrayUpdate() const 00723 { 00724 if (!myArrayUpdated) 00725 { 00726 // Save the previous texture 00727 GLint previous; 00728 GLCheck(glGetIntegerv(GL_TEXTURE_BINDING_2D, &previous)); 00729 00730 // Resize the destination array of pixels 00731 myPixels.resize(myWidth * myHeight); 00732 00733 if ((myWidth == myTextureWidth) && (myHeight == myTextureHeight) && !myPixelsFlipped) 00734 { 00735 // Texture and array have the same size, we can use a direct copy 00736 00737 // Copy pixels from texture to array 00738 GLCheck(glBindTexture(GL_TEXTURE_2D, myTexture)); 00739 GLCheck(glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, &myPixels[0])); 00740 } 00741 else 00742 { 00743 // Texture and array don't have the same size, we have to use a slower algorithm 00744 00745 // All the pixels will first be copied to a temporary array 00746 ColorArray allPixels(myTextureWidth * myTextureHeight); 00747 GLCheck(glBindTexture(GL_TEXTURE_2D, myTexture)); 00748 GLCheck(glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, &allPixels[0])); 00749 00750 // Then we copy the useful pixels from the temporary array to the final one 00751 const Color* src = &allPixels[0]; 00752 Color* dst = &myPixels[0]; 00753 int srcPitch = myTextureWidth; 00754 00755 // Handle the case where source pixels are flipped vertically 00756 if (myPixelsFlipped) 00757 { 00758 src += myTextureWidth * (myHeight - 1); 00759 srcPitch = -srcPitch; 00760 } 00761 00762 for (unsigned int i = 0; i < myHeight; ++i) 00763 { 00764 std::copy(src, src + myWidth, dst); 00765 src += srcPitch; 00766 dst += myWidth; 00767 } 00768 } 00769 00770 // Restore the previous texture 00771 GLCheck(glBindTexture(GL_TEXTURE_2D, previous)); 00772 00773 myArrayUpdated = true; 00774 } 00775 } 00776 00777 00781 void Image::Use() const 00782 { 00783 EnsureTextureUpdate(); 00784 } 00785 00786 00790 void Image::Reset() 00791 { 00792 DestroyTexture(); 00793 00794 myWidth = 0; 00795 myHeight = 0; 00796 myTextureWidth = 0; 00797 myTextureHeight = 0; 00798 myTexture = 0; 00799 myIsSmooth = true; 00800 myTextureUpdated = true; 00801 myArrayUpdated = true; 00802 myPixelsFlipped = false; 00803 myPixels.clear(); 00804 } 00805 00806 00810 void Image::DestroyTexture() 00811 { 00812 // Destroy the internal texture 00813 if (myTexture) 00814 { 00815 GLuint Texture = static_cast<GLuint>(myTexture); 00816 GLCheck(glDeleteTextures(1, &Texture)); 00817 myTexture = 0; 00818 myTextureUpdated = true; 00819 myArrayUpdated = true; 00820 } 00821 } 00822 00823 } // namespace sf
:: Copyright © 2007-2008 Laurent Gomila, all rights reserved :: Documentation generated by doxygen 1.5.2 ::