ASW Lib
A.D.S. Games SDL Wrapper Library. A library targeted at Allegro4 users who want to switch to SDL3 and use modern c++.
Loading...
Searching...
No Matches
draw.cpp
Go to the documentation of this file.
2
3#include <SDL3/SDL.h>
4#include <SDL3_image/SDL_image.h>
5#include <SDL3_ttf/SDL_ttf.h>
6#include <cmath>
7#include <numbers>
8
10#include "./asw/modules/util.h"
11
13{
15 if (r == nullptr) {
16 return;
17 }
18
19 SDL_SetRenderDrawColor(r, color.r, color.g, color.b, color.a);
20 SDL_RenderClear(r);
21}
22
23void asw::draw::sprite(const asw::Texture& tex, const asw::Vec2<float>& position)
24{
26 if (r == nullptr) {
27 return;
28 }
29
30 auto size = asw::util::get_texture_size(tex);
31
32 SDL_FRect dest;
33 dest.x = position.x;
34 dest.y = position.y;
35 dest.w = size.x;
36 dest.h = size.y;
37
38 SDL_RenderTexture(r, tex.get(), nullptr, &dest);
39}
40
42 const asw::Texture& tex, const asw::Vec2<float>& position, bool flip_x, bool flip_y)
43{
45 if (r == nullptr) {
46 return;
47 }
48
49 auto size = asw::util::get_texture_size(tex);
50
51 SDL_FRect dest;
52 dest.x = position.x;
53 dest.y = position.y;
54 dest.w = size.x;
55 dest.h = size.y;
56
57 SDL_FlipMode flip = SDL_FLIP_NONE;
58
59 if (flip_x) {
60 flip = static_cast<SDL_FlipMode>(flip | SDL_FLIP_HORIZONTAL);
61 }
62
63 if (flip_y) {
64 flip = static_cast<SDL_FlipMode>(flip | SDL_FLIP_VERTICAL);
65 }
66
67 SDL_RenderTextureRotated(r, tex.get(), nullptr, &dest, 0, nullptr, flip);
68}
69
71{
73 if (r == nullptr) {
74 return;
75 }
76
77 SDL_FRect dest;
78 dest.x = position.position.x;
79 dest.y = position.position.y;
80 dest.w = position.size.x;
81 dest.h = position.size.y;
82
83 SDL_RenderTexture(r, tex.get(), nullptr, &dest);
84}
85
87 const asw::Texture& tex, const asw::Vec2<float>& position, float angle)
88{
90 if (r == nullptr) {
91 return;
92 }
93
94 auto size = asw::util::get_texture_size(tex);
95
96 SDL_FRect dest;
97 dest.x = position.x;
98 dest.y = position.y;
99 dest.w = size.x;
100 dest.h = size.y;
101
102 // Rad to deg
103 const double angleDeg = angle * (180.0 / std::numbers::pi);
104
105 SDL_RenderTextureRotated(r, tex.get(), nullptr, &dest, angleDeg, nullptr, SDL_FLIP_NONE);
106}
107
109 const asw::Texture& tex, const asw::Quad<float>& source, const asw::Quad<float>& dest)
110{
111 auto* r = asw::display::get_renderer();
112 if (r == nullptr) {
113 return;
114 }
115
116 SDL_FRect r_src;
117 r_src.x = source.position.x;
118 r_src.y = source.position.y;
119 r_src.w = source.size.x;
120 r_src.h = source.size.y;
121
122 SDL_FRect r_dest;
123 r_dest.x = dest.position.x;
124 r_dest.y = dest.position.y;
125 r_dest.w = dest.size.x;
126 r_dest.h = dest.size.y;
127
128 SDL_RenderTexture(r, tex.get(), &r_src, &r_dest);
129}
130
132 const asw::Quad<float>& dest, float angle)
133{
134 auto* r = asw::display::get_renderer();
135 if (r == nullptr) {
136 return;
137 }
138
139 SDL_FRect r_src;
140 r_src.x = source.position.x;
141 r_src.y = source.position.y;
142 r_src.w = source.size.x;
143 r_src.h = source.size.y;
144
145 SDL_FRect r_dest;
146 r_dest.x = dest.position.x;
147 r_dest.y = dest.position.y;
148 r_dest.w = dest.size.x;
149 r_dest.h = dest.size.y;
150
151 const double angleDeg = angle * (180.0 / std::numbers::pi);
152
153 SDL_RenderTextureRotated(r, tex.get(), &r_src, &r_dest, angleDeg, nullptr, SDL_FLIP_NONE);
154}
155
156void asw::draw::text(const asw::Font& font, const std::string& text,
157 const asw::Vec2<float>& position, asw::Color color, asw::TextJustify justify)
158{
159 auto* r = asw::display::get_renderer();
160 if (text.empty() || r == nullptr) {
161 return;
162 }
163
164 const auto sdlColor = SDL_Color { color.r, color.g, color.b, color.a };
165 SDL_Surface* textSurface = TTF_RenderText_Blended(font.get(), text.c_str(), 0, sdlColor);
166 SDL_Texture* textTexture = SDL_CreateTextureFromSurface(r, textSurface);
167
168 SDL_SetTextureBlendMode(textTexture, SDL_BLENDMODE_BLEND);
169 SDL_SetTextureScaleMode(textTexture, SDL_SCALEMODE_LINEAR);
170
171 SDL_FRect dest;
172 dest.x = position.x;
173 dest.y = position.y;
174 dest.w = float(textSurface->w);
175 dest.h = float(textSurface->h);
176
177 // Justification settings
178 if (justify == asw::TextJustify::Center) {
179 dest.x -= dest.w / 2.0F;
180 } else if (justify == asw::TextJustify::Right) {
181 dest.x -= dest.w;
182 }
183
184 SDL_RenderTexture(r, textTexture, nullptr, &dest);
185 SDL_DestroySurface(textSurface);
186 SDL_DestroyTexture(textTexture);
187}
188
189void asw::draw::point(const asw::Vec2<float>& position, asw::Color color)
190{
191 auto* r = asw::display::get_renderer();
192 if (r == nullptr) {
193 return;
194 }
195
196 SDL_SetRenderDrawColor(r, color.r, color.g, color.b, color.a);
197 SDL_RenderPoint(r, position.x, position.y);
198}
199
201 const asw::Vec2<float>& position1, const asw::Vec2<float>& position2, asw::Color color)
202{
203 auto* r = asw::display::get_renderer();
204 if (r == nullptr) {
205 return;
206 }
207
208 SDL_SetRenderDrawColor(r, color.r, color.g, color.b, color.a);
209 SDL_RenderLine(r, position1.x, position1.y, position2.x, position2.y);
210}
211
212void asw::draw::rect(const asw::Quad<float>& position, asw::Color color)
213{
214 auto* r = asw::display::get_renderer();
215 if (r == nullptr) {
216 return;
217 }
218
219 SDL_SetRenderDrawColor(r, color.r, color.g, color.b, color.a);
220 SDL_FRect rect;
221 rect.x = position.position.x;
222 rect.y = position.position.y;
223 rect.w = position.size.x;
224 rect.h = position.size.y;
225
226 SDL_RenderRect(r, &rect);
227}
228
230{
231 auto* r = asw::display::get_renderer();
232 if (r == nullptr) {
233 return;
234 }
235
236 SDL_SetRenderDrawColor(r, color.r, color.g, color.b, color.a);
237 SDL_FRect rect;
238 rect.x = position.position.x;
239 rect.y = position.position.y;
240 rect.w = position.size.x;
241 rect.h = position.size.y;
242
243 SDL_RenderFillRect(r, &rect);
244}
245
246void asw::draw::circle(const asw::Vec2<float>& position, float radius, asw::Color color)
247{
248 auto* r = asw::display::get_renderer();
249 if (r == nullptr) {
250 return;
251 }
252
253 SDL_SetRenderDrawColor(r, color.r, color.g, color.b, color.a);
254
255 // Midpoint circle algorithm — no trig, integer arithmetic only
256 auto x = radius;
257 auto y = 0.0F;
258 auto err = 1.0F - x;
259 const float cx = position.x;
260 const float cy = position.y;
261
262 while (x >= y) {
263 SDL_RenderPoint(r, cx + x, cy + y);
264 SDL_RenderPoint(r, cx - x, cy + y);
265 SDL_RenderPoint(r, cx + x, cy - y);
266 SDL_RenderPoint(r, cx - x, cy - y);
267 SDL_RenderPoint(r, cx + y, cy + x);
268 SDL_RenderPoint(r, cx - y, cy + x);
269 SDL_RenderPoint(r, cx + y, cy - x);
270 SDL_RenderPoint(r, cx - y, cy - x);
271 y++;
272 if (err < 0) {
273 err += (2.0F * y) + 1.0F;
274 } else {
275 x--;
276 err += (2.0F * (y - x)) + 1.0F;
277 }
278 }
279}
280
281void asw::draw::circle_fill(const asw::Vec2<float>& position, float radius, asw::Color color)
282{
283 auto* r = asw::display::get_renderer();
284 if (r == nullptr) {
285 return;
286 }
287
288 SDL_SetRenderDrawColor(r, color.r, color.g, color.b, color.a);
289
290 // Midpoint circle with horizontal scanlines — no gaps, no trig
291 float x = radius;
292 float y = 0.0F;
293 float err = 1.0F - x;
294 const float cx = position.x;
295 const float cy = position.y;
296
297 while (x >= y) {
298 SDL_RenderLine(r, cx - x, cy + y, cx + x, cy + y);
299 SDL_RenderLine(r, cx - x, cy - y, cx + x, cy - y);
300 SDL_RenderLine(r, cx - y, cy + x, cx + y, cy + x);
301 SDL_RenderLine(r, cx - y, cy - x, cx + y, cy - x);
302 y++;
303 if (err < 0) {
304 err += (2.0F * y) + 1.0F;
305 } else {
306 x--;
307 err += (2.0F * (y - x)) + 1.0F;
308 }
309 }
310}
311
313{
314 SDL_SetTextureBlendMode(texture.get(), static_cast<SDL_BlendMode>(mode));
315}
316
317void asw::draw::set_alpha(const asw::Texture& texture, float alpha)
318{
319 SDL_SetTextureAlphaModFloat(texture.get(), alpha);
320}
A 2D rectangle in space.
Definition geometry.h:433
Vec2< T > size
The size of the rectangle.
Definition geometry.h:600
Vec2< T > position
The position of the rectangle.
Definition geometry.h:597
A 2D vector in space.
Definition geometry.h:21
T y
The y component of the vector.
Definition geometry.h:218
T x
The x component of the vector.
Definition geometry.h:215
Display and window routines for the ASW library.
Routines for drawing sprites and primitives to the screen.
asw::Renderer * get_renderer()
Get the SDL renderer.
Definition display.cpp:62
void sprite(const asw::Texture &tex, const asw::Vec2< float > &position)
Draw a sprite.
Definition draw.cpp:23
void circle_fill(const asw::Vec2< float > &position, float radius, asw::Color color)
Draw a filled circle.
Definition draw.cpp:281
void clear_color(asw::Color color)
Clear the screen to a color.
Definition draw.cpp:12
void line(const asw::Vec2< float > &position1, const asw::Vec2< float > &position2, asw::Color color)
Draw a line.
Definition draw.cpp:200
void rotate_sprite(const asw::Texture &tex, const asw::Vec2< float > &position, float angle)
Draw a sprite with the option to rotate it.
Definition draw.cpp:86
void stretch_sprite(const asw::Texture &tex, const asw::Quad< float > &position)
Draw a sprite with the option to stretch it.
Definition draw.cpp:70
void text(const asw::Font &font, const std::string &text, const asw::Vec2< float > &position, asw::Color color, asw::TextJustify justify=asw::TextJustify::Left)
Draw text.
Definition draw.cpp:156
void stretch_sprite_rotate_blit(const asw::Texture &tex, const asw::Quad< float > &source, const asw::Quad< float > &dest, float angle)
Draw a sprite with the option to stretch and rotate a portion of it.
Definition draw.cpp:131
void rect(const asw::Quad< float > &position, asw::Color color)
Draw a rectangle.
Definition draw.cpp:212
void circle(const asw::Vec2< float > &position, float radius, asw::Color color)
Draw a circle.
Definition draw.cpp:246
void rect_fill(const asw::Quad< float > &position, asw::Color color)
Draw a filled rectangle.
Definition draw.cpp:229
void sprite_flip(const asw::Texture &tex, const asw::Vec2< float > &position, bool flip_x, bool flip_y)
Draw a sprite with the option to flip it.
Definition draw.cpp:41
void point(const asw::Vec2< float > &position, asw::Color color)
Draw a point.
Definition draw.cpp:189
void set_blend_mode(const asw::Texture &texture, asw::BlendMode mode)
Set the blend mode of a texture.
Definition draw.cpp:312
void stretch_sprite_blit(const asw::Texture &tex, const asw::Quad< float > &source, const asw::Quad< float > &dest)
Draw a sprite with the option to stretch a portion of it.
Definition draw.cpp:108
void set_alpha(const asw::Texture &texture, float alpha)
Set the alpha of a texture.
Definition draw.cpp:317
asw::Vec2< float > get_texture_size(const asw::Texture &tex)
Get texture size.
Definition util.cpp:15
std::shared_ptr< TTF_Font > Font
Alias for a shared pointer to an TTF_Font.
Definition types.h:41
std::shared_ptr< SDL_Texture > Texture
Alias for a shared pointer to an SDL_Texture.
Definition types.h:38
BlendMode
Mappings from SDL_BLENDMODE to ASW BlendMode.
Definition types.h:20
TextJustify
Text justification options for text rendering.
Definition types.h:31
RGBA color struct with 8-bit channels.
Definition color.h:11
uint8_t b
Definition color.h:14
uint8_t r
Definition color.h:12
uint8_t g
Definition color.h:13
uint8_t a
Definition color.h:15
General utility functions.