Mercurial > sdl-ios-xcode
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); |