comparison libmlk-core/mlk/core/texture.c @ 431:8f59201dc76b

core: cleanup hierarchy
author David Demelier <markand@malikania.fr>
date Sat, 15 Oct 2022 20:23:14 +0200
parents src/libmlk-core/core/texture.c@1645433e008d
children e1eebc6bf25d
comparison
equal deleted inserted replaced
430:1645433e008d 431:8f59201dc76b
1 /*
2 * texture.c -- basic texture management
3 *
4 * Copyright (c) 2020-2022 David Demelier <markand@malikania.fr>
5 *
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19 #include <assert.h>
20 #include <string.h>
21
22 #include "color.h"
23 #include "error.h"
24 #include "texture.h"
25 #include "texture_p.h"
26 #include "util.h"
27 #include "window.h"
28 #include "window_p.h"
29
30 int
31 texture_new(struct texture *tex, unsigned int w, unsigned int h)
32 {
33 assert(tex);
34 assert(w);
35 assert(h);
36
37 tex->handle = SDL_CreateTexture(RENDERER(),
38 SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, w, h);
39
40 if (!tex->handle) {
41 tex->w = tex->h = 0;
42 return ERR_SDL;
43 }
44
45 tex->w = w;
46 tex->h = h;
47
48 return 0;
49 }
50
51 int
52 texture_ok(const struct texture *tex)
53 {
54 return tex && tex->handle && tex->w && tex->h;
55 }
56
57 int
58 texture_set_blend_mode(struct texture *tex, enum texture_blend blend)
59 {
60 assert(tex);
61 assert(blend >= TEXTURE_BLEND_NONE && blend <= TEXTURE_BLEND_MODULATE);
62
63 static const SDL_BlendMode table[] = {
64 [TEXTURE_BLEND_NONE] = SDL_BLENDMODE_NONE,
65 [TEXTURE_BLEND_BLEND] = SDL_BLENDMODE_BLEND,
66 [TEXTURE_BLEND_ADD] = SDL_BLENDMODE_ADD,
67 [TEXTURE_BLEND_MODULATE] = SDL_BLENDMODE_MOD
68 };
69
70 if (SDL_SetTextureBlendMode(tex->handle, table[blend]) < 0)
71 return errorf("%s", SDL_GetError());
72
73 return 0;
74 }
75
76 int
77 texture_set_alpha_mod(struct texture *tex, unsigned int alpha)
78 {
79 assert(texture_ok(tex));
80 assert(alpha <= 255);
81
82 if (SDL_SetTextureAlphaMod(tex->handle, alpha) < 0)
83 return errorf("%s", SDL_GetError());
84
85 return 0;
86 }
87
88 int
89 texture_set_color_mod(struct texture *tex, unsigned long color)
90 {
91 assert(texture_ok(tex));
92
93 if (SDL_SetTextureColorMod(tex->handle, COLOR_R(color), COLOR_G(color), COLOR_B(color)) < 0)
94 return errorf("%s", SDL_GetError());
95
96 return 0;
97 }
98
99 int
100 texture_draw(const struct texture *tex, int x, int y)
101 {
102 assert(tex);
103
104 SDL_Rect dst = {
105 .x = x,
106 .y = y,
107 .w = tex->w,
108 .h = tex->h
109 };
110
111 if (SDL_RenderCopy(RENDERER(), tex->handle, NULL, &dst) < 0)
112 return errorf("%s", SDL_GetError());
113
114 return 0;
115 }
116
117 int
118 texture_scale(const struct texture *tex,
119 int src_x,
120 int src_y,
121 unsigned src_w,
122 unsigned src_h,
123 int dst_x,
124 int dst_y,
125 unsigned dst_w,
126 unsigned dst_h,
127 double angle)
128 {
129 const SDL_Rect src = {
130 .x = src_x,
131 .y = src_y,
132 .w = src_w,
133 .h = src_h
134 };
135 const SDL_Rect dst = {
136 .x = dst_x,
137 .y = dst_y,
138 .w = dst_w,
139 .h = dst_h
140 };
141
142 if (SDL_RenderCopyEx(RENDERER(), tex->handle, &src, &dst, angle, NULL, SDL_FLIP_NONE) < 0)
143 return errorf("%s", SDL_GetError());
144
145 return 0;
146 }
147
148 void
149 texture_finish(struct texture *tex)
150 {
151 assert(tex);
152
153 if (tex->handle)
154 SDL_DestroyTexture(tex->handle);
155
156 memset(tex, 0, sizeof (*tex));
157 }
158
159 /* private */
160
161 int
162 texture_from_surface(struct texture *tex, SDL_Surface *surface)
163 {
164 assert(tex);
165 assert(surface);
166
167 if (!(tex->handle = SDL_CreateTextureFromSurface(RENDERER(), surface))) {
168 tex->w = tex->h = 0;
169 return ERR_SDL;
170 }
171
172 tex->w = surface->w;
173 tex->h = surface->h;
174
175 SDL_FreeSurface(surface);
176
177 return 0;
178 }