-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathconvgltex.c
113 lines (96 loc) · 3.22 KB
/
convgltex.c
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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
/*
* SDL surface conversion to OpenGL texture formats
*
* Mattias Engdegård
*
* Use, modification and distribution of this source is allowed without
* limitation, warranty or liability of any kind.
*/
#include <string.h>
#include <SDL.h>
#include <SDL_image.h>
/*
* Convert a surface into one suitable as an OpenGL texture;
* in RGBA format if want_alpha is nonzero, or in RGB format otherwise.
*
* The surface may have a colourkey, which is then translated to an alpha
* channel if RGBA is desired.
*
* Return the resulting texture, or NULL on error. The original surface is
* always freed.
*/
SDL_Surface * conv_surf_gl (SDL_Surface * s, int want_alpha)
{
Uint32 rmask, gmask, bmask, amask;
SDL_Surface * conv;
int bpp = want_alpha ? 32 : 24;
/* SDL interprets each pixel as a 24 or 32-bit number, so our
masks must depend on the endianness (byte order) of the
machine. */
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
rmask = 0xff000000 >> (32 - bpp);
gmask = 0x00ff0000 >> (32 - bpp);
bmask = 0x0000ff00 >> (32 - bpp);
amask = 0x000000ff >> (32 - bpp);
#else /* */
rmask = 0x000000ff;
gmask = 0x0000ff00;
bmask = 0x00ff0000;
amask = want_alpha ? 0xff000000 : 0;
#endif /* */
/* check if the surface happens to be in the right format */
if (s->format->BitsPerPixel == bpp
&&s->format->Rmask == rmask
&&s->format->Gmask == gmask
&&s->format->Bmask == bmask
&&s->format->Amask == amask &&!(s->flags & SDL_SRCCOLORKEY)) {
/* no conversion needed */
return s;
}
/* wrong format, conversion necessary */
/* SDL surfaces are created with lines padded to start at 32-bit boundaries
which suits OpenGL well (as long as GL_UNPACK_ALIGNMENT remains
unchanged from its initial value of 4) */
conv =
SDL_CreateRGBSurface (SDL_SWSURFACE, s->w, s->h, bpp, rmask, gmask,
bmask, amask);
if (!conv) {
SDL_FreeSurface (conv);
return NULL;
}
if (want_alpha) {
/* SDL sets the SDL_SRCALPHA flag on all surfaces with an
alpha channel. We need to clear that flag for the copy,
since SDL would attempt to alpha-blend our image otherwise */
SDL_SetAlpha (s, 0, 255);
}
/*
* Do the conversion. If the source surface has a colourkey, then it
* will be used in the blit. We use the fact that newly created software
* surfaces are zero-filled, so the pixels not blitted will remain
* transparent.
*/
if (SDL_BlitSurface (s, NULL, conv, NULL) < 0) {
/* blit error */
SDL_FreeSurface (conv);
conv = NULL;
}
SDL_FreeSurface (s);
return conv;
}
/*
* A sample use of conv_surf_gl():
*
* Load an image from a file, and convert it to RGB or RGBA format,
* depending on the image.
*
* Return the resulting surface, or NULL on error
*/
/*
SDL_Surface *load_gl_texture(char *file)
{
SDL_Surface *s = IMG_Load(file);
if(!s)
return NULL;
return conv_surf_gl(s, s->format->Amask || (s->flags & SDL_SRCCOLORKEY));
} */