2 * Copyright (C) 2003 Robert Kooima
4 * NEVERBALL is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published
6 * by the Free Software Foundation; either version 2 of the License,
7 * or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
17 #include <SDL_image.h>
23 #include "base_config.h"
25 /*---------------------------------------------------------------------------*/
27 void image_snap(char *filename, int w, int h)
31 SDL_Surface *buf = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 24,
32 RMASK, GMASK, BMASK, 0);
33 SDL_Surface *img = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 24,
34 RMASK, GMASK, BMASK, 0);
36 glReadPixels(0, 0, w, h, GL_RGB, GL_UNSIGNED_BYTE, buf->pixels);
38 for (i = 0; i < h; i++)
39 memcpy((GLubyte *) img->pixels + 3 * w * i,
40 (GLubyte *) buf->pixels + 3 * w * (h - i), 3 * w);
42 SDL_SaveBMP(img, filename);
48 void image_size(int *W, int *H, int w, int h)
53 while (*W < w) *W *= 2;
54 while (*H < h) *H *= 2;
57 /*---------------------------------------------------------------------------*/
59 void image_swab(SDL_Surface *src)
61 int i, j, b = (src->format->BitsPerPixel == 32) ? 4 : 3;
65 unsigned char *s = (unsigned char *) src->pixels;
68 /* Iterate over each pixel of the image. */
70 for (i = 0; i < src->h; i++)
71 for (j = 0; j < src->w; j++)
73 int k = (i * src->w + j) * b;
75 /* Swap the red and blue channels of each. */
82 SDL_UnlockSurface(src);
85 void image_white(SDL_Surface *src)
87 int i, j, b = (src->format->BitsPerPixel == 32) ? 4 : 3;
91 unsigned char *s = (unsigned char *) src->pixels;
93 /* Iterate over each pixel of the image. */
95 for (i = 0; i < src->h; i++)
96 for (j = 0; j < src->w; j++)
98 int k = (i * src->w + j) * b;
100 /* Whiten the RGB channels without touching any Alpha. */
107 SDL_UnlockSurface(src);
110 SDL_Surface *image_scale(SDL_Surface *src, int n)
114 int k, b = (src->format->BitsPerPixel == 32) ? 4 : 3;
116 SDL_Surface *dst = SDL_CreateRGBSurface(SDL_SWSURFACE,
119 src->format->BitsPerPixel,
126 SDL_LockSurface(src);
127 SDL_LockSurface(dst);
129 unsigned char *s = (unsigned char *) src->pixels;
130 unsigned char *d = (unsigned char *) dst->pixels;
132 /* Iterate each component of each distination pixel. */
134 for (di = 0; di < src->h / n; di++)
135 for (dj = 0; dj < src->w / n; dj++)
136 for (k = 0; k < b; k++)
140 /* Average the NxN source pixel block for each. */
142 for (si = di * n; si < (di + 1) * n; si++)
143 for (sj = dj * n; sj < (dj + 1) * n; sj++)
144 c += s[(si * src->w + sj) * b + k];
146 d[(di * dst->w + dj) * b + k] =
147 (unsigned char) (c / (n * n));
150 SDL_UnlockSurface(dst);
151 SDL_UnlockSurface(src);
157 /*---------------------------------------------------------------------------*/
160 * Create on OpenGL texture object using the given SDL surface and
161 * format, scaled using the current scale factor. When scaling,
162 * assume dimensions are used only for layout and lie about the size.
164 GLuint make_image_from_surf(int *w, int *h, SDL_Surface *s)
166 /*int t = config_get_d(CONFIG_TEXTURES);*/
167 int t = 0; /* TODO: Fint a way to revert CONFIG_TEXTURES */
170 glGenTextures(1, &o);
171 glBindTexture(GL_TEXTURE_2D, o);
175 SDL_Surface *d = image_scale(s, t);
177 /* Load the scaled image. */
179 if (d->format->BitsPerPixel == 32)
180 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, d->w, d->h, 0,
181 GL_RGBA, GL_UNSIGNED_BYTE, d->pixels);
183 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, d->w, d->h, 0,
184 GL_RGB, GL_UNSIGNED_BYTE, d->pixels);
190 /* Load the unscaled image. */
192 if (s->format->BitsPerPixel == 32)
193 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, s->w, s->h, 0,
194 GL_RGBA, GL_UNSIGNED_BYTE, s->pixels);
196 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, s->w, s->h, 0,
197 GL_RGB, GL_UNSIGNED_BYTE, s->pixels);
200 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
201 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
203 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
204 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
212 /*---------------------------------------------------------------------------*/
215 * Load an image from the named file. If the image is not RGBA,
216 * convert it to RGBA. Return an OpenGL texture object.
218 GLuint make_image_from_file(int *W, int *H,
219 int *w, int *h, const char *name)
229 if ((src = IMG_Load(config_data(name))))
234 image_size(&w2, &h2, src->w, src->h);
239 /* Create a new destination surface. */
241 if ((dst = SDL_CreateRGBSurface(SDL_SWSURFACE, w2, h2, 32,
242 RMASK, GMASK, BMASK, AMASK)))
244 /* Copy source pixels to the center of the destination. */
246 rect.x = (Sint16) (w2 - src->w) / 2;
247 rect.y = (Sint16) (h2 - src->h) / 2;
249 SDL_SetAlpha(src, 0, 0);
250 SDL_BlitSurface(src, NULL, dst, &rect);
252 o = make_image_from_surf(W, H, dst);
254 SDL_FreeSurface(dst);
256 SDL_FreeSurface(src);
261 /*---------------------------------------------------------------------------*/
264 * Render the given string using the given font. Transfer the image
265 * to a surface of power-of-2 size large enough to fit the string.
266 * Return an OpenGL texture object.
268 GLuint make_image_from_font(int *W, int *H,
269 int *w, int *h, const char *text, TTF_Font *font, int k)
271 SDL_Color fg = { 0xFF, 0xFF, 0xFF, 0xFF };
279 /* Render the text. */
281 if (text && strlen(text) > 0)
283 if ((src = TTF_RenderUTF8_Blended(font, text, fg)))
288 image_size(&w2, &h2, src->w, src->h);
293 /* Create a new destination surface. */
295 if ((dst = SDL_CreateRGBSurface(SDL_SWSURFACE, w2, h2, 32,
296 RMASK, GMASK, BMASK, AMASK)))
298 /* Copy source pixels to the center of the destination. */
300 rect.x = (Sint16) (w2 - src->w) / 2;
301 rect.y = (Sint16) (h2 - src->h) / 2;
303 SDL_SetAlpha(src, 0, 0);
304 SDL_BlitSurface(src, NULL, dst, &rect);
308 o = make_image_from_surf(W, H, dst);
310 SDL_FreeSurface(dst);
312 SDL_FreeSurface(src);
331 /*---------------------------------------------------------------------------*/