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>
25 /*---------------------------------------------------------------------------*/
27 void image_snap(char *filename)
29 int w = config_get_d(CONFIG_WIDTH);
30 int h = config_get_d(CONFIG_HEIGHT);
33 SDL_Surface *buf = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 24,
34 RMASK, GMASK, BMASK, 0);
35 SDL_Surface *img = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 24,
36 RMASK, GMASK, BMASK, 0);
38 glReadPixels(0, 0, w, h, GL_RGB, GL_UNSIGNED_BYTE, buf->pixels);
40 for (i = 0; i < h; i++)
41 memcpy((GLubyte *) img->pixels + 3 * w * i,
42 (GLubyte *) buf->pixels + 3 * w * (h - i), 3 * w);
44 SDL_SaveBMP(img, filename);
50 void image_size(int *W, int *H, int w, int h)
55 while (*W < w) *W *= 2;
56 while (*H < h) *H *= 2;
59 /*---------------------------------------------------------------------------*/
61 void image_swab(SDL_Surface *src)
63 int i, j, b = (src->format->BitsPerPixel == 32) ? 4 : 3;
67 unsigned char *s = (unsigned char *) src->pixels;
70 /* Iterate over each pixel of the image. */
72 for (i = 0; i < src->h; i++)
73 for (j = 0; j < src->w; j++)
75 int k = (i * src->w + j) * b;
77 /* Swap the red and blue channels of each. */
84 SDL_UnlockSurface(src);
87 void image_white(SDL_Surface *src)
89 int i, j, b = (src->format->BitsPerPixel == 32) ? 4 : 3;
93 unsigned char *s = (unsigned char *) src->pixels;
95 /* Iterate over each pixel of the image. */
97 for (i = 0; i < src->h; i++)
98 for (j = 0; j < src->w; j++)
100 int k = (i * src->w + j) * b;
102 /* Whiten the RGB channels without touching any Alpha. */
109 SDL_UnlockSurface(src);
112 SDL_Surface *image_scale(SDL_Surface *src, int n)
116 int k, b = (src->format->BitsPerPixel == 32) ? 4 : 3;
118 SDL_Surface *dst = SDL_CreateRGBSurface(SDL_SWSURFACE,
121 src->format->BitsPerPixel,
128 SDL_LockSurface(src);
129 SDL_LockSurface(dst);
131 unsigned char *s = (unsigned char *) src->pixels;
132 unsigned char *d = (unsigned char *) dst->pixels;
134 /* Iterate each component of each distination pixel. */
136 for (di = 0; di < src->h / n; di++)
137 for (dj = 0; dj < src->w / n; dj++)
138 for (k = 0; k < b; k++)
142 /* Average the NxN source pixel block for each. */
144 for (si = di * n; si < (di + 1) * n; si++)
145 for (sj = dj * n; sj < (dj + 1) * n; sj++)
146 c += s[(si * src->w + sj) * b + k];
148 d[(di * dst->w + dj) * b + k] =
149 (unsigned char) (c / (n * n));
152 SDL_UnlockSurface(dst);
153 SDL_UnlockSurface(src);
159 /*---------------------------------------------------------------------------*/
162 * Create on OpenGL texture object using the given SDL surface and
163 * format, scaled using the current scale factor. When scaling,
164 * assume dimensions are used only for layout and lie about the size.
166 GLuint make_image_from_surf(int *w, int *h, SDL_Surface *s)
168 int t = config_get_d(CONFIG_TEXTURES);
171 glGenTextures(1, &o);
172 glBindTexture(GL_TEXTURE_2D, o);
176 SDL_Surface *d = image_scale(s, t);
178 /* Load the scaled image. */
180 if (d->format->BitsPerPixel == 32)
181 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, d->w, d->h, 0,
182 GL_RGBA, GL_UNSIGNED_BYTE, d->pixels);
184 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, d->w, d->h, 0,
185 GL_RGB, GL_UNSIGNED_BYTE, d->pixels);
191 /* Load the unscaled image. */
193 if (s->format->BitsPerPixel == 32)
194 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, s->w, s->h, 0,
195 GL_RGBA, GL_UNSIGNED_BYTE, s->pixels);
197 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, s->w, s->h, 0,
198 GL_RGB, GL_UNSIGNED_BYTE, s->pixels);
201 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
202 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
204 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
205 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
213 /*---------------------------------------------------------------------------*/
216 * Load an image from the named file. If the image is not RGBA,
217 * convert it to RGBA. Return an OpenGL texture object.
219 GLuint make_image_from_file(int *W, int *H,
220 int *w, int *h, const char *name)
230 if ((src = IMG_Load(config_data(name))))
235 image_size(&w2, &h2, src->w, src->h);
240 /* Create a new destination surface. */
242 if ((dst = SDL_CreateRGBSurface(SDL_SWSURFACE, w2, h2, 32,
243 RMASK, GMASK, BMASK, AMASK)))
245 /* Copy source pixels to the center of the destination. */
247 rect.x = (Sint16) (w2 - src->w) / 2;
248 rect.y = (Sint16) (h2 - src->h) / 2;
250 SDL_SetAlpha(src, 0, 0);
251 SDL_BlitSurface(src, NULL, dst, &rect);
253 o = make_image_from_surf(W, H, dst);
255 SDL_FreeSurface(dst);
257 SDL_FreeSurface(src);
262 /*---------------------------------------------------------------------------*/
265 * Render the given string using the given font. Transfer the image
266 * to a surface of power-of-2 size large enough to fit the string.
267 * Return an OpenGL texture object.
269 GLuint make_image_from_font(int *W, int *H,
270 int *w, int *h, const char *text, TTF_Font *font, int k)
272 SDL_Color fg = { 0xFF, 0xFF, 0xFF, 0xFF };
280 /* Render the text. */
282 if (text && strlen(text) > 0)
284 if ((src = TTF_RenderUTF8_Blended(font, text, fg)))
289 image_size(&w2, &h2, src->w, src->h);
294 /* Create a new destination surface. */
296 if ((dst = SDL_CreateRGBSurface(SDL_SWSURFACE, w2, h2, 32,
297 RMASK, GMASK, BMASK, AMASK)))
299 /* Copy source pixels to the center of the destination. */
301 rect.x = (Sint16) (w2 - src->w) / 2;
302 rect.y = (Sint16) (h2 - src->h) / 2;
304 SDL_SetAlpha(src, 0, 0);
305 SDL_BlitSurface(src, NULL, dst, &rect);
309 o = make_image_from_surf(W, H, dst);
311 SDL_FreeSurface(dst);
313 SDL_FreeSurface(src);
332 /*---------------------------------------------------------------------------*/