libmx2 2.2.1
C++20 multimedia and game-engine library (SDL2 / OpenGL / Vulkan)
Loading...
Searching...
No Matches
texture.hpp
Go to the documentation of this file.
1/**
2 * @file texture.hpp
3 * @brief SDL_Texture RAII wrapper with loading, saving, and flip utilities.
4 */
5#ifndef _TEXTURE_H___
6#define _TEXTURE_H___
7
8#include"SDL.h"
9#include<string>
10#include<iostream>
11#include<vector>
12#include"tee_stream.hpp"
13#include<optional>
14#include"wrapper.hpp"
15
16namespace mx {
17
18 class mxWindow;
19
20/**
21 * @class Texture
22 * @brief RAII wrapper around an SDL_Texture.
23 *
24 * Manages the lifetime of an SDL_Texture and provides helpers for loading
25 * from image files, creating blank textures, saving to BMP, and an in-place
26 * vertical flip of an SDL_Surface. Only move semantics are supported;
27 * copying is disabled to prevent double-free.
28 */
29 class Texture {
30 public:
31 /** @brief Default constructor — no texture loaded. */
32 Texture() = default;
33 Texture(const Texture &tex) = delete;
34
35 /** @brief Move constructor — transfers ownership of the SDL_Texture. */
36 Texture(Texture &&tex);
37 Texture &operator=(const Texture &tex) = delete;
38
39 /** @brief Move-assign — transfers ownership of the SDL_Texture. */
41
42 /** @brief Destructor — destroys the SDL_Texture if held. */
43 ~Texture();
44
45 /**
46 * @brief Create an empty (blank) texture of the given dimensions.
47 * @param window Owning window supplying the renderer.
48 * @param width Texture width in pixels.
49 * @param height Texture height in pixels.
50 */
51 void createTexture(mxWindow *window, int width, int height);
52
53 /**
54 * @brief Load a texture from an image file.
55 * @param window Owning window supplying the renderer.
56 * @param filename Path to the image file (PNG, BMP, etc.).
57 */
58 void loadTexture(mxWindow *window, const std::string &filename);
59
60 /**
61 * @brief Load a texture with optional colour-key transparency.
62 * @param window Owning window.
63 * @param filename Image file path.
64 * @param w Output: loaded image width.
65 * @param h Output: loaded image height.
66 * @param color If @c true, apply the colour key.
67 * @param key Colour to treat as transparent.
68 */
69 void loadTexture(mxWindow *window, const std::string &filename, int &w, int &h, bool color, SDL_Color key);
70
71 /**
72 * @brief Save the texture to a file.
73 * @param window Owning window supplying the renderer.
74 * @param filename Destination file path (BMP format).
75 * @return @c true on success.
76 */
77 bool saveTexture(mxWindow *window, const std::string &filename);
78
79 /**
80 * @brief Return the SDL_Texture as an optional.
81 * @return std::optional with the texture, or std::nullopt if not loaded.
82 */
83 std::optional<SDL_Texture *> handle() const {
84 if(texture)
85 return texture;
86 return std::nullopt;
87 }
88
89 /**
90 * @brief Unwrap the SDL_Texture pointer, throwing on null.
91 * @return Raw SDL_Texture pointer.
92 * @throws mx::Exception if texture is not loaded.
93 */
94 SDL_Texture *unwrap() const {
95 if(texture) {
96 return texture;
97 }
98 throw Exception("unwrap: Invalid texture");
99 return 0;
100 }
101
102 /**
103 * @brief Return a Wrapper around the SDL_Texture handle.
104 * @return Wrapper<SDL_Texture*> holding the pointer or nullopt.
105 */
107 if(texture)
108 return texture;
109
110 return std::nullopt;
111 }
112
113 /**
114 * @brief Flip an SDL_Surface vertically (in-place).
115 * @param surface Surface to flip.
116 * @return The same surface pointer after flipping.
117 */
118 static SDL_Surface* flipSurface(SDL_Surface* surface) {
119 if (SDL_LockSurface(surface) != 0) {
120 return surface;
121 }
122 Uint8* pixels = (Uint8*)surface->pixels;
123 int pitch = surface->pitch;
124 std::vector<Uint8> tempRow(pitch);
125 for (int y = 0; y < surface->h / 2; ++y) {
126 Uint8* row1 = pixels + y * pitch;
127 Uint8* row2 = pixels + (surface->h - y - 1) * pitch;
128 memcpy(tempRow.data(), row1, pitch);
129 memcpy(row1, row2, pitch);
130 memcpy(row2, tempRow.data(), pitch);
131 }
132 SDL_UnlockSurface(surface);
133 return surface;
134 }
135
136 /** @return Width of the loaded texture in pixels. */
137 int width() const { return width_; }
138 /** @return Height of the loaded texture in pixels. */
139 int height() const { return height_; }
140 private:
141 SDL_Texture *texture = nullptr; ///< Managed SDL texture handle.
142 int width_ = 0; ///< Cached texture width.
143 int height_ = 0; ///< Cached texture height.
144
145 int imageType(const std::string &type);
146 bool saveBMP(SDL_Texture *texture, SDL_Renderer *renderer, const std::string &name);
147 };
148
149}
150
151#endif
General-purpose exception class for the mx library.
Definition exception.hpp:20
int height() const
Definition texture.hpp:139
int width() const
Definition texture.hpp:137
int width_
Cached texture width.
Definition texture.hpp:142
static SDL_Surface * flipSurface(SDL_Surface *surface)
Flip an SDL_Surface vertically (in-place).
Definition texture.hpp:118
~Texture()
Destructor — destroys the SDL_Texture if held.
Definition texture.cpp:119
SDL_Texture * texture
Managed SDL texture handle.
Definition texture.hpp:141
int height_
Cached texture height.
Definition texture.hpp:143
bool saveTexture(mxWindow *window, const std::string &filename)
Save the texture to a file.
Definition texture.cpp:99
Texture()=default
Default constructor — no texture loaded.
int imageType(const std::string &type)
Definition texture.cpp:124
Texture(const Texture &tex)=delete
Texture & operator=(const Texture &tex)=delete
SDL_Texture * unwrap() const
Unwrap the SDL_Texture pointer, throwing on null.
Definition texture.hpp:94
void createTexture(mxWindow *window, int width, int height)
Create an empty (blank) texture of the given dimensions.
Definition texture.cpp:34
Wrapper< SDL_Texture * > wrapper() const
Return a Wrapper around the SDL_Texture handle.
Definition texture.hpp:106
bool saveBMP(SDL_Texture *texture, SDL_Renderer *renderer, const std::string &name)
Definition texture.cpp:137
std::optional< SDL_Texture * > handle() const
Return the SDL_Texture as an optional.
Definition texture.hpp:83
void loadTexture(mxWindow *window, const std::string &filename)
Load a texture from an image file.
Definition texture.cpp:44
A nullable smart wrapper around a raw pointer.
Definition wrapper.hpp:36
Main SDL2 application window.
Definition mx.hpp:47
Definition cfg.cpp:11
Tee stream utilities that duplicate output to two sinks simultaneously.
Type-safe nullable pointer wrapper inspired by Rust's Option<T>.