The Battle for Wesnoth  1.17.4+dev
render_utils.hpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2017 - 2022
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 #pragma once
16 
17 #include "sdl/rect.hpp"
18 #include "sdl/texture.hpp"
19 #include "video.hpp"
20 
21 #include <SDL2/SDL_rect.h>
22 #include <SDL2/SDL_render.h>
23 
24 #include <cassert>
25 #include <functional>
26 
27 /**
28  * Sets the renderer output target to the specified texture.
29  */
31 {
32 public:
34  : renderer_(CVideo::get_singleton().get_renderer())
35  , last_target_(nullptr)
36  {
37  if(renderer_) {
38  // Validate we can render to this texture.
39  assert(t.get_info().access == SDL_TEXTUREACCESS_TARGET);
40 
41  last_target_ = SDL_GetRenderTarget(renderer_);
42  SDL_SetRenderTarget(renderer_, t);
43  }
44  }
45 
47  {
48  if(renderer_) {
49  SDL_SetRenderTarget(renderer_, last_target_);
50  }
51  }
52 
53 private:
54  SDL_Renderer* renderer_;
55  SDL_Texture* last_target_; // TODO: use the texture wrapper?
56 };
57 
58 using sdl_rect_getter = void (*)(SDL_Renderer*, SDL_Rect*);
59 using sdl_rect_setter = int (*)(SDL_Renderer*, const SDL_Rect*);
60 
61 /**
62  * Base class for renderer RAII helpers that operate on SDL_Rects.
63  *
64  * @tparam G Getter function. Will fetch the current applicable rect.
65  * That will be restored as the applicable state once this object is destroyed.
66  * @tparam S Setter function.
67  */
68 template<sdl_rect_getter G, sdl_rect_setter S>
70 {
71 public:
72  explicit render_raii_rect_setter_base(SDL_Rect* rect)
73  : operate_(rect != nullptr)
74  , last_rect_()
75  , renderer_(CVideo::get_singleton().get_renderer())
76  {
77  if(renderer_ && operate_) {
78  std::invoke(G, renderer_, &last_rect_);
79  std::invoke(S, renderer_, rect);
80  }
81  }
82 
84  {
85  if(renderer_ && operate_) {
86  if(last_rect_ != sdl::empty_rect) {
87  std::invoke(S, renderer_, &last_rect_);
88  } else {
89  std::invoke(S, renderer_, nullptr);
90  }
91  }
92  }
93 
94 private:
95  const bool operate_;
96  SDL_Rect last_rect_;
97  SDL_Renderer* renderer_;
98 };
99 
100 /**
101  * Sets the renderer clip rect.
102  */
104  &SDL_RenderGetClipRect,
105  &SDL_RenderSetClipRect>;
106 
107 /**
108  * Sets the renderer viewport rect.
109  */
111  &SDL_RenderGetViewport,
112  &SDL_RenderSetViewport>;
113 
114 
115 /**
116  * Set renderer drawing color.
117  */
118 inline void set_draw_color(SDL_Renderer* renderer, uint8_t r, uint8_t g, uint8_t b, uint8_t a)
119 {
120  SDL_SetRenderDrawColor(renderer, r, g, b, a);
121 }
122 
123 /**
124  * Set renderer drawing color.
125  */
126 inline void set_draw_color(SDL_Renderer* renderer, color_t color)
127 {
128  set_draw_color(renderer, color.r, color.g, color.b, color.a);
129 }
130 
131 /*
132  * TEXTURE SETTERS =========================================================================
133  * Need to decide if these need their own file.
134  */
135 
136 inline void set_texture_alpha(texture& t, uint8_t amount)
137 {
138  SDL_SetTextureAlphaMod(t, amount);
139 }
140 
141 inline void set_texture_blend_color(texture& t, uint8_t r, uint8_t g, uint8_t b)
142 {
143  SDL_SetTextureColorMod(t, r, g, b);
144 }
145 
146 inline void set_texture_blend_mode(texture& t, SDL_BlendMode mode)
147 {
148  SDL_SetTextureBlendMode(t, mode);
149 }
150 
151 /**
152  * Sets the texture scale quality. Note this should be called *before* a texture
153  * is created, since the hint has no effect on existing textures or render ops.
154  *
155  * @param value The scaling mode. Use either 'linear' or 'nearest'.
156  */
157 inline void set_texture_scale_quality(const std::string& value)
158 {
159  SDL_SetHintWithPriority(SDL_HINT_RENDER_SCALE_QUALITY, value.c_str(), SDL_HINT_OVERRIDE);
160 }
void set_draw_color(SDL_Renderer *renderer, uint8_t r, uint8_t g, uint8_t b, uint8_t a)
Set renderer drawing color.
void(*)(SDL_Renderer *, SDL_Rect *) sdl_rect_getter
#define a
Definition: video.hpp:35
SDL_Texture * last_target_
Base class for renderer RAII helpers that operate on SDL_Rects.
Wrapper class to encapsulate creation and management of an SDL_Texture.
Definition: texture.hpp:27
void set_texture_blend_color(texture &t, uint8_t r, uint8_t g, uint8_t b)
#define b
Sets the renderer output target to the specified texture.
void set_texture_scale_quality(const std::string &value)
Sets the texture scale quality.
uint8_t r
Red value.
Definition: color.hpp:178
uint8_t a
Alpha value.
Definition: color.hpp:187
void set_texture_alpha(texture &t, uint8_t amount)
void set_texture_blend_mode(texture &t, SDL_BlendMode mode)
SDL_Renderer * renderer_
render_raii_rect_setter_base(SDL_Rect *rect)
int(*)(SDL_Renderer *, const SDL_Rect *) sdl_rect_setter
double g
Definition: astarsearch.cpp:65
render_target_setter(texture &t)
const info get_info() const
Queries metadata about the texture, such as its dimensions.
Definition: texture.hpp:56
Contains the SDL_Rect helper code.
double t
Definition: astarsearch.cpp:65
constexpr const SDL_Rect empty_rect
Definition: rect.hpp:32
uint8_t g
Green value.
Definition: color.hpp:181
uint8_t b
Blue value.
Definition: color.hpp:184