comparison src/video/SDL_renderer_gl.c @ 1974:70deaf574153

Added paletted OpenGL texture support.
author Sam Lantinga <slouken@libsdl.org>
date Sun, 06 Aug 2006 23:34:59 +0000
parents db3ba6c0d0df
children ccef0d0c40c6
comparison
equal deleted inserted replaced
1973:81255f93dfcd 1974:70deaf574153
64 64
65 SDL_RenderDriver GL_RenderDriver = { 65 SDL_RenderDriver GL_RenderDriver = {
66 GL_CreateRenderer, 66 GL_CreateRenderer,
67 { 67 {
68 "opengl", 68 "opengl",
69 (SDL_RENDERER_PRESENTDISCARD | SDL_RENDERER_PRESENTVSYNC | 69 (SDL_RENDERER_SINGLEBUFFER | SDL_RENDERER_PRESENTDISCARD |
70 SDL_RENDERER_ACCELERATED), 70 SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_ACCELERATED),
71 (SDL_TEXTUREBLENDMODE_NONE | SDL_TEXTUREBLENDMODE_MASK | 71 (SDL_TEXTUREBLENDMODE_NONE | SDL_TEXTUREBLENDMODE_MASK |
72 SDL_TEXTUREBLENDMODE_BLEND | SDL_TEXTUREBLENDMODE_ADD | 72 SDL_TEXTUREBLENDMODE_BLEND | SDL_TEXTUREBLENDMODE_ADD |
73 SDL_TEXTUREBLENDMODE_MOD), 73 SDL_TEXTUREBLENDMODE_MOD),
74 (SDL_TEXTURESCALEMODE_NONE | SDL_TEXTURESCALEMODE_FAST | 74 (SDL_TEXTURESCALEMODE_NONE | SDL_TEXTURESCALEMODE_FAST |
75 SDL_TEXTURESCALEMODE_SLOW), 75 SDL_TEXTURESCALEMODE_SLOW),
97 97
98 typedef struct 98 typedef struct
99 { 99 {
100 SDL_GLContext context; 100 SDL_GLContext context;
101 SDL_bool updateSize; 101 SDL_bool updateSize;
102 SDL_bool GL_EXT_paletted_texture_supported;
102 SDL_bool GL_ARB_texture_rectangle_supported; 103 SDL_bool GL_ARB_texture_rectangle_supported;
103 int blendMode; 104 int blendMode;
104 int scaleMode; 105 int scaleMode;
105 106
106 /* OpenGL functions */ 107 /* OpenGL functions */
107 #define SDL_PROC(ret,func,params) ret (APIENTRY *func) params; 108 #define SDL_PROC(ret,func,params) ret (APIENTRY *func) params;
108 #include "SDL_glfuncs.h" 109 #include "SDL_glfuncs.h"
109 #undef SDL_PROC 110 #undef SDL_PROC
111
112 PFNGLCOLORTABLEEXTPROC glColorTableEXT;
110 } GL_RenderData; 113 } GL_RenderData;
111 114
112 typedef struct 115 typedef struct
113 { 116 {
114 GLuint texture; 117 GLuint texture;
115 GLenum type; 118 GLenum type;
116 GLfloat texw; 119 GLfloat texw;
117 GLfloat texh; 120 GLfloat texh;
118 GLenum format; 121 GLenum format;
119 GLenum formattype; 122 GLenum formattype;
123 Uint8 *palette;
120 void *pixels; 124 void *pixels;
121 int pitch; 125 int pitch;
122 SDL_DirtyRectList dirty; 126 SDL_DirtyRectList dirty;
123 } GL_TextureData; 127 } GL_TextureData;
124 128
198 GL_CreateRenderer(SDL_Window * window, Uint32 flags) 202 GL_CreateRenderer(SDL_Window * window, Uint32 flags)
199 { 203 {
200 SDL_Renderer *renderer; 204 SDL_Renderer *renderer;
201 GL_RenderData *data; 205 GL_RenderData *data;
202 GLint value; 206 GLint value;
203 207 int doublebuffer;
208
209 /* Render directly to the window, unless we're compositing */
210 #ifndef __MACOSX__
211 if (flags & SDL_RENDERER_SINGLEBUFFER) {
212 SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 0);
213 }
214 #endif
204 if (!(window->flags & SDL_WINDOW_OPENGL)) { 215 if (!(window->flags & SDL_WINDOW_OPENGL)) {
205 if (SDL_RecreateWindow(window, window->flags | SDL_WINDOW_OPENGL) < 0) { 216 if (SDL_RecreateWindow(window, window->flags | SDL_WINDOW_OPENGL) < 0) {
206 return NULL; 217 return NULL;
207 } 218 }
208 } 219 }
263 } 274 }
264 if (SDL_GL_GetSwapInterval() > 0) { 275 if (SDL_GL_GetSwapInterval() > 0) {
265 renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC; 276 renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC;
266 } 277 }
267 278
279 if (SDL_GL_GetAttribute(SDL_GL_DOUBLEBUFFER, &doublebuffer) == 0) {
280 if (!doublebuffer) {
281 renderer->info.flags |= SDL_RENDERER_SINGLEBUFFER;
282 }
283 }
284
268 data->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &value); 285 data->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &value);
269 renderer->info.max_texture_width = value; 286 renderer->info.max_texture_width = value;
270 data->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &value); 287 data->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &value);
271 renderer->info.max_texture_height = value; 288 renderer->info.max_texture_height = value;
272 289
273 if (SDL_GL_ExtensionSupported("GL_ARB_texture_rectangle") 290 if (SDL_GL_ExtensionSupported("GL_ARB_texture_rectangle")
274 || SDL_GL_ExtensionSupported("GL_EXT_texture_rectangle")) { 291 || SDL_GL_ExtensionSupported("GL_EXT_texture_rectangle")) {
275 data->GL_ARB_texture_rectangle_supported = SDL_TRUE; 292 data->GL_ARB_texture_rectangle_supported = SDL_TRUE;
293 }
294 if (SDL_GL_ExtensionSupported("GL_EXT_paletted_texture")) {
295 data->GL_EXT_paletted_texture_supported = SDL_TRUE;
296 data->glColorTableEXT =
297 (PFNGLCOLORTABLEEXTPROC) SDL_GL_GetProcAddress("glColorTableEXT");
298 } else {
299 /* Don't advertise support for 8-bit indexed texture format */
300 Uint32 i, j;
301 SDL_RendererInfo *info = &renderer->info;
302 for (i = 0, j = 0; i < info->num_texture_formats; ++i) {
303 if (info->texture_formats[i] != SDL_PIXELFORMAT_INDEX8) {
304 info->texture_formats[j++] = info->texture_formats[i];
305 }
306 }
307 --info->num_texture_formats;
276 } 308 }
277 309
278 /* Set up parameters for rendering */ 310 /* Set up parameters for rendering */
279 data->blendMode = -1; 311 data->blendMode = -1;
280 data->scaleMode = -1; 312 data->scaleMode = -1;
349 internalFormat = GL_RGB; 381 internalFormat = GL_RGB;
350 format = GL_COLOR_INDEX; 382 format = GL_COLOR_INDEX;
351 type = GL_BITMAP; 383 type = GL_BITMAP;
352 break; 384 break;
353 case SDL_PIXELFORMAT_INDEX8: 385 case SDL_PIXELFORMAT_INDEX8:
354 internalFormat = GL_RGB; 386 if (!renderdata->GL_EXT_paletted_texture_supported) {
387 SDL_SetError("Unsupported texture format");
388 return -1;
389 }
390 internalFormat = GL_COLOR_INDEX8_EXT;
355 format = GL_COLOR_INDEX; 391 format = GL_COLOR_INDEX;
356 type = GL_UNSIGNED_BYTE; 392 type = GL_UNSIGNED_BYTE;
357 break; 393 break;
358 case SDL_PIXELFORMAT_RGB332: 394 case SDL_PIXELFORMAT_RGB332:
359 internalFormat = GL_R3_G3_B2; 395 internalFormat = GL_R3_G3_B2;
427 463
428 data = (GL_TextureData *) SDL_calloc(1, sizeof(*data)); 464 data = (GL_TextureData *) SDL_calloc(1, sizeof(*data));
429 if (!data) { 465 if (!data) {
430 SDL_OutOfMemory(); 466 SDL_OutOfMemory();
431 return -1; 467 return -1;
468 }
469
470 if (texture->format == SDL_PIXELFORMAT_INDEX8) {
471 data->palette = (Uint8 *) SDL_malloc(3 * 256 * sizeof(Uint8));
472 if (!data->palette) {
473 SDL_OutOfMemory();
474 SDL_free(data);
475 return -1;
476 }
477 SDL_memset(data->palette, 0xFF, 3 * 256 * sizeof(Uint8));
432 } 478 }
433 479
434 texture->driverdata = data; 480 texture->driverdata = data;
435 481
436 renderdata->glGetError(); 482 renderdata->glGetError();
465 GL_SetTexturePalette(SDL_Renderer * renderer, SDL_Texture * texture, 511 GL_SetTexturePalette(SDL_Renderer * renderer, SDL_Texture * texture,
466 const SDL_Color * colors, int firstcolor, int ncolors) 512 const SDL_Color * colors, int firstcolor, int ncolors)
467 { 513 {
468 GL_RenderData *renderdata = (GL_RenderData *) renderer->driverdata; 514 GL_RenderData *renderdata = (GL_RenderData *) renderer->driverdata;
469 GL_TextureData *data = (GL_TextureData *) texture->driverdata; 515 GL_TextureData *data = (GL_TextureData *) texture->driverdata;
470 516 Uint8 *palette;
517
518 if (!data->palette) {
519 SDL_SetError("Texture doesn't have a palette");
520 return -1;
521 }
522 palette = data->palette + firstcolor * 3;
523 while (ncolors--) {
524 *palette++ = colors->r;
525 *palette++ = colors->g;
526 *palette++ = colors->b;
527 ++colors;
528 }
529 renderdata->glBindTexture(data->type, data->texture);
530 renderdata->glColorTableEXT(data->type, GL_RGB8, 256, GL_RGB,
531 GL_UNSIGNED_BYTE, data->palette);
471 return 0; 532 return 0;
472 } 533 }
473 534
474 static int 535 static int
475 GL_GetTexturePalette(SDL_Renderer * renderer, SDL_Texture * texture, 536 GL_GetTexturePalette(SDL_Renderer * renderer, SDL_Texture * texture,
476 SDL_Color * colors, int firstcolor, int ncolors) 537 SDL_Color * colors, int firstcolor, int ncolors)
477 { 538 {
539 GL_RenderData *renderdata = (GL_RenderData *) renderer->driverdata;
478 GL_TextureData *data = (GL_TextureData *) texture->driverdata; 540 GL_TextureData *data = (GL_TextureData *) texture->driverdata;
479 541 Uint8 *palette;
542
543 if (!data->palette) {
544 SDL_SetError("Texture doesn't have a palette");
545 return -1;
546 }
547 palette = data->palette + firstcolor * 3;
548 while (ncolors--) {
549 colors->r = *palette++;
550 colors->g = *palette++;
551 colors->b = *palette++;
552 colors->unused = SDL_ALPHA_OPAQUE;
553 ++colors;
554 }
480 return 0; 555 return 0;
481 } 556 }
482 557
483 static void 558 static void
484 SetupTextureUpdate(GL_RenderData * renderdata, SDL_Texture * texture, 559 SetupTextureUpdate(GL_RenderData * renderdata, SDL_Texture * texture,
701 return; 776 return;
702 } 777 }
703 if (data->texture) { 778 if (data->texture) {
704 renderdata->glDeleteTextures(1, &data->texture); 779 renderdata->glDeleteTextures(1, &data->texture);
705 } 780 }
781 if (data->palette) {
782 SDL_free(data->palette);
783 }
706 if (data->pixels) { 784 if (data->pixels) {
707 SDL_free(data->pixels); 785 SDL_free(data->pixels);
708 } 786 }
709 SDL_FreeDirtyRects(&data->dirty); 787 SDL_FreeDirtyRects(&data->dirty);
710 SDL_free(data); 788 SDL_free(data);