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