The Battle for Wesnoth  1.19.5+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, &w_, &h_);
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  const char* scale_quality = linear_interpolation ? "linear" : "nearest";
67  SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, scale_quality);
68 
69  texture_.reset(SDL_CreateTextureFromSurface(renderer, surf), &cleanup_texture);
70  if(!texture_) {
71  ERR_SDL << "When creating texture from surface: " << SDL_GetError();
72  }
73 
74  w_ = surf->w; h_ = surf->h;
75 
76  finalize();
77 }
78 
79 texture::texture(int width, int height, SDL_TextureAccess access)
80  : texture_()
81 {
82  reset(width, height, access);
83 }
84 
86 {
87  set_blend_mode(SDL_BLENDMODE_BLEND);
88 }
89 
90 uint32_t texture::get_format() const
91 {
92  uint32_t ret;
93  if(texture_) {
94  SDL_QueryTexture(texture_.get(), &ret, nullptr, nullptr, nullptr);
95  } else {
96  ret = SDL_PIXELFORMAT_UNKNOWN;
97  }
98  return ret;
99 }
100 
102 {
103  int ret;
104  if(texture_) {
105  SDL_QueryTexture(texture_.get(), nullptr, &ret, nullptr, nullptr);
106  } else {
107  ret = -1;
108  }
109  return ret;
110 }
111 
113 {
114  point ret;
115  if(texture_) {
116  SDL_QueryTexture(texture_.get(), nullptr, nullptr, &ret.x, &ret.y);
117  } else {
118  ret = {0, 0};
119  }
120  return ret;
121 }
122 
124 {
125  w_ = p.x;
126  h_ = p.y;
127 }
128 
129 void texture::set_src(const rect& r)
130 {
131  rect dsrc = r.intersect({0, 0, w_, h_});
132  point rsize = get_raw_size();
133  if (draw_size() == rsize) {
134  src_ = dsrc;
135  } else {
136  src_.x = (dsrc.x * rsize.x) / w_;
137  src_.y = (dsrc.y * rsize.y) / h_;
138  src_.w = (dsrc.w * rsize.x) / w_;
139  src_.h = (dsrc.h * rsize.y) / h_;
140  }
141  has_src_ = true;
142 }
143 
145 {
146  rect max = {{}, get_raw_size()};
147  src_ = r.intersect(max);
148  has_src_ = true;
149 }
150 
151 void texture::set_alpha_mod(uint8_t alpha)
152 {
153  if (texture_) {
154  SDL_SetTextureAlphaMod(texture_.get(), alpha);
155  }
156 }
157 
158 uint8_t texture::get_alpha_mod() const
159 {
160  if (!texture_) {
161  return 0;
162  }
163  uint8_t a;
164  SDL_GetTextureAlphaMod(texture_.get(), &a);
165  return a;
166 }
167 
169 {
170  if (texture_) {
171  SDL_SetTextureColorMod(texture_.get(), c.r, c.g, c.b);
172  }
173 }
174 void texture::set_color_mod(uint8_t r, uint8_t g, uint8_t b)
175 {
176  if (texture_) {
177  SDL_SetTextureColorMod(texture_.get(), r, g, b);
178  }
179 }
180 
182 {
183  if (!texture_) {
184  return {0,0,0};
185  }
186  color_t c;
187  SDL_GetTextureColorMod(texture_.get(), &c.r, &c.g, &c.b);
188  return c;
189 }
190 
191 void texture::set_blend_mode(SDL_BlendMode b)
192 {
193  if (texture_) {
194  SDL_SetTextureBlendMode(texture_.get(), b);
195  }
196 }
197 
198 SDL_BlendMode texture::get_blend_mode() const
199 {
200  if (!texture_) {
201  return SDL_BLENDMODE_NONE;
202  }
203  SDL_BlendMode b;
204  SDL_GetTextureBlendMode(texture_.get(), &b);
205  return b;
206 }
207 
209 {
210  if(texture_) {
211  texture_.reset();
212  }
213  w_ = 0; h_ = 0;
214  has_src_ = false;
215 }
216 
217 void texture::reset(int width, int height, SDL_TextureAccess access)
218 {
219  // No-op if texture is null.
220  reset();
221 
222  SDL_Renderer* renderer = video::get_renderer();
223  if(!renderer) {
224  return;
225  }
226 
227  texture_.reset(SDL_CreateTexture(renderer, default_texture_format, access, width, height), &cleanup_texture);
228  if(!texture_) {
229  ERR_SDL << "When creating texture: " << SDL_GetError();
230  return;
231  }
232 
233  w_ = width; h_ = height;
234  has_src_ = false;
235 
236  finalize();
237 }
238 
239 void texture::assign(SDL_Texture* t)
240 {
241  texture_.reset(t, &cleanup_texture);
242  if (t) {
243  SDL_QueryTexture(t, nullptr, nullptr, &w_, &h_);
244  } else {
245  w_ = 0;
246  h_ = 0;
247  }
248  has_src_ = false;
249 }
250 
251 texture::info::info(SDL_Texture* t)
252  : format(SDL_PIXELFORMAT_UNKNOWN)
253  , access(-1)
254  , w(0)
255  , h(0)
256 {
257  if (t) {
258  SDL_QueryTexture(t, &format, &access, &w, &h);
259  }
260 }
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:158
rect src_
uninitialized by default.
Definition: texture.hpp:218
SDL_BlendMode get_blend_mode() const
Definition: texture.cpp:198
int get_access() const
The texture access mode.
Definition: texture.cpp:101
uint32_t get_format() const
The internal texture format.
Definition: texture.cpp:90
std::shared_ptr< SDL_Texture > texture_
Definition: texture.hpp:214
void set_blend_mode(SDL_BlendMode)
Blend mode.
Definition: texture.cpp:191
bool has_src_
true iff the source rect is valid
Definition: texture.hpp:217
void finalize()
Definition: texture.cpp:85
void reset()
Releases ownership of the managed texture and resets the ptr to null.
Definition: texture.cpp:208
void set_src(const rect &r)
Set the source region of the texture used for drawing operations.
Definition: texture.cpp:129
int w_
Definition: texture.hpp:215
texture()=default
Default ctor.
point draw_size() const
The size of the texture in draw-space.
Definition: texture.hpp:122
void set_draw_size(int w, int h)
Set the intended size of the texture, in draw-space.
Definition: texture.hpp:131
point get_raw_size() const
The raw internal texture size.
Definition: texture.cpp:112
void assign(SDL_Texture *t)
Replaces ownership of the managed texture with the given one.
Definition: texture.cpp:239
void set_alpha_mod(uint8_t alpha)
Alpha modifier.
Definition: texture.cpp:151
color_t get_color_mod() const
Definition: texture.cpp:181
void set_src_raw(const rect &r)
Set the source region of the texture used for drawing operations.
Definition: texture.cpp:144
void set_color_mod(uint8_t r, uint8_t g, uint8_t b)
Colour modifier.
Definition: texture.cpp:174
int h_
Definition: texture.hpp:216
static SDL_Renderer * renderer()
Definition: draw.cpp:31
int w
Standard logging facilities (interface).
scale_quality
Definition: picture.hpp:172
SDL_Renderer * get_renderer()
Definition: video.cpp:644
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:47
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
info(SDL_Texture *t)
Definition: texture.cpp:251
mock_char c
mock_party p
#define ERR_SDL
Definition: texture.cpp:24
static lg::log_domain log_sdl("SDL")
#define h
#define b