The Battle for Wesnoth 1.21.0-dev
 
Loading...
Searching...
No Matches
texture.cpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2017 - 2025
3 Part of the Battle for Wesnoth Project https://www.wesnoth.org/
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY.
11
12 See the COPYING file for more details.
13*/
14
15#include "sdl/texture.hpp"
16
17#include "color.hpp"
18#include "log.hpp"
19#include "sdl/point.hpp"
20#include "sdl/surface.hpp"
21#include "video.hpp"
22
23static lg::log_domain log_sdl("SDL");
24#define ERR_SDL LOG_STREAM(err, log_sdl)
25
26namespace
27{
28// The default pixel format to create textures with.
29const SDL_PixelFormat default_texture_format = SDL_PIXELFORMAT_ARGB8888;
30
31void cleanup_texture(SDL_Texture* t)
32{
33 if(t != nullptr) {
34 SDL_DestroyTexture(t);
35 }
36}
37
38} // namespace
39
40texture::texture(SDL_Texture* txt)
41 : texture_(txt, &cleanup_texture)
42{
43 if (txt) {
44 SDL_PropertiesID props = SDL_GetTextureProperties(txt);
45 size_.x = SDL_GetNumberProperty(props, SDL_PROP_TEXTURE_WIDTH_NUMBER, 0);
46 size_.y = SDL_GetNumberProperty(props, SDL_PROP_TEXTURE_HEIGHT_NUMBER, 0);
47 finalize();
48 }
49}
50
51texture::texture(const surface& surf, bool linear_interpolation)
52 : texture()
53{
54 if (!surf) {
55 return;
56 }
57
58 if (surf->w == 0 && surf->h == 0) {
59 return;
60 }
61
62 SDL_Renderer* renderer = video::get_renderer();
63 if(!renderer) {
64 return;
65 }
66
67 texture_.reset(SDL_CreateTextureFromSurface(renderer, surf), &cleanup_texture);
68 if(!texture_) {
69 ERR_SDL << "When creating texture from surface: " << SDL_GetError();
70 }
71 SDL_SetTextureScaleMode(texture_.get(), linear_interpolation ? SDL_SCALEMODE_LINEAR : SDL_SCALEMODE_NEAREST);
72
73 size_ = {surf->w, surf->h};
74
75 finalize();
76}
77
78texture::texture(int width, int height, SDL_TextureAccess access)
79 : texture_()
80{
81 reset(width, height, access);
82}
83
85{
86 set_blend_mode(SDL_BLENDMODE_BLEND);
87}
88
89uint32_t texture::get_format() const
90{
91 if(texture_) {
92 SDL_PropertiesID props = SDL_GetTextureProperties(texture_.get());
93 return SDL_GetNumberProperty(props, SDL_PROP_TEXTURE_FORMAT_NUMBER, 0);
94 } else {
95 return SDL_PIXELFORMAT_UNKNOWN;
96 }
97}
98
100{
101 if(texture_) {
102 SDL_PropertiesID props = SDL_GetTextureProperties(texture_.get());
103 return SDL_GetNumberProperty(props, SDL_PROP_TEXTURE_ACCESS_NUMBER, 0);
104 } else {
105 return -1;
106 }
107}
108
110{
111 if(texture_) {
112 SDL_PropertiesID props = SDL_GetTextureProperties(texture_.get());
113 return {
114 static_cast<int>(SDL_GetNumberProperty(props, SDL_PROP_TEXTURE_WIDTH_NUMBER, 0)),
115 static_cast<int>(SDL_GetNumberProperty(props, SDL_PROP_TEXTURE_HEIGHT_NUMBER, 0))
116 };
117 } else {
118 return {0, 0};
119 }
120}
121
122void texture::set_src(const rect& r)
123{
124 rect dsrc = r.intersect(rect{{0, 0}, size_});
125 point rsize = get_raw_size();
126 if (draw_size() == rsize) {
127 src_ = dsrc;
128 } else {
129 src_ = rect {
130 (dsrc.x * rsize.x) / size_.x,
131 (dsrc.y * rsize.y) / size_.y,
132 (dsrc.w * rsize.x) / size_.x,
133 (dsrc.h * rsize.y) / size_.y
134 };
135 }
136 has_src_ = true;
137}
138
140{
141 rect max = {{0, 0}, get_raw_size()};
142 src_ = r.intersect(max);
143 has_src_ = true;
144}
145
146void texture::set_alpha_mod(uint8_t alpha)
147{
148 if (texture_) {
149 SDL_SetTextureAlphaMod(texture_.get(), alpha);
150 }
151}
152
154{
155 if (!texture_) {
156 return 0;
157 }
158 uint8_t a;
159 SDL_GetTextureAlphaMod(texture_.get(), &a);
160 return a;
161}
162
164{
165 set_color_mod(c.r, c.g, c.b);
166}
167
168void texture::set_color_mod(uint8_t r, uint8_t g, uint8_t b)
169{
170 if (texture_) {
171 SDL_SetTextureColorMod(texture_.get(), r, g, b);
172 }
173}
174
176{
177 if (!texture_) {
178 return {0,0,0};
179 }
180 color_t c;
181 SDL_GetTextureColorMod(texture_.get(), &c.r, &c.g, &c.b);
182 return c;
183}
184
185void texture::set_blend_mode(SDL_BlendMode b)
186{
187 if (texture_) {
188 SDL_SetTextureBlendMode(texture_.get(), b);
189 }
190}
191
192SDL_BlendMode texture::get_blend_mode() const
193{
194 if (!texture_) {
195 return SDL_BLENDMODE_NONE;
196 }
197 SDL_BlendMode b;
198 SDL_GetTextureBlendMode(texture_.get(), &b);
199 return b;
200}
201
203{
204 if(texture_) {
205 texture_.reset();
206 }
207 size_ = {0, 0};
208 has_src_ = false;
209}
210
211void texture::reset(int width, int height, SDL_TextureAccess access)
212{
213 // No-op if texture is null.
214 reset();
215
216 SDL_Renderer* renderer = video::get_renderer();
217 if(!renderer) {
218 return;
219 }
220
221 texture_.reset(SDL_CreateTexture(renderer, default_texture_format, access, width, height), &cleanup_texture);
222 if(!texture_) {
223 ERR_SDL << "When creating texture: " << SDL_GetError();
224 return;
225 }
226
227 size_ = {width, height};
228 has_src_ = false;
229
230 finalize();
231}
232
233void texture::assign(SDL_Texture* t)
234{
235 texture_.reset(t, &cleanup_texture);
237 has_src_ = false;
238}
239
241 : format(SDL_PIXELFORMAT_UNKNOWN)
242 , access(-1)
243 , size(0, 0)
244{
245 if (t) {
246 SDL_PropertiesID props = SDL_GetTextureProperties(t);
247 format = SDL_GetNumberProperty(props, SDL_PROP_TEXTURE_FORMAT_NUMBER, 0);
248 access = SDL_GetNumberProperty(props, SDL_PROP_TEXTURE_ACCESS_NUMBER, 0);
249 size.x = SDL_GetNumberProperty(props, SDL_PROP_TEXTURE_WIDTH_NUMBER, 0);
250 size.y = SDL_GetNumberProperty(props, SDL_PROP_TEXTURE_HEIGHT_NUMBER, 0);
251 }
252}
double t
Wrapper class to encapsulate creation and management of an SDL_Texture.
Definition texture.hpp:33
uint8_t get_alpha_mod() const
Definition texture.cpp:153
rect src_
uninitialized by default.
Definition texture.hpp:215
SDL_BlendMode get_blend_mode() const
Definition texture.cpp:192
int get_access() const
The texture access mode.
Definition texture.cpp:99
uint32_t get_format() const
The internal texture format.
Definition texture.cpp:89
std::shared_ptr< SDL_Texture > texture_
Definition texture.hpp:212
void set_blend_mode(SDL_BlendMode mode)
Blend mode.
Definition texture.cpp:185
bool has_src_
true iff the source rect is valid
Definition texture.hpp:214
void finalize()
Definition texture.cpp:84
void reset()
Releases ownership of the managed texture and resets the ptr to null.
Definition texture.cpp:202
void set_src(const rect &r)
Set the source region of the texture used for drawing operations.
Definition texture.cpp:122
texture()=default
Default ctor.
point draw_size() const
The size of the texture in draw-space.
Definition texture.hpp:120
point size_
Definition texture.hpp:213
point get_raw_size() const
The raw internal texture size.
Definition texture.cpp:109
void assign(SDL_Texture *t)
Replaces ownership of the managed texture with the given one.
Definition texture.cpp:233
void set_alpha_mod(uint8_t alpha)
Alpha modifier.
Definition texture.cpp:146
color_t get_color_mod() const
Definition texture.cpp:175
void set_src_raw(const rect &r)
Set the source region of the texture used for drawing operations.
Definition texture.cpp:139
void set_color_mod(uint8_t r, uint8_t g, uint8_t b)
Colour modifier.
Definition texture.cpp:168
static SDL_Renderer * renderer()
Definition draw.cpp:33
Standard logging facilities (interface).
SDL_Renderer * get_renderer()
Definition video.cpp:703
surface surf
Image.
The basic class for representing 8-bit RGB or RGBA colour values.
Definition color.hpp:51
Holds a 2D point.
Definition point.hpp:25
An abstract description of a rectangle with integer coordinates.
Definition rect.hpp:49
rect intersect(const rect &r) const
Calculates the intersection of this rectangle and another; that is, the maximal rectangle that is con...
Definition rect.cpp:92
uint32_t format
Definition texture.hpp:71
info(SDL_Texture *t)
Definition texture.cpp:240
#define ERR_SDL
Definition texture.cpp:24
static lg::log_domain log_sdl("SDL")
#define g
#define c
#define b