mirror of
https://github.com/SFML/SFML.git
synced 2024-11-25 04:41:05 +08:00
Split sf::Image into sf::Image and sf::Texture (implements issue #18)
This commit is contained in:
parent
d337a98321
commit
e509f01180
@ -18,14 +18,14 @@ int main()
|
||||
sf::RenderWindow window(sf::VideoMode(800, 600), "SFML OpenGL", sf::Style::Default, sf::ContextSettings(32));
|
||||
|
||||
// Create a sprite for the background
|
||||
sf::Image backgroundImage;
|
||||
if (!backgroundImage.LoadFromFile("resources/background.jpg"))
|
||||
sf::Texture backgroundTexture;
|
||||
if (!backgroundTexture.LoadFromFile("resources/background.jpg"))
|
||||
return EXIT_FAILURE;
|
||||
sf::Sprite background(backgroundImage);
|
||||
sf::Sprite background(backgroundTexture);
|
||||
|
||||
// Load an OpenGL texture.
|
||||
// We could directly use a sf::Image as an OpenGL texture (with its Bind() member function),
|
||||
// but here we want more control on it (generate mipmaps, ...) so we create a new one from the image pixels
|
||||
// We could directly use a sf::Texture as an OpenGL texture (with its Bind() member function),
|
||||
// but here we want more control on it (generate mipmaps, ...) so we create a new one from an image
|
||||
GLuint texture = 0;
|
||||
{
|
||||
sf::Image image;
|
||||
|
@ -33,12 +33,12 @@ int main()
|
||||
}
|
||||
sf::Sound ballSound(ballSoundBuffer);
|
||||
|
||||
// Load the images used in the game
|
||||
sf::Image backgroundImage, leftPaddleImage, rightPaddleImage, ballImage;
|
||||
if (!backgroundImage.LoadFromFile("resources/background.jpg") ||
|
||||
!leftPaddleImage.LoadFromFile("resources/paddle_left.png") ||
|
||||
!rightPaddleImage.LoadFromFile("resources/paddle_right.png") ||
|
||||
!ballImage.LoadFromFile("resources/ball.png"))
|
||||
// Load the textures used in the game
|
||||
sf::Texture backgroundTexture, leftPaddleTexture, rightPaddleTexture, ballTexture;
|
||||
if (!backgroundTexture.LoadFromFile("resources/background.jpg") ||
|
||||
!leftPaddleTexture.LoadFromFile("resources/paddle_left.png") ||
|
||||
!rightPaddleTexture.LoadFromFile("resources/paddle_right.png") ||
|
||||
!ballTexture.LoadFromFile("resources/ball.png"))
|
||||
{
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
@ -56,10 +56,10 @@ int main()
|
||||
end.SetColor(sf::Color(50, 50, 250));
|
||||
|
||||
// Create the sprites of the background, the paddles and the ball
|
||||
sf::Sprite background(backgroundImage);
|
||||
sf::Sprite leftPaddle(leftPaddleImage);
|
||||
sf::Sprite rightPaddle(rightPaddleImage);
|
||||
sf::Sprite ball(ballImage);
|
||||
sf::Sprite background(backgroundTexture);
|
||||
sf::Sprite leftPaddle(leftPaddleTexture);
|
||||
sf::Sprite rightPaddle(rightPaddleTexture);
|
||||
sf::Sprite ball(ballTexture);
|
||||
|
||||
leftPaddle.Move(10, (window.GetView().GetSize().y - leftPaddle.GetSize().y) / 2);
|
||||
rightPaddle.Move(window.GetView().GetSize().x - rightPaddle.GetSize().x - 10, (window.GetView().GetSize().y - rightPaddle.GetSize().y) / 2);
|
||||
|
@ -4,7 +4,7 @@
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/Graphics.hpp>
|
||||
#include <map>
|
||||
#include <math.h>
|
||||
#include <cmath>
|
||||
|
||||
|
||||
void DisplayError();
|
||||
@ -88,32 +88,31 @@ int main()
|
||||
// Create the main window
|
||||
sf::RenderWindow window(sf::VideoMode(800, 600), "SFML Shader");
|
||||
|
||||
// Create the render image
|
||||
sf::RenderImage image;
|
||||
if (!image.Create(window.GetWidth(), window.GetHeight()))
|
||||
// Create the render texture
|
||||
sf::RenderTexture texture;
|
||||
if (!texture.Create(window.GetWidth(), window.GetHeight()))
|
||||
return EXIT_FAILURE;
|
||||
|
||||
// Load a background image to display
|
||||
sf::Image backgroundImage;
|
||||
if (!backgroundImage.LoadFromFile("resources/background.jpg"))
|
||||
// Load a background texture to display
|
||||
sf::Texture backgroundTexture;
|
||||
if (!backgroundTexture.LoadFromFile("resources/background.jpg"))
|
||||
return EXIT_FAILURE;
|
||||
sf::Sprite background(backgroundImage);
|
||||
backgroundImage.SetSmooth(false);
|
||||
sf::Sprite background(backgroundTexture);
|
||||
|
||||
// Load a sprite which we'll move into the scene
|
||||
sf::Image entityImage;
|
||||
if (!entityImage.LoadFromFile("resources/sprite.png"))
|
||||
sf::Texture entityTexture;
|
||||
if (!entityTexture.LoadFromFile("resources/sprite.png"))
|
||||
return EXIT_FAILURE;
|
||||
sf::Sprite entity(entityImage);
|
||||
sf::Sprite entity(entityTexture);
|
||||
|
||||
// Load the text font
|
||||
sf::Font font;
|
||||
if (!font.LoadFromFile("resources/sansation.ttf"))
|
||||
return EXIT_FAILURE;
|
||||
|
||||
// Load the image needed for the wave shader
|
||||
sf::Image waveImage;
|
||||
if (!waveImage.LoadFromFile("resources/wave.jpg"))
|
||||
// Load the texture needed for the wave shader
|
||||
sf::Texture waveTexture;
|
||||
if (!waveTexture.LoadFromFile("resources/wave.jpg"))
|
||||
return EXIT_FAILURE;
|
||||
|
||||
// Load all shaders
|
||||
@ -138,7 +137,7 @@ int main()
|
||||
shaders["edge"].SetCurrentTexture("texture");
|
||||
shaders["fisheye"].SetCurrentTexture("texture");
|
||||
shaders["wave"].SetCurrentTexture("texture");
|
||||
shaders["wave"].SetTexture("wave", waveImage);
|
||||
shaders["wave"].SetTexture("wave", waveTexture);
|
||||
shaders["pixelate"].SetCurrentTexture("texture");
|
||||
|
||||
// Define a string for displaying the description of the current shader
|
||||
@ -211,19 +210,19 @@ int main()
|
||||
globalShader.Update(mouseX, mouseY);
|
||||
|
||||
// Animate the entity
|
||||
float entityX = (cos(clock.GetElapsedTime() * 0.0013f) + 1.2f) * 300;
|
||||
float entityY = (cos(clock.GetElapsedTime() * 0.0008f) + 1.2f) * 200;
|
||||
float entityX = (std::cos(clock.GetElapsedTime() * 0.0013f) + 1.2f) * 300;
|
||||
float entityY = (std::cos(clock.GetElapsedTime() * 0.0008f) + 1.2f) * 200;
|
||||
entity.SetPosition(entityX, entityY);
|
||||
entity.Rotate(window.GetFrameTime() * 0.1f);
|
||||
|
||||
// Draw the background and the moving entity to the render image
|
||||
image.Clear();
|
||||
image.Draw(background, backgroundShader.GetShader());
|
||||
image.Draw(entity, entityShader.GetShader());
|
||||
image.Display();
|
||||
// Draw the background and the moving entity to the render texture
|
||||
texture.Clear();
|
||||
texture.Draw(background, backgroundShader.GetShader());
|
||||
texture.Draw(entity, entityShader.GetShader());
|
||||
texture.Display();
|
||||
|
||||
// Draw the contents of the render image to the window
|
||||
sf::Sprite screen(image.GetImage());
|
||||
// Draw the contents of the render texture to the window
|
||||
sf::Sprite screen(texture.GetTexture());
|
||||
window.Draw(screen, globalShader.GetShader());
|
||||
|
||||
// Draw the interface texts
|
||||
|
@ -75,12 +75,12 @@ INT WINAPI WinMain(HINSTANCE instance, HINSTANCE, LPSTR, INT)
|
||||
sf::RenderWindow SFMLView1(view1);
|
||||
sf::RenderWindow SFMLView2(view2);
|
||||
|
||||
// Load some images to display
|
||||
sf::Image image1, image2;
|
||||
if (!image1.LoadFromFile("resources/image1.jpg") || !image2.LoadFromFile("resources/image2.jpg"))
|
||||
// Load some textures to display
|
||||
sf::Texture texture1, texture2;
|
||||
if (!texture1.LoadFromFile("resources/image1.jpg") || !texture2.LoadFromFile("resources/image2.jpg"))
|
||||
return EXIT_FAILURE;
|
||||
sf::Sprite sprite1(image1);
|
||||
sf::Sprite sprite2(image2);
|
||||
sf::Sprite sprite1(texture1);
|
||||
sf::Sprite sprite2(texture2);
|
||||
sprite1.SetOrigin(sprite1.GetSize() / 2.f);
|
||||
sprite1.SetPosition(sprite1.GetSize() / 2.f);
|
||||
|
||||
|
@ -52,16 +52,12 @@ public :
|
||||
Sound();
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Construct the sound with parameters
|
||||
/// \brief Construct the sound with a buffer
|
||||
///
|
||||
/// \param buffer Sound buffer containing the audio data to play with the sound
|
||||
/// \param loop Should the sound loop?
|
||||
/// \param pitch Pitch of the sound
|
||||
/// \param volume Volume of the sound, in the range [0, 100]
|
||||
/// \param position 3D position of the sound source in the audio scene
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
Sound(const SoundBuffer& buffer, bool loop = false, float pitch = 1.f, float volume = 100.f, const Vector3f& position = Vector3f(0, 0, 0));
|
||||
Sound(const SoundBuffer& buffer);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Copy constructor
|
||||
|
@ -301,8 +301,8 @@ private :
|
||||
/// The sound is then restituted by playing these samples at
|
||||
/// a high rate (for example, 44100 samples per second is the
|
||||
/// standard rate used for playing CDs). In short, audio samples
|
||||
/// are like image pixels, and a sf::SoundBuffer is similar to
|
||||
/// a sf::Image.
|
||||
/// are like texture pixels, and a sf::SoundBuffer is similar to
|
||||
/// a sf::Texture.
|
||||
///
|
||||
/// A sound buffer can be loaded from a file (see LoadFromFile()
|
||||
/// for the complete list of supported formats), from memory, from
|
||||
|
@ -35,12 +35,13 @@
|
||||
#include <SFML/Graphics/Glyph.hpp>
|
||||
#include <SFML/Graphics/Image.hpp>
|
||||
#include <SFML/Graphics/Renderer.hpp>
|
||||
#include <SFML/Graphics/RenderImage.hpp>
|
||||
#include <SFML/Graphics/RenderTexture.hpp>
|
||||
#include <SFML/Graphics/RenderWindow.hpp>
|
||||
#include <SFML/Graphics/Shader.hpp>
|
||||
#include <SFML/Graphics/Shape.hpp>
|
||||
#include <SFML/Graphics/Sprite.hpp>
|
||||
#include <SFML/Graphics/Text.hpp>
|
||||
#include <SFML/Graphics/Texture.hpp>
|
||||
#include <SFML/Graphics/View.hpp>
|
||||
|
||||
|
||||
|
@ -63,17 +63,6 @@ class SFML_API Drawable
|
||||
{
|
||||
public :
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Default constructor
|
||||
///
|
||||
/// \param position Position of the object
|
||||
/// \param scale Scale factor
|
||||
/// \param rotation Orientation, in degrees
|
||||
/// \param color Global color of the object
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
Drawable(const Vector2f& position = Vector2f(0, 0), const Vector2f& scale = Vector2f(1, 1), float rotation = 0.f, const Color& color = Color(255, 255, 255));
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Virtual destructor
|
||||
///
|
||||
@ -452,6 +441,12 @@ public :
|
||||
|
||||
protected :
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Default constructor
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
Drawable();
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Get the transform matrix of the object
|
||||
///
|
||||
@ -532,7 +527,7 @@ private :
|
||||
/// \li transformations (position, rotation, scale, local origin)
|
||||
/// \li global overlay color
|
||||
/// \li blending mode with background pixels
|
||||
/// \li the ability to be drawn on a sf::RenderTarget (either RenderWindow or RenderImage)
|
||||
/// \li the ability to be drawn on a sf::RenderTarget (either RenderWindow or RenderTexture)
|
||||
///
|
||||
/// Please note that all these attributes are hardware accelerated,
|
||||
/// therefore they are extremely cheap to use (unlike older
|
||||
@ -591,7 +586,7 @@ private :
|
||||
/// target.Draw(mySubSprite);
|
||||
/// }
|
||||
///
|
||||
/// sf::Image myTexture;
|
||||
/// sf::Texture myTexture;
|
||||
/// sf::Sprite mySubSprite;
|
||||
/// };
|
||||
/// \endcode
|
||||
|
@ -32,7 +32,7 @@
|
||||
#include <SFML/System/Vector2.hpp>
|
||||
#include <SFML/System/String.hpp>
|
||||
#include <SFML/Graphics/Glyph.hpp>
|
||||
#include <SFML/Graphics/Image.hpp>
|
||||
#include <SFML/Graphics/Texture.hpp>
|
||||
#include <SFML/Graphics/Rect.hpp>
|
||||
#include <map>
|
||||
#include <string>
|
||||
@ -174,18 +174,18 @@ public :
|
||||
int GetLineSpacing(unsigned int characterSize) const;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Retrieve the image containing the loaded glyphs of a certain size
|
||||
/// \brief Retrieve the texture containing the loaded glyphs of a certain size
|
||||
///
|
||||
/// The contents of the returned image changes as more glyphs
|
||||
/// The contents of the returned texture changes as more glyphs
|
||||
/// are requested, thus it is not very relevant. It is mainly
|
||||
/// used internally by sf::Text.
|
||||
///
|
||||
/// \param characterSize Reference character size
|
||||
///
|
||||
/// \return Image containing the glyphs of the requested size
|
||||
/// \return Texture containing the glyphs of the requested size
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
const Image& GetImage(unsigned int characterSize) const;
|
||||
const Texture& GetTexture(unsigned int characterSize) const;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Overload of assignment operator
|
||||
@ -240,8 +240,8 @@ private :
|
||||
Page();
|
||||
|
||||
GlyphTable Glyphs; ///< Table mapping code points to their corresponding glyph
|
||||
Image Texture; ///< Image containing the pixels of the glyphs
|
||||
unsigned int NextRow; ///< Y position of the next new row in the image
|
||||
Texture Texture; ///< Texture containing the pixels of the glyphs
|
||||
unsigned int NextRow; ///< Y position of the next new row in the texture
|
||||
std::vector<Row> Rows; ///< List containing the position of all the existing rows
|
||||
};
|
||||
|
||||
@ -288,7 +288,7 @@ private :
|
||||
////////////////////////////////////////////////////////////
|
||||
// Types
|
||||
////////////////////////////////////////////////////////////
|
||||
typedef std::map<unsigned int, Page> PageTable; ///< Table mapping a character size to its page (image)
|
||||
typedef std::map<unsigned int, Page> PageTable; ///< Table mapping a character size to its page (texture)
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Member data
|
||||
|
@ -53,7 +53,7 @@ public :
|
||||
////////////////////////////////////////////////////////////
|
||||
int Advance; ///< Offset to move horizontically to the next character
|
||||
IntRect Bounds; ///< Bounding rectangle of the glyph, in coordinates relative to the baseline
|
||||
IntRect SubRect; ///< Texture coordinates of the glyph inside the font's image
|
||||
IntRect SubRect; ///< Texture coordinates of the glyph inside the font's texture
|
||||
};
|
||||
|
||||
} // namespace sf
|
||||
@ -70,7 +70,7 @@ public :
|
||||
///
|
||||
/// The sf::Glyph structure provides the information needed
|
||||
/// to handle the glyph:
|
||||
/// \li its coordinates in the font's image
|
||||
/// \li its coordinates in the font's texture
|
||||
/// \li its bounding rect
|
||||
/// \li the offset to apply to get the starting position of the next glyph
|
||||
///
|
||||
|
@ -29,7 +29,6 @@
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/System/Resource.hpp>
|
||||
#include <SFML/Window/GlResource.hpp>
|
||||
#include <SFML/Graphics/Color.hpp>
|
||||
#include <SFML/Graphics/Rect.hpp>
|
||||
#include <string>
|
||||
@ -38,16 +37,13 @@
|
||||
|
||||
namespace sf
|
||||
{
|
||||
class Renderer;
|
||||
class RenderImage;
|
||||
class RenderWindow;
|
||||
class InputStream;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Class for loading, manipulating and saving images
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
class SFML_API Image : public Resource<Image>, GlResource
|
||||
class SFML_API Image
|
||||
{
|
||||
public :
|
||||
|
||||
@ -60,18 +56,29 @@ public :
|
||||
Image();
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Copy constructor
|
||||
/// \brief Create the image and fill it with a unique color
|
||||
///
|
||||
/// \param copy instance to copy
|
||||
/// \param width Width of the image
|
||||
/// \param height Height of the image
|
||||
/// \param color Fill color
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
Image(const Image& copy);
|
||||
void Create(unsigned int width, unsigned int height, const Color& color = Color(0, 0, 0));
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Destructor
|
||||
/// \brief Create the image from an arry of pixels
|
||||
///
|
||||
/// The \a pixels array is assumed to contain 32-bits RGBA pixels,
|
||||
/// and have the given \a width and \a height. If not, this is
|
||||
/// an undefined behaviour.
|
||||
/// If \a pixels is null, an empty image is created.
|
||||
///
|
||||
/// \param width Width of the image
|
||||
/// \param height Height of the image
|
||||
/// \param pixels Array of pixels to copy to the image
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
~Image();
|
||||
void Create(unsigned int width, unsigned int height, const Uint8* pixels);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Load the image from a file on disk
|
||||
@ -79,15 +86,13 @@ public :
|
||||
/// The supported image formats are bmp, png, tga, jpg, gif,
|
||||
/// psd, hdr and pic. Some format options are not supported,
|
||||
/// like progressive jpeg.
|
||||
/// The maximum size for an image depends on the graphics
|
||||
/// driver and can be retrieve with the GetMaximumSize function.
|
||||
/// If this function fails, the image is left unchanged.
|
||||
///
|
||||
/// \param filename Path of the image file to load
|
||||
///
|
||||
/// \return True if loading was successful
|
||||
///
|
||||
/// \see LoadFromMemory, LoadFromStream, LoadFromPixels, SaveToFile
|
||||
/// \see LoadFromMemory, LoadFromStream, SaveToFile
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
bool LoadFromFile(const std::string& filename);
|
||||
@ -98,8 +103,6 @@ public :
|
||||
/// The supported image formats are bmp, png, tga, jpg, gif,
|
||||
/// psd, hdr and pic. Some format options are not supported,
|
||||
/// like progressive jpeg.
|
||||
/// The maximum size for an image depends on the graphics
|
||||
/// driver and can be retrieve with the GetMaximumSize function.
|
||||
/// If this function fails, the image is left unchanged.
|
||||
///
|
||||
/// \param data Pointer to the file data in memory
|
||||
@ -107,7 +110,7 @@ public :
|
||||
///
|
||||
/// \return True if loading was successful
|
||||
///
|
||||
/// \see LoadFromFile, LoadFromStream, LoadFromPixels
|
||||
/// \see LoadFromFile, LoadFromStream
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
bool LoadFromMemory(const void* data, std::size_t size);
|
||||
@ -126,30 +129,11 @@ public :
|
||||
///
|
||||
/// \return True if loading was successful
|
||||
///
|
||||
/// \see LoadFromFile, LoadFromMemory, LoadFromPixels
|
||||
/// \see LoadFromFile, LoadFromMemory
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
bool LoadFromStream(InputStream& stream);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Load the image from an array of pixels
|
||||
///
|
||||
/// The \a pixels argument must point to an array of 32 bits
|
||||
/// RGBA pixels. In other words, the pixel array must have
|
||||
/// this memory layout: [r0 g0 b0 a0 r1 g1 b1 a1 r2...]
|
||||
/// If this function fails, the image is left unchanged.
|
||||
///
|
||||
/// \param width Width of the image
|
||||
/// \param height Height of the image
|
||||
/// \param pixels Pointer to the pixels in memory
|
||||
///
|
||||
/// \return True if loading was successful
|
||||
///
|
||||
/// \see LoadFromFile, LoadFromMemory, SaveToFile
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
bool LoadFromPixels(unsigned int width, unsigned int height, const Uint8* pixels);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Save the image to a file on disk
|
||||
///
|
||||
@ -162,27 +146,33 @@ public :
|
||||
///
|
||||
/// \return True if saving was successful
|
||||
///
|
||||
/// \see LoadFromFile, LoadFromMemory, LoadFromPixels
|
||||
/// \see Create, LoadFromFile, LoadFromMemory
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
bool SaveToFile(const std::string& filename) const;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Create the image and fill it with a unique color
|
||||
/// \brief Return the width of the image
|
||||
///
|
||||
/// If this function fails, the image is left unchanged.
|
||||
/// \return Width in pixels
|
||||
///
|
||||
/// \param width Width of the image
|
||||
/// \param height Height of the image
|
||||
/// \param color Fill color
|
||||
///
|
||||
/// \return True if creation was successful
|
||||
/// \see GetHeight
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
bool Create(unsigned int width, unsigned int height, const Color& color = Color(0, 0, 0));
|
||||
unsigned int GetWidth() const;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Create a transparency mask from a specified colorkey
|
||||
/// \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
|
||||
///
|
||||
/// This function sets the alpha value of every pixel matching
|
||||
/// the given color to \a alpha (0 by default), so that they
|
||||
@ -197,11 +187,11 @@ public :
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Copy pixels from another image onto this one
|
||||
///
|
||||
/// This function does a slow pixel copy and should only
|
||||
/// be used at initialization time. It can be used to prepare
|
||||
/// a complex static image from several others, but if you
|
||||
/// need this kind of feature in real-time you'd better use
|
||||
/// sf::RenderImage.
|
||||
/// This function does a slow pixel copy and should not be
|
||||
/// used intensively. It can be used to prepare a complex
|
||||
/// static image from several others, but if you need this
|
||||
/// kind of feature in real-time you'd better use sf::RenderTexture.
|
||||
///
|
||||
/// If \a sourceRect is empty, the whole image is copied.
|
||||
/// If \a applyAlpha is set to true, the transparency of
|
||||
/// source pixels is applied. If it is false, the pixels are
|
||||
@ -216,22 +206,6 @@ public :
|
||||
////////////////////////////////////////////////////////////
|
||||
void Copy(const Image& source, unsigned int destX, unsigned int destY, const IntRect& sourceRect = IntRect(0, 0, 0, 0), bool applyAlpha = false);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Copy the contents of a window to the image
|
||||
///
|
||||
/// If \a sourceRect is empty, the whole window is copied.
|
||||
/// Warning: this is a slow operation, if you need to draw
|
||||
/// dynamic contents to an image then use sf::RenderImage.
|
||||
/// If this function fails, the image is left unchanged.
|
||||
///
|
||||
/// \param window Window to capture
|
||||
/// \param sourceRect Sub-rectangle of the screen to copy
|
||||
///
|
||||
/// \return True if copy was successful
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
bool CopyScreen(RenderWindow& window, const IntRect& sourceRect = IntRect(0, 0, 0, 0));
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Change the color of a pixel
|
||||
///
|
||||
@ -273,207 +247,19 @@ public :
|
||||
/// modify the image, so you should never store it for too long.
|
||||
/// If the image is empty, a null pointer is returned.
|
||||
///
|
||||
/// \return Const pointer to the array of pixels
|
||||
/// \return Read-only pointer to the array of pixels
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
const Uint8* GetPixelsPtr() const;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Update the whole image from an array of pixels
|
||||
///
|
||||
/// The \a pixels array is assumed to have the same size as
|
||||
/// the image, and to store RGBA 32 bits pixels.
|
||||
/// See the other overload of this function to update only
|
||||
/// a sub-rectangle of the image.
|
||||
/// This function does nothing if \a pixels is null.
|
||||
///
|
||||
/// \param pixels Array of pixels to write to the image
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
void UpdatePixels(const Uint8* pixels);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Update a sub-rectangle of the image from an array of pixels
|
||||
///
|
||||
/// The \a pixels array is assumed to store RGBA 32 bits pixels.
|
||||
/// Warning: for performances reasons, this function doesn't
|
||||
/// perform any check; thus you're responsible of ensuring that
|
||||
/// \a rectangle does not exceed the image size, and that
|
||||
/// \a pixels contains enough elements.
|
||||
/// This function does nothing if \a pixels is null.
|
||||
/// See the other overload of this function to update the
|
||||
/// whole image.
|
||||
///
|
||||
/// \param rectangle Sub-rectangle of the image to update
|
||||
/// \param pixels Array of pixels to write to the image
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
void UpdatePixels(const Uint8* pixels, const IntRect& rectangle);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Activate the image for rendering
|
||||
///
|
||||
/// This function is mainly used internally by the SFML
|
||||
/// render system. However it can be useful when
|
||||
/// using sf::Image together with OpenGL code (it calls
|
||||
/// glBindTexture).
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
void Bind() const;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Enable or disable the smooth filter
|
||||
///
|
||||
/// When the filter is activated, the image appears smoother
|
||||
/// so that pixels are less noticeable. However if you want
|
||||
/// the image to look exactly the same as its source file, you
|
||||
/// should disable it.
|
||||
/// The smooth filter is disabled by default.
|
||||
///
|
||||
/// \param smooth True to enable smoothing, false to disable it
|
||||
///
|
||||
/// \see IsSmooth
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
void SetSmooth(bool smooth);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Tell whether the smooth filter is enabled or not
|
||||
///
|
||||
/// \return True if smoothing is enabled, false if it is disabled
|
||||
///
|
||||
/// \see SetSmooth
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
bool IsSmooth() const;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Return the width of the image
|
||||
///
|
||||
/// \return Width in pixels
|
||||
///
|
||||
/// \see GetHeight
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
unsigned int GetWidth() const;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Return the height of the image
|
||||
///
|
||||
/// \return Height in pixels
|
||||
///
|
||||
/// \see GetWidth
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
unsigned int GetHeight() const;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Convert a rectangle of pixels into texture coordinates
|
||||
///
|
||||
/// This function is used by code that needs to map the image
|
||||
/// to some OpenGL geometry. It converts the source rectangle,
|
||||
/// expressed in pixels, to float coordinates in the range [0, 1].
|
||||
///
|
||||
/// \param rectangle Rectangle to convert
|
||||
///
|
||||
/// \return Texture coordinates corresponding to \a rectangle
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
FloatRect GetTexCoords(const IntRect& rectangle) const;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Get the maximum image size allowed
|
||||
///
|
||||
/// This maximum size is defined by the graphics driver.
|
||||
/// You can expect a value of 512 pixels for low-end graphics
|
||||
/// card, and up to 8192 pixels for newer hardware.
|
||||
///
|
||||
/// \return Maximum size allowed for images, in pixels
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
static unsigned int GetMaximumSize();
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Overload of assignment operator
|
||||
///
|
||||
/// \param right Instance to assign
|
||||
///
|
||||
/// \return Reference to self
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
Image& operator =(const Image& right);
|
||||
|
||||
private :
|
||||
|
||||
friend class Renderer;
|
||||
friend class RenderImage;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Get a valid image size according to hardware support
|
||||
///
|
||||
/// This function checks whether the graphics driver supports
|
||||
/// non power of two sizes or not, and adjusts the size
|
||||
/// accordingly.
|
||||
/// The returned size is greater than or equal to the original size.
|
||||
///
|
||||
/// \param Size size to convert
|
||||
///
|
||||
/// \return Valid nearest size (greater than or equal to specified size)
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
static unsigned int GetValidSize(unsigned int size);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Create the OpenGL texture
|
||||
///
|
||||
/// If this function fails, the image's members are left unchanged.
|
||||
///
|
||||
/// \param width Texture width
|
||||
/// \param height Texture height
|
||||
///
|
||||
/// \return True if texture was successfully created, false if it failed
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
bool CreateTexture(unsigned int width, unsigned int height);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Make sure that the texture in video memory is
|
||||
/// synchronized with the pixels cache
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
void EnsureTextureUpdate() const;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Make sure the pixels cache is synchronized with
|
||||
/// the texture in video memory
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
void EnsureArrayUpdate() const;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Make sure that the image is ready to be used
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
void Use() const;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Types
|
||||
////////////////////////////////////////////////////////////
|
||||
typedef std::vector<Uint8> ColorArray; ///< Array of colors
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Member data
|
||||
////////////////////////////////////////////////////////////
|
||||
unsigned int myWidth; ///< Image width
|
||||
unsigned int myHeight; ///< Image Height
|
||||
unsigned int myTextureWidth; ///< Actual texture width (can be greater than image width because of padding)
|
||||
unsigned int myTextureHeight; ///< Actual texture height (can be greater than image height because of padding)
|
||||
unsigned int myTexture; ///< Internal texture identifier
|
||||
bool myIsSmooth; ///< Status of the smooth filter
|
||||
mutable ColorArray myPixels; ///< Pixels of the image
|
||||
mutable bool myTextureUpdated; ///< Status of synchronization between pixels in central memory and the internal texture un video memory
|
||||
mutable bool myArrayUpdated; ///< Status of synchronization between pixels in central memory and the internal texture un video memory
|
||||
mutable bool myPixelsFlipped; ///< To work around the inconsistency in Y orientation
|
||||
std::vector<Uint8> myPixels; ///< Pixels of the image
|
||||
};
|
||||
|
||||
} // namespace sf
|
||||
@ -489,7 +275,7 @@ private :
|
||||
/// sf::Image is an abstraction to manipulate images
|
||||
/// as bidimensional arrays of pixels. The class provides
|
||||
/// functions to load, read, write and save pixels, as well
|
||||
/// as many other useful functions to...
|
||||
/// as many other useful functions.
|
||||
///
|
||||
/// sf::Image can handle a unique internal representation of
|
||||
/// pixels, which is RGBA 32 bits. This means that a pixel
|
||||
@ -497,8 +283,8 @@ private :
|
||||
/// channels -- just like a sf::Color.
|
||||
/// All the functions that return an array of pixels follow
|
||||
/// this rule, and all parameters that you pass to sf::Image
|
||||
/// functions (such as LoadFromPixels or UpdatePixels) must
|
||||
/// use this representation as well.
|
||||
/// functions (such as LoadFromPixels) must use this
|
||||
/// representation as well.
|
||||
///
|
||||
/// A sf::Image can be copied, but it is a heavy resource and
|
||||
/// if possible you should always use [const] references to
|
||||
@ -506,7 +292,7 @@ private :
|
||||
///
|
||||
/// Usage example:
|
||||
/// \code
|
||||
/// // Load an image file
|
||||
/// // Load an image file from a file
|
||||
/// sf::Image background;
|
||||
/// if (!background.LoadFromFile("background.jpg"))
|
||||
/// return -1;
|
||||
@ -529,6 +315,6 @@ private :
|
||||
/// return -1;
|
||||
/// \endcode
|
||||
///
|
||||
/// \see sf::Sprite
|
||||
/// \see sf::Texture
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
|
@ -41,7 +41,7 @@ class Drawable;
|
||||
class Shader;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Base class for all render targets (window, image, ...)
|
||||
/// \brief Base class for all render targets (window, texture, ...)
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
class SFML_API RenderTarget : NonCopyable
|
||||
@ -331,6 +331,6 @@ private :
|
||||
/// OpenGL states are not messed up by calling the SaveGLStates /
|
||||
/// RestoreGLStates functions.
|
||||
///
|
||||
/// \see sf::RenderWindow, sf::RenderImage, sf::View
|
||||
/// \see sf::RenderWindow, sf::RenderTexture, sf::View
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
|
@ -22,13 +22,13 @@
|
||||
//
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef SFML_RENDERIMAGE_HPP
|
||||
#define SFML_RENDERIMAGE_HPP
|
||||
#ifndef SFML_RENDERTEXTURE_HPP
|
||||
#define SFML_RENDERTEXTURE_HPP
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/Graphics/Image.hpp>
|
||||
#include <SFML/Graphics/Texture.hpp>
|
||||
#include <SFML/Graphics/RenderTarget.hpp>
|
||||
|
||||
|
||||
@ -36,48 +36,48 @@ namespace sf
|
||||
{
|
||||
namespace priv
|
||||
{
|
||||
class RenderImageImpl;
|
||||
class RenderTextureImpl;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Target for off-screen 2D rendering into an image
|
||||
/// \brief Target for off-screen 2D rendering into an texture
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
class SFML_API RenderImage : public RenderTarget
|
||||
class SFML_API RenderTexture : public RenderTarget
|
||||
{
|
||||
public :
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Default constructor
|
||||
///
|
||||
/// Constructs an empty, invalid render-image. You must
|
||||
/// call Create to have a valid render-image.
|
||||
/// Constructs an empty, invalid render-texture. You must
|
||||
/// call Create to have a valid render-texture.
|
||||
///
|
||||
/// \see Create
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
RenderImage();
|
||||
RenderTexture();
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Destructor
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
virtual ~RenderImage();
|
||||
virtual ~RenderTexture();
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Create the render-image
|
||||
/// \brief Create the render-texture
|
||||
///
|
||||
/// Before calling this function, the render-image is in
|
||||
/// Before calling this function, the render-texture is in
|
||||
/// an invalid state, thus it is mandatory to call it before
|
||||
/// doing anything with the render-image.
|
||||
/// doing anything with the render-texture.
|
||||
/// The last parameter, \a depthBuffer, is useful if you want
|
||||
/// to use the render-image for 3D OpenGL rendering that requires
|
||||
/// to use the render-texture for 3D OpenGL rendering that requires
|
||||
/// a depth-buffer. Otherwise it is unnecessary, and you should
|
||||
/// leave this parameter to false (which is its default value).
|
||||
///
|
||||
/// \param width Width of the render-image
|
||||
/// \param height Height of the render-image
|
||||
/// \param depthBuffer Do you want this render-image to have a depth buffer?
|
||||
/// \param width Width of the render-texture
|
||||
/// \param height Height of the render-texture
|
||||
/// \param depthBuffer Do you want this render-texture to have a depth buffer?
|
||||
///
|
||||
/// \return True if creation has been successful
|
||||
///
|
||||
@ -85,9 +85,9 @@ public :
|
||||
bool Create(unsigned int width, unsigned int height, bool depthBuffer = false);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Enable or disable image smoothing
|
||||
/// \brief Enable or disable texture smoothing
|
||||
///
|
||||
/// This function is similar to Image::SetSmooth.
|
||||
/// This function is similar to Texture::SetSmooth.
|
||||
/// This parameter is enabled by default.
|
||||
///
|
||||
/// \param smooth True to enable smoothing, false to disable it
|
||||
@ -100,7 +100,7 @@ public :
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Tell whether the smooth filtering is enabled or not
|
||||
///
|
||||
/// \return True if image smoothing is enabled
|
||||
/// \return True if texture smoothing is enabled
|
||||
///
|
||||
/// \see SetSmooth
|
||||
///
|
||||
@ -108,12 +108,12 @@ public :
|
||||
bool IsSmooth() const;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Activate of deactivate the render-image for rendering
|
||||
/// \brief Activate of deactivate the render-texture for rendering
|
||||
///
|
||||
/// This function makes the render-image's context current for
|
||||
/// This function makes the render-texture's context current for
|
||||
/// future OpenGL rendering operations (so you shouldn't care
|
||||
/// about it if you're not doing direct OpenGL stuff).
|
||||
/// Only one context can be current on a thread, so if you
|
||||
/// Only one context can be current in a thread, so if you
|
||||
/// want to draw OpenGL geometry to another render target
|
||||
/// (like a RenderWindow) don't forget to activate it again.
|
||||
///
|
||||
@ -125,18 +125,18 @@ public :
|
||||
bool SetActive(bool active = true);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Update the contents of the target image
|
||||
/// \brief Update the contents of the target texture
|
||||
///
|
||||
/// This function updates the target image with what
|
||||
/// This function updates the target texture with what
|
||||
/// has been drawn so far. Like for windows, calling this
|
||||
/// function is mandatory at the end of rendering. Not calling
|
||||
/// it may leave the image in an undefined state.
|
||||
/// it may leave the texture in an undefined state.
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
void Display();
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Return the width of the rendering region of the image
|
||||
/// \brief Return the width of the rendering region of the texture
|
||||
///
|
||||
/// The returned value is the size that you passed to
|
||||
/// the Create function.
|
||||
@ -149,7 +149,7 @@ public :
|
||||
virtual unsigned int GetWidth() const;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Return the height of the rendering region of the image
|
||||
/// \brief Return the height of the rendering region of the texture
|
||||
///
|
||||
/// The returned value is the size that you passed to
|
||||
/// the Create function.
|
||||
@ -162,25 +162,25 @@ public :
|
||||
virtual unsigned int GetHeight() const;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Get a read-only reference to the target image
|
||||
/// \brief Get a read-only reference to the target texture
|
||||
///
|
||||
/// After drawing to the render-image and calling Display,
|
||||
/// you can retrieve the updated image using this function,
|
||||
/// After drawing to the render-texture and calling Display,
|
||||
/// you can retrieve the updated texture using this function,
|
||||
/// and draw it using a sprite (for example).
|
||||
/// The internal sf::Image of a render-image is always the
|
||||
/// The internal sf::Texture of a render-texture is always the
|
||||
/// same instance, so that it is possible to call this function
|
||||
/// once and keep a reference to the image even after is it
|
||||
/// once and keep a reference to the texture even after it is
|
||||
/// modified.
|
||||
///
|
||||
/// \return Const reference to the image
|
||||
/// \return Const reference to the texture
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
const Image& GetImage() const;
|
||||
const Texture& GetTexture() const;
|
||||
|
||||
private :
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Activate the targt efor rendering
|
||||
/// \brief Activate the target for rendering
|
||||
///
|
||||
/// This function is called by the base class
|
||||
/// everytime it's going to use OpenGL calls.
|
||||
@ -195,28 +195,28 @@ private :
|
||||
////////////////////////////////////////////////////////////
|
||||
// Member data
|
||||
////////////////////////////////////////////////////////////
|
||||
Image myImage; ///< Target image to draw on
|
||||
priv::RenderImageImpl* myRenderImage; ///< Platform / hardware specific implementation
|
||||
Texture myTexture; ///< Target texture to draw on
|
||||
priv::RenderTextureImpl* myRenderTexture; ///< Platform/hardware specific implementation
|
||||
};
|
||||
|
||||
} // namespace sf
|
||||
|
||||
|
||||
#endif // SFML_RENDERIMAGE_HPP
|
||||
#endif // SFML_RENDERTEXTURE_HPP
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \class sf::RenderImage
|
||||
/// \class sf::RenderTexture
|
||||
/// \ingroup graphics
|
||||
///
|
||||
/// sf::RenderImage is the little brother of sf::RenderWindow.
|
||||
/// sf::RenderTexture is the little brother of sf::RenderWindow.
|
||||
/// It implements the same 2D drawing and OpenGL-related functions
|
||||
/// (see their base class sf::RenderTarget for more details),
|
||||
/// the difference is that the result is stored in an off-screen
|
||||
/// image rather than being show in a window.
|
||||
/// texture rather than being show in a window.
|
||||
///
|
||||
/// Rendering to an image can be useful in a variety of situations:
|
||||
/// \li precomputing a complex static image (like a level's background from multiple tiles)
|
||||
/// Rendering to a texture can be useful in a variety of situations:
|
||||
/// \li precomputing a complex static texture (like a level's background from multiple tiles)
|
||||
/// \li applying post-effects to the whole scene with shaders
|
||||
/// \li creating a sprite from a 3D object rendered with OpenGL
|
||||
/// \li etc.
|
||||
@ -224,16 +224,12 @@ private :
|
||||
/// Usage example:
|
||||
///
|
||||
/// \code
|
||||
/// // First of all: make sure that rendering to image is supported
|
||||
/// if (!sf::RenderImage::IsAvailable())
|
||||
/// return -1;
|
||||
///
|
||||
/// // Create a new render-window
|
||||
/// sf::RenderWindow window(sf::VideoMode(800, 600), "SFML window");
|
||||
///
|
||||
/// // Create a new render-image
|
||||
/// sf::RenderImage image;
|
||||
/// if (!image.Create(500, 500))
|
||||
/// // Create a new render-texture
|
||||
/// sf::RenderTexture texture;
|
||||
/// if (!texture.Create(500, 500))
|
||||
/// return -1
|
||||
///
|
||||
/// // The main loop
|
||||
@ -242,22 +238,22 @@ private :
|
||||
/// // Event processing
|
||||
/// // ...
|
||||
///
|
||||
/// // Clear the whole image with red color
|
||||
/// image.Clear(sf::Color::Red);
|
||||
/// // Clear the whole texture with red color
|
||||
/// texture.Clear(sf::Color::Red);
|
||||
///
|
||||
/// // Draw stuff to the image
|
||||
/// image.Draw(sprite); // sprite is a sf::Sprite
|
||||
/// image.Draw(shape); // shape is a sf::Shape
|
||||
/// image.Draw(text); // text is a sf::Text
|
||||
/// // Draw stuff to the texture
|
||||
/// texture.Draw(sprite); // sprite is a sf::Sprite
|
||||
/// texture.Draw(shape); // shape is a sf::Shape
|
||||
/// texture.Draw(text); // text is a sf::Text
|
||||
///
|
||||
/// // We're done drawing to the image
|
||||
/// image.Display();
|
||||
/// // We're done drawing to the texture
|
||||
/// texture.Display();
|
||||
///
|
||||
/// // Now we start rendering to the window, clear it first
|
||||
/// window.Clear();
|
||||
///
|
||||
/// // Draw the image
|
||||
/// sf::Sprite sprite(image.GetImage());
|
||||
/// // Draw the texture
|
||||
/// sf::Sprite sprite(texture.GetTexture());
|
||||
/// window.Draw(sprite);
|
||||
///
|
||||
/// // End the current frame and display its contents on screen
|
||||
@ -265,11 +261,11 @@ private :
|
||||
/// }
|
||||
/// \endcode
|
||||
///
|
||||
/// Like sf::RenderWindow, sf::RenderImage is still able to render direct
|
||||
/// Like sf::RenderWindow, sf::RenderTexture is still able to render direct
|
||||
/// OpenGL stuff. It is even possible to mix together OpenGL calls
|
||||
/// and regular SFML drawing commands. If you need a depth buffer for
|
||||
/// 3D rendering, don't forget to request it when calling RenderImage::Create.
|
||||
/// 3D rendering, don't forget to request it when calling RenderTexture::Create.
|
||||
///
|
||||
/// \see sf::RenderTarget, sf::RenderWindow, sf::View
|
||||
/// \see sf::RenderTarget, sf::RenderWindow, sf::View, sf::Texture
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
@ -28,8 +28,8 @@
|
||||
////////////////////////////////////////////////////////////
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/Graphics/Image.hpp>
|
||||
#include <SFML/Graphics/RenderTarget.hpp>
|
||||
#include <SFML/Graphics/Image.hpp>
|
||||
#include <SFML/Window/Window.hpp>
|
||||
#include <string>
|
||||
|
||||
@ -125,6 +125,22 @@ public :
|
||||
////////////////////////////////////////////////////////////
|
||||
virtual unsigned int GetHeight() const;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Copy the current contents of the window to an image
|
||||
///
|
||||
/// This is a slow operation, whose main purpose is to make
|
||||
/// screenshots of the application. If you want to update an
|
||||
/// image with the contents of the window and then use it for
|
||||
/// drawing, you should rather use a sf::Texture and its
|
||||
/// Update(Window&) function.
|
||||
/// You can also draw things directly to a texture with the
|
||||
/// sf::RenderTexture class.
|
||||
///
|
||||
/// \return Image containing the captured contents
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
Image Capture() const;
|
||||
|
||||
private :
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
@ -260,6 +276,6 @@ private :
|
||||
/// }
|
||||
/// \endcode
|
||||
///
|
||||
/// \see sf::Window, sf::RenderTarget, sf::RenderImage, sf::View
|
||||
/// \see sf::Window, sf::RenderTarget, sf::RenderTexture, sf::View
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
|
@ -38,8 +38,8 @@
|
||||
|
||||
namespace sf
|
||||
{
|
||||
class Image;
|
||||
class Shader;
|
||||
class Texture;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Handles the low-level rendering (states and geometry)
|
||||
@ -120,9 +120,6 @@ public :
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Set a new model-view matrix
|
||||
///
|
||||
/// Note: any call to this function after a call to BeginBatch
|
||||
/// will be ignored, and delayed until BeginBatch is called again.
|
||||
///
|
||||
/// \param matrix New model-view matrix
|
||||
///
|
||||
/// \see ApplyModelView
|
||||
@ -133,9 +130,6 @@ public :
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Combine a new model-view matrix with the current one
|
||||
///
|
||||
/// Note: any call to this function after a call to BeginBatch
|
||||
/// will be ignored, and delayed until BeginBatch is called again.
|
||||
///
|
||||
/// \param matrix Model-view matrix to combine
|
||||
///
|
||||
/// \see SetModelView
|
||||
@ -146,9 +140,6 @@ public :
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Set a new projection matrix
|
||||
///
|
||||
/// Note: any call to this function after a call to BeginBatch
|
||||
/// will be ignored, and delayed until BeginBatch is called again.
|
||||
///
|
||||
/// \param matrix New projection matrix
|
||||
///
|
||||
/// \see ApplyProjection
|
||||
@ -160,8 +151,6 @@ public :
|
||||
/// \brief Set the current global color
|
||||
///
|
||||
/// This color will be modulated with each vertex's color.
|
||||
/// Note: any call to this function after a call to BeginBatch
|
||||
/// will be ignored, and delayed until BeginBatch is called again.
|
||||
///
|
||||
/// \param color New global color
|
||||
///
|
||||
@ -174,8 +163,6 @@ public :
|
||||
/// \brief Modulate the current global color with a new one
|
||||
///
|
||||
/// This color will be modulated with each vertex's color.
|
||||
/// Note: any call to this function after a call to BeginBatch
|
||||
/// will be ignored, and delayed until BeginBatch is called again.
|
||||
///
|
||||
/// \param color Color to modulate
|
||||
///
|
||||
@ -187,9 +174,6 @@ public :
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Set the current viewport
|
||||
///
|
||||
/// Note: any call to this function after a call to BeginBatch
|
||||
/// will be ignored, and delayed until BeginBatch is called again.
|
||||
///
|
||||
/// \param viewport New viewport to apply
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
@ -198,9 +182,6 @@ public :
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Set the current alpha-blending mode
|
||||
///
|
||||
/// Note: any call to this function after a call to BeginBatch
|
||||
/// will be ignored, and delayed until BeginBatch is called again.
|
||||
///
|
||||
/// \param mode New blending mode
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
@ -209,20 +190,14 @@ public :
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Set the current texture
|
||||
///
|
||||
/// Note: any call to this function after a call to BeginBatch
|
||||
/// will be ignored, and delayed until BeginBatch is called again.
|
||||
///
|
||||
/// \param texture New texture
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
void SetTexture(const Image* texture);
|
||||
void SetTexture(const Texture* texture);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Set the current shader
|
||||
///
|
||||
/// Note: any call to this function after a call to BeginBatch
|
||||
/// will be ignored, and delayed until BeginBatch is called again.
|
||||
///
|
||||
/// \param shader New Shader
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
@ -349,8 +324,8 @@ private :
|
||||
RenderTarget& myTarget; ///< Reference to the render target owning this renderer
|
||||
States myStatesStack[64]; ///< Stack of render states
|
||||
States* myStates; ///< Current set of render states
|
||||
const Image* myTexture; ///< Current texture
|
||||
unsigned int myTextureId; ///< Current texture identifier (the sf::Image instance may be the same, but not the internal OpenGL texture)
|
||||
const Texture* myTexture; ///< Current texture
|
||||
unsigned int myTextureId; ///< Current texture identifier (the sf::Texture instance may be the same, but not the internal OpenGL texture)
|
||||
const Shader* myShader; ///< Current pixel shader
|
||||
Blend::Mode myBlendMode; ///< Current blending mode
|
||||
IntRect myViewport; ///< Current target viewport
|
||||
|
@ -29,7 +29,7 @@
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/Config.hpp>
|
||||
#include <SFML/Graphics/Image.hpp>
|
||||
#include <SFML/Graphics/Texture.hpp>
|
||||
#include <SFML/Window/GlResource.hpp>
|
||||
#include <SFML/System/Vector2.hpp>
|
||||
#include <SFML/System/Vector3.hpp>
|
||||
@ -253,35 +253,35 @@ public :
|
||||
/// \brief Change a texture parameter of the shader
|
||||
///
|
||||
/// \a name is the name of the texture to change in the shader.
|
||||
/// This function maps an external image to the texture variable;
|
||||
/// to use the current texture of the object being drawn, use
|
||||
/// SetCurrentTexture instead.
|
||||
/// This function maps an external texture to the given shader
|
||||
/// variable; to use the current texture of the object being drawn,
|
||||
/// use SetCurrentTexture instead.
|
||||
/// Example:
|
||||
/// \code
|
||||
/// // These are the variables in the pixel shader
|
||||
/// uniform sampler2D texture;
|
||||
/// uniform sampler2D the_texture;
|
||||
/// \endcode
|
||||
/// \code
|
||||
/// sf::Image image;
|
||||
/// sf::Texture texture;
|
||||
/// ...
|
||||
/// shader.SetTexture("texture", image);
|
||||
/// shader.SetTexture("the_texture", texture);
|
||||
/// \endcode
|
||||
/// It is important to note that \a texture must remain alive as long
|
||||
/// as the shader uses it, no copy is made internally.
|
||||
///
|
||||
/// \param name Name of the texture in the shader
|
||||
/// \param texture Image to assign
|
||||
/// \param texture Texture to assign
|
||||
///
|
||||
/// \see SetParameter, SetCurrentTexture
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
void SetTexture(const std::string& name, const Image& texture);
|
||||
void SetTexture(const std::string& name, const Texture& texture);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Set the current object texture in the shader
|
||||
///
|
||||
/// This function maps a shader texture variable to the
|
||||
/// image of the object being drawn.
|
||||
/// texture of the object being drawn.
|
||||
/// Example:
|
||||
/// \code
|
||||
/// // This is the variable in the pixel shader
|
||||
@ -384,7 +384,7 @@ private :
|
||||
////////////////////////////////////////////////////////////
|
||||
// Types
|
||||
////////////////////////////////////////////////////////////
|
||||
typedef std::map<int, const Image*> TextureTable;
|
||||
typedef std::map<int, const Texture*> TextureTable;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Member data
|
||||
@ -427,7 +427,7 @@ private :
|
||||
/// \code
|
||||
/// shader.SetParameter("offset", 2.f);
|
||||
/// shader.SetParameter("color", 0.5f, 0.8f, 0.3f);
|
||||
/// shader.SetTexture("overlay", image); // image is a sf::Image
|
||||
/// shader.SetTexture("overlay", texture); // texture is a sf::Texture
|
||||
/// shader.SetCurrentTexture("texture");
|
||||
/// \endcode
|
||||
///
|
||||
@ -442,8 +442,8 @@ private :
|
||||
///
|
||||
/// Shaders can be used on any drawable, but they are mainly
|
||||
/// made for sf::Sprite. Using a shader on a sf::String is more
|
||||
/// limited, because the texture of the string is not the
|
||||
/// actual text that you see on screen, it is a big image
|
||||
/// limited, because the texture of the text is not the
|
||||
/// actual text that you see on screen, it is a big texture
|
||||
/// containing all the characters of the font in an arbitrary
|
||||
/// order. Thus, texture lookups on pixels other than the current
|
||||
/// one may not give you the expected result. Using a shader
|
||||
@ -453,18 +453,18 @@ private :
|
||||
/// Shaders can also be used to apply global post-effects to the
|
||||
/// current contents of the target (like the old sf::PostFx class
|
||||
/// in SFML 1). This can be done in two different ways:
|
||||
/// \li draw everything to a sf::RenderImage, then draw it to
|
||||
/// \li draw everything to a sf::RenderTexture, then draw it to
|
||||
/// the main target using the shader
|
||||
/// \li draw everything directly to the main target, then use
|
||||
/// sf::Image::CopyScreen to copy its contents to an image and
|
||||
/// draw it to the main target using the shader
|
||||
/// sf::Texture::Update(Window&) to copy its contents to a texture
|
||||
/// and draw it to the main target using the shader
|
||||
///
|
||||
/// The first technique is more optimized because it doesn't involve
|
||||
/// retrieving the target's pixels to system memory, but the
|
||||
/// second one doesn't impact the rendering process and can be
|
||||
/// easily inserted anywhere.
|
||||
///
|
||||
/// Like sf::Image that can be used as a raw OpenGL texture,
|
||||
/// Like sf::Texture that can be used as a raw OpenGL texture,
|
||||
/// sf::Shader can also be used directly as a raw fragment
|
||||
/// shader for custom OpenGL geometry.
|
||||
/// \code
|
||||
|
@ -534,6 +534,6 @@ private :
|
||||
/// window.Draw(sf::Shape::Circle(500, 500, 20, sf::Color::Blue, 5, sf::Color::Black));
|
||||
/// \endcode
|
||||
///
|
||||
/// \see sf::Image
|
||||
/// \see sf::Sprite
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
|
@ -35,10 +35,10 @@
|
||||
|
||||
namespace sf
|
||||
{
|
||||
class Image;
|
||||
class Texture;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Drawable representation of an image, with its
|
||||
/// \brief Drawable representation of a texture, with its
|
||||
/// own transformations, color, blend mode, etc.
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
@ -49,56 +49,50 @@ public :
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Default constructor
|
||||
///
|
||||
/// Creates an empty sprite with no source image.
|
||||
/// Creates an empty sprite with no source texture.
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
Sprite();
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Construct the sprite from a source image
|
||||
/// \brief Construct the sprite from a source texture
|
||||
///
|
||||
/// \param image Source image, that the sprite will display
|
||||
/// \param position Position of the sprite in the scene
|
||||
/// \param scale Scale factor of the sprite
|
||||
/// \param rotation Rotation angle, in degrees
|
||||
/// \param color Global color of the sprite
|
||||
///
|
||||
/// \see SetImage
|
||||
/// \see SetTexture
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
explicit Sprite(const Image& image, const Vector2f& position = Vector2f(0, 0), const Vector2f& scale = Vector2f(1, 1), float rotation = 0.f, const Color& color = Color(255, 255, 255, 255));
|
||||
explicit Sprite(const Texture& texture);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Change the source image of the sprite
|
||||
/// \brief Change the source texture of the sprite
|
||||
///
|
||||
/// The \a image argument refers to an image that must
|
||||
/// The \a texture argument refers to a texture that must
|
||||
/// exist as long as the sprite uses it. Indeed, the sprite
|
||||
/// doesn't store its own copy of the image, but rather keeps
|
||||
/// doesn't store its own copy of the texture, but rather keeps
|
||||
/// a pointer to the one that you passed to this function.
|
||||
/// If the source image is destroyed and the sprite tries to
|
||||
/// If the source texture is destroyed and the sprite tries to
|
||||
/// use it, it may appear as a white rectangle.
|
||||
/// If \a adjustToNewSize is true, the SubRect property of
|
||||
/// the sprite is adjusted to the size of the new image. If
|
||||
/// the sprite is adjusted to the size of the new texture. If
|
||||
/// it is false, the SubRect is unchanged.
|
||||
///
|
||||
/// \param image New image
|
||||
/// \param adjustToNewSize Should the sub-rect be adjusted to the size of the new image?
|
||||
/// \param texture New texture
|
||||
/// \param adjustToNewSize Should the sub-rect be adjusted to the size of the new texture?
|
||||
///
|
||||
/// \see GetImage, SetSubRect
|
||||
/// \see GetTexture, SetSubRect
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
void SetImage(const Image& image, bool adjustToNewSize = false);
|
||||
void SetTexture(const Texture& texture, bool adjustToNewSize = false);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Set the part of the image that the sprite will display
|
||||
/// \brief Set the part of the texture that the sprite will display
|
||||
///
|
||||
/// The sub-rectangle is useful when you don't want to display
|
||||
/// the whole image, but rather a part of it.
|
||||
/// By default, the sub-rectangle covers the entire image.
|
||||
/// the whole texture, but rather a part of it.
|
||||
/// By default, the sub-rectangle covers the entire texture.
|
||||
///
|
||||
/// \param rectangle Rectangle defining the region of the image to display
|
||||
/// \param rectangle Rectangle defining the region of the texture to display
|
||||
///
|
||||
/// \see GetSubRect, SetImage
|
||||
/// \see GetSubRect, SetTexture
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
void SetSubRect(const IntRect& rectangle);
|
||||
@ -157,24 +151,24 @@ public :
|
||||
void FlipY(bool flipped);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Get the source image of the sprite
|
||||
/// \brief Get the source texture of the sprite
|
||||
///
|
||||
/// If the sprite has no source image, or if the image
|
||||
/// If the sprite has no source texture, or if the texture
|
||||
/// doesn't exist anymore, a NULL pointer is returned.
|
||||
/// The returned pointer is const, which means that you can't
|
||||
/// modify the image when you retrieve it with this function.
|
||||
/// modify the texture when you retrieve it with this function.
|
||||
///
|
||||
/// \return Pointer to the sprite's image
|
||||
/// \return Pointer to the sprite's texture
|
||||
///
|
||||
/// \see SetImage
|
||||
/// \see SetTexture
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
const Image* GetImage() const;
|
||||
const Texture* GetTexture() const;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Get the region of the image displayed by the sprite
|
||||
/// \brief Get the region of the texture displayed by the sprite
|
||||
///
|
||||
/// \return Rectangle defining the region of the image
|
||||
/// \return Rectangle defining the region of the texture
|
||||
///
|
||||
/// \see SetSubRect
|
||||
///
|
||||
@ -194,25 +188,6 @@ public :
|
||||
////////////////////////////////////////////////////////////
|
||||
Vector2f GetSize() const;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Get the color of a given pixel in the sprite
|
||||
///
|
||||
/// This function returns the source image pixel, multiplied
|
||||
/// by the global color of the sprite.
|
||||
/// The input point must be in local coordinates. If you have
|
||||
/// a global point, you can use the TransformToLocal function
|
||||
/// to make it local.
|
||||
/// This function doesn't perform any check, you must ensure that
|
||||
/// the \a x and \a y coordinates are not out of bounds.
|
||||
///
|
||||
/// \param x X coordinate of the pixel to get
|
||||
/// \param y Y coordinate of the pixel to get
|
||||
///
|
||||
/// \return Color of the pixel
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
Color GetPixel(unsigned int x, unsigned int y) const;
|
||||
|
||||
protected :
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
@ -229,8 +204,8 @@ private :
|
||||
////////////////////////////////////////////////////////////
|
||||
// Member data
|
||||
////////////////////////////////////////////////////////////
|
||||
ResourcePtr<Image> myImage; ///< Image used to draw the sprite
|
||||
IntRect mySubRect; ///< Sub-rectangle of source image to assign to the sprite
|
||||
ResourcePtr<Texture> myTexture; ///< Texture used to draw the sprite
|
||||
IntRect mySubRect; ///< Sub-rectangle of source texture to assign to the sprite
|
||||
bool myIsFlippedX; ///< Is the sprite flipped on the X axis ?
|
||||
bool myIsFlippedY; ///< Is the sprite flipped on the Y axis ?
|
||||
};
|
||||
@ -246,39 +221,39 @@ private :
|
||||
/// \ingroup graphics
|
||||
///
|
||||
/// sf::Sprite is a drawable class that allows to easily display
|
||||
/// an image (or a part of it) on a render target.
|
||||
/// a texture (or a part of it) on a render target.
|
||||
///
|
||||
/// It inherits all the functions from sf::Drawable:
|
||||
/// position, rotation, scale, origin, global color and blend
|
||||
/// mode. It also adds sprite-specific properties such as the
|
||||
/// image to use, the part of it to display, and some convenience
|
||||
/// texture to use, the part of it to display, and some convenience
|
||||
/// functions to flip or resize the sprite.
|
||||
///
|
||||
/// sf::Sprite works in combination with the sf::Image class, which
|
||||
/// loads and provides the pixel data of a given image.
|
||||
/// sf::Sprite works in combination with the sf::Texture class, which
|
||||
/// loads and provides the pixel data of a given texture.
|
||||
///
|
||||
/// The separation of sf::Sprite and sf::Image allows more flexibility
|
||||
/// and better performances: indeed a sf::Image is a heavy resource,
|
||||
/// The separation of sf::Sprite and sf::Texture allows more flexibility
|
||||
/// and better performances: indeed a sf::Texture is a heavy resource,
|
||||
/// and any operation on it is slow (often too slow for real-time
|
||||
/// applications). On the other side, a sf::Sprite is a lightweight
|
||||
/// object which can use the pixel data of a sf::Image and draw
|
||||
/// object which can use the pixel data of a sf::Texture and draw
|
||||
/// it with its own transformation / color / blending attributes.
|
||||
///
|
||||
/// It is important to note that the sf::Sprite instance doesn't
|
||||
/// copy the image that it uses, it only keeps a reference to it.
|
||||
/// Thus, a sf::Image must not be destructed while it is
|
||||
/// copy the texture that it uses, it only keeps a reference to it.
|
||||
/// Thus, a sf::Texture must not be destructed while it is
|
||||
/// used by a sf::Sprite (i.e. never write a function that
|
||||
/// uses a local sf::Image instance for creating a sprite).
|
||||
/// uses a local sf::Texture instance for creating a sprite).
|
||||
///
|
||||
/// Usage example:
|
||||
/// \code
|
||||
/// // Declare and load an image
|
||||
/// sf::Image image;
|
||||
/// image.LoadFromFile("image.png");
|
||||
/// // Declare and load a texture
|
||||
/// sf::Texture texture;
|
||||
/// texture.LoadFromFile("texture.png");
|
||||
///
|
||||
/// // Create a sprite
|
||||
/// sf::Sprite sprite;
|
||||
/// sprite.SetImage(image);
|
||||
/// sprite.SetTexture(texture);
|
||||
/// sprite.SetSubRect(sf::IntRect(10, 10, 50, 30));
|
||||
/// sprite.Resize(100, 60);
|
||||
///
|
||||
@ -286,6 +261,6 @@ private :
|
||||
/// window.Draw(sprite); // window is a sf::RenderWindow
|
||||
/// \endcode
|
||||
///
|
||||
/// \see sf::Image
|
||||
/// \see sf::Texture
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
|
551
include/SFML/Graphics/Texture.hpp
Normal file
551
include/SFML/Graphics/Texture.hpp
Normal file
@ -0,0 +1,551 @@
|
||||
////////////////////////////////////////////////////////////
|
||||
//
|
||||
// SFML - Simple and Fast Multimedia Library
|
||||
// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied warranty.
|
||||
// In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it freely,
|
||||
// subject to the following restrictions:
|
||||
//
|
||||
// 1. The origin of this software must not be misrepresented;
|
||||
// you must not claim that you wrote the original software.
|
||||
// If you use this software in a product, an acknowledgment
|
||||
// in the product documentation would be appreciated but is not required.
|
||||
//
|
||||
// 2. Altered source versions must be plainly marked as such,
|
||||
// and must not be misrepresented as being the original software.
|
||||
//
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
//
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef SFML_TEXTURE_HPP
|
||||
#define SFML_TEXTURE_HPP
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/System/Resource.hpp>
|
||||
#include <SFML/Window/GlResource.hpp>
|
||||
#include <SFML/Graphics/Image.hpp>
|
||||
|
||||
|
||||
namespace sf
|
||||
{
|
||||
class Window;
|
||||
class Renderer;
|
||||
class RenderTexture;
|
||||
class InputStream;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Image living on the graphics card that can be used for drawing
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
class SFML_API Texture : public Resource<Texture>, GlResource
|
||||
{
|
||||
public :
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Default constructor
|
||||
///
|
||||
/// Creates an empty texture.
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
Texture();
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Copy constructor
|
||||
///
|
||||
/// \param copy instance to copy
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
Texture(const Texture& copy);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Destructor
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
~Texture();
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Create the texture
|
||||
///
|
||||
/// If this function fails, the texture is left unchanged.
|
||||
///
|
||||
/// \param width Width of the texture
|
||||
/// \param height Height of the texture
|
||||
///
|
||||
/// \return True if creation was successful
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
bool Create(unsigned int width, unsigned int height);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Load the texture from a file on disk
|
||||
///
|
||||
/// This function is a shortcut for the following code:
|
||||
/// \code
|
||||
/// sf::Image image;
|
||||
/// image.LoadFromFile(filename);
|
||||
/// texture.LoadFromImage(image, area);
|
||||
/// \endcode
|
||||
///
|
||||
/// The \a area argument can be used to load only a sub-rectangle
|
||||
/// of the whole image. If you want the entire image then leave
|
||||
/// the default value (which is an empty IntRect).
|
||||
/// If the \a area rectangle crosses the bounds of the image, it
|
||||
/// is adjusted to fit the image size.
|
||||
///
|
||||
/// The maximum size for a texture depends on the graphics
|
||||
/// driver and can be retrieved with the GetMaximumSize function.
|
||||
///
|
||||
/// If this function fails, the texture is left unchanged.
|
||||
///
|
||||
/// \param filename Path of the image file to load
|
||||
/// \param area Area of the image to load
|
||||
///
|
||||
/// \return True if loading was successful
|
||||
///
|
||||
/// \see LoadFromMemory, LoadFromStream, LoadFromImage
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
bool LoadFromFile(const std::string& filename, const IntRect& area = IntRect());
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Load the texture from a file in memory
|
||||
///
|
||||
/// This function is a shortcut for the following code:
|
||||
/// \code
|
||||
/// sf::Image image;
|
||||
/// image.LoadFromMemory(data, size);
|
||||
/// texture.LoadFromImage(image, area);
|
||||
/// \endcode
|
||||
///
|
||||
/// The \a area argument can be used to load only a sub-rectangle
|
||||
/// of the whole image. If you want the entire image then leave
|
||||
/// the default value (which is an empty IntRect).
|
||||
/// If the \a area rectangle crosses the bounds of the image, it
|
||||
/// is adjusted to fit the image size.
|
||||
///
|
||||
/// The maximum size for a texture depends on the graphics
|
||||
/// driver and can be retrieved with the GetMaximumSize function.
|
||||
///
|
||||
/// If this function fails, the texture is left unchanged.
|
||||
///
|
||||
/// \param data Pointer to the file data in memory
|
||||
/// \param size Size of the data to load, in bytes
|
||||
/// \param area Area of the image to load
|
||||
///
|
||||
/// \return True if loading was successful
|
||||
///
|
||||
/// \see LoadFromFile, LoadFromStream, LoadFromImage
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
bool LoadFromMemory(const void* data, std::size_t size, const IntRect& area = IntRect());
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Load the texture from a file in memory
|
||||
///
|
||||
/// This function is a shortcut for the following code:
|
||||
/// \code
|
||||
/// sf::Image image;
|
||||
/// image.LoadFromStream(stream);
|
||||
/// texture.LoadFromImage(image, area);
|
||||
/// \endcode
|
||||
///
|
||||
/// The \a area argument can be used to load only a sub-rectangle
|
||||
/// of the whole image. If you want the entire image then leave
|
||||
/// the default value (which is an empty IntRect).
|
||||
/// If the \a area rectangle crosses the bounds of the image, it
|
||||
/// is adjusted to fit the image size.
|
||||
///
|
||||
/// The maximum size for a texture depends on the graphics
|
||||
/// driver and can be retrieved with the GetMaximumSize function.
|
||||
///
|
||||
/// If this function fails, the texture is left unchanged.
|
||||
///
|
||||
/// \param stream Source stream to read from
|
||||
/// \param area Area of the image to load
|
||||
///
|
||||
/// \return True if loading was successful
|
||||
///
|
||||
/// \see LoadFromFile, LoadFromMemory, LoadFromImage
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
bool LoadFromStream(sf::InputStream& stream, const IntRect& area = IntRect());
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Load the texture from an image
|
||||
///
|
||||
/// The \a area argument can be used to load only a sub-rectangle
|
||||
/// of the whole image. If you want the entire image then leave
|
||||
/// the default value (which is an empty IntRect).
|
||||
/// If the \a area rectangle crosses the bounds of the image, it
|
||||
/// is adjusted to fit the image size.
|
||||
///
|
||||
/// The maximum size for a texture depends on the graphics
|
||||
/// driver and can be retrieved with the GetMaximumSize function.
|
||||
///
|
||||
/// If this function fails, the texture is left unchanged.
|
||||
///
|
||||
/// \param image Image to load into the texture
|
||||
/// \param area Area of the image to load
|
||||
///
|
||||
/// \return True if loading was successful
|
||||
///
|
||||
/// \see LoadFromFile, LoadFromMemory
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
bool LoadFromImage(const Image& image, const IntRect& area = IntRect());
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Return the width of the texture
|
||||
///
|
||||
/// \return Width in pixels
|
||||
///
|
||||
/// \see GetHeight
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
unsigned int GetWidth() 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
|
||||
///
|
||||
/// This function performs a slow operation that downloads
|
||||
/// the texture's pixels from the graphics card and copies
|
||||
/// them to a new image, potentially applying transformations
|
||||
/// to pixels if necessary (texture may be padded or flipped).
|
||||
///
|
||||
/// \return Image containing the texture's pixels
|
||||
///
|
||||
/// \see LoadFromImage
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
Image CopyToImage() const;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Update the whole texture from an array of pixels
|
||||
///
|
||||
/// The \a pixels array is assumed to have the same size as
|
||||
/// the \a area rectangle, and to contain 32-bits RGBA pixels.
|
||||
///
|
||||
/// No additional check is performed on the size of the pixel
|
||||
/// array, passing invalid arguments will lead to an undefined
|
||||
/// behaviour.
|
||||
///
|
||||
/// This function does nothing if \a pixels is null or if the
|
||||
/// texture was not previously created.
|
||||
///
|
||||
/// \param pixels Array of pixels to copy to the texture
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
void Update(const Uint8* pixels);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Update a part of the texture from an array of pixels
|
||||
///
|
||||
/// The size of the \a pixels array must match the \a width and
|
||||
/// \a height arguments, and it must contain 32-bits RGBA pixels.
|
||||
///
|
||||
/// No additional check is performed on the size of the pixel
|
||||
/// array or the bounds of the area to update, passing invalid
|
||||
/// arguments will lead to an undefined behaviour.
|
||||
///
|
||||
/// This function does nothing if \a pixels is null or if the
|
||||
/// texture was not previously created.
|
||||
///
|
||||
/// \param pixels Array of pixels to copy to the texture
|
||||
/// \param width Width of the pixel region contained in \a pixels
|
||||
/// \param height Height of the pixel region contained in \a pixels
|
||||
/// \param x X offset in the texture where to copy the source pixels
|
||||
/// \param y Y offset in the texture where to copy the source pixels
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
void Update(const Uint8* pixels, unsigned int width, unsigned int height, unsigned int x, unsigned int y);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Update the texture from an image
|
||||
///
|
||||
/// Although the source image can be smaller than the texture,
|
||||
/// this function is usually used for updating the whole texture.
|
||||
/// The other overload, which has (x, y) additional arguments,
|
||||
/// is more convenient for updating a sub-area of the texture.
|
||||
///
|
||||
/// No additional check is performed on the size of the image,
|
||||
/// passing an image bigger than the texture will lead to an
|
||||
/// undefined behaviour.
|
||||
///
|
||||
/// This function does nothing if the texture was not
|
||||
/// previously created.
|
||||
///
|
||||
/// \param image Image to copy to the texture
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
void Update(const Image& image);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Update a part of the texture from an image
|
||||
///
|
||||
/// No additional check is performed on the size of the image,
|
||||
/// passing an invalid combination of image size and offset
|
||||
/// will lead to an undefined behaviour.
|
||||
///
|
||||
/// This function does nothing if the texture was not
|
||||
/// previously created.
|
||||
///
|
||||
/// \param image Image to copy to the texture
|
||||
/// \param x X offset in the texture where to copy the source image
|
||||
/// \param y Y offset in the texture where to copy the source image
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
void Update(const Image& image, unsigned int x, unsigned int y);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Update the texture from the contents of a window
|
||||
///
|
||||
/// Although the source window can be smaller than the texture,
|
||||
/// this function is usually used for updating the whole texture.
|
||||
/// The other overload, which has (x, y) additional arguments,
|
||||
/// is more convenient for updating a sub-area of the texture.
|
||||
///
|
||||
/// No additional check is performed on the size of the window,
|
||||
/// passing a window bigger than the texture will lead to an
|
||||
/// undefined behaviour.
|
||||
///
|
||||
/// This function does nothing if either the texture or the window
|
||||
/// was not previously created.
|
||||
///
|
||||
/// \param window Window to copy to the texture
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
void Update(const Window& window);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Update a part of the texture from the contents of a window
|
||||
///
|
||||
/// No additional check is performed on the size of the window,
|
||||
/// passing an invalid combination of window size and offset
|
||||
/// will lead to an undefined behaviour.
|
||||
///
|
||||
/// This function does nothing if either the texture or the window
|
||||
/// was not previously created.
|
||||
///
|
||||
/// \param window Window to copy to the texture
|
||||
/// \param x X offset in the texture where to copy the source window
|
||||
/// \param y Y offset in the texture where to copy the source window
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
void Update(const Window& window, unsigned int x, unsigned int y);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Activate the texture for rendering
|
||||
///
|
||||
/// This function is mainly used internally by the SFML
|
||||
/// render system. However it can be useful when
|
||||
/// using sf::Texture together with OpenGL code (this function
|
||||
/// is equivalent to glBindTexture).
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
void Bind() const;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Enable or disable the smooth filter
|
||||
///
|
||||
/// When the filter is activated, the texture appears smoother
|
||||
/// so that pixels are less noticeable. However if you want
|
||||
/// the texture to look exactly the same as its source file,
|
||||
/// you should leave it disabled.
|
||||
/// The smooth filter is disabled by default.
|
||||
///
|
||||
/// \param smooth True to enable smoothing, false to disable it
|
||||
///
|
||||
/// \see IsSmooth
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
void SetSmooth(bool smooth);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Tell whether the smooth filter is enabled or not
|
||||
///
|
||||
/// \return True if smoothing is enabled, false if it is disabled
|
||||
///
|
||||
/// \see SetSmooth
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
bool IsSmooth() const;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Convert a rectangle of pixels into texture coordinates
|
||||
///
|
||||
/// This function is used by code that needs to map the texture
|
||||
/// to some OpenGL geometry. It converts the source rectangle,
|
||||
/// expressed in pixels, to float coordinates in the range [0, 1].
|
||||
///
|
||||
/// \param rectangle Rectangle to convert
|
||||
///
|
||||
/// \return Texture coordinates corresponding to \a rectangle
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
FloatRect GetTexCoords(const IntRect& rectangle) const;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Overload of assignment operator
|
||||
///
|
||||
/// \param right Instance to assign
|
||||
///
|
||||
/// \return Reference to self
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
Texture& operator =(const Texture& right);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Get the maximum texture size allowed
|
||||
///
|
||||
/// This maximum size is defined by the graphics driver.
|
||||
/// You can expect a value of 512 pixels for low-end graphics
|
||||
/// card, and up to 8192 pixels or more for newer hardware.
|
||||
///
|
||||
/// \return Maximum size allowed for textures, in pixels
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
static unsigned int GetMaximumSize();
|
||||
|
||||
private :
|
||||
|
||||
friend class Renderer;
|
||||
friend class RenderTexture;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Get a valid image size according to hardware support
|
||||
///
|
||||
/// This function checks whether the graphics driver supports
|
||||
/// non power of two sizes or not, and adjusts the size
|
||||
/// accordingly.
|
||||
/// The returned size is greater than or equal to the original size.
|
||||
///
|
||||
/// \param Size size to convert
|
||||
///
|
||||
/// \return Valid nearest size (greater than or equal to specified size)
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
static unsigned int GetValidSize(unsigned int size);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Member data
|
||||
////////////////////////////////////////////////////////////
|
||||
unsigned int myWidth; ///< Image width
|
||||
unsigned int myHeight; ///< Image Height
|
||||
unsigned int myTextureWidth; ///< Actual texture width (can be greater than image width because of padding)
|
||||
unsigned int myTextureHeight; ///< Actual texture height (can be greater than image height because of padding)
|
||||
unsigned int myTexture; ///< Internal texture identifier
|
||||
bool myIsSmooth; ///< Status of the smooth filter
|
||||
mutable bool myPixelsFlipped; ///< To work around the inconsistency in Y orientation
|
||||
};
|
||||
|
||||
} // namespace sf
|
||||
|
||||
|
||||
#endif // SFML_TEXTURE_HPP
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \class sf::Texture
|
||||
/// \ingroup graphics
|
||||
///
|
||||
/// sf::Texture stores pixels that can be drawn, with a sprite
|
||||
/// for example. A texture lives in the graphics card memory,
|
||||
/// therefore it is very fast to draw a texture to a render target,
|
||||
/// or copy a render target to a texture (the graphics card can
|
||||
/// access both directly).
|
||||
///
|
||||
/// Being stored in the graphics card memory has some drawbacks.
|
||||
/// A texture cannot be manipulated as freely as a sf::Image,
|
||||
/// you need to prepare the pixels first and then upload them
|
||||
/// to the texture in a single operation (see Texture::Update).
|
||||
///
|
||||
/// sf::Texture makes it easy to convert from/to sf::Image, but
|
||||
/// keep in mind that these calls require transfers between
|
||||
/// the graphics card and the central memory, therefore they are
|
||||
/// slow operations.
|
||||
///
|
||||
/// A texture can be loaded from an image, but also directly
|
||||
/// from a file/memory/stream. The necessary shortcuts are defined
|
||||
/// so that you don't need an image first for the most common cases.
|
||||
/// However, if you want to perform some modifications on the pixels
|
||||
/// before creating the final texture, you can load your file to a
|
||||
/// sf::Image, do whatever you need with the pixels, and then call
|
||||
/// Texture::LoadFromImage.
|
||||
///
|
||||
/// Since they live in the graphics card memory, the pixels of a texture
|
||||
/// cannot be accessed without a slow copy first. And they cannot be
|
||||
/// accessed individually. Therefore, if you need to read the texture's
|
||||
/// pixels (like for pixel-perfect collisions), it is recommended to
|
||||
/// store the collision information separately, for example in an array
|
||||
/// of booleans.
|
||||
///
|
||||
/// Like sf::Image, sf::Texture can handle a unique internal
|
||||
/// representation of pixels, which is RGBA 32 bits. This means
|
||||
/// that a pixel must be composed of 8 bits red, green, blue and
|
||||
/// alpha channels -- just like a sf::Color.
|
||||
///
|
||||
/// Usage example:
|
||||
/// \code
|
||||
/// // This example shows the most common use of sf::Texture:
|
||||
/// // drawing a sprite
|
||||
///
|
||||
/// // Load a texture from a file
|
||||
/// sf::Texture texture;
|
||||
/// if (!texture.LoadFromFile("texture.png"))
|
||||
/// return -1;
|
||||
///
|
||||
/// // Assign it to a sprite
|
||||
/// sf::Sprite sprite;
|
||||
/// sprite.SetTexture(texture);
|
||||
///
|
||||
/// // Draw the textured sprite
|
||||
/// window.Draw(sprite); // window is a sf::RenderWindow
|
||||
/// \endcode
|
||||
///
|
||||
/// \code
|
||||
/// // This example shows another common use of sf::Texture:
|
||||
/// // streaming real-time data, like video frames
|
||||
///
|
||||
/// // Create an empty texture
|
||||
/// sf::Texture texture;
|
||||
/// if (!texture.Create(640, 480))
|
||||
/// return -1;
|
||||
///
|
||||
/// // Create a sprite that will display the texture
|
||||
/// sf::Sprite sprite(texture);
|
||||
///
|
||||
/// while (...) // the main loop
|
||||
/// {
|
||||
/// ...
|
||||
///
|
||||
/// // update the texture
|
||||
/// sf::Uint8* pixels = ...; // get a fresh chunk of pixels (the next frame of a movie, for example)
|
||||
/// texture.Update(pixels);
|
||||
///
|
||||
/// // draw it
|
||||
/// window.Draw(sprite);
|
||||
///
|
||||
/// ...
|
||||
/// }
|
||||
///
|
||||
/// \endcode
|
||||
///
|
||||
/// \see sf::Sprite, sf::Image, sf::RenderTexture
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
@ -297,7 +297,7 @@ private :
|
||||
/// A view is composed of a source rectangle, which defines
|
||||
/// what part of the 2D scene is shown, and a target viewport,
|
||||
/// which defines where the contents of the source rectangle
|
||||
/// will be displayed on the render target (window or render-image).
|
||||
/// will be displayed on the render target (window or texture).
|
||||
///
|
||||
/// The viewport allows to map the scene to a custom part
|
||||
/// of the render target, and can be used for split-screen
|
||||
@ -336,6 +336,6 @@ private :
|
||||
/// window.Draw(someText);
|
||||
/// \endcode
|
||||
///
|
||||
/// \see RenderWindow, RenderImage
|
||||
/// \see sf::RenderWindow, sf::RenderTexture
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
|
@ -98,7 +98,7 @@ public :
|
||||
/// This class allows users to define their own file input sources
|
||||
/// from which SFML can load resources.
|
||||
///
|
||||
/// SFML resource classes like sf::Image and
|
||||
/// SFML resource classes like sf::Texture and
|
||||
/// sf::SoundBuffer provide LoadFromFile and LoadFromMemory functions,
|
||||
/// which read data from conventional sources. However, if you
|
||||
/// have data coming from a different source (over a network,
|
||||
@ -130,11 +130,11 @@ public :
|
||||
/// ...
|
||||
/// };
|
||||
///
|
||||
/// // now you can load images...
|
||||
/// sf::Image image;
|
||||
/// // now you can load textures...
|
||||
/// sf::Texture texture;
|
||||
/// ZipStream stream("resources.zip");
|
||||
/// stream.Open("images/img.png");
|
||||
/// image.LoadFromStream(stream);
|
||||
/// texture.LoadFromStream(stream);
|
||||
///
|
||||
/// // musics...
|
||||
/// sf::Music music;
|
||||
|
@ -275,8 +275,8 @@ private :
|
||||
///
|
||||
/// These two classes are heavily used internally in SFML
|
||||
/// to safely handle resources and the classes that use them:
|
||||
/// \li sf::Image / sf::Sprite
|
||||
/// \li sf::Font / sf::String
|
||||
/// \li sf::Texture / sf::Sprite
|
||||
/// \li sf::Font / sf::Text
|
||||
/// \li sf::SoundBuffer / sf::Sound
|
||||
///
|
||||
/// sf::Resource and sf::ResourcePtr are designed for internal use,
|
||||
|
@ -39,14 +39,10 @@ Sound::Sound()
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
Sound::Sound(const SoundBuffer& buffer, bool loop, float pitch, float volume, const Vector3f& position) :
|
||||
Sound::Sound(const SoundBuffer& buffer) :
|
||||
myBuffer(NULL)
|
||||
{
|
||||
SetBuffer(buffer);
|
||||
SetLoop(loop);
|
||||
SetPitch(pitch);
|
||||
SetVolume(volume);
|
||||
SetPosition(position);
|
||||
}
|
||||
|
||||
|
||||
|
@ -25,14 +25,14 @@ set(SRC
|
||||
${INCROOT}/Rect.inl
|
||||
${SRCROOT}/Renderer.cpp
|
||||
${INCROOT}/Renderer.hpp
|
||||
${SRCROOT}/RenderImage.cpp
|
||||
${INCROOT}/RenderImage.hpp
|
||||
${SRCROOT}/RenderImageImpl.cpp
|
||||
${SRCROOT}/RenderImageImpl.hpp
|
||||
${SRCROOT}/RenderImageImplFBO.cpp
|
||||
${SRCROOT}/RenderImageImplFBO.hpp
|
||||
${SRCROOT}/RenderImageImplDefault.cpp
|
||||
${SRCROOT}/RenderImageImplDefault.hpp
|
||||
${SRCROOT}/RenderTexture.cpp
|
||||
${INCROOT}/RenderTexture.hpp
|
||||
${SRCROOT}/RenderTextureImpl.cpp
|
||||
${SRCROOT}/RenderTextureImpl.hpp
|
||||
${SRCROOT}/RenderTextureImplFBO.cpp
|
||||
${SRCROOT}/RenderTextureImplFBO.hpp
|
||||
${SRCROOT}/RenderTextureImplDefault.cpp
|
||||
${SRCROOT}/RenderTextureImplDefault.hpp
|
||||
${SRCROOT}/RenderTarget.cpp
|
||||
${INCROOT}/RenderTarget.hpp
|
||||
${SRCROOT}/RenderWindow.cpp
|
||||
@ -45,6 +45,8 @@ set(SRC
|
||||
${INCROOT}/Sprite.hpp
|
||||
${SRCROOT}/Text.cpp
|
||||
${INCROOT}/Text.hpp
|
||||
${SRCROOT}/Texture.cpp
|
||||
${INCROOT}/Texture.hpp
|
||||
${SRCROOT}/View.cpp
|
||||
${INCROOT}/View.hpp
|
||||
${SRCROOT}/stb_image/stb_image.h
|
||||
|
@ -33,20 +33,6 @@
|
||||
|
||||
namespace sf
|
||||
{
|
||||
////////////////////////////////////////////////////////////
|
||||
Drawable::Drawable(const Vector2f& position, const Vector2f& scale, float rotation, const Color& color) :
|
||||
myPosition (position),
|
||||
myScale (scale),
|
||||
myOrigin (0, 0),
|
||||
myRotation (rotation),
|
||||
myColor (color),
|
||||
myBlendMode (Blend::Alpha),
|
||||
myMatrixUpdated (false),
|
||||
myInvMatrixUpdated(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
Drawable::~Drawable()
|
||||
{
|
||||
@ -267,6 +253,20 @@ Vector2f Drawable::TransformToGlobal(const Vector2f& point) const
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
Drawable::Drawable() :
|
||||
myPosition (0, 0),
|
||||
myScale (1, 1),
|
||||
myOrigin (0, 0),
|
||||
myRotation (0),
|
||||
myColor (255, 255, 255, 255),
|
||||
myBlendMode (Blend::Alpha),
|
||||
myMatrixUpdated (false),
|
||||
myInvMatrixUpdated(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
const Matrix3& Drawable::GetMatrix() const
|
||||
{
|
||||
|
@ -309,7 +309,7 @@ int Font::GetLineSpacing(unsigned int characterSize) const
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
const Image& Font::GetImage(unsigned int characterSize) const
|
||||
const Texture& Font::GetTexture(unsigned int characterSize) const
|
||||
{
|
||||
return myPages[characterSize].Texture;
|
||||
}
|
||||
@ -493,12 +493,11 @@ Glyph Font::LoadGlyph(Uint32 codePoint, unsigned int characterSize, bool bold) c
|
||||
}
|
||||
|
||||
// Write the pixels to the texture
|
||||
IntRect subrect = glyph.SubRect;
|
||||
subrect.Left += padding;
|
||||
subrect.Top += padding;
|
||||
subrect.Width -= 2 * padding;
|
||||
subrect.Height -= 2 * padding;
|
||||
page.Texture.UpdatePixels(&myPixelBuffer[0], subrect);
|
||||
unsigned int x = glyph.SubRect.Left + padding;
|
||||
unsigned int y = glyph.SubRect.Top + padding;
|
||||
unsigned int width = glyph.SubRect.Width - 2 * padding;
|
||||
unsigned int height = glyph.SubRect.Height - 2 * padding;
|
||||
page.Texture.Update(&myPixelBuffer[0], width, height, x, y);
|
||||
}
|
||||
|
||||
// Delete the FT glyph
|
||||
@ -545,19 +544,17 @@ IntRect Font::FindGlyphRect(Page& page, unsigned int width, unsigned int height)
|
||||
// Not enough space: resize the texture if possible
|
||||
unsigned int textureWidth = page.Texture.GetWidth();
|
||||
unsigned int textureHeight = page.Texture.GetHeight();
|
||||
if ((textureWidth * 2 <= Image::GetMaximumSize()) && (textureHeight * 2 <= Image::GetMaximumSize()))
|
||||
if ((textureWidth * 2 <= Texture::GetMaximumSize()) && (textureHeight * 2 <= Texture::GetMaximumSize()))
|
||||
{
|
||||
// Make the texture 2 times bigger
|
||||
std::size_t size = textureWidth * textureHeight * 4;
|
||||
std::vector<Uint8> pixels(size);
|
||||
memcpy(&pixels[0], page.Texture.GetPixelsPtr(), size);
|
||||
page.Texture.Create(textureWidth * 2, textureHeight * 2, Color(255, 255, 255, 0));
|
||||
page.Texture.UpdatePixels(&pixels[0], IntRect(0, 0, textureWidth, textureHeight));
|
||||
sf::Image pixels = page.Texture.CopyToImage();
|
||||
page.Texture.Create(textureWidth * 2, textureHeight * 2);
|
||||
page.Texture.Update(pixels);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Oops, we've reached the maximum texture size...
|
||||
Err() << "Failed to add a new character to the font: the maximum image size has been reached" << std::endl;
|
||||
Err() << "Failed to add a new character to the font: the maximum texture size has been reached" << std::endl;
|
||||
return IntRect(0, 0, 2, 2);
|
||||
}
|
||||
}
|
||||
@ -603,13 +600,17 @@ Font::Page::Page() :
|
||||
NextRow(2)
|
||||
{
|
||||
// Make sure that the texture is initialized by default
|
||||
Texture.Create(128, 128, Color(255, 255, 255, 0));
|
||||
Texture.SetSmooth(true);
|
||||
sf::Image image;
|
||||
image.Create(128, 128, Color(255, 255, 255, 0));
|
||||
|
||||
// Reserve a 2x2 white square for texturing underlines
|
||||
for (int x = 0; x < 2; ++x)
|
||||
for (int y = 0; y < 2; ++y)
|
||||
Texture.SetPixel(x, y, Color(255, 255, 255, 255));
|
||||
image.SetPixel(x, y, Color(255, 255, 255, 255));
|
||||
|
||||
// Create the texture
|
||||
Texture.LoadFromImage(image);
|
||||
Texture.SetSmooth(true);
|
||||
}
|
||||
|
||||
} // namespace sf
|
||||
|
@ -27,12 +27,8 @@
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/Graphics/Image.hpp>
|
||||
#include <SFML/Graphics/ImageLoader.hpp>
|
||||
#include <SFML/Graphics/RenderImage.hpp>
|
||||
#include <SFML/Graphics/RenderWindow.hpp>
|
||||
#include <SFML/Graphics/GLCheck.hpp>
|
||||
#include <SFML/System/Err.hpp>
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
#include <cstring>
|
||||
|
||||
|
||||
@ -41,167 +37,19 @@ namespace sf
|
||||
////////////////////////////////////////////////////////////
|
||||
Image::Image() :
|
||||
myWidth (0),
|
||||
myHeight (0),
|
||||
myTextureWidth (0),
|
||||
myTextureHeight (0),
|
||||
myTexture (0),
|
||||
myIsSmooth (false),
|
||||
myTextureUpdated(true),
|
||||
myArrayUpdated (true),
|
||||
myPixelsFlipped (false)
|
||||
myHeight(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
Image::Image(const Image& copy) :
|
||||
Resource<Image>()
|
||||
void Image::Create(unsigned int width, unsigned int height, const Color& color)
|
||||
{
|
||||
// First make sure that the source image is up-to-date
|
||||
copy.EnsureArrayUpdate();
|
||||
// Assign the new size
|
||||
myWidth = width;
|
||||
myHeight = height;
|
||||
|
||||
// Copy all its members
|
||||
myWidth = copy.myWidth;
|
||||
myHeight = copy.myHeight;
|
||||
myTextureWidth = copy.myTextureWidth;
|
||||
myTextureHeight = copy.myTextureHeight;
|
||||
myTexture = 0;
|
||||
myIsSmooth = copy.myIsSmooth;
|
||||
myPixels = copy.myPixels;
|
||||
myTextureUpdated = true;
|
||||
myArrayUpdated = true;
|
||||
myPixelsFlipped = false; // pixels can't be flipped, this is handled in copy.EnsureArrayUpdate()
|
||||
|
||||
// Create the texture
|
||||
CreateTexture(myWidth, myHeight);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
Image::~Image()
|
||||
{
|
||||
// Destroy the OpenGL texture
|
||||
if (myTexture)
|
||||
{
|
||||
EnsureGlContext();
|
||||
|
||||
GLuint Texture = static_cast<GLuint>(myTexture);
|
||||
GLCheck(glDeleteTextures(1, &Texture));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
bool Image::LoadFromFile(const std::string& filename)
|
||||
{
|
||||
// Forward the job to the image loader
|
||||
std::vector<Uint8> pixels;
|
||||
unsigned int width;
|
||||
unsigned int height;
|
||||
if (priv::ImageLoader::GetInstance().LoadImageFromFile(filename, pixels, width, height))
|
||||
{
|
||||
// Loading succeeded : we can create the texture
|
||||
if (CreateTexture(width, height))
|
||||
{
|
||||
// Copy the pixels
|
||||
myPixels.swap(pixels);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
bool Image::LoadFromMemory(const void* data, std::size_t size)
|
||||
{
|
||||
// Forward the job to the image loader
|
||||
std::vector<Uint8> pixels;
|
||||
unsigned int width;
|
||||
unsigned int height;
|
||||
if (priv::ImageLoader::GetInstance().LoadImageFromMemory(data, size, pixels, width, height))
|
||||
{
|
||||
// Loading succeeded : we can create the texture
|
||||
if (CreateTexture(width, height))
|
||||
{
|
||||
// Copy the pixels
|
||||
myPixels.swap(pixels);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
bool Image::LoadFromStream(InputStream& stream)
|
||||
{
|
||||
// Forward the job to the image loader
|
||||
std::vector<Uint8> pixels;
|
||||
unsigned int width;
|
||||
unsigned int height;
|
||||
if (priv::ImageLoader::GetInstance().LoadImageFromStream(stream, pixels, width, height))
|
||||
{
|
||||
// Loading succeeded : we can create the texture
|
||||
if (CreateTexture(width, height))
|
||||
{
|
||||
// Copy the pixels
|
||||
myPixels.swap(pixels);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
bool Image::LoadFromPixels(unsigned int width, unsigned int height, const Uint8* data)
|
||||
{
|
||||
if (data)
|
||||
{
|
||||
// Create the internal texture
|
||||
if (CreateTexture(width, height))
|
||||
{
|
||||
// Copy the pixels
|
||||
std::size_t size = width * height * 4;
|
||||
myPixels.resize(size);
|
||||
std::memcpy(&myPixels[0], data, size); // faster than vector::assign
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// No data provided : create a white image
|
||||
return Create(width, height, Color(255, 255, 255));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
bool Image::SaveToFile(const std::string& filename) const
|
||||
{
|
||||
// Check if the array of pixels needs to be updated
|
||||
EnsureArrayUpdate();
|
||||
|
||||
// Let the image loader save our pixel array into the image
|
||||
return priv::ImageLoader::GetInstance().SaveImageToFile(filename, myPixels, myWidth, myHeight);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
bool Image::Create(unsigned int width, unsigned int height, const Color& color)
|
||||
{
|
||||
// First create the texture
|
||||
if (CreateTexture(width, height))
|
||||
{
|
||||
// Resize the pixel buffer
|
||||
myPixels.resize(width * height * 4);
|
||||
|
||||
@ -215,22 +63,78 @@ bool Image::Create(unsigned int width, unsigned int height, const Color& color)
|
||||
*ptr++ = color.b;
|
||||
*ptr++ = color.a;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void Image::Create(unsigned int width, unsigned int height, const Uint8* pixels)
|
||||
{
|
||||
if (pixels)
|
||||
{
|
||||
// Assign the new size
|
||||
myWidth = width;
|
||||
myHeight = height;
|
||||
|
||||
// Copy the pixels
|
||||
std::size_t size = width * height * 4;
|
||||
myPixels.resize(size);
|
||||
std::memcpy(&myPixels[0], pixels, size); // faster than vector::assign
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
// Create an empty image
|
||||
myWidth = 0;
|
||||
myHeight = 0;
|
||||
myPixels.clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
bool Image::LoadFromFile(const std::string& filename)
|
||||
{
|
||||
return priv::ImageLoader::GetInstance().LoadImageFromFile(filename, myPixels, myWidth, myHeight);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
bool Image::LoadFromMemory(const void* data, std::size_t size)
|
||||
{
|
||||
return priv::ImageLoader::GetInstance().LoadImageFromMemory(data, size, myPixels, myWidth, myHeight);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
bool Image::LoadFromStream(InputStream& stream)
|
||||
{
|
||||
return priv::ImageLoader::GetInstance().LoadImageFromStream(stream, myPixels, myWidth, myHeight);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
bool Image::SaveToFile(const std::string& filename) const
|
||||
{
|
||||
return priv::ImageLoader::GetInstance().SaveImageToFile(filename, myPixels, myWidth, myHeight);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
unsigned int Image::GetWidth() const
|
||||
{
|
||||
return myWidth;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
unsigned int Image::GetHeight() const
|
||||
{
|
||||
return myHeight;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void Image::CreateMaskFromColor(const Color& color, Uint8 alpha)
|
||||
{
|
||||
// Check if the array of pixels needs to be updated
|
||||
EnsureArrayUpdate();
|
||||
|
||||
// Make sure that the image is not empty
|
||||
if (!myPixels.empty())
|
||||
{
|
||||
@ -243,9 +147,6 @@ void Image::CreateMaskFromColor(const Color& color, Uint8 alpha)
|
||||
ptr[3] = alpha;
|
||||
ptr += 4;
|
||||
}
|
||||
|
||||
// The texture will need to be updated
|
||||
myTextureUpdated = false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -257,10 +158,6 @@ void Image::Copy(const Image& source, unsigned int destX, unsigned int destY, co
|
||||
if ((source.myWidth == 0) || (source.myHeight == 0) || (myWidth == 0) || (myHeight == 0))
|
||||
return;
|
||||
|
||||
// Make sure both images have up-to-date arrays
|
||||
EnsureArrayUpdate();
|
||||
source.EnsureArrayUpdate();
|
||||
|
||||
// Adjust the source rectangle
|
||||
IntRect srcRect = sourceRect;
|
||||
if (srcRect.Width == 0 || (srcRect.Height == 0))
|
||||
@ -330,84 +227,24 @@ void Image::Copy(const Image& source, unsigned int destX, unsigned int destY, co
|
||||
dstPixels += dstStride;
|
||||
}
|
||||
}
|
||||
|
||||
// The texture will need an update
|
||||
myTextureUpdated = false;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
bool Image::CopyScreen(RenderWindow& window, const IntRect& sourceRect)
|
||||
{
|
||||
// Adjust the source rectangle
|
||||
IntRect rect = sourceRect;
|
||||
if (rect.Width == 0 || (rect.Height == 0))
|
||||
{
|
||||
rect.Left = 0;
|
||||
rect.Top = 0;
|
||||
rect.Width = window.GetWidth();
|
||||
rect.Height = window.GetHeight();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (rect.Left < 0) rect.Left = 0;
|
||||
if (rect.Top < 0) rect.Top = 0;
|
||||
if (rect.Width > static_cast<int>(window.GetWidth())) rect.Width = window.GetWidth();
|
||||
if (rect.Height > static_cast<int>(window.GetHeight())) rect.Height = window.GetHeight();
|
||||
}
|
||||
|
||||
// We can then create the texture
|
||||
if (window.SetActive() && CreateTexture(rect.Width, rect.Height))
|
||||
{
|
||||
GLint previous;
|
||||
GLCheck(glGetIntegerv(GL_TEXTURE_BINDING_2D, &previous));
|
||||
|
||||
GLCheck(glBindTexture(GL_TEXTURE_2D, myTexture));
|
||||
int y = window.GetHeight() - (rect.Top + rect.Height); // Y axis is inverted
|
||||
GLCheck(glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, rect.Left, y, myWidth, myHeight));
|
||||
|
||||
GLCheck(glBindTexture(GL_TEXTURE_2D, previous));
|
||||
|
||||
myTextureUpdated = true;
|
||||
myArrayUpdated = false;
|
||||
myPixelsFlipped = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void Image::SetPixel(unsigned int x, unsigned int y, const Color& color)
|
||||
{
|
||||
// First check if the array of pixels needs to be updated
|
||||
EnsureArrayUpdate();
|
||||
|
||||
// Copy the color components
|
||||
Uint8* pixel = &myPixels[(x + y * myWidth) * 4];
|
||||
*pixel++ = color.r;
|
||||
*pixel++ = color.g;
|
||||
*pixel++ = color.b;
|
||||
*pixel++ = color.a;
|
||||
|
||||
// The texture will need to be updated
|
||||
myTextureUpdated = false;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
Color Image::GetPixel(unsigned int x, unsigned int y) const
|
||||
{
|
||||
// First check if the array of pixels needs to be updated
|
||||
EnsureArrayUpdate();
|
||||
|
||||
// Get the color at (x, y)
|
||||
const Uint8* pixel = &myPixels[(x + y * myWidth) * 4];
|
||||
|
||||
return Color(pixel[0], pixel[1], pixel[2], pixel[3]);
|
||||
}
|
||||
|
||||
@ -415,9 +252,6 @@ Color Image::GetPixel(unsigned int x, unsigned int y) const
|
||||
////////////////////////////////////////////////////////////
|
||||
const Uint8* Image::GetPixelsPtr() const
|
||||
{
|
||||
// First check if the array of pixels needs to be updated
|
||||
EnsureArrayUpdate();
|
||||
|
||||
if (!myPixels.empty())
|
||||
{
|
||||
return &myPixels[0];
|
||||
@ -429,339 +263,4 @@ const Uint8* Image::GetPixelsPtr() const
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void Image::UpdatePixels(const Uint8* pixels)
|
||||
{
|
||||
if (pixels && myTexture)
|
||||
{
|
||||
EnsureGlContext();
|
||||
|
||||
GLint previous;
|
||||
GLCheck(glGetIntegerv(GL_TEXTURE_BINDING_2D, &previous));
|
||||
|
||||
// Update the texture from the array of pixels
|
||||
GLCheck(glBindTexture(GL_TEXTURE_2D, myTexture));
|
||||
GLCheck(glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, myWidth, myHeight, GL_RGBA, GL_UNSIGNED_BYTE, pixels));
|
||||
|
||||
GLCheck(glBindTexture(GL_TEXTURE_2D, previous));
|
||||
|
||||
myArrayUpdated = false;
|
||||
myTextureUpdated = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void Image::UpdatePixels(const Uint8* pixels, const IntRect& rectangle)
|
||||
{
|
||||
// Make sure that the texture is up-to-date
|
||||
EnsureTextureUpdate();
|
||||
|
||||
if (pixels && myTexture)
|
||||
{
|
||||
GLint previous;
|
||||
GLCheck(glGetIntegerv(GL_TEXTURE_BINDING_2D, &previous));
|
||||
|
||||
// Update the texture from the array of pixels
|
||||
GLCheck(glBindTexture(GL_TEXTURE_2D, myTexture));
|
||||
GLCheck(glTexSubImage2D(GL_TEXTURE_2D, 0, rectangle.Left, rectangle.Top, rectangle.Width, rectangle.Height, GL_RGBA, GL_UNSIGNED_BYTE, pixels));
|
||||
|
||||
GLCheck(glBindTexture(GL_TEXTURE_2D, previous));
|
||||
|
||||
// The pixel cache is no longer up-to-date
|
||||
myArrayUpdated = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void Image::Bind() const
|
||||
{
|
||||
// First check if the texture needs to be updated
|
||||
EnsureTextureUpdate();
|
||||
|
||||
// Bind it
|
||||
GLCheck(glBindTexture(GL_TEXTURE_2D, myTexture));
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void Image::SetSmooth(bool smooth)
|
||||
{
|
||||
if (smooth != myIsSmooth)
|
||||
{
|
||||
myIsSmooth = smooth;
|
||||
|
||||
if (myTexture)
|
||||
{
|
||||
EnsureGlContext();
|
||||
|
||||
GLint previous;
|
||||
GLCheck(glGetIntegerv(GL_TEXTURE_BINDING_2D, &previous));
|
||||
|
||||
GLCheck(glBindTexture(GL_TEXTURE_2D, myTexture));
|
||||
GLCheck(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, myIsSmooth ? GL_LINEAR : GL_NEAREST));
|
||||
GLCheck(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, myIsSmooth ? GL_LINEAR : GL_NEAREST));
|
||||
|
||||
GLCheck(glBindTexture(GL_TEXTURE_2D, previous));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
unsigned int Image::GetWidth() const
|
||||
{
|
||||
return myWidth;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
unsigned int Image::GetHeight() const
|
||||
{
|
||||
return myHeight;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
bool Image::IsSmooth() const
|
||||
{
|
||||
return myIsSmooth;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
FloatRect Image::GetTexCoords(const IntRect& rect) const
|
||||
{
|
||||
if ((myTextureWidth != 0) && (myTextureHeight != 0))
|
||||
{
|
||||
float width = static_cast<float>(myTextureWidth);
|
||||
float height = static_cast<float>(myTextureHeight);
|
||||
|
||||
if (myPixelsFlipped)
|
||||
{
|
||||
return FloatRect( rect.Left / width,
|
||||
(myHeight - rect.Top) / height,
|
||||
rect.Width / width,
|
||||
-rect.Height / height);
|
||||
}
|
||||
else
|
||||
{
|
||||
return FloatRect(rect.Left / width,
|
||||
rect.Top / height,
|
||||
rect.Width / width,
|
||||
rect.Height / height);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return FloatRect(0, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
unsigned int Image::GetMaximumSize()
|
||||
{
|
||||
EnsureGlContext();
|
||||
|
||||
GLint size;
|
||||
GLCheck(glGetIntegerv(GL_MAX_TEXTURE_SIZE, &size));
|
||||
|
||||
return static_cast<unsigned int>(size);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
Image& Image::operator =(const Image& right)
|
||||
{
|
||||
Image temp(right);
|
||||
|
||||
std::swap(myWidth, temp.myWidth);
|
||||
std::swap(myHeight, temp.myHeight);
|
||||
std::swap(myTextureWidth, temp.myTextureWidth);
|
||||
std::swap(myTextureHeight, temp.myTextureHeight);
|
||||
std::swap(myTexture, temp.myTexture);
|
||||
std::swap(myIsSmooth, temp.myIsSmooth);
|
||||
std::swap(myArrayUpdated, temp.myArrayUpdated);
|
||||
std::swap(myTextureUpdated, temp.myTextureUpdated);
|
||||
std::swap(myPixelsFlipped, temp.myPixelsFlipped);
|
||||
std::swap(myPixels, temp.myPixels);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
unsigned int Image::GetValidSize(unsigned int size)
|
||||
{
|
||||
EnsureGlContext();
|
||||
|
||||
// Make sure that GLEW is initialized
|
||||
priv::EnsureGlewInit();
|
||||
|
||||
if (GLEW_ARB_texture_non_power_of_two)
|
||||
{
|
||||
// If hardware supports NPOT textures, then just return the unmodified size
|
||||
return size;
|
||||
}
|
||||
else
|
||||
{
|
||||
// If hardware doesn't support NPOT textures, we calculate the nearest power of two
|
||||
unsigned int powerOfTwo = 1;
|
||||
while (powerOfTwo < size)
|
||||
powerOfTwo *= 2;
|
||||
|
||||
return powerOfTwo;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
bool Image::CreateTexture(unsigned int width, unsigned int height)
|
||||
{
|
||||
// Check if texture parameters are valid before creating it
|
||||
if (!width || !height)
|
||||
return false;
|
||||
|
||||
// Compute the internal texture dimensions depending on NPOT textures support
|
||||
unsigned int textureWidth = GetValidSize(width);
|
||||
unsigned int textureHeight = GetValidSize(height);
|
||||
|
||||
// Check the maximum texture size
|
||||
unsigned int maxSize = GetMaximumSize();
|
||||
if ((textureWidth > maxSize) || (textureHeight > maxSize))
|
||||
{
|
||||
Err() << "Failed to create image, its internal size is too high "
|
||||
<< "(" << textureWidth << "x" << textureHeight << ", "
|
||||
<< "maximum is " << maxSize << "x" << maxSize << ")"
|
||||
<< std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// All the validity checks passed, we can store the new texture settings
|
||||
myWidth = width;
|
||||
myHeight = height;
|
||||
myTextureWidth = textureWidth;
|
||||
myTextureHeight = textureHeight;
|
||||
|
||||
EnsureGlContext();
|
||||
|
||||
// Create the OpenGL texture if it doesn't exist yet
|
||||
if (!myTexture)
|
||||
{
|
||||
GLuint texture;
|
||||
GLCheck(glGenTextures(1, &texture));
|
||||
myTexture = static_cast<unsigned int>(texture);
|
||||
}
|
||||
|
||||
// Initialize the texture
|
||||
GLint previous;
|
||||
GLCheck(glGetIntegerv(GL_TEXTURE_BINDING_2D, &previous));
|
||||
GLCheck(glBindTexture(GL_TEXTURE_2D, myTexture));
|
||||
GLCheck(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, myTextureWidth, myTextureHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL));
|
||||
GLCheck(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
|
||||
GLCheck(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
|
||||
GLCheck(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, myIsSmooth ? GL_LINEAR : GL_NEAREST));
|
||||
GLCheck(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, myIsSmooth ? GL_LINEAR : GL_NEAREST));
|
||||
GLCheck(glBindTexture(GL_TEXTURE_2D, previous));
|
||||
|
||||
myTextureUpdated = false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void Image::EnsureTextureUpdate() const
|
||||
{
|
||||
if (!myTextureUpdated)
|
||||
{
|
||||
if (myTexture && !myPixels.empty())
|
||||
{
|
||||
EnsureGlContext();
|
||||
|
||||
GLint previous;
|
||||
GLCheck(glGetIntegerv(GL_TEXTURE_BINDING_2D, &previous));
|
||||
|
||||
// Update the texture with the pixels array in RAM
|
||||
GLCheck(glBindTexture(GL_TEXTURE_2D, myTexture));
|
||||
GLCheck(glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, myWidth, myHeight, GL_RGBA, GL_UNSIGNED_BYTE, &myPixels[0]));
|
||||
myPixelsFlipped = false;
|
||||
|
||||
GLCheck(glBindTexture(GL_TEXTURE_2D, previous));
|
||||
}
|
||||
|
||||
myTextureUpdated = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void Image::EnsureArrayUpdate() const
|
||||
{
|
||||
if (!myArrayUpdated)
|
||||
{
|
||||
EnsureGlContext();
|
||||
|
||||
// Save the previous texture
|
||||
GLint previous;
|
||||
GLCheck(glGetIntegerv(GL_TEXTURE_BINDING_2D, &previous));
|
||||
|
||||
// Resize the destination array of pixels
|
||||
myPixels.resize(myWidth * myHeight * 4);
|
||||
|
||||
if ((myWidth == myTextureWidth) && (myHeight == myTextureHeight) && !myPixelsFlipped)
|
||||
{
|
||||
// Texture and array have the same size, we can use a direct copy
|
||||
|
||||
// Copy pixels from texture to array
|
||||
GLCheck(glBindTexture(GL_TEXTURE_2D, myTexture));
|
||||
GLCheck(glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, &myPixels[0]));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Texture and array don't have the same size, we have to use a slower algorithm
|
||||
|
||||
// All the pixels will first be copied to a temporary array
|
||||
ColorArray allPixels(myTextureWidth * myTextureHeight * 4);
|
||||
GLCheck(glBindTexture(GL_TEXTURE_2D, myTexture));
|
||||
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
|
||||
const Uint8* src = &allPixels[0];
|
||||
Uint8* dst = &myPixels[0];
|
||||
int srcPitch = myTextureWidth * 4;
|
||||
int dstPitch = myWidth * 4;
|
||||
|
||||
// Handle the case where source pixels are flipped vertically
|
||||
if (myPixelsFlipped)
|
||||
{
|
||||
src += srcPitch * (myHeight - 1);
|
||||
srcPitch = -srcPitch;
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < myHeight; ++i)
|
||||
{
|
||||
std::memcpy(dst, src, dstPitch);
|
||||
src += srcPitch;
|
||||
dst += dstPitch;
|
||||
}
|
||||
}
|
||||
|
||||
// Restore the previous texture
|
||||
GLCheck(glBindTexture(GL_TEXTURE_2D, previous));
|
||||
|
||||
myArrayUpdated = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void Image::Use() const
|
||||
{
|
||||
EnsureTextureUpdate();
|
||||
}
|
||||
|
||||
} // namespace sf
|
||||
|
@ -25,57 +25,57 @@
|
||||
////////////////////////////////////////////////////////////
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/Graphics/RenderImage.hpp>
|
||||
#include <SFML/Graphics/RenderImageImplFBO.hpp>
|
||||
#include <SFML/Graphics/RenderImageImplDefault.hpp>
|
||||
#include <SFML/Graphics/RenderTexture.hpp>
|
||||
#include <SFML/Graphics/RenderTextureImplFBO.hpp>
|
||||
#include <SFML/Graphics/RenderTextureImplDefault.hpp>
|
||||
#include <SFML/System/Err.hpp>
|
||||
|
||||
|
||||
namespace sf
|
||||
{
|
||||
////////////////////////////////////////////////////////////
|
||||
RenderImage::RenderImage() :
|
||||
myRenderImage(NULL)
|
||||
RenderTexture::RenderTexture() :
|
||||
myRenderTexture(NULL)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
RenderImage::~RenderImage()
|
||||
RenderTexture::~RenderTexture()
|
||||
{
|
||||
delete myRenderImage;
|
||||
delete myRenderTexture;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
bool RenderImage::Create(unsigned int width, unsigned int height, bool depthBuffer)
|
||||
bool RenderTexture::Create(unsigned int width, unsigned int height, bool depthBuffer)
|
||||
{
|
||||
// Create the image
|
||||
if (!myImage.Create(width, height))
|
||||
// Create the texture
|
||||
if (!myTexture.Create(width, height))
|
||||
{
|
||||
Err() << "Impossible to create render image (failed to create the target image)" << std::endl;
|
||||
Err() << "Impossible to create render texture (failed to create the target texture)" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// We disable smoothing by default for render images
|
||||
// We disable smoothing by default for render textures
|
||||
SetSmooth(false);
|
||||
|
||||
// Create the implementation
|
||||
delete myRenderImage;
|
||||
if (priv::RenderImageImplFBO::IsAvailable())
|
||||
delete myRenderTexture;
|
||||
if (priv::RenderTextureImplFBO::IsAvailable())
|
||||
{
|
||||
// Use frame-buffer object (FBO)
|
||||
myRenderImage = new priv::RenderImageImplFBO;
|
||||
myRenderTexture = new priv::RenderTextureImplFBO;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Use default implementation
|
||||
myRenderImage = new priv::RenderImageImplDefault;
|
||||
myRenderTexture = new priv::RenderTextureImplDefault;
|
||||
}
|
||||
|
||||
// Initialize the render image
|
||||
if (!myRenderImage->Create(width, height, myImage.myTexture, depthBuffer))
|
||||
// Initialize the render texture
|
||||
if (!myRenderTexture->Create(width, height, myTexture.myTexture, depthBuffer))
|
||||
return false;
|
||||
|
||||
// We can now initialize the render target part
|
||||
@ -86,64 +86,61 @@ bool RenderImage::Create(unsigned int width, unsigned int height, bool depthBuff
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void RenderImage::SetSmooth(bool smooth)
|
||||
void RenderTexture::SetSmooth(bool smooth)
|
||||
{
|
||||
myImage.SetSmooth(smooth);
|
||||
myTexture.SetSmooth(smooth);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
bool RenderImage::IsSmooth() const
|
||||
bool RenderTexture::IsSmooth() const
|
||||
{
|
||||
return myImage.IsSmooth();
|
||||
return myTexture.IsSmooth();
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
bool RenderImage::SetActive(bool active)
|
||||
bool RenderTexture::SetActive(bool active)
|
||||
{
|
||||
return myRenderImage && myRenderImage->Activate(active);
|
||||
return myRenderTexture && myRenderTexture->Activate(active);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void RenderImage::Display()
|
||||
void RenderTexture::Display()
|
||||
{
|
||||
// Update the target image
|
||||
// Update the target texture
|
||||
if (SetActive(true))
|
||||
{
|
||||
myRenderImage->UpdateTexture(myImage.myTexture);
|
||||
|
||||
myImage.myPixelsFlipped = true;
|
||||
myImage.myArrayUpdated = false;
|
||||
myImage.myTextureUpdated = true;
|
||||
myRenderTexture->UpdateTexture(myTexture.myTexture);
|
||||
myTexture.myPixelsFlipped = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
unsigned int RenderImage::GetWidth() const
|
||||
unsigned int RenderTexture::GetWidth() const
|
||||
{
|
||||
return myImage.GetWidth();
|
||||
return myTexture.GetWidth();
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
unsigned int RenderImage::GetHeight() const
|
||||
unsigned int RenderTexture::GetHeight() const
|
||||
{
|
||||
return myImage.GetHeight();
|
||||
return myTexture.GetHeight();
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
const Image& RenderImage::GetImage() const
|
||||
const Texture& RenderTexture::GetTexture() const
|
||||
{
|
||||
return myImage;
|
||||
return myTexture;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
bool RenderImage::Activate(bool active)
|
||||
bool RenderTexture::Activate(bool active)
|
||||
{
|
||||
return SetActive(active);
|
||||
}
|
@ -25,7 +25,7 @@
|
||||
////////////////////////////////////////////////////////////
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/Graphics/RenderImageImpl.hpp>
|
||||
#include <SFML/Graphics/RenderTextureImpl.hpp>
|
||||
|
||||
|
||||
namespace sf
|
||||
@ -33,7 +33,7 @@ namespace sf
|
||||
namespace priv
|
||||
{
|
||||
////////////////////////////////////////////////////////////
|
||||
RenderImageImpl::~RenderImageImpl()
|
||||
RenderTextureImpl::~RenderTextureImpl()
|
||||
{
|
||||
// Nothing to do
|
||||
}
|
@ -22,8 +22,8 @@
|
||||
//
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef SFML_RENDERIMAGEIMPL_HPP
|
||||
#define SFML_RENDERIMAGEIMPL_HPP
|
||||
#ifndef SFML_RENDERTEXTUREIMPL_HPP
|
||||
#define SFML_RENDERTEXTUREIMPL_HPP
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Headers
|
||||
@ -36,10 +36,10 @@ namespace sf
|
||||
namespace priv
|
||||
{
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Abstract base class for render-image implementations
|
||||
/// \brief Abstract base class for render-texture implementations
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
class RenderImageImpl : NonCopyable
|
||||
class RenderTextureImpl : NonCopyable
|
||||
{
|
||||
public :
|
||||
|
||||
@ -47,14 +47,14 @@ public :
|
||||
/// \brief Destructor
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
virtual ~RenderImageImpl();
|
||||
virtual ~RenderTextureImpl();
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Create the render image implementation
|
||||
/// \brief Create the render texture implementation
|
||||
///
|
||||
/// \param width Width of the image to render to
|
||||
/// \param height Height of the image to render to
|
||||
/// \param textureId OpenGL texture identifier of the target image
|
||||
/// \param width Width of the texture to render to
|
||||
/// \param height Height of the texture to render to
|
||||
/// \param textureId OpenGL identifier of the target texture
|
||||
/// \param depthBuffer Is a depth buffer requested?
|
||||
///
|
||||
/// \return True if creation has been successful
|
||||
@ -63,7 +63,7 @@ public :
|
||||
virtual bool Create(unsigned int width, unsigned int height, unsigned int textureId, bool depthBuffer) = 0;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Activate or deactivate the render image for rendering
|
||||
/// \brief Activate or deactivate the render texture for rendering
|
||||
///
|
||||
/// \param active True to activate, false to deactivate
|
||||
///
|
||||
@ -86,4 +86,4 @@ public :
|
||||
} // namespace sf
|
||||
|
||||
|
||||
#endif // SFML_RENDERIMAGEIMPL_HPP
|
||||
#endif // SFML_RENDERTEXTUREIMPL_HPP
|
@ -25,7 +25,7 @@
|
||||
////////////////////////////////////////////////////////////
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/Graphics/RenderImageImplDefault.hpp>
|
||||
#include <SFML/Graphics/RenderTextureImplDefault.hpp>
|
||||
#include <SFML/Graphics/GLCheck.hpp>
|
||||
#include <SFML/Window/Context.hpp>
|
||||
#include <SFML/System/Err.hpp>
|
||||
@ -36,7 +36,7 @@ namespace sf
|
||||
namespace priv
|
||||
{
|
||||
////////////////////////////////////////////////////////////
|
||||
RenderImageImplDefault::RenderImageImplDefault() :
|
||||
RenderTextureImplDefault::RenderTextureImplDefault() :
|
||||
myContext(0),
|
||||
myWidth (0),
|
||||
myHeight (0)
|
||||
@ -46,7 +46,7 @@ myHeight (0)
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
RenderImageImplDefault::~RenderImageImplDefault()
|
||||
RenderTextureImplDefault::~RenderTextureImplDefault()
|
||||
{
|
||||
// Destroy the context
|
||||
delete myContext;
|
||||
@ -54,33 +54,33 @@ RenderImageImplDefault::~RenderImageImplDefault()
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
bool RenderImageImplDefault::Create(unsigned int width, unsigned int height, unsigned int, bool depthBuffer)
|
||||
bool RenderTextureImplDefault::Create(unsigned int width, unsigned int height, unsigned int, bool depthBuffer)
|
||||
{
|
||||
// Store the dimensions
|
||||
myWidth = width;
|
||||
myHeight = height;
|
||||
|
||||
// Create the in-memory OpenGL context
|
||||
myContext = new Context(ContextSettings(depthBuffer ? 32 : 0, 0, 4), width, height);
|
||||
myContext = new Context(ContextSettings(depthBuffer ? 32 : 0), width, height);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
bool RenderImageImplDefault::Activate(bool active)
|
||||
bool RenderTextureImplDefault::Activate(bool active)
|
||||
{
|
||||
return myContext->SetActive(active);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void RenderImageImplDefault::UpdateTexture(unsigned int textureId)
|
||||
void RenderTextureImplDefault::UpdateTexture(unsigned int textureId)
|
||||
{
|
||||
GLint previous;
|
||||
GLCheck(glGetIntegerv(GL_TEXTURE_BINDING_2D, &previous));
|
||||
|
||||
// Copy the rendered pixels to the image
|
||||
// Copy the rendered pixels to the texture
|
||||
GLCheck(glBindTexture(GL_TEXTURE_2D, textureId));
|
||||
GLCheck(glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, myWidth, myHeight));
|
||||
|
@ -22,13 +22,13 @@
|
||||
//
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef SFML_RENDERIMAGEIMPLDEFAULT_HPP
|
||||
#define SFML_RENDERIMAGEIMPLDEFAULT_HPP
|
||||
#ifndef SFML_RENDERTEXTUREIMPLDEFAULT_HPP
|
||||
#define SFML_RENDERTEXTUREIMPLDEFAULT_HPP
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/Graphics/RenderImageImpl.hpp>
|
||||
#include <SFML/Graphics/RenderTextureImpl.hpp>
|
||||
#include <SFML/Window/GlResource.hpp>
|
||||
#include <SFML/Window/Context.hpp>
|
||||
|
||||
@ -38,11 +38,11 @@ namespace sf
|
||||
namespace priv
|
||||
{
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Default specialization of RenderImageImpl,
|
||||
/// \brief Default specialization of RenderTextureImpl,
|
||||
/// using a in-memory context
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
class RenderImageImplDefault : public RenderImageImpl, GlResource
|
||||
class RenderTextureImplDefault : public RenderTextureImpl, GlResource
|
||||
{
|
||||
public :
|
||||
|
||||
@ -50,22 +50,22 @@ public :
|
||||
/// \brief Default constructor
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
RenderImageImplDefault();
|
||||
RenderTextureImplDefault();
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Destructor
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
~RenderImageImplDefault();
|
||||
~RenderTextureImplDefault();
|
||||
|
||||
private :
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Create the render image implementation
|
||||
/// \brief Create the render texture implementation
|
||||
///
|
||||
/// \param width Width of the image to render to
|
||||
/// \param height Height of the image to render to
|
||||
/// \param textureId OpenGL texture identifier of the target image
|
||||
/// \param width Width of the texture to render to
|
||||
/// \param height Height of the texture to render to
|
||||
/// \param textureId OpenGL identifier of the target texture
|
||||
/// \param depthBuffer Is a depth buffer requested?
|
||||
///
|
||||
/// \return True if creation has been successful
|
||||
@ -74,7 +74,7 @@ private :
|
||||
virtual bool Create(unsigned int width, unsigned int height, unsigned int textureId, bool depthBuffer);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Activate or deactivate the render image for rendering
|
||||
/// \brief Activate or deactivate the render texture for rendering
|
||||
///
|
||||
/// \param active True to activate, false to deactivate
|
||||
///
|
||||
@ -104,4 +104,4 @@ private :
|
||||
} // namespace sf
|
||||
|
||||
|
||||
#endif // SFML_RENDERIMAGEIMPLDEFAULT_HPP
|
||||
#endif // SFML_RENDERTEXTUREIMPLDEFAULT_HPP
|
@ -25,8 +25,8 @@
|
||||
////////////////////////////////////////////////////////////
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/Graphics/RenderImageImplFBO.hpp>
|
||||
#include <SFML/Graphics/Image.hpp>
|
||||
#include <SFML/Graphics/RenderTextureImplFBO.hpp>
|
||||
#include <SFML/Graphics/Texture.hpp>
|
||||
#include <SFML/Graphics/GLCheck.hpp>
|
||||
#include <SFML/System/Err.hpp>
|
||||
|
||||
@ -36,7 +36,7 @@ namespace sf
|
||||
namespace priv
|
||||
{
|
||||
////////////////////////////////////////////////////////////
|
||||
RenderImageImplFBO::RenderImageImplFBO() :
|
||||
RenderTextureImplFBO::RenderTextureImplFBO() :
|
||||
myFrameBuffer(0),
|
||||
myDepthBuffer(0)
|
||||
{
|
||||
@ -45,7 +45,7 @@ myDepthBuffer(0)
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
RenderImageImplFBO::~RenderImageImplFBO()
|
||||
RenderTextureImplFBO::~RenderTextureImplFBO()
|
||||
{
|
||||
EnsureGlContext();
|
||||
|
||||
@ -69,7 +69,7 @@ RenderImageImplFBO::~RenderImageImplFBO()
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
bool RenderImageImplFBO::IsAvailable()
|
||||
bool RenderTextureImplFBO::IsAvailable()
|
||||
{
|
||||
EnsureGlContext();
|
||||
|
||||
@ -81,7 +81,7 @@ bool RenderImageImplFBO::IsAvailable()
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
bool RenderImageImplFBO::Create(unsigned int width, unsigned int height, unsigned int textureId, bool depthBuffer)
|
||||
bool RenderTextureImplFBO::Create(unsigned int width, unsigned int height, unsigned int textureId, bool depthBuffer)
|
||||
{
|
||||
//Create the context
|
||||
myContext = new Context;
|
||||
@ -92,7 +92,7 @@ bool RenderImageImplFBO::Create(unsigned int width, unsigned int height, unsigne
|
||||
myFrameBuffer = static_cast<unsigned int>(frameBuffer);
|
||||
if (!myFrameBuffer)
|
||||
{
|
||||
Err() << "Impossible to create render image (failed to create the frame buffer object)" << std::endl;
|
||||
Err() << "Impossible to create render texture (failed to create the frame buffer object)" << std::endl;
|
||||
return false;
|
||||
}
|
||||
GLCheck(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, myFrameBuffer));
|
||||
@ -105,7 +105,7 @@ bool RenderImageImplFBO::Create(unsigned int width, unsigned int height, unsigne
|
||||
myDepthBuffer = static_cast<unsigned int>(depth);
|
||||
if (!myDepthBuffer)
|
||||
{
|
||||
Err() << "Impossible to create render image (failed to create the attached depth buffer)" << std::endl;
|
||||
Err() << "Impossible to create render texture (failed to create the attached depth buffer)" << std::endl;
|
||||
return false;
|
||||
}
|
||||
GLCheck(glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, myDepthBuffer));
|
||||
@ -113,14 +113,14 @@ bool RenderImageImplFBO::Create(unsigned int width, unsigned int height, unsigne
|
||||
GLCheck(glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, myDepthBuffer));
|
||||
}
|
||||
|
||||
// Link the image to the frame buffer
|
||||
// Link the texture to the frame buffer
|
||||
GLCheck(glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, textureId, 0));
|
||||
|
||||
// A final check, just to be sure...
|
||||
if (glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) != GL_FRAMEBUFFER_COMPLETE_EXT)
|
||||
{
|
||||
GLCheck(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0));
|
||||
Err() << "Impossible to create render image (failed to link the target image to the frame buffer)" << std::endl;
|
||||
Err() << "Impossible to create render texture (failed to link the target texture to the frame buffer)" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -129,13 +129,13 @@ bool RenderImageImplFBO::Create(unsigned int width, unsigned int height, unsigne
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
bool RenderImageImplFBO::Activate(bool active)
|
||||
bool RenderTextureImplFBO::Activate(bool active)
|
||||
{
|
||||
return myContext->SetActive(active);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void RenderImageImplFBO::UpdateTexture(unsigned int)
|
||||
void RenderTextureImplFBO::UpdateTexture(unsigned int)
|
||||
{
|
||||
glFlush();
|
||||
}
|
@ -22,13 +22,13 @@
|
||||
//
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef SFML_RENDERIMAGEIMPLFBO_HPP
|
||||
#define SFML_RENDERIMAGEIMPLFBO_HPP
|
||||
#ifndef SFML_RENDERTEXTUREIMPLFBO_HPP
|
||||
#define SFML_RENDERTEXTUREIMPLFBO_HPP
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/Graphics/RenderImageImpl.hpp>
|
||||
#include <SFML/Graphics/RenderTextureImpl.hpp>
|
||||
#include <SFML/Window/Context.hpp>
|
||||
#include <SFML/Window/GlResource.hpp>
|
||||
|
||||
@ -38,11 +38,11 @@ namespace sf
|
||||
namespace priv
|
||||
{
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Specialization of RenderImageImpl using the
|
||||
/// Frame Buffer Object OpenGL extension
|
||||
/// \brief Specialization of RenderTextureImpl using the
|
||||
/// FrameBuffer Object OpenGL extension
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
class RenderImageImplFBO : public RenderImageImpl, GlResource
|
||||
class RenderTextureImplFBO : public RenderTextureImpl, GlResource
|
||||
{
|
||||
public :
|
||||
|
||||
@ -50,18 +50,18 @@ public :
|
||||
/// \brief Default constructor
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
RenderImageImplFBO();
|
||||
RenderTextureImplFBO();
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Destructor
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
~RenderImageImplFBO();
|
||||
~RenderTextureImplFBO();
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Check whether the system supports FBOs or not
|
||||
///
|
||||
/// \return True if FBO render images are supported
|
||||
/// \return True if FBO render textures are supported
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
static bool IsAvailable();
|
||||
@ -69,11 +69,11 @@ public :
|
||||
private :
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Create the render image implementation
|
||||
/// \brief Create the render texture implementation
|
||||
///
|
||||
/// \param width Width of the image to render to
|
||||
/// \param height Height of the image to render to
|
||||
/// \param textureId OpenGL texture identifier of the target image
|
||||
/// \param width Width of the texture to render to
|
||||
/// \param height Height of the texture to render to
|
||||
/// \param textureId OpenGL identifier of the target texture
|
||||
/// \param depthBuffer Is a depth buffer requested?
|
||||
///
|
||||
/// \return True if creation has been successful
|
||||
@ -82,7 +82,7 @@ private :
|
||||
virtual bool Create(unsigned int width, unsigned int height, unsigned int textureId, bool depthBuffer);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Activate or deactivate the render image for rendering
|
||||
/// \brief Activate or deactivate the render texture for rendering
|
||||
///
|
||||
/// \param active True to activate, false to deactivate
|
||||
///
|
||||
@ -112,4 +112,4 @@ private :
|
||||
} // namespace sf
|
||||
|
||||
|
||||
#endif // SFML_RENDERIMAGEIMPLFBO_HPP
|
||||
#endif // SFML_RENDERTEXTUREIMPLFBO_HPP
|
@ -26,6 +26,7 @@
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/Graphics/RenderWindow.hpp>
|
||||
#include <SFML/Graphics/GLCheck.hpp>
|
||||
|
||||
|
||||
namespace sf
|
||||
@ -81,6 +82,30 @@ unsigned int RenderWindow::GetHeight() const
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
Image RenderWindow::Capture() const
|
||||
{
|
||||
Image image;
|
||||
if (SetActive())
|
||||
{
|
||||
int width = static_cast<int>(GetWidth());
|
||||
int height = static_cast<int>(GetHeight());
|
||||
|
||||
// copy rows one by one and flip them (OpenGL's origin is bottom while SFML's origin is top)
|
||||
std::vector<Uint8> pixels(width * height * 4);
|
||||
for (int i = 0; i < height; ++i)
|
||||
{
|
||||
Uint8* ptr = &pixels[i * width * 4];
|
||||
GLCheck(glReadPixels(0, height - i - 1, width, 1, GL_RGBA, GL_UNSIGNED_BYTE, ptr));
|
||||
}
|
||||
|
||||
image.Create(width, height, &pixels[0]);
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void RenderWindow::OnCreate()
|
||||
{
|
||||
|
@ -27,7 +27,7 @@
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/Graphics/Renderer.hpp>
|
||||
#include <SFML/Graphics/RenderTarget.hpp>
|
||||
#include <SFML/Graphics/Image.hpp>
|
||||
#include <SFML/Graphics/Texture.hpp>
|
||||
#include <SFML/Graphics/Shader.hpp>
|
||||
#include <SFML/Graphics/GLCheck.hpp>
|
||||
|
||||
@ -202,7 +202,7 @@ void Renderer::SetBlendMode(Blend::Mode mode)
|
||||
{
|
||||
// Alpha blending
|
||||
// glBlendFuncSeparateEXT is used when available to avoid an incorrect alpha value when the target
|
||||
// is a RenderImage -- in this case the alpha value must be written directly to the target buffer
|
||||
// is a RenderTexture -- in this case the alpha value must be written directly to the target buffer
|
||||
default :
|
||||
case Blend::Alpha :
|
||||
if (GLEW_EXT_blend_func_separate)
|
||||
@ -231,7 +231,7 @@ void Renderer::SetBlendMode(Blend::Mode mode)
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void Renderer::SetTexture(const Image* texture)
|
||||
void Renderer::SetTexture(const Texture* texture)
|
||||
{
|
||||
if ((texture != myTexture) || (texture && (texture->myTexture != myTextureId)) || !myTextureIsValid)
|
||||
{
|
||||
@ -246,12 +246,6 @@ void Renderer::SetTexture(const Image* texture)
|
||||
myTextureId = texture ? texture->myTexture : 0;
|
||||
myTextureIsValid = true;
|
||||
}
|
||||
else if (texture && myTextureIsValid)
|
||||
{
|
||||
// If the texture was already the current one, make sure that
|
||||
// it is synchronized (in case it was modified since last use)
|
||||
texture->Use();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -225,7 +225,7 @@ void Shader::SetParameter(const std::string& name, const Vector3f& v)
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void Shader::SetTexture(const std::string& name, const Image& texture)
|
||||
void Shader::SetTexture(const std::string& name, const Texture& texture)
|
||||
{
|
||||
if (myShaderProgram)
|
||||
{
|
||||
|
@ -26,7 +26,7 @@
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/Graphics/Sprite.hpp>
|
||||
#include <SFML/Graphics/Image.hpp>
|
||||
#include <SFML/Graphics/Texture.hpp>
|
||||
#include <SFML/Graphics/Renderer.hpp>
|
||||
#include <utility>
|
||||
|
||||
@ -35,6 +35,7 @@ namespace sf
|
||||
{
|
||||
////////////////////////////////////////////////////////////
|
||||
Sprite::Sprite() :
|
||||
Drawable (),
|
||||
mySubRect (0, 0, 1, 1),
|
||||
myIsFlippedX(false),
|
||||
myIsFlippedY(false)
|
||||
@ -44,31 +45,31 @@ myIsFlippedY(false)
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
Sprite::Sprite(const Image& image, const Vector2f& position, const Vector2f& scale, float rotation, const Color& color) :
|
||||
Drawable (position, scale, rotation, color),
|
||||
Sprite::Sprite(const Texture& texture) :
|
||||
Drawable (),
|
||||
mySubRect (0, 0, 1, 1),
|
||||
myIsFlippedX(false),
|
||||
myIsFlippedY(false)
|
||||
{
|
||||
SetImage(image);
|
||||
SetTexture(texture);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void Sprite::SetImage(const Image& image, bool adjustToNewSize)
|
||||
void Sprite::SetTexture(const Texture& texture, bool adjustToNewSize)
|
||||
{
|
||||
// If there was no valid image before, force adjusting to the new image size
|
||||
if (!myImage)
|
||||
// If there was no valid texture before, force adjusting to the new texture size
|
||||
if (!myTexture)
|
||||
adjustToNewSize = true;
|
||||
|
||||
// If we want to adjust the size and the new image is valid, we adjust the source rectangle
|
||||
if (adjustToNewSize && (image.GetWidth() > 0) && (image.GetHeight() > 0))
|
||||
// If we want to adjust the size and the new texture is valid, we adjust the source rectangle
|
||||
if (adjustToNewSize && (texture.GetWidth() > 0) && (texture.GetHeight() > 0))
|
||||
{
|
||||
SetSubRect(IntRect(0, 0, image.GetWidth(), image.GetHeight()));
|
||||
SetSubRect(IntRect(0, 0, texture.GetWidth(), texture.GetHeight()));
|
||||
}
|
||||
|
||||
// Assign the new image
|
||||
myImage = ℑ
|
||||
// Assign the new texture
|
||||
myTexture = &texture;
|
||||
}
|
||||
|
||||
|
||||
@ -109,9 +110,9 @@ void Sprite::FlipY(bool flipped)
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
const Image* Sprite::GetImage() const
|
||||
const Texture* Sprite::GetTexture() const
|
||||
{
|
||||
return myImage;
|
||||
return myTexture;
|
||||
}
|
||||
|
||||
|
||||
@ -129,26 +130,6 @@ Vector2f Sprite::GetSize() const
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
Color Sprite::GetPixel(unsigned int x, unsigned int y) const
|
||||
{
|
||||
if (myImage)
|
||||
{
|
||||
unsigned int imageX = mySubRect.Left + x;
|
||||
unsigned int imageY = mySubRect.Top + y;
|
||||
|
||||
if (myIsFlippedX) imageX = mySubRect.Width - imageX - 1;
|
||||
if (myIsFlippedY) imageY = mySubRect.Height - imageY - 1;
|
||||
|
||||
return myImage->GetPixel(imageX, imageY) * GetColor();
|
||||
}
|
||||
else
|
||||
{
|
||||
return GetColor();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void Sprite::Render(RenderTarget&, Renderer& renderer) const
|
||||
{
|
||||
@ -156,10 +137,10 @@ void Sprite::Render(RenderTarget&, Renderer& renderer) const
|
||||
float width = static_cast<float>(mySubRect.Width);
|
||||
float height = static_cast<float>(mySubRect.Height);
|
||||
|
||||
// Check if the image is valid, and calculate the texture coordinates
|
||||
// Check if the texture is valid, and calculate the texture coordinates
|
||||
FloatRect coords;
|
||||
if (myImage)
|
||||
coords = myImage->GetTexCoords(mySubRect);
|
||||
if (myTexture)
|
||||
coords = myTexture->GetTexCoords(mySubRect);
|
||||
|
||||
// Compute the texture coordinates
|
||||
float left = coords.Left;
|
||||
@ -170,7 +151,7 @@ void Sprite::Render(RenderTarget&, Renderer& renderer) const
|
||||
if (myIsFlippedY) std::swap(top, bottom);
|
||||
|
||||
// Bind the texture
|
||||
renderer.SetTexture(myImage);
|
||||
renderer.SetTexture(myTexture);
|
||||
|
||||
// Draw the sprite's geometry
|
||||
renderer.Begin(Renderer::TriangleStrip);
|
||||
|
@ -26,7 +26,7 @@
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/Graphics/Text.hpp>
|
||||
#include <SFML/Graphics/Image.hpp>
|
||||
#include <SFML/Graphics/Texture.hpp>
|
||||
#include <SFML/Graphics/Renderer.hpp>
|
||||
|
||||
|
||||
@ -190,7 +190,7 @@ void Text::Render(RenderTarget&, Renderer& renderer) const
|
||||
return;
|
||||
|
||||
// Bind the font texture
|
||||
const Image& texture = myFont->GetImage(myCharacterSize);
|
||||
const Texture& texture = myFont->GetTexture(myCharacterSize);
|
||||
renderer.SetTexture(&texture);
|
||||
|
||||
// Computes values related to the text style
|
||||
|
506
src/SFML/Graphics/Texture.cpp
Normal file
506
src/SFML/Graphics/Texture.cpp
Normal file
@ -0,0 +1,506 @@
|
||||
////////////////////////////////////////////////////////////
|
||||
//
|
||||
// SFML - Simple and Fast Multimedia Library
|
||||
// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied warranty.
|
||||
// In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it freely,
|
||||
// subject to the following restrictions:
|
||||
//
|
||||
// 1. The origin of this software must not be misrepresented;
|
||||
// you must not claim that you wrote the original software.
|
||||
// If you use this software in a product, an acknowledgment
|
||||
// in the product documentation would be appreciated but is not required.
|
||||
//
|
||||
// 2. Altered source versions must be plainly marked as such,
|
||||
// and must not be misrepresented as being the original software.
|
||||
//
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
//
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/Graphics/Texture.hpp>
|
||||
#include <SFML/Graphics/Image.hpp>
|
||||
#include <SFML/Graphics/GLCheck.hpp>
|
||||
#include <SFML/Window/Window.hpp>
|
||||
#include <SFML/System/Err.hpp>
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
|
||||
|
||||
namespace sf
|
||||
{
|
||||
////////////////////////////////////////////////////////////
|
||||
Texture::Texture() :
|
||||
myWidth (0),
|
||||
myHeight (0),
|
||||
myTextureWidth (0),
|
||||
myTextureHeight(0),
|
||||
myTexture (0),
|
||||
myIsSmooth (false),
|
||||
myPixelsFlipped(false)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
Texture::Texture(const Texture& copy) :
|
||||
Resource<Texture>(),
|
||||
myWidth (0),
|
||||
myHeight (0),
|
||||
myTextureWidth (0),
|
||||
myTextureHeight(0),
|
||||
myTexture (0),
|
||||
myIsSmooth (false),
|
||||
myPixelsFlipped(false)
|
||||
{
|
||||
LoadFromImage(copy.CopyToImage());
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
Texture::~Texture()
|
||||
{
|
||||
// Destroy the OpenGL texture
|
||||
if (myTexture)
|
||||
{
|
||||
EnsureGlContext();
|
||||
|
||||
GLuint Texture = static_cast<GLuint>(myTexture);
|
||||
GLCheck(glDeleteTextures(1, &Texture));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
bool Texture::Create(unsigned int width, unsigned int height)
|
||||
{
|
||||
// Check if texture parameters are valid before creating it
|
||||
if (!width || !height)
|
||||
{
|
||||
Err() << "Failed to create texture, invalid size (" << width << "x" << height << ")" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Compute the internal texture dimensions depending on NPOT textures support
|
||||
unsigned int textureWidth = GetValidSize(width);
|
||||
unsigned int textureHeight = GetValidSize(height);
|
||||
|
||||
// Check the maximum texture size
|
||||
unsigned int maxSize = GetMaximumSize();
|
||||
if ((textureWidth > maxSize) || (textureHeight > maxSize))
|
||||
{
|
||||
Err() << "Failed to create texture, its internal size is too high "
|
||||
<< "(" << textureWidth << "x" << textureHeight << ", "
|
||||
<< "maximum is " << maxSize << "x" << maxSize << ")"
|
||||
<< std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// All the validity checks passed, we can store the new texture settings
|
||||
myWidth = width;
|
||||
myHeight = height;
|
||||
myTextureWidth = textureWidth;
|
||||
myTextureHeight = textureHeight;
|
||||
myPixelsFlipped = false;
|
||||
|
||||
EnsureGlContext();
|
||||
|
||||
// Create the OpenGL texture if it doesn't exist yet
|
||||
if (!myTexture)
|
||||
{
|
||||
GLuint texture;
|
||||
GLCheck(glGenTextures(1, &texture));
|
||||
myTexture = static_cast<unsigned int>(texture);
|
||||
}
|
||||
|
||||
// Save the current texture binding
|
||||
GLint previous;
|
||||
GLCheck(glGetIntegerv(GL_TEXTURE_BINDING_2D, &previous));
|
||||
|
||||
// Initialize the texture
|
||||
GLCheck(glBindTexture(GL_TEXTURE_2D, myTexture));
|
||||
GLCheck(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, myTextureWidth, myTextureHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL));
|
||||
GLCheck(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
|
||||
GLCheck(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
|
||||
GLCheck(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, myIsSmooth ? GL_LINEAR : GL_NEAREST));
|
||||
GLCheck(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, myIsSmooth ? GL_LINEAR : GL_NEAREST));
|
||||
|
||||
// Restore the previous texture
|
||||
GLCheck(glBindTexture(GL_TEXTURE_2D, previous));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
bool Texture::LoadFromFile(const std::string& filename, const IntRect& area)
|
||||
{
|
||||
Image image;
|
||||
return image.LoadFromFile(filename) && LoadFromImage(image, area);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
bool Texture::LoadFromMemory(const void* data, std::size_t size, const IntRect& area)
|
||||
{
|
||||
Image image;
|
||||
return image.LoadFromMemory(data, size) && LoadFromImage(image, area);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
bool Texture::LoadFromStream(InputStream& stream, const IntRect& area)
|
||||
{
|
||||
Image image;
|
||||
return image.LoadFromStream(stream) && LoadFromImage(image, area);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
bool Texture::LoadFromImage(const Image& image, const IntRect& area)
|
||||
{
|
||||
// Retrieve the image size
|
||||
int width = static_cast<int>(image.GetWidth());
|
||||
int height = static_cast<int>(image.GetHeight());
|
||||
|
||||
// Load the entire image if the source area is either empty or contains the whole image
|
||||
if (area.Width == 0 || (area.Height == 0) ||
|
||||
((area.Left <= 0) && (area.Top <= 0) && (area.Width >= width) && (area.Height >= height)))
|
||||
{
|
||||
// Load the entire image
|
||||
if (Create(image.GetWidth(), image.GetHeight()))
|
||||
{
|
||||
Update(image);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Load a sub-area of the image
|
||||
|
||||
// Adjust the rectangle to the size of the image
|
||||
IntRect rectangle = area;
|
||||
if (rectangle.Left < 0) rectangle.Left = 0;
|
||||
if (rectangle.Top < 0) rectangle.Top = 0;
|
||||
if (rectangle.Width > width) rectangle.Width = width;
|
||||
if (rectangle.Height > height) rectangle.Height = height;
|
||||
|
||||
// Create the texture and upload the pixels
|
||||
if (Create(rectangle.Width, rectangle.Height))
|
||||
{
|
||||
// Save the current texture binding
|
||||
GLint previous;
|
||||
GLCheck(glGetIntegerv(GL_TEXTURE_BINDING_2D, &previous));
|
||||
|
||||
// Copy the pixels to the texture, row by row
|
||||
const Uint8* pixels = image.GetPixelsPtr() + rectangle.Left + (width * rectangle.Top);
|
||||
GLCheck(glBindTexture(GL_TEXTURE_2D, myTexture));
|
||||
for (int i = 0; i < rectangle.Height; ++i)
|
||||
{
|
||||
GLCheck(glTexSubImage2D(GL_TEXTURE_2D, 0, 0, i, myWidth, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels));
|
||||
pixels += width;
|
||||
}
|
||||
myPixelsFlipped = false;
|
||||
|
||||
// Restore the previous texture
|
||||
GLCheck(glBindTexture(GL_TEXTURE_2D, previous));
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
unsigned int Texture::GetWidth() const
|
||||
{
|
||||
return myWidth;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
unsigned int Texture::GetHeight() const
|
||||
{
|
||||
return myHeight;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
Image Texture::CopyToImage() const
|
||||
{
|
||||
// Easy case: empty texture
|
||||
if (!myTexture)
|
||||
return Image();
|
||||
|
||||
EnsureGlContext();
|
||||
|
||||
// Save the previous texture
|
||||
GLint previous;
|
||||
GLCheck(glGetIntegerv(GL_TEXTURE_BINDING_2D, &previous));
|
||||
|
||||
// Create an array of pixels
|
||||
std::vector<Uint8> pixels(myWidth * myHeight * 4);
|
||||
|
||||
if ((myWidth == myTextureWidth) && (myHeight == myTextureHeight) && !myPixelsFlipped)
|
||||
{
|
||||
// Texture is not padded nor flipped, we can use a direct copy
|
||||
GLCheck(glBindTexture(GL_TEXTURE_2D, myTexture));
|
||||
GLCheck(glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, &pixels[0]));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Texture is either padded or flipped, we have to use a slower algorithm
|
||||
|
||||
// All the pixels will first be copied to a temporary array
|
||||
std::vector<Uint8> allPixels(myTextureWidth * myTextureHeight * 4);
|
||||
GLCheck(glBindTexture(GL_TEXTURE_2D, myTexture));
|
||||
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
|
||||
const Uint8* src = &allPixels[0];
|
||||
Uint8* dst = &pixels[0];
|
||||
int srcPitch = myTextureWidth * 4;
|
||||
int dstPitch = myWidth * 4;
|
||||
|
||||
// Handle the case where source pixels are flipped vertically
|
||||
if (myPixelsFlipped)
|
||||
{
|
||||
src += srcPitch * (myHeight - 1);
|
||||
srcPitch = -srcPitch;
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < myHeight; ++i)
|
||||
{
|
||||
std::memcpy(dst, src, dstPitch);
|
||||
src += srcPitch;
|
||||
dst += dstPitch;
|
||||
}
|
||||
}
|
||||
|
||||
// Restore the previous texture
|
||||
GLCheck(glBindTexture(GL_TEXTURE_2D, previous));
|
||||
|
||||
// Create the image
|
||||
Image image;
|
||||
image.Create(myWidth, myHeight, &pixels[0]);
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void Texture::Update(const Uint8* pixels)
|
||||
{
|
||||
// Update the whole texture
|
||||
Update(pixels, myWidth, myHeight, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void Texture::Update(const Uint8* pixels, unsigned int width, unsigned int height, unsigned int x, unsigned int y)
|
||||
{
|
||||
assert(x + width <= myWidth);
|
||||
assert(y + height <= myHeight);
|
||||
|
||||
if (pixels && myTexture)
|
||||
{
|
||||
EnsureGlContext();
|
||||
|
||||
// Save the current texture binding
|
||||
GLint previous;
|
||||
GLCheck(glGetIntegerv(GL_TEXTURE_BINDING_2D, &previous));
|
||||
|
||||
// Copy pixels from the given array to the texture
|
||||
GLCheck(glBindTexture(GL_TEXTURE_2D, myTexture));
|
||||
GLCheck(glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels));
|
||||
myPixelsFlipped = false;
|
||||
|
||||
// Restore the previous texture
|
||||
GLCheck(glBindTexture(GL_TEXTURE_2D, previous));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void Texture::Update(const Image& image)
|
||||
{
|
||||
// Update the whole texture
|
||||
Update(image.GetPixelsPtr(), image.GetWidth(), image.GetHeight(), 0, 0);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void Texture::Update(const Image& image, unsigned int x, unsigned int y)
|
||||
{
|
||||
Update(image.GetPixelsPtr(), image.GetWidth(), image.GetHeight(), x, y);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void Texture::Update(const Window& window)
|
||||
{
|
||||
Update(window, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void Texture::Update(const Window& window, unsigned int x, unsigned int y)
|
||||
{
|
||||
assert(x + window.GetWidth() <= myWidth);
|
||||
assert(y + window.GetHeight() <= myHeight);
|
||||
|
||||
if (myTexture && window.SetActive(true))
|
||||
{
|
||||
// Save the current texture binding
|
||||
GLint previous;
|
||||
GLCheck(glGetIntegerv(GL_TEXTURE_BINDING_2D, &previous));
|
||||
|
||||
// Copy pixels from the back-buffer to the texture
|
||||
GLCheck(glBindTexture(GL_TEXTURE_2D, myTexture));
|
||||
GLCheck(glCopyTexSubImage2D(GL_TEXTURE_2D, 0, x, y, 0, 0, window.GetWidth(), window.GetHeight()));
|
||||
myPixelsFlipped = true;
|
||||
|
||||
// Restore the previous texture
|
||||
GLCheck(glBindTexture(GL_TEXTURE_2D, previous));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void Texture::Bind() const
|
||||
{
|
||||
GLCheck(glBindTexture(GL_TEXTURE_2D, myTexture));
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void Texture::SetSmooth(bool smooth)
|
||||
{
|
||||
if (smooth != myIsSmooth)
|
||||
{
|
||||
myIsSmooth = smooth;
|
||||
|
||||
if (myTexture)
|
||||
{
|
||||
EnsureGlContext();
|
||||
|
||||
GLint previous;
|
||||
GLCheck(glGetIntegerv(GL_TEXTURE_BINDING_2D, &previous));
|
||||
|
||||
GLCheck(glBindTexture(GL_TEXTURE_2D, myTexture));
|
||||
GLCheck(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, myIsSmooth ? GL_LINEAR : GL_NEAREST));
|
||||
GLCheck(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, myIsSmooth ? GL_LINEAR : GL_NEAREST));
|
||||
|
||||
GLCheck(glBindTexture(GL_TEXTURE_2D, previous));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
bool Texture::IsSmooth() const
|
||||
{
|
||||
return myIsSmooth;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
FloatRect Texture::GetTexCoords(const IntRect& rect) const
|
||||
{
|
||||
if ((myTextureWidth != 0) && (myTextureHeight != 0))
|
||||
{
|
||||
float width = static_cast<float>(myTextureWidth);
|
||||
float height = static_cast<float>(myTextureHeight);
|
||||
|
||||
if (myPixelsFlipped)
|
||||
{
|
||||
return FloatRect( rect.Left / width,
|
||||
(myHeight - rect.Top) / height,
|
||||
rect.Width / width,
|
||||
-rect.Height / height);
|
||||
}
|
||||
else
|
||||
{
|
||||
return FloatRect(rect.Left / width,
|
||||
rect.Top / height,
|
||||
rect.Width / width,
|
||||
rect.Height / height);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return FloatRect(0, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
unsigned int Texture::GetMaximumSize()
|
||||
{
|
||||
EnsureGlContext();
|
||||
|
||||
GLint size;
|
||||
GLCheck(glGetIntegerv(GL_MAX_TEXTURE_SIZE, &size));
|
||||
|
||||
return static_cast<unsigned int>(size);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
Texture& Texture::operator =(const Texture& right)
|
||||
{
|
||||
Texture temp(right);
|
||||
|
||||
std::swap(myWidth, temp.myWidth);
|
||||
std::swap(myHeight, temp.myHeight);
|
||||
std::swap(myTextureWidth, temp.myTextureWidth);
|
||||
std::swap(myTextureHeight, temp.myTextureHeight);
|
||||
std::swap(myTexture, temp.myTexture);
|
||||
std::swap(myIsSmooth, temp.myIsSmooth);
|
||||
std::swap(myPixelsFlipped, temp.myPixelsFlipped);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
unsigned int Texture::GetValidSize(unsigned int size)
|
||||
{
|
||||
EnsureGlContext();
|
||||
|
||||
// Make sure that GLEW is initialized
|
||||
priv::EnsureGlewInit();
|
||||
|
||||
if (GLEW_ARB_texture_non_power_of_two)
|
||||
{
|
||||
// If hardware supports NPOT textures, then just return the unmodified size
|
||||
return size;
|
||||
}
|
||||
else
|
||||
{
|
||||
// If hardware doesn't support NPOT textures, we calculate the nearest power of two
|
||||
unsigned int powerOfTwo = 1;
|
||||
while (powerOfTwo < size)
|
||||
powerOfTwo *= 2;
|
||||
|
||||
return powerOfTwo;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace sf
|
Loading…
Reference in New Issue
Block a user