Replaced getWidth/getHeight with getSize in sf::Texture and sf::Image

This commit is contained in:
Laurent Gomila 2012-03-31 22:37:13 +02:00
parent b2f3787db1
commit 17e6a45a90
12 changed files with 127 additions and 180 deletions

View File

@ -34,7 +34,7 @@ int main()
return EXIT_FAILURE; return EXIT_FAILURE;
glGenTextures(1, &texture); glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture); glBindTexture(GL_TEXTURE_2D, texture);
gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, image.getWidth(), image.getHeight(), GL_RGBA, GL_UNSIGNED_BYTE, image.getPixelsPtr()); gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, image.getSize().x, image.getSize().y, GL_RGBA, GL_UNSIGNED_BYTE, image.getPixelsPtr());
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
} }

View File

@ -81,7 +81,7 @@ INT WINAPI WinMain(HINSTANCE instance, HINSTANCE, LPSTR, INT)
return EXIT_FAILURE; return EXIT_FAILURE;
sf::Sprite sprite1(texture1); sf::Sprite sprite1(texture1);
sf::Sprite sprite2(texture2); sf::Sprite sprite2(texture2);
sprite1.setOrigin(texture1.getWidth() / 2.f, texture1.getHeight() / 2.f); sprite1.setOrigin(sf::Vector2f(texture1.getSize()) / 2.f);
sprite1.setPosition(sprite1.getOrigin()); sprite1.setPosition(sprite1.getOrigin());
// Create a clock for measuring elapsed time // Create a clock for measuring elapsed time

View File

@ -150,24 +150,12 @@ public :
bool saveToFile(const std::string& filename) const; bool saveToFile(const std::string& filename) const;
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Return the width of the image /// \brief Return the size of the image
/// ///
/// \return Width in pixels /// \return Size in pixels
///
/// \see getHeight
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
unsigned int getWidth() const; Vector2u getSize() const;
////////////////////////////////////////////////////////////
/// \brief Return the height of the image
///
/// \return Height in pixels
///
/// \see getWidth
///
////////////////////////////////////////////////////////////
unsigned int getHeight() const;
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Create a transparency mask from a specified color-key /// \brief Create a transparency mask from a specified color-key
@ -269,8 +257,7 @@ private :
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
// Member data // Member data
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
unsigned int m_width; ///< Image width Vector2u m_size; ///< Image size
unsigned int m_height; ///< Image Height
std::vector<Uint8> m_pixels; ///< Pixels of the image std::vector<Uint8> m_pixels; ///< Pixels of the image
}; };

View File

@ -214,24 +214,12 @@ public :
bool loadFromImage(const Image& image, const IntRect& area = IntRect()); bool loadFromImage(const Image& image, const IntRect& area = IntRect());
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Return the width of the texture /// \brief Return the size of the texture
/// ///
/// \return Width in pixels /// \return Size in pixels
///
/// \see getHeight
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
unsigned int getWidth() const; Vector2u getSize() const;
////////////////////////////////////////////////////////////
/// \brief Return the height of the texture
///
/// \return Height in pixels
///
/// \see getWidth
///
////////////////////////////////////////////////////////////
unsigned int getHeight() const;
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Copy the texture pixels to an image /// \brief Copy the texture pixels to an image
@ -489,10 +477,8 @@ private :
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
// Member data // Member data
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
unsigned int m_width; ///< Image width Vector2u m_size; ///< Public texture size
unsigned int m_height; ///< Image Height Vector2u m_actualSize; ///< Actual texture size (can be greater than public size because of padding)
unsigned int m_textureWidth; ///< Actual texture width (can be greater than image width because of padding)
unsigned int m_textureHeight; ///< Actual texture height (can be greater than image height because of padding)
unsigned int m_texture; ///< Internal texture identifier unsigned int m_texture; ///< Internal texture identifier
bool m_isSmooth; ///< Status of the smooth filter bool m_isSmooth; ///< Status of the smooth filter
bool m_isRepeated; ///< Is the texture in repeat mode? bool m_isRepeated; ///< Is the texture in repeat mode?

View File

@ -519,7 +519,7 @@ IntRect Font::findGlyphRect(Page& page, unsigned int width, unsigned int height)
continue; continue;
// Check if there's enough horizontal space left in the row // Check if there's enough horizontal space left in the row
if (width > page.texture.getWidth() - it->width) if (width > page.texture.getSize().x - it->width)
continue; continue;
// Make sure that this new row is the best found so far // Make sure that this new row is the best found so far
@ -535,11 +535,11 @@ IntRect Font::findGlyphRect(Page& page, unsigned int width, unsigned int height)
if (!row) if (!row)
{ {
int rowHeight = height + height / 10; int rowHeight = height + height / 10;
if (page.nextRow + rowHeight >= page.texture.getHeight()) if (page.nextRow + rowHeight >= page.texture.getSize().y)
{ {
// Not enough space: resize the texture if possible // Not enough space: resize the texture if possible
unsigned int textureWidth = page.texture.getWidth(); unsigned int textureWidth = page.texture.getSize().x;
unsigned int textureHeight = page.texture.getHeight(); unsigned int textureHeight = page.texture.getSize().y;
if ((textureWidth * 2 <= Texture::getMaximumSize()) && (textureHeight * 2 <= Texture::getMaximumSize())) if ((textureWidth * 2 <= Texture::getMaximumSize()) && (textureHeight * 2 <= Texture::getMaximumSize()))
{ {
// Make the texture 2 times bigger // Make the texture 2 times bigger

View File

@ -36,8 +36,7 @@ namespace sf
{ {
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
Image::Image() : Image::Image() :
m_width (0), m_size(0, 0)
m_height(0)
{ {
} }
@ -47,8 +46,8 @@ m_height(0)
void Image::create(unsigned int width, unsigned int height, const Color& color) void Image::create(unsigned int width, unsigned int height, const Color& color)
{ {
// Assign the new size // Assign the new size
m_width = width; m_size.x = width;
m_height = height; m_size.y = height;
// Resize the pixel buffer // Resize the pixel buffer
m_pixels.resize(width * height * 4); m_pixels.resize(width * height * 4);
@ -72,8 +71,8 @@ void Image::create(unsigned int width, unsigned int height, const Uint8* pixels)
if (pixels) if (pixels)
{ {
// Assign the new size // Assign the new size
m_width = width; m_size.x = width;
m_height = height; m_size.y = height;
// Copy the pixels // Copy the pixels
std::size_t size = width * height * 4; std::size_t size = width * height * 4;
@ -83,8 +82,8 @@ void Image::create(unsigned int width, unsigned int height, const Uint8* pixels)
else else
{ {
// Create an empty image // Create an empty image
m_width = 0; m_size.x = 0;
m_height = 0; m_size.y = 0;
m_pixels.clear(); m_pixels.clear();
} }
} }
@ -93,42 +92,35 @@ void Image::create(unsigned int width, unsigned int height, const Uint8* pixels)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
bool Image::loadFromFile(const std::string& filename) bool Image::loadFromFile(const std::string& filename)
{ {
return priv::ImageLoader::getInstance().loadImageFromFile(filename, m_pixels, m_width, m_height); return priv::ImageLoader::getInstance().loadImageFromFile(filename, m_pixels, m_size);
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
bool Image::loadFromMemory(const void* data, std::size_t size) bool Image::loadFromMemory(const void* data, std::size_t size)
{ {
return priv::ImageLoader::getInstance().loadImageFromMemory(data, size, m_pixels, m_width, m_height); return priv::ImageLoader::getInstance().loadImageFromMemory(data, size, m_pixels, m_size);
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
bool Image::loadFromStream(InputStream& stream) bool Image::loadFromStream(InputStream& stream)
{ {
return priv::ImageLoader::getInstance().loadImageFromStream(stream, m_pixels, m_width, m_height); return priv::ImageLoader::getInstance().loadImageFromStream(stream, m_pixels, m_size);
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
bool Image::saveToFile(const std::string& filename) const bool Image::saveToFile(const std::string& filename) const
{ {
return priv::ImageLoader::getInstance().saveImageToFile(filename, m_pixels, m_width, m_height); return priv::ImageLoader::getInstance().saveImageToFile(filename, m_pixels, m_size);
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
unsigned int Image::getWidth() const Vector2u Image::getSize() const
{ {
return m_width; return m_size;
}
////////////////////////////////////////////////////////////
unsigned int Image::getHeight() const
{
return m_height;
} }
@ -155,7 +147,7 @@ void Image::createMaskFromColor(const Color& color, Uint8 alpha)
void Image::copy(const Image& source, unsigned int destX, unsigned int destY, const IntRect& sourceRect, bool applyAlpha) void Image::copy(const Image& source, unsigned int destX, unsigned int destY, const IntRect& sourceRect, bool applyAlpha)
{ {
// Make sure that both images are valid // Make sure that both images are valid
if ((source.m_width == 0) || (source.m_height == 0) || (m_width == 0) || (m_height == 0)) if ((source.m_size.x == 0) || (source.m_size.y == 0) || (m_size.x == 0) || (m_size.y == 0))
return; return;
// Adjust the source rectangle // Adjust the source rectangle
@ -164,22 +156,22 @@ void Image::copy(const Image& source, unsigned int destX, unsigned int destY, co
{ {
srcRect.left = 0; srcRect.left = 0;
srcRect.top = 0; srcRect.top = 0;
srcRect.width = source.m_width; srcRect.width = source.m_size.x;
srcRect.height = source.m_height; srcRect.height = source.m_size.y;
} }
else else
{ {
if (srcRect.left < 0) srcRect.left = 0; if (srcRect.left < 0) srcRect.left = 0;
if (srcRect.top < 0) srcRect.top = 0; if (srcRect.top < 0) srcRect.top = 0;
if (srcRect.width > static_cast<int>(source.m_width)) srcRect.width = source.m_width; if (srcRect.width > static_cast<int>(source.m_size.x)) srcRect.width = source.m_size.x;
if (srcRect.height > static_cast<int>(source.m_height)) srcRect.height = source.m_height; if (srcRect.height > static_cast<int>(source.m_size.y)) srcRect.height = source.m_size.y;
} }
// Then find the valid bounds of the destination rectangle // Then find the valid bounds of the destination rectangle
int width = srcRect.width; int width = srcRect.width;
int height = srcRect.height; int height = srcRect.height;
if (destX + width > m_width) width = m_width - destX; if (destX + width > m_size.x) width = m_size.x - destX;
if (destY + height > m_height) height = m_height - destY; if (destY + height > m_size.y) height = m_size.y - destY;
// Make sure the destination area is valid // Make sure the destination area is valid
if ((width <= 0) || (height <= 0)) if ((width <= 0) || (height <= 0))
@ -188,10 +180,10 @@ void Image::copy(const Image& source, unsigned int destX, unsigned int destY, co
// Precompute as much as possible // Precompute as much as possible
int pitch = width * 4; int pitch = width * 4;
int rows = height; int rows = height;
int srcStride = source.m_width * 4; int srcStride = source.m_size.x * 4;
int dstStride = m_width * 4; int dstStride = m_size.x * 4;
const Uint8* srcPixels = &source.m_pixels[0] + (srcRect.left + srcRect.top * source.m_width) * 4; const Uint8* srcPixels = &source.m_pixels[0] + (srcRect.left + srcRect.top * source.m_size.x) * 4;
Uint8* dstPixels = &m_pixels[0] + (destX + destY * m_width) * 4; Uint8* dstPixels = &m_pixels[0] + (destX + destY * m_size.x) * 4;
// Copy the pixels // Copy the pixels
if (applyAlpha) if (applyAlpha)
@ -233,7 +225,7 @@ void Image::copy(const Image& source, unsigned int destX, unsigned int destY, co
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
void Image::setPixel(unsigned int x, unsigned int y, const Color& color) void Image::setPixel(unsigned int x, unsigned int y, const Color& color)
{ {
Uint8* pixel = &m_pixels[(x + y * m_width) * 4]; Uint8* pixel = &m_pixels[(x + y * m_size.x) * 4];
*pixel++ = color.r; *pixel++ = color.r;
*pixel++ = color.g; *pixel++ = color.g;
*pixel++ = color.b; *pixel++ = color.b;
@ -244,7 +236,7 @@ void Image::setPixel(unsigned int x, unsigned int y, const Color& color)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
Color Image::getPixel(unsigned int x, unsigned int y) const Color Image::getPixel(unsigned int x, unsigned int y) const
{ {
const Uint8* pixel = &m_pixels[(x + y * m_width) * 4]; const Uint8* pixel = &m_pixels[(x + y * m_size.x) * 4];
return Color(pixel[0], pixel[1], pixel[2], pixel[3]); return Color(pixel[0], pixel[1], pixel[2], pixel[3]);
} }
@ -270,11 +262,11 @@ void Image::flipHorizontally()
if (!m_pixels.empty()) if (!m_pixels.empty())
{ {
std::vector<Uint8> before = m_pixels; std::vector<Uint8> before = m_pixels;
for (unsigned int y = 0; y < m_height; ++y) for (unsigned int y = 0; y < m_size.y; ++y)
{ {
const Uint8* source = &before[y * m_width * 4]; const Uint8* source = &before[y * m_size.x * 4];
Uint8* dest = &m_pixels[(y + 1) * m_width * 4 - 4]; Uint8* dest = &m_pixels[(y + 1) * m_size.x * 4 - 4];
for (unsigned int x = 0; x < m_width; ++x) for (unsigned int x = 0; x < m_size.x; ++x)
{ {
dest[0] = source[0]; dest[0] = source[0];
dest[1] = source[1]; dest[1] = source[1];
@ -295,11 +287,11 @@ void Image::flipVertically()
if (!m_pixels.empty()) if (!m_pixels.empty())
{ {
std::vector<Uint8> before = m_pixels; std::vector<Uint8> before = m_pixels;
const Uint8* source = &before[m_width * (m_height - 1) * 4]; const Uint8* source = &before[m_size.x * (m_size.y - 1) * 4];
Uint8* dest = &m_pixels[0]; Uint8* dest = &m_pixels[0];
std::size_t rowSize = m_width * 4; std::size_t rowSize = m_size.x * 4;
for (unsigned int y = 0; y < m_height; ++y) for (unsigned int y = 0; y < m_size.y; ++y)
{ {
std::memcpy(dest, source, rowSize); std::memcpy(dest, source, rowSize);
source -= rowSize; source -= rowSize;

View File

@ -96,20 +96,20 @@ ImageLoader::~ImageLoader()
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
bool ImageLoader::loadImageFromFile(const std::string& filename, std::vector<Uint8>& pixels, unsigned int& width, unsigned int& height) bool ImageLoader::loadImageFromFile(const std::string& filename, std::vector<Uint8>& pixels, Vector2u& size)
{ {
// Clear the array (just in case) // Clear the array (just in case)
pixels.clear(); pixels.clear();
// Load the image and get a pointer to the pixels in memory // Load the image and get a pointer to the pixels in memory
int imgWidth, imgHeight, imgChannels; int width, height, channels;
unsigned char* ptr = stbi_load(filename.c_str(), &imgWidth, &imgHeight, &imgChannels, STBI_rgb_alpha); unsigned char* ptr = stbi_load(filename.c_str(), &width, &height, &channels, STBI_rgb_alpha);
if (ptr && imgWidth && imgHeight) if (ptr && width && height)
{ {
// Assign the image properties // Assign the image properties
width = imgWidth; size.x = width;
height = imgHeight; size.y = height;
// Copy the loaded pixels to the pixel buffer // Copy the loaded pixels to the pixel buffer
pixels.resize(width * height * 4); pixels.resize(width * height * 4);
@ -131,24 +131,24 @@ bool ImageLoader::loadImageFromFile(const std::string& filename, std::vector<Uin
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
bool ImageLoader::loadImageFromMemory(const void* data, std::size_t size, std::vector<Uint8>& pixels, unsigned int& width, unsigned int& height) bool ImageLoader::loadImageFromMemory(const void* data, std::size_t dataSize, std::vector<Uint8>& pixels, Vector2u& size)
{ {
// Check input parameters // Check input parameters
if (data && size) if (data && dataSize)
{ {
// Clear the array (just in case) // Clear the array (just in case)
pixels.clear(); pixels.clear();
// Load the image and get a pointer to the pixels in memory // Load the image and get a pointer to the pixels in memory
int imgWidth, imgHeight, imgChannels; int width, height, channels;
const unsigned char* buffer = static_cast<const unsigned char*>(data); const unsigned char* buffer = static_cast<const unsigned char*>(data);
unsigned char* ptr = stbi_load_from_memory(buffer, static_cast<int>(size), &imgWidth, &imgHeight, &imgChannels, STBI_rgb_alpha); unsigned char* ptr = stbi_load_from_memory(buffer, static_cast<int>(dataSize), &width, &height, &channels, STBI_rgb_alpha);
if (ptr && imgWidth && imgHeight) if (ptr && width && height)
{ {
// Assign the image properties // Assign the image properties
width = imgWidth; size.x = width;
height = imgHeight; size.y = height;
// Copy the loaded pixels to the pixel buffer // Copy the loaded pixels to the pixel buffer
pixels.resize(width * height * 4); pixels.resize(width * height * 4);
@ -176,7 +176,7 @@ bool ImageLoader::loadImageFromMemory(const void* data, std::size_t size, std::v
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
bool ImageLoader::loadImageFromStream(InputStream& stream, std::vector<Uint8>& pixels, unsigned int& width, unsigned int& height) bool ImageLoader::loadImageFromStream(InputStream& stream, std::vector<Uint8>& pixels, Vector2u& size)
{ {
// Clear the array (just in case) // Clear the array (just in case)
pixels.clear(); pixels.clear();
@ -188,14 +188,14 @@ bool ImageLoader::loadImageFromStream(InputStream& stream, std::vector<Uint8>& p
callbacks.eof = &eof; callbacks.eof = &eof;
// Load the image and get a pointer to the pixels in memory // Load the image and get a pointer to the pixels in memory
int imgWidth, imgHeight, imgChannels; int width, height, channels;
unsigned char* ptr = stbi_load_from_callbacks(&callbacks, &stream, &imgWidth, &imgHeight, &imgChannels, STBI_rgb_alpha); unsigned char* ptr = stbi_load_from_callbacks(&callbacks, &stream, &width, &height, &channels, STBI_rgb_alpha);
if (ptr && imgWidth && imgHeight) if (ptr && width && height)
{ {
// Assign the image properties // Assign the image properties
width = imgWidth; size.x = width;
height = imgHeight; size.y = height;
// Copy the loaded pixels to the pixel buffer // Copy the loaded pixels to the pixel buffer
pixels.resize(width * height * 4); pixels.resize(width * height * 4);
@ -217,10 +217,10 @@ bool ImageLoader::loadImageFromStream(InputStream& stream, std::vector<Uint8>& p
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
bool ImageLoader::saveImageToFile(const std::string& filename, const std::vector<Uint8>& pixels, unsigned int width, unsigned int height) bool ImageLoader::saveImageToFile(const std::string& filename, const std::vector<Uint8>& pixels, const Vector2u& size)
{ {
// Make sure the image is not empty // Make sure the image is not empty
if (!pixels.empty() && width && height) if (!pixels.empty() && (size.x > 0) && (size.y > 0))
{ {
// Deduce the image type from its extension // Deduce the image type from its extension
if (filename.size() > 3) if (filename.size() > 3)
@ -231,25 +231,25 @@ bool ImageLoader::saveImageToFile(const std::string& filename, const std::vector
if (toLower(extension) == "bmp") if (toLower(extension) == "bmp")
{ {
// BMP format // BMP format
if (stbi_write_bmp(filename.c_str(), width, height, 4, &pixels[0])) if (stbi_write_bmp(filename.c_str(), size.x, size.y, 4, &pixels[0]))
return true; return true;
} }
else if (toLower(extension) == "tga") else if (toLower(extension) == "tga")
{ {
// TGA format // TGA format
if (stbi_write_tga(filename.c_str(), width, height, 4, &pixels[0])) if (stbi_write_tga(filename.c_str(), size.x, size.y, 4, &pixels[0]))
return true; return true;
} }
else if(toLower(extension) == "png") else if(toLower(extension) == "png")
{ {
// PNG format // PNG format
if (stbi_write_png(filename.c_str(), width, height, 4, &pixels[0], 0)) if (stbi_write_png(filename.c_str(), size.x, size.y, 4, &pixels[0], 0))
return true; return true;
} }
else if (toLower(extension) == "jpg") else if (toLower(extension) == "jpg")
{ {
// JPG format // JPG format
if (writeJpg(filename, pixels, width, height)) if (writeJpg(filename, pixels, size.x, size.y))
return true; return true;
} }
} }

View File

@ -29,6 +29,7 @@
// Headers // Headers
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
#include <SFML/System/NonCopyable.hpp> #include <SFML/System/NonCopyable.hpp>
#include <SFML/System/Vector2.hpp>
#include <string> #include <string>
#include <vector> #include <vector>
@ -60,53 +61,49 @@ public :
/// ///
/// \param filename Path of image file to load /// \param filename Path of image file to load
/// \param pixels Array of pixels to fill with loaded image /// \param pixels Array of pixels to fill with loaded image
/// \param width Width of loaded image, in pixels /// \param size Size of loaded image, in pixels
/// \param height Height of loaded image, in pixels
/// ///
/// \return True if loading was successful /// \return True if loading was successful
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
bool loadImageFromFile(const std::string& filename, std::vector<Uint8>& pixels, unsigned int& width, unsigned int& height); bool loadImageFromFile(const std::string& filename, std::vector<Uint8>& pixels, Vector2u& size);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Load an image from a file in memory /// \brief Load an image from a file in memory
/// ///
/// \param data Pointer to the file data in memory /// \param data Pointer to the file data in memory
/// \param size Size of the data to load, in bytes /// \param dataSize Size of the data to load, in bytes
/// \param pixels Array of pixels to fill with loaded image /// \param pixels Array of pixels to fill with loaded image
/// \param width Width of loaded image, in pixels /// \param size Size of loaded image, in pixels
/// \param height Height of loaded image, in pixels
/// ///
/// \return True if loading was successful /// \return True if loading was successful
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
bool loadImageFromMemory(const void* data, std::size_t size, std::vector<Uint8>& pixels, unsigned int& width, unsigned int& height); bool loadImageFromMemory(const void* data, std::size_t dataSize, std::vector<Uint8>& pixels, Vector2u& size);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Load an image from a custom stream /// \brief Load an image from a custom stream
/// ///
/// \param stream Source stream to read from /// \param stream Source stream to read from
/// \param pixels Array of pixels to fill with loaded image /// \param pixels Array of pixels to fill with loaded image
/// \param width Width of loaded image, in pixels /// \param size Size of loaded image, in pixels
/// \param height Height of loaded image, in pixels
/// ///
/// \return True if loading was successful /// \return True if loading was successful
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
bool loadImageFromStream(InputStream& stream, std::vector<Uint8>& pixels, unsigned int& width, unsigned int& height); bool loadImageFromStream(InputStream& stream, std::vector<Uint8>& pixels, Vector2u& size);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \bref Save an array of pixels as an image file /// \bref Save an array of pixels as an image file
/// ///
/// \param filename Path of image file to save /// \param filename Path of image file to save
/// \param pixels Array of pixels to save to image /// \param pixels Array of pixels to save to image
/// \param width Width of image to save, in pixels /// \param size Size of image to save, in pixels
/// \param height Height of image to save, in pixels
/// ///
/// \return True if saving was successful /// \return True if saving was successful
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
bool saveImageToFile(const std::string& filename, const std::vector<Uint8>& pixels, unsigned int width, unsigned int height); bool saveImageToFile(const std::string& filename, const std::vector<Uint8>& pixels, const Vector2u& size);
private : private :

View File

@ -121,7 +121,7 @@ void RenderTexture::display()
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
Vector2u RenderTexture::getSize() const Vector2u RenderTexture::getSize() const
{ {
return Vector2u(m_texture.getWidth(), m_texture.getHeight()); return m_texture.getSize();
} }

View File

@ -59,7 +59,7 @@ void Shape::setTexture(const Texture* texture, bool resetRect)
{ {
// Recompute the texture area if requested, or if there was no texture before // Recompute the texture area if requested, or if there was no texture before
if (texture && (resetRect || !m_texture)) if (texture && (resetRect || !m_texture))
setTextureRect(IntRect(0, 0, texture->getWidth(), texture->getHeight())); setTextureRect(IntRect(0, 0, texture->getSize().x, texture->getSize().y));
// Assign the new texture // Assign the new texture
m_texture = texture; m_texture = texture;

View File

@ -64,7 +64,7 @@ void Sprite::setTexture(const Texture& texture, bool resetRect)
{ {
// Recompute the texture area if requested, or if there was no valid texture before // Recompute the texture area if requested, or if there was no valid texture before
if (resetRect || !m_texture) if (resetRect || !m_texture)
setTextureRect(IntRect(0, 0, texture.getWidth(), texture.getHeight())); setTextureRect(IntRect(0, 0, texture.getSize().x, texture.getSize().y));
// Assign the new texture // Assign the new texture
m_texture = &texture; m_texture = &texture;

View File

@ -56,10 +56,8 @@ namespace sf
{ {
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
Texture::Texture() : Texture::Texture() :
m_width (0), m_size (0, 0),
m_height (0), m_actualSize (0, 0),
m_textureWidth (0),
m_textureHeight(0),
m_texture (0), m_texture (0),
m_isSmooth (false), m_isSmooth (false),
m_isRepeated (false), m_isRepeated (false),
@ -72,10 +70,8 @@ m_cacheId (getUniqueId())
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
Texture::Texture(const Texture& copy) : Texture::Texture(const Texture& copy) :
m_width (0), m_size (0, 0),
m_height (0), m_actualSize (0, 0),
m_textureWidth (0),
m_textureHeight(0),
m_texture (0), m_texture (0),
m_isSmooth (copy.m_isSmooth), m_isSmooth (copy.m_isSmooth),
m_isRepeated (copy.m_isRepeated), m_isRepeated (copy.m_isRepeated),
@ -105,32 +101,30 @@ Texture::~Texture()
bool Texture::create(unsigned int width, unsigned int height) bool Texture::create(unsigned int width, unsigned int height)
{ {
// Check if texture parameters are valid before creating it // Check if texture parameters are valid before creating it
if (!width || !height) if ((m_size.x == 0) || (m_size.y == 0))
{ {
err() << "Failed to create texture, invalid size (" << width << "x" << height << ")" << std::endl; err() << "Failed to create texture, invalid size (" << m_size.x << "x" << m_size.y << ")" << std::endl;
return false; return false;
} }
// Compute the internal texture dimensions depending on NPOT textures support // Compute the internal texture dimensions depending on NPOT textures support
unsigned int textureWidth = getValidSize(width); Vector2u actualSize(getValidSize(width), getValidSize(height));
unsigned int textureHeight = getValidSize(height);
// Check the maximum texture size // Check the maximum texture size
unsigned int maxSize = getMaximumSize(); unsigned int maxSize = getMaximumSize();
if ((textureWidth > maxSize) || (textureHeight > maxSize)) if ((actualSize.x > maxSize) || (actualSize.y > maxSize))
{ {
err() << "Failed to create texture, its internal size is too high " err() << "Failed to create texture, its internal size is too high "
<< "(" << textureWidth << "x" << textureHeight << ", " << "(" << actualSize.x << "x" << actualSize.y << ", "
<< "maximum is " << maxSize << "x" << maxSize << ")" << "maximum is " << maxSize << "x" << maxSize << ")"
<< std::endl; << std::endl;
return false; return false;
} }
// All the validity checks passed, we can store the new texture settings // All the validity checks passed, we can store the new texture settings
m_width = width; m_size.x = width;
m_height = height; m_size.y = height;
m_textureWidth = textureWidth; m_actualSize = actualSize;
m_textureHeight = textureHeight;
m_pixelsFlipped = false; m_pixelsFlipped = false;
ensureGlContext(); ensureGlContext();
@ -148,7 +142,7 @@ bool Texture::create(unsigned int width, unsigned int height)
// Initialize the texture // Initialize the texture
glCheck(glBindTexture(GL_TEXTURE_2D, m_texture)); glCheck(glBindTexture(GL_TEXTURE_2D, m_texture));
glCheck(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, m_textureWidth, m_textureHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL)); glCheck(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, m_actualSize.x, m_actualSize.y, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL));
glCheck(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, m_isRepeated ? GL_REPEAT : GL_CLAMP_TO_EDGE)); glCheck(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, m_isRepeated ? GL_REPEAT : GL_CLAMP_TO_EDGE));
glCheck(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, m_isRepeated ? GL_REPEAT : GL_CLAMP_TO_EDGE)); glCheck(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, m_isRepeated ? GL_REPEAT : GL_CLAMP_TO_EDGE));
glCheck(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, m_isSmooth ? GL_LINEAR : GL_NEAREST)); glCheck(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, m_isSmooth ? GL_LINEAR : GL_NEAREST));
@ -187,15 +181,15 @@ bool Texture::loadFromStream(InputStream& stream, const IntRect& area)
bool Texture::loadFromImage(const Image& image, const IntRect& area) bool Texture::loadFromImage(const Image& image, const IntRect& area)
{ {
// Retrieve the image size // Retrieve the image size
int width = static_cast<int>(image.getWidth()); int width = static_cast<int>(image.getSize().x);
int height = static_cast<int>(image.getHeight()); int height = static_cast<int>(image.getSize().y);
// Load the entire image if the source area is either empty or contains the whole image // Load the entire image if the source area is either empty or contains the whole image
if (area.width == 0 || (area.height == 0) || if (area.width == 0 || (area.height == 0) ||
((area.left <= 0) && (area.top <= 0) && (area.width >= width) && (area.height >= height))) ((area.left <= 0) && (area.top <= 0) && (area.width >= width) && (area.height >= height)))
{ {
// Load the entire image // Load the entire image
if (create(image.getWidth(), image.getHeight())) if (create(image.getSize().x, image.getSize().y))
{ {
update(image); update(image);
return true; return true;
@ -227,7 +221,7 @@ bool Texture::loadFromImage(const Image& image, const IntRect& area)
glCheck(glBindTexture(GL_TEXTURE_2D, m_texture)); glCheck(glBindTexture(GL_TEXTURE_2D, m_texture));
for (int i = 0; i < rectangle.height; ++i) for (int i = 0; i < rectangle.height; ++i)
{ {
glCheck(glTexSubImage2D(GL_TEXTURE_2D, 0, 0, i, m_width, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels)); glCheck(glTexSubImage2D(GL_TEXTURE_2D, 0, 0, i, rectangle.width, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels));
pixels += 4 * width; pixels += 4 * width;
} }
@ -242,16 +236,9 @@ bool Texture::loadFromImage(const Image& image, const IntRect& area)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
unsigned int Texture::getWidth() const Vector2u Texture::getSize() const
{ {
return m_width; return m_size;
}
////////////////////////////////////////////////////////////
unsigned int Texture::getHeight() const
{
return m_height;
} }
@ -268,9 +255,9 @@ Image Texture::copyToImage() const
priv::TextureSaver save; priv::TextureSaver save;
// Create an array of pixels // Create an array of pixels
std::vector<Uint8> pixels(m_width * m_height * 4); std::vector<Uint8> pixels(m_size.x * m_size.y * 4);
if ((m_width == m_textureWidth) && (m_height == m_textureHeight) && !m_pixelsFlipped) if ((m_size == m_actualSize) && !m_pixelsFlipped)
{ {
// Texture is not padded nor flipped, we can use a direct copy // Texture is not padded nor flipped, we can use a direct copy
glCheck(glBindTexture(GL_TEXTURE_2D, m_texture)); glCheck(glBindTexture(GL_TEXTURE_2D, m_texture));
@ -281,24 +268,24 @@ Image Texture::copyToImage() const
// Texture is either padded or flipped, we have to use a slower algorithm // Texture is either padded or flipped, we have to use a slower algorithm
// All the pixels will first be copied to a temporary array // All the pixels will first be copied to a temporary array
std::vector<Uint8> allPixels(m_textureWidth * m_textureHeight * 4); std::vector<Uint8> allPixels(m_actualSize.x * m_actualSize.y * 4);
glCheck(glBindTexture(GL_TEXTURE_2D, m_texture)); glCheck(glBindTexture(GL_TEXTURE_2D, m_texture));
glCheck(glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, &allPixels[0])); glCheck(glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, &allPixels[0]));
// Then we copy the useful pixels from the temporary array to the final one // Then we copy the useful pixels from the temporary array to the final one
const Uint8* src = &allPixels[0]; const Uint8* src = &allPixels[0];
Uint8* dst = &pixels[0]; Uint8* dst = &pixels[0];
int srcPitch = m_textureWidth * 4; int srcPitch = m_actualSize.x * 4;
int dstPitch = m_width * 4; int dstPitch = m_size.x * 4;
// Handle the case where source pixels are flipped vertically // Handle the case where source pixels are flipped vertically
if (m_pixelsFlipped) if (m_pixelsFlipped)
{ {
src += srcPitch * (m_height - 1); src += srcPitch * (m_size.y - 1);
srcPitch = -srcPitch; srcPitch = -srcPitch;
} }
for (unsigned int i = 0; i < m_height; ++i) for (unsigned int i = 0; i < m_size.y; ++i)
{ {
std::memcpy(dst, src, dstPitch); std::memcpy(dst, src, dstPitch);
src += srcPitch; src += srcPitch;
@ -308,7 +295,7 @@ Image Texture::copyToImage() const
// Create the image // Create the image
Image image; Image image;
image.create(m_width, m_height, &pixels[0]); image.create(m_size.x, m_size.y, &pixels[0]);
return image; return image;
} }
@ -318,15 +305,15 @@ Image Texture::copyToImage() const
void Texture::update(const Uint8* pixels) void Texture::update(const Uint8* pixels)
{ {
// Update the whole texture // Update the whole texture
update(pixels, m_width, m_height, 0, 0); update(pixels, m_size.x, m_size.y, 0, 0);
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
void Texture::update(const Uint8* pixels, unsigned int width, unsigned int height, unsigned int x, unsigned int y) void Texture::update(const Uint8* pixels, unsigned int width, unsigned int height, unsigned int x, unsigned int y)
{ {
assert(x + width <= m_width); assert(x + width <= m_size.x);
assert(y + height <= m_height); assert(y + height <= m_size.y);
if (pixels && m_texture) if (pixels && m_texture)
{ {
@ -348,14 +335,14 @@ void Texture::update(const Uint8* pixels, unsigned int width, unsigned int heigh
void Texture::update(const Image& image) void Texture::update(const Image& image)
{ {
// Update the whole texture // Update the whole texture
update(image.getPixelsPtr(), image.getWidth(), image.getHeight(), 0, 0); update(image.getPixelsPtr(), image.getSize().x, image.getSize().y, 0, 0);
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
void Texture::update(const Image& image, unsigned int x, unsigned int y) void Texture::update(const Image& image, unsigned int x, unsigned int y)
{ {
update(image.getPixelsPtr(), image.getWidth(), image.getHeight(), x, y); update(image.getPixelsPtr(), image.getSize().x, image.getSize().y, x, y);
} }
@ -369,8 +356,8 @@ void Texture::update(const Window& window)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
void Texture::update(const Window& window, unsigned int x, unsigned int y) void Texture::update(const Window& window, unsigned int x, unsigned int y)
{ {
assert(x + window.getSize().x <= m_width); assert(x + window.getSize().x <= m_size.x);
assert(y + window.getSize().y <= m_height); assert(y + window.getSize().y <= m_size.y);
if (m_texture && window.setActive(true)) if (m_texture && window.setActive(true))
{ {
@ -404,15 +391,15 @@ void Texture::bind(CoordinateType coordinateType) const
// setup scale factors that convert the range [0 .. size] to [0 .. 1] // setup scale factors that convert the range [0 .. size] to [0 .. 1]
if (coordinateType == Pixels) if (coordinateType == Pixels)
{ {
matrix[0] = 1.f / m_textureWidth; matrix[0] = 1.f / m_actualSize.x;
matrix[5] = 1.f / m_textureHeight; matrix[5] = 1.f / m_actualSize.y;
} }
// If pixels are flipped we must invert the Y axis // If pixels are flipped we must invert the Y axis
if (m_pixelsFlipped) if (m_pixelsFlipped)
{ {
matrix[5] = -matrix[5]; matrix[5] = -matrix[5];
matrix[13] = static_cast<float>(m_height / m_textureHeight); matrix[13] = static_cast<float>(m_size.y / m_actualSize.y);
} }
// Load the matrix // Load the matrix
@ -500,10 +487,8 @@ Texture& Texture::operator =(const Texture& right)
{ {
Texture temp(right); Texture temp(right);
std::swap(m_width, temp.m_width); std::swap(m_size, temp.m_size);
std::swap(m_height, temp.m_height); std::swap(m_actualSize, temp.m_actualSize);
std::swap(m_textureWidth, temp.m_textureWidth);
std::swap(m_textureHeight, temp.m_textureHeight);
std::swap(m_texture, temp.m_texture); std::swap(m_texture, temp.m_texture);
std::swap(m_isSmooth, temp.m_isSmooth); std::swap(m_isSmooth, temp.m_isSmooth);
std::swap(m_isRepeated, temp.m_isRepeated); std::swap(m_isRepeated, temp.m_isRepeated);