The Battle for Wesnoth  1.19.8+dev
texture.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2017 - 2024
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 
23 static lg::log_domain log_sdl("SDL");
24 #define ERR_SDL LOG_STREAM(err, log_sdl)
25 
26 namespace
27 {
28 // The default pixel format to create textures with.
29 const int default_texture_format = SDL_PIXELFORMAT_ARGB8888;
30 
31 void cleanup_texture(SDL_Texture* t)
32 {
33  if(t != nullptr) {
34  SDL_DestroyTexture(t);
35  }
36 }
37 
38 } // namespace
39 
40 texture::texture(SDL_Texture* txt)
41  : texture_(txt, &cleanup_texture)
42 {
43  if (txt) {
44  SDL_QueryTexture(txt, nullptr, nullptr, &size_.x, &size_.y);
45  finalize();
46  }
47 }
48 
49 texture::texture(const surface& surf, bool linear_interpolation)
50  : texture()
51 {
52  if (!surf) {
53  return;
54  }
55 
56  if (surf->w == 0 && surf->h == 0) {
57  return;
58  }
59 
60  SDL_Renderer* renderer = video::get_renderer();
61  if(!renderer) {
62  return;
63  }
64 
65  // Filtering mode must be set before texture creation.
66  set_texture_scale_quality(linear_interpolation ? "linear" : "nearest");
67 
68  texture_.reset(SDL_CreateTextureFromSurface(renderer, surf), &cleanup_texture);
69  if(!texture_) {
70  ERR_SDL << "When creating texture from surface: " << SDL_GetError();
71  }
72 
73  size_ = {surf->w, surf->h};
74 
75  finalize();
76 }
77 
78 texture::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 
89 uint32_t texture::get_format() const
90 {
91  return get_info().format;
92 }
93 
95 {
96  return get_info().access;
97 }
98 
100 {
101  return get_info().size;
102 }
103 
104 void texture::set_src(const rect& r)
105 {
106  rect dsrc = r.intersect(rect{{0, 0}, size_});
107  point rsize = get_raw_size();
108  if (draw_size() == rsize) {
109  src_ = dsrc;
110  } else {
111  src_ = rect {
112  (dsrc.x * rsize.x) / size_.x,
113  (dsrc.y * rsize.y) / size_.y,
114  (dsrc.w * rsize.x) / size_.x,
115  (dsrc.h * rsize.y) / size_.y
116  };
117  }
118  has_src_ = true;
119 }
120 
122 {
123  rect max = {{0, 0}, get_raw_size()};
124  src_ = r.intersect(max);
125  has_src_ = true;
126 }
127 
128 void texture::set_alpha_mod(uint8_t alpha)
129 {
130  if (texture_) {
131  SDL_SetTextureAlphaMod(texture_.get(), alpha);
132  }
133 }
134 
135 uint8_t texture::get_alpha_mod() const
136 {
137  if (!texture_) {
138  return 0;
139  }
140  uint8_t a;
141  SDL_GetTextureAlphaMod(texture_.get(), &a);
142  return a;
143 }
144 
146 {
147  set_color_mod(c.r, c.g, c.b);
148 }
149 
150 void texture::set_color_mod(uint8_t r, uint8_t g, uint8_t b)
151 {
152  if (texture_) {
153  SDL_SetTextureColorMod(texture_.get(), r, g, b);
154  }
155 }
156 
158 {
159  if (!texture_) {
160  return {0,0,0};
161  }
162  color_t c;
163  SDL_GetTextureColorMod(texture_.get(), &c.r, &c.g, &c.b);
164  return c;
165 }
166 
167 void texture::set_blend_mode(SDL_BlendMode b)
168 {
169  if (texture_) {
170  SDL_SetTextureBlendMode(texture_.get(), b);
171  }
172 }
173 
174 SDL_BlendMode texture::get_blend_mode() const
175 {
176  if (!texture_) {
177  return SDL_BLENDMODE_NONE;
178  }
179  SDL_BlendMode b;
180  SDL_GetTextureBlendMode(texture_.get(), &b);
181  return b;
182 }
183 
185 {
186  if(texture_) {
187  texture_.reset();
188  }
189  size_ = {0, 0};
190  has_src_ = false;
191 }
192 
193 void texture::reset(int width, int height, SDL_TextureAccess access)
194 {
195  // No-op if texture is null.
196  reset();
197 
198  SDL_Renderer* renderer = video::get_renderer();
199  if(!renderer) {
200  return;
201  }
202 
203  texture_.reset(SDL_CreateTexture(renderer, default_texture_format, access, width, height), &cleanup_texture);
204  if(!texture_) {
205  ERR_SDL << "When creating texture: " << SDL_GetError();
206  return;
207  }
208 
209  size_ = {width, height};
210  has_src_ = false;
211 
212  finalize();
213 }
214 
215 void texture::assign(SDL_Texture* t)
216 {
217  texture_.reset(t, &cleanup_texture);
218  size_ = get_raw_size();
219  has_src_ = false;
220 }
221 
222 texture::info::info(SDL_Texture* t)
223  : format(SDL_PIXELFORMAT_UNKNOWN)
224  , access(-1)
225  , size(0, 0)
226 {
227  if (t) {
228  SDL_QueryTexture(t, &format, &access, &size.x, &size.y);
229  }
230 }
double t
Definition: astarsearch.cpp:63
double g
Definition: astarsearch.cpp:63
Wrapper class to encapsulate creation and management of an SDL_Texture.
Definition: texture.hpp:33
uint8_t get_alpha_mod() const
Definition: texture.cpp:135
rect src_
uninitialized by default.
Definition: texture.hpp:215
SDL_BlendMode get_blend_mode() const
Definition: texture.cpp:174
int get_access() const
The texture access mode.
Definition: texture.cpp:94
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:167
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:184
void set_src(const rect &r)
Set the source region of the texture used for drawing operations.
Definition: texture.cpp:104
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:99
void assign(SDL_Texture *t)
Replaces ownership of the managed texture with the given one.
Definition: texture.cpp:215
void set_alpha_mod(uint8_t alpha)
Alpha modifier.
Definition: texture.cpp:128
color_t get_color_mod() const
Definition: texture.cpp:157
void set_src_raw(const rect &r)
Set the source region of the texture used for drawing operations.
Definition: texture.cpp:121
const info get_info() const
Queries metadata about the texture, such as its dimensions.
Definition: texture.hpp:77
void set_color_mod(uint8_t r, uint8_t g, uint8_t b)
Colour modifier.
Definition: texture.cpp:150
static SDL_Renderer * renderer()
Definition: draw.cpp:31
Standard logging facilities (interface).
std::size_t size(std::string_view str)
Length in characters of a UTF-8 string.
Definition: unicode.cpp:85
SDL_Renderer * get_renderer()
Definition: video.cpp:659
surface surf
Image.
The basic class for representing 8-bit RGB or RGBA colour values.
Definition: color.hpp:59
Holds a 2D point.
Definition: point.hpp:25
An abstract description of a rectangle with integer coordinates.
Definition: rect.hpp:49
rect intersect(const SDL_Rect &r) const
Calculates the intersection of this rectangle and another; that is, the maximal rectangle that is con...
Definition: rect.cpp:91
uint32_t format
Definition: texture.hpp:71
point size
Definition: texture.hpp:73
info(SDL_Texture *t)
Definition: texture.cpp:222
mock_char c
#define ERR_SDL
Definition: texture.cpp:24
static lg::log_domain log_sdl("SDL")
void set_texture_scale_quality(const char *value)
Sets the texture scale quality.
Definition: texture.hpp:224
#define b