-
Notifications
You must be signed in to change notification settings - Fork 1
/
sdl_extra.hpp
79 lines (61 loc) · 2.28 KB
/
sdl_extra.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
#pragma once
#include <algorithm>
#include <SDL2/SDL.h>
#include "math.hpp"
// blits a single colored pixel onto the given surface at the given point
inline void SDL_Blit(SDL_Surface* surface, int x, int y, const SDL_Color& color)
{
SDL_Rect rect{ x, y, 1, 1 };
SDL_FillRect(surface, &rect, SDL_MapRGBA(surface->format, color.r, color.g, color.b, color.a));
}
// blits a 3x3 rectangle around the given pixel
inline void SDL_BlitBig(SDL_Surface* surface, int x, int y, const SDL_Color& color)
{
SDL_Blit(surface, x - 1, y - 1, color);
SDL_Blit(surface, x + 0, y - 1, color);
SDL_Blit(surface, x + 1, y - 1, color);
SDL_Blit(surface, x - 1, y + 0, color);
SDL_Blit(surface, x + 0, y + 0, color);
SDL_Blit(surface, x + 1, y + 0, color);
SDL_Blit(surface, x - 1, y + 1, color);
SDL_Blit(surface, x + 0, y + 1, color);
SDL_Blit(surface, x + 1, y + 1, color);
}
// reads the color of a single pixel in the given surface
inline SDL_Color SDL_ReadPixel(SDL_Surface* surface, int x, int y)
{
int bpp = surface->format->BytesPerPixel;
Uint8* pixel_data = (Uint8*)surface->pixels + y * surface->pitch + x * bpp;
Uint32 pixel = 0;
switch (bpp)
{
case 1:
pixel = *pixel_data;
break;
case 2:
pixel = *(Uint16*)pixel_data;
break;
case 3:
if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
{ pixel = (pixel_data[0] << 16) | (pixel_data[1] << 8) | pixel_data[2]; }
else
{ pixel = pixel_data[0] | (pixel_data[1] << 8) | (pixel_data[2] << 16); }
break;
case 4:
pixel = *(Uint32*)pixel_data;
break;
}
SDL_Color color;
SDL_GetRGBA(pixel, surface->format, &color.r, &color.g, &color.b, &color.a);
return color;
}
// samples a pixel in the given surface using normalized coordinates
inline SDL_Color SDL_Sample(SDL_Surface* surface, float u, float v)
{
auto x = (int)Lerp(0.0f, float(surface->w), u);
auto y = (int)Lerp(float(surface->h), 0.0f, v);
if (x >= 0 && x <= surface->w && y >= 0 && y <= surface->h)
{ return SDL_ReadPixel(surface, std::min(x, surface->w - 1), std::min(y, surface->h - 1)); }
else
{ return { 0, 0, 0, 255 }; }
}