2 * SDLEMU library - Free sdl related functions library
3 * Copyrigh(c) 1999-2002 sdlemu development crew
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 Version 1.0.001 - 4-10-2004
23 - Added support for 16, 24 and 32 bit textures * new *;
24 - Added support for 16, 24 and 32 bit texture rendering *new*;
28 #include "sdlemu_opengl.h"
30 static SDL_Surface *texture = 0;
31 static GLuint texid = 0;
32 static GLfloat texcoord[4];
33 static unsigned int glFilter;
34 static unsigned int texturebpp = 0; // 16, 24 or 32 bpp
36 static inline int power_of_two(int input)
46 void sdlemu_init_opengl(SDL_Surface * src, int texturetype, float size, int filter, int src_bpp)
49 Uint32 rmask, gmask, bmask, amask;
51 // We allow the developer to set its own texture bpp. But if the value is NULL or
52 // not equal to 16, 24 or 32, we make the texturebpp the same as the BPP from src.
53 if ( (src_bpp != NULL) && ( (src_bpp == 16) || (src_bpp == 24) || (src_bpp == 32) ) )
56 texturebpp = src->format->BitsPerPixel;
58 printf("\nOpenGL driver information :\n");
60 printf("Vendor: %s\n", glGetString(GL_VENDOR));
61 printf("Renderer: %s\n", glGetString(GL_RENDERER));
62 printf("Version: %s\n", glGetString(GL_VERSION));
63 printf("OpenGL Texture BPP: %d\n", texturebpp);
64 printf("OpenGL drawmethod: ");
69 printf("GL_QUAD rendering\n\n");
72 printf("GL_TRIANGLE rendering\n\n");
78 // Texture width/height should be power of 2
79 // So, find the largest power of two that will contain both the width and height
80 // w = power_of_two(src->w);
81 // h = power_of_two(src->h);
88 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
90 // rmask = 0xff000000;
91 // gmask = 0x00ff0000;
92 // bmask = 0x0000ff00;
93 // amask = 0x00000000;
102 // rmask = 0x000000ff;
103 // gmask = 0x0000ff00;
104 // bmask = 0x00ff0000;
105 // amask = 0x00000000;
116 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
130 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
144 // create texture surface
145 texture = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, texturebpp, rmask, gmask, bmask, amask);
147 #if SDL_BYTEORDER == SDL_LIL_ENDIAN
148 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000);
150 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF);
154 // setup 2D gl environment
155 //glPushAttrib(GL_ENABLE_BIT);
156 //glDisable(GL_DEPTH_TEST);
157 //glDisable(GL_CULL_FACE);
158 //glEnable(GL_TEXTURE_2D);
161 glDisable(GL_LIGHTING);
162 glDisable(GL_CULL_FACE);
163 glDisable(GL_DEPTH_TEST);
165 glDisable(GL_NORMALIZE);
166 glDisable(GL_ALPHA_TEST);
167 glEnable(GL_TEXTURE_2D);
168 glBlendFunc (GL_SRC_ALPHA, GL_ONE);
170 glViewport(0, 0, src->w * size, src->h * size);
172 glMatrixMode(GL_PROJECTION);
176 glOrtho(0.0, (GLdouble)(src->w * size), (GLdouble)(src->h * size), 0.0, 0.0, 1.0);
177 glMatrixMode(GL_MODELVIEW);
181 // texture coordinates
184 texcoord[2] = (GLfloat)(src->w) / texture->w;
185 texcoord[3] = (GLfloat)(src->h) / texture->h;
187 // create an RGBA texture for the texture surface
188 glGenTextures(1, &texid);
189 glBindTexture(GL_TEXTURE_2D, texid);
193 printf("OpenGL filters: enabled\n");
194 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
195 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
199 printf("OpenGL filters: disabled\n");
200 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
201 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
204 switch ( texturebpp )
207 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB5, texture->w, texture->h, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
210 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, texture->w, texture->h, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
214 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, texture->w, texture->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
220 void sdlemu_draw_texture(SDL_Surface * dst, SDL_Surface * src, int texturetype)
222 //SDL_Rect rect = { 0, 0, src->w, src->h };
224 // convert color-indexed surface to RGB texture
225 //SDL_BlitSurface(src, &rect, texture, &rect);
228 SDL_BlitSurface(src, NULL, texture, NULL);
230 // printf("Rmask - src : %d\n", src->format->Rmask);
231 // printf("Gmask - src : %d\n", src->format->Gmask);
232 // printf("Bmask - src : %d\n", src->format->Bmask);
233 // printf("Amask - src : %d\n", src->format->Amask);
235 // printf("Rmask - texture : %d\n", texture->format->Rmask);
236 // printf("Gmask - texture : %d\n", texture->format->Gmask);
237 // printf("Bmask - texture : %d\n", texture->format->Bmask);
238 // printf("Amask - texture : %d\n", texture->format->Amask);
240 // Texturemap complete texture to surface so we have free scaling
242 switch ( texturebpp )
245 // GL_UNSIGNED_SHORT_5_6_5
246 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, texture->w, texture->h,
247 GL_RGB, GL_UNSIGNED_SHORT_5_6_5, texture->pixels);
250 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, texture->w, texture->h,
251 GL_RGB, GL_UNSIGNED_BYTE, texture->pixels);
255 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, texture->w, texture->h,
256 GL_RGBA, GL_UNSIGNED_BYTE, texture->pixels);
264 glTexCoord2f(texcoord[0], texcoord[1]);
266 glTexCoord2f(texcoord[2], texcoord[1]);
267 glVertex2f(dst->w , 0);
268 glTexCoord2f(texcoord[2], texcoord[3]);
269 glVertex2f(dst->w , dst->h );
270 glTexCoord2f(texcoord[0], texcoord[3]);
271 glVertex2f(0, dst->h );
275 glBegin(GL_TRIANGLE_STRIP);
276 glTexCoord2f(texcoord[0], texcoord[1]); glVertex3i(0, 0, 0);
277 glTexCoord2f(texcoord[2], texcoord[1]); glVertex3i(dst->w, 0, 0);
278 glTexCoord2f(texcoord[0], texcoord[3]); glVertex3i(0, dst->h, 0);
279 glTexCoord2f(texcoord[2], texcoord[3]); glVertex3i(dst->w, dst->h, 0);
284 SDL_GL_SwapBuffers();
289 void sdlemu_close_opengl(void)
292 SDL_FreeSurface(texture);
297 // Resize the texture
298 // This should honor the glFilter flag that is passed in to the initialization code,
299 // but, at the moment, it doesn't...
302 void sdlemu_resize_texture(SDL_Surface * src, SDL_Surface * dst, int filter, int src_bpp)
304 // Texture width/height should be power of 2
305 // So, find the largest power of two that will contain both the width and height
306 //int w = power_of_two(src->w), h = power_of_two(src->h);
307 int w = 512, h = 512;
308 Uint32 rmask, gmask, bmask, amask;
310 // We allow the developer to set its own texture bpp. But if the value is NULL or
311 // not equal to 16, 24 or 32, we make the texturebpp the same as the BPP from src.
312 if ( (src_bpp != NULL) && ( (src_bpp == 16) || (src_bpp == 24) || (src_bpp == 32) ) )
313 texturebpp = src_bpp;
315 texturebpp = src->format->BitsPerPixel;
317 // Delete old texture (if allocated)
319 SDL_FreeSurface(texture);
321 // create texture surface
322 //NOTE: Seems the byte order here *is* important! (Perhaps only for 32 BPP?)
324 // NOTE : Nope! Not any more. We can now producte textures based upon 16, 24 or 32 bpp.
325 switch ( texturebpp )
328 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
330 // rmask = 0xff000000;
331 // gmask = 0x00ff0000;
332 // bmask = 0x0000ff00;
333 // amask = 0x00000000;
342 // rmask = 0x000000ff;
343 // gmask = 0x0000ff00;
344 // bmask = 0x00ff0000;
345 // amask = 0x00000000;
355 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
369 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
383 // create texture surface
384 texture = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, texturebpp, rmask, gmask, bmask, amask);
386 #if SDL_BYTEORDER == SDL_LIL_ENDIAN
387 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000);
389 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF);
395 texture = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 32,
396 #if SDL_BYTEORDER == SDL_LIL_ENDIAN
397 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000);
399 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF);
402 // setup 2D gl environment
403 //glPushAttrib(GL_ENABLE_BIT);
404 //glDisable(GL_DEPTH_TEST);
405 //glDisable(GL_CULL_FACE);
406 //glEnable(GL_TEXTURE_2D);
409 glDisable(GL_LIGHTING);
410 glDisable(GL_CULL_FACE);
411 glDisable(GL_DEPTH_TEST);
413 glDisable(GL_NORMALIZE);
414 glDisable(GL_ALPHA_TEST);
415 glEnable(GL_TEXTURE_2D);
416 glBlendFunc (GL_SRC_ALPHA, GL_ONE);
418 glViewport(0, 0, dst->w, dst->h);
420 glMatrixMode(GL_PROJECTION);
424 glOrtho(0.0, (GLdouble)dst->w, (GLdouble)dst->h, 0.0, 0.0, 1.0);
425 glMatrixMode(GL_MODELVIEW);
429 // texture coordinates
430 texcoord[0] = 0.0f, texcoord[1] = 0.0f,
431 texcoord[2] = (GLfloat)(src->w) / texture->w,
432 texcoord[3] = (GLfloat)(src->h) / texture->h;
434 // create an RGBA texture for the texture surface
435 glGenTextures(1, &texid);
436 glBindTexture(GL_TEXTURE_2D, texid);
441 printf("OpenGL filters: enabled\n");
442 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
443 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
447 printf("OpenGL filters: disabled\n");
448 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
449 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
452 switch ( texturebpp )
455 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB5, texture->w, texture->h, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
458 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, texture->w, texture->h, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
462 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, texture->w, texture->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
466 //glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, texture->w, texture->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);