comparison src/video/SDL_renderer_gl.c @ 2835:f38257b5d936

Initial pixel shader support for YUV textures in the GL renderer. This work is not complete yet!
author Ryan C. Gordon <icculus@icculus.org>
date Sat, 06 Dec 2008 00:56:47 +0000
parents c2e182a37f5f
children b128b94ed31e
comparison
equal deleted inserted replaced
2834:feb6ccdb888f 2835:f38257b5d936
38 /* OpenGL renderer implementation */ 38 /* OpenGL renderer implementation */
39 39
40 /* Details on optimizing the texture path on Mac OS X: 40 /* Details on optimizing the texture path on Mac OS X:
41 http://developer.apple.com/documentation/GraphicsImaging/Conceptual/OpenGL-MacProgGuide/opengl_texturedata/chapter_10_section_2.html 41 http://developer.apple.com/documentation/GraphicsImaging/Conceptual/OpenGL-MacProgGuide/opengl_texturedata/chapter_10_section_2.html
42 */ 42 */
43
44 /* !!! FIXME: this should go in a higher level than the GL renderer. */
45 static __inline__ int
46 bytes_per_pixel(const Uint32 format)
47 {
48 switch (format) {
49 case SDL_PIXELFORMAT_UYVY:
50 /* !!! FIXME: other YUV formats here... */
51 return 2;
52 default:
53 return SDL_BYTESPERPIXEL(format);
54 }
55 return -1; /* shouldn't ever hit this. */
56 }
57
43 58
44 static const float inv255f = 1.0f / 255.0f; 59 static const float inv255f = 1.0f / 255.0f;
45 60
46 static SDL_Renderer *GL_CreateRenderer(SDL_Window * window, Uint32 flags); 61 static SDL_Renderer *GL_CreateRenderer(SDL_Window * window, Uint32 flags);
47 static int GL_ActivateRenderer(SDL_Renderer * renderer); 62 static int GL_ActivateRenderer(SDL_Renderer * renderer);
122 { 137 {
123 SDL_GLContext context; 138 SDL_GLContext context;
124 SDL_bool updateSize; 139 SDL_bool updateSize;
125 SDL_bool GL_ARB_texture_rectangle_supported; 140 SDL_bool GL_ARB_texture_rectangle_supported;
126 SDL_bool GL_EXT_paletted_texture_supported; 141 SDL_bool GL_EXT_paletted_texture_supported;
142 SDL_bool GL_ARB_fragment_program_supported;
127 int blendMode; 143 int blendMode;
128 int scaleMode; 144 int scaleMode;
129 145
130 /* OpenGL functions */ 146 /* OpenGL functions */
131 #define SDL_PROC(ret,func,params) ret (APIENTRY *func) params; 147 #define SDL_PROC(ret,func,params) ret (APIENTRY *func) params;
133 #undef SDL_PROC 149 #undef SDL_PROC
134 150
135 PFNGLCOLORTABLEEXTPROC glColorTableEXT; 151 PFNGLCOLORTABLEEXTPROC glColorTableEXT;
136 void (*glTextureRangeAPPLE) (GLenum target, GLsizei length, 152 void (*glTextureRangeAPPLE) (GLenum target, GLsizei length,
137 const GLvoid * pointer); 153 const GLvoid * pointer);
154
155 PFNGLGETPROGRAMIVARBPROC glGetProgramivARB;
156 PFNGLGETPROGRAMSTRINGARBPROC glGetProgramStringARB;
157 PFNGLPROGRAMLOCALPARAMETER4FVARBPROC glProgramLocalParameter4fvARB;
158 PFNGLDELETEPROGRAMSARBPROC glDeleteProgramsARB;
159 PFNGLGENPROGRAMSARBPROC glGenProgramsARB;
160 PFNGLBINDPROGRAMARBPROC glBindProgramARB;
161 PFNGLPROGRAMSTRINGARBPROC glProgramStringARB;
162
163 /* (optional) fragment programs */
164 GLuint fragment_program_UYVY;
138 } GL_RenderData; 165 } GL_RenderData;
139 166
140 typedef struct 167 typedef struct
141 { 168 {
142 GLuint texture; 169 GLuint texture;
170 GLuint shader;
143 GLenum type; 171 GLenum type;
144 GLfloat texw; 172 GLfloat texw;
145 GLfloat texh; 173 GLfloat texh;
146 GLenum format; 174 GLenum format;
147 GLenum formattype; 175 GLenum formattype;
346 data->glTextureRangeAPPLE = 374 data->glTextureRangeAPPLE =
347 (void (*)(GLenum, GLsizei, const GLvoid *)) 375 (void (*)(GLenum, GLsizei, const GLvoid *))
348 SDL_GL_GetProcAddress("glTextureRangeAPPLE"); 376 SDL_GL_GetProcAddress("glTextureRangeAPPLE");
349 } 377 }
350 378
379 /* we might use fragment programs for YUV data, etc. */
380 if (SDL_GL_ExtensionSupported("GL_ARB_fragment_program")) {
381 /* !!! FIXME: this doesn't check for errors. */
382 /* !!! FIXME: this should really reuse the glfuncs.h stuff. */
383 data->glGetProgramivARB = (PFNGLGETPROGRAMIVARBPROC)
384 SDL_GL_GetProcAddress("glGetProgramivARB");
385 data->glGetProgramStringARB = (PFNGLGETPROGRAMSTRINGARBPROC)
386 SDL_GL_GetProcAddress("glGetProgramStringARB");
387 data->glProgramLocalParameter4fvARB =
388 (PFNGLPROGRAMLOCALPARAMETER4FVARBPROC)
389 SDL_GL_GetProcAddress("glProgramLocalParameter4fvARB");
390 data->glDeleteProgramsARB = (PFNGLDELETEPROGRAMSARBPROC)
391 SDL_GL_GetProcAddress("glDeleteProgramsARB");
392 data->glGenProgramsARB = (PFNGLGENPROGRAMSARBPROC)
393 SDL_GL_GetProcAddress("glGenProgramsARB");
394 data->glBindProgramARB = (PFNGLBINDPROGRAMARBPROC)
395 SDL_GL_GetProcAddress("glBindProgramARB");
396 data->glProgramStringARB = (PFNGLPROGRAMSTRINGARBPROC)
397 SDL_GL_GetProcAddress("glProgramStringARB");
398 data->GL_ARB_fragment_program_supported = SDL_TRUE;
399 }
400
351 /* Set up parameters for rendering */ 401 /* Set up parameters for rendering */
352 data->blendMode = -1; 402 data->blendMode = -1;
353 data->scaleMode = -1; 403 data->scaleMode = -1;
354 data->glDisable(GL_DEPTH_TEST); 404 data->glDisable(GL_DEPTH_TEST);
355 data->glDisable(GL_CULL_FACE); 405 data->glDisable(GL_CULL_FACE);
404 value <<= 1; 454 value <<= 1;
405 } 455 }
406 return value; 456 return value;
407 } 457 }
408 458
459
460 #define DEBUG_PROGRAM_COMPILE 1
461
462 static GLuint
463 compile_shader(GL_RenderData *data, GLenum shader_type, const char *source)
464 {
465 #if DEBUG_PROGRAM_COMPILE
466 printf("compiling shader:\n%s\n\n", source);
467 #endif
468
469 GLuint program = 0;
470
471 data->glGetError(); /* flush any existing error state. */
472 data->glGenProgramsARB(1, &program);
473 data->glBindProgramARB(shader_type, program);
474 data->glProgramStringARB(shader_type, GL_PROGRAM_FORMAT_ASCII_ARB,
475 SDL_strlen(source), source);
476
477 if (data->glGetError() == GL_INVALID_OPERATION)
478 {
479 #if DEBUG_PROGRAM_COMPILE
480 GLint pos = 0;
481 const GLubyte *errstr;
482 data->glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &pos);
483 errstr = data->glGetString(GL_PROGRAM_ERROR_STRING_ARB);
484 printf("program compile error at position %d: %s\n\n",
485 (int) pos, (const char *) errstr);
486 #endif
487 data->glBindProgramARB(shader_type, 0);
488 data->glDeleteProgramsARB(1, &program);
489 return 0;
490 } // if
491
492 return program;
493 }
494
495 // UYVY to RGB equasion...
496 // R = 1.164(Y-16) + 1.596(Cr-128)
497 // G = 1.164(Y-16) - 0.813(Cr-128) - 0.391(Cb-128)
498 // B = 1.164(Y-16) + 2.018(Cb-128)
499 // Byte layout is Cb, Y1, Cr, Y2.
500 // 4 bytes == 2 pixels: Y1/Cb/Cr, Y2/Cb/Cr
501 // !!! FIXME: this ignores blendmodes, etc.
502 // !!! FIXME: this could be more efficient...use a dot product for green, not convert to 255.0 range, etc.
503 static const char *fragment_program_UYVY_source_code =
504 "!!ARBfp1.0\n"
505
506 // outputs...
507 "OUTPUT outcolor = result.color;\n"
508
509 // scratch registers...
510 "TEMP uyvy;\n"
511 "TEMP luminance;\n"
512 "TEMP work;\n"
513
514 // We need 32 bits to store the data, but each pixel is 16 bits in itself.
515 // halve the coordinates to grab the correct 32 bits for the fragment.
516 "MUL work, fragment.texcoord, { 0.5, 1.0, 1.0, 1.0 };\n"
517
518 // Sample the YUV texture. Cb, Y1, Cr, Y2, are stored in r,g,b,a.
519 // !!! FIXME: "RECT" needs to be "2D" if we're not using texture_rectangle extension. :/
520 "TEX uyvy, work, texture[0], RECT;\n"
521
522 // Scale from 0.0/1.0 to 0.0/255.0 and do subtractions. (!!! FIXME: optimize!)
523 "MUL uyvy, uyvy, { 255.0, 255.0, 255.0, 255.0 };\n"
524 "SUB uyvy, uyvy, { 128.0, 16.0, 128.0, 16.0 };\n"
525
526 // Choose the luminance component by texcoord.
527 // !!! FIXME: laziness wins out for now... just average Y1 and Y2.
528 "ADD luminance, uyvy.yyyy, uyvy.wwww;\n"
529 "MUL luminance, luminance, { 0.5, 0.5, 0.5, 0.5 };\n"
530
531 // Multiply luminance by its magic value.
532 "MUL luminance, luminance, { 1.164, 1.164, 1.164, 1.164 };\n"
533
534 // uyvy.xyzw becomes Cr/Cr/Cb/Cb, with multiplications.
535 "MUL uyvy, uyvy.zzxx, { 1.596, -0.813, 2.018, -0.391 };\n"
536
537 // Add luminance Cr and Cb, store to RGB channels.
538 "ADD work.rgb, luminance, uyvy;\n"
539
540 // Do final addition for Green channel. (!!! FIXME: this should be a DPH?)
541 "ADD work.g, work.g, uyvy.w;\n"
542
543 // Scale back to 0.0/1.0. (this number is 1.0/255.0).
544 "MUL work, work, { 0.0039215686274509803, 0.0039215686274509803, 0.0039215686274509803, 0.0039215686274509803 };\n"
545
546 // Make sure alpha channel is fully opaque. (!!! FIXME: blend modes!)
547 "MOV work.a, { 1.0 };\n"
548
549 // Store out the final fragment color.
550 "MOV outcolor, work;\n"
551
552 // ...and we're done.
553 "END\n";
554
555
409 static int 556 static int
410 GL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) 557 GL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
411 { 558 {
412 GL_RenderData *renderdata = (GL_RenderData *) renderer->driverdata; 559 GL_RenderData *renderdata = (GL_RenderData *) renderer->driverdata;
413 SDL_Window *window = SDL_GetWindowFromID(renderer->window); 560 SDL_Window *window = SDL_GetWindowFromID(renderer->window);
414 GL_TextureData *data; 561 GL_TextureData *data;
415 GLint internalFormat; 562 GLint internalFormat;
416 GLenum format, type; 563 GLenum format, type;
417 int texture_w, texture_h; 564 int texture_w, texture_h;
565 GLuint shader = 0;
418 GLenum result; 566 GLenum result;
419 567
420 switch (texture->format) { 568 switch (texture->format) {
421 case SDL_PIXELFORMAT_INDEX1LSB: 569 case SDL_PIXELFORMAT_INDEX1LSB:
422 case SDL_PIXELFORMAT_INDEX1MSB: 570 case SDL_PIXELFORMAT_INDEX1MSB:
502 case SDL_PIXELFORMAT_ARGB2101010: 650 case SDL_PIXELFORMAT_ARGB2101010:
503 internalFormat = GL_RGB10_A2; 651 internalFormat = GL_RGB10_A2;
504 format = GL_BGRA; 652 format = GL_BGRA;
505 type = GL_UNSIGNED_INT_2_10_10_10_REV; 653 type = GL_UNSIGNED_INT_2_10_10_10_REV;
506 break; 654 break;
655 case SDL_PIXELFORMAT_UYVY:
656 if (renderdata->GL_ARB_fragment_program_supported) {
657 if (renderdata->fragment_program_UYVY == 0) {
658 renderdata->fragment_program_UYVY =
659 compile_shader(renderdata, GL_FRAGMENT_PROGRAM_ARB,
660 fragment_program_UYVY_source_code);
661 if (renderdata->fragment_program_UYVY == 0) {
662 SDL_SetError("Fragment program compile error");
663 return -1;
664 }
665 }
666 shader = renderdata->fragment_program_UYVY;
667 internalFormat = GL_RGBA;
668 format = GL_RGBA;
669 type = GL_UNSIGNED_BYTE;
670 } else {
671 SDL_SetError("Unsupported texture format");
672 return -1;
673 }
674 break;
507 default: 675 default:
508 SDL_SetError("Unsupported texture format"); 676 SDL_SetError("Unsupported texture format");
509 return -1; 677 return -1;
510 } 678 }
511 679
512 data = (GL_TextureData *) SDL_calloc(1, sizeof(*data)); 680 data = (GL_TextureData *) SDL_calloc(1, sizeof(*data));
513 if (!data) { 681 if (!data) {
514 SDL_OutOfMemory(); 682 SDL_OutOfMemory();
515 return -1; 683 return -1;
516 } 684 }
685
686 data->shader = shader;
517 687
518 if (texture->format == SDL_PIXELFORMAT_INDEX8) { 688 if (texture->format == SDL_PIXELFORMAT_INDEX8) {
519 data->palette = (Uint8 *) SDL_malloc(3 * 256 * sizeof(Uint8)); 689 data->palette = (Uint8 *) SDL_malloc(3 * 256 * sizeof(Uint8));
520 if (!data->palette) { 690 if (!data->palette) {
521 SDL_OutOfMemory(); 691 SDL_OutOfMemory();
524 } 694 }
525 SDL_memset(data->palette, 0xFF, 3 * 256 * sizeof(Uint8)); 695 SDL_memset(data->palette, 0xFF, 3 * 256 * sizeof(Uint8));
526 } 696 }
527 697
528 if (texture->access == SDL_TEXTUREACCESS_STREAMING) { 698 if (texture->access == SDL_TEXTUREACCESS_STREAMING) {
529 data->pitch = texture->w * SDL_BYTESPERPIXEL(texture->format); 699 data->pitch = texture->w * bytes_per_pixel(texture->format);
530 data->pixels = SDL_malloc(texture->h * data->pitch); 700 data->pixels = SDL_malloc(texture->h * data->pitch);
531 if (!data->pixels) { 701 if (!data->pixels) {
532 SDL_OutOfMemory(); 702 SDL_OutOfMemory();
533 SDL_free(data); 703 SDL_free(data);
534 return -1; 704 return -1;
541 renderdata->glGenTextures(1, &data->texture); 711 renderdata->glGenTextures(1, &data->texture);
542 if (renderdata->GL_ARB_texture_rectangle_supported) { 712 if (renderdata->GL_ARB_texture_rectangle_supported) {
543 data->type = GL_TEXTURE_RECTANGLE_ARB; 713 data->type = GL_TEXTURE_RECTANGLE_ARB;
544 texture_w = texture->w; 714 texture_w = texture->w;
545 texture_h = texture->h; 715 texture_h = texture->h;
546 data->texw = (GLfloat) texture->w; 716 data->texw = (GLfloat) texture_w;
547 data->texh = (GLfloat) texture->h; 717 data->texh = (GLfloat) texture_h;
548 } else { 718 } else {
549 data->type = GL_TEXTURE_2D; 719 data->type = GL_TEXTURE_2D;
550 texture_w = power_of_2(texture->w); 720 texture_w = power_of_2(texture->w);
551 texture_h = power_of_2(texture->h); 721 texture_h = power_of_2(texture->h);
552 data->texw = (GLfloat) texture->w / texture_w; 722 data->texw = (GLfloat) (texture->w) / texture_w;
553 data->texh = (GLfloat) texture->h / texture_h; 723 data->texh = (GLfloat) texture->h / texture_h;
554 } 724 }
725
555 data->format = format; 726 data->format = format;
556 data->formattype = type; 727 data->formattype = type;
557 renderdata->glBindTexture(data->type, data->texture); 728 renderdata->glBindTexture(data->type, data->texture);
558 renderdata->glTexParameteri(data->type, GL_TEXTURE_MIN_FILTER, 729 renderdata->glTexParameteri(data->type, GL_TEXTURE_MIN_FILTER,
559 GL_NEAREST); 730 GL_NEAREST);
561 GL_NEAREST); 732 GL_NEAREST);
562 renderdata->glTexParameteri(data->type, GL_TEXTURE_WRAP_S, 733 renderdata->glTexParameteri(data->type, GL_TEXTURE_WRAP_S,
563 GL_CLAMP_TO_EDGE); 734 GL_CLAMP_TO_EDGE);
564 renderdata->glTexParameteri(data->type, GL_TEXTURE_WRAP_T, 735 renderdata->glTexParameteri(data->type, GL_TEXTURE_WRAP_T,
565 GL_CLAMP_TO_EDGE); 736 GL_CLAMP_TO_EDGE);
566 #ifdef __MACOSX__ 737 #if 0 //def __MACOSX__
567 #ifndef GL_TEXTURE_STORAGE_HINT_APPLE 738 #ifndef GL_TEXTURE_STORAGE_HINT_APPLE
568 #define GL_TEXTURE_STORAGE_HINT_APPLE 0x85BC 739 #define GL_TEXTURE_STORAGE_HINT_APPLE 0x85BC
569 #endif 740 #endif
570 #ifndef STORAGE_CACHED_APPLE 741 #ifndef STORAGE_CACHED_APPLE
571 #define STORAGE_CACHED_APPLE 0x85BE 742 #define STORAGE_CACHED_APPLE 0x85BE
596 texture_h, 0, format, type, data->pixels); 767 texture_h, 0, format, type, data->pixels);
597 } else 768 } else
598 #endif 769 #endif
599 #endif 770 #endif
600 { 771 {
772 printf("teximage2d(%d,%d,%d,%d)\n", (int) texture_w, (int) texture_h);
601 renderdata->glTexImage2D(data->type, 0, internalFormat, texture_w, 773 renderdata->glTexImage2D(data->type, 0, internalFormat, texture_w,
602 texture_h, 0, format, type, NULL); 774 texture_h, 0, format, type, NULL);
603 } 775 }
604 result = renderdata->glGetError(); 776 result = renderdata->glGetError();
605 if (result != GL_NO_ERROR) { 777 if (result != GL_NO_ERROR) {
677 } else if (texture->format == SDL_PIXELFORMAT_INDEX1MSB) { 849 } else if (texture->format == SDL_PIXELFORMAT_INDEX1MSB) {
678 renderdata->glPixelStorei(GL_UNPACK_LSB_FIRST, 0); 850 renderdata->glPixelStorei(GL_UNPACK_LSB_FIRST, 0);
679 } 851 }
680 renderdata->glPixelStorei(GL_UNPACK_ALIGNMENT, 1); 852 renderdata->glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
681 renderdata->glPixelStorei(GL_UNPACK_ROW_LENGTH, 853 renderdata->glPixelStorei(GL_UNPACK_ROW_LENGTH,
682 pitch / SDL_BYTESPERPIXEL(texture->format)); 854 pitch / bytes_per_pixel(texture->format));
683 } 855 }
684 856
685 static int 857 static int
686 GL_SetTextureColorMod(SDL_Renderer * renderer, SDL_Texture * texture) 858 GL_SetTextureColorMod(SDL_Renderer * renderer, SDL_Texture * texture)
687 { 859 {
739 GLenum result; 911 GLenum result;
740 912
741 renderdata->glGetError(); 913 renderdata->glGetError();
742 SetupTextureUpdate(renderdata, texture, pitch); 914 SetupTextureUpdate(renderdata, texture, pitch);
743 renderdata->glBindTexture(data->type, data->texture); 915 renderdata->glBindTexture(data->type, data->texture);
916 printf("texsubimage2d(%d,%d,%d,%d)\n", (int) rect->x, (int) rect->y, (int) rect->w, (int) rect->h);
744 renderdata->glTexSubImage2D(data->type, 0, rect->x, rect->y, rect->w, 917 renderdata->glTexSubImage2D(data->type, 0, rect->x, rect->y, rect->w,
745 rect->h, data->format, data->formattype, 918 rect->h, data->format, data->formattype,
746 pixels); 919 pixels);
747 result = renderdata->glGetError(); 920 result = renderdata->glGetError();
748 if (result != GL_NO_ERROR) { 921 if (result != GL_NO_ERROR) {
763 SDL_AddDirtyRect(&data->dirty, rect); 936 SDL_AddDirtyRect(&data->dirty, rect);
764 } 937 }
765 938
766 *pixels = 939 *pixels =
767 (void *) ((Uint8 *) data->pixels + rect->y * data->pitch + 940 (void *) ((Uint8 *) data->pixels + rect->y * data->pitch +
768 rect->x * SDL_BYTESPERPIXEL(texture->format)); 941 rect->x * bytes_per_pixel(texture->format));
769 *pitch = data->pitch; 942 *pitch = data->pitch;
770 return 0; 943 return 0;
771 } 944 }
772 945
773 static void 946 static void
812 GLfloat minu, maxu, minv, maxv; 985 GLfloat minu, maxu, minv, maxv;
813 986
814 if (texturedata->dirty.list) { 987 if (texturedata->dirty.list) {
815 SDL_DirtyRect *dirty; 988 SDL_DirtyRect *dirty;
816 void *pixels; 989 void *pixels;
817 int bpp = SDL_BYTESPERPIXEL(texture->format); 990 int bpp = bytes_per_pixel(texture->format);
818 int pitch = texturedata->pitch; 991 int pitch = texturedata->pitch;
819 992
820 SetupTextureUpdate(data, texture, pitch); 993 SetupTextureUpdate(data, texture, pitch);
821 data->glBindTexture(texturedata->type, texturedata->texture); 994 data->glBindTexture(texturedata->type, texturedata->texture);
822 for (dirty = texturedata->dirty.list; dirty; dirty = dirty->next) { 995 for (dirty = texturedata->dirty.list; dirty; dirty = dirty->next) {
823 SDL_Rect *rect = &dirty->rect; 996 SDL_Rect *rect = &dirty->rect;
824 pixels = 997 pixels =
825 (void *) ((Uint8 *) texturedata->pixels + rect->y * pitch + 998 (void *) ((Uint8 *) texturedata->pixels + rect->y * pitch +
826 rect->x * bpp); 999 rect->x * bpp);
1000 printf("texsubimage2d(%d,%d,%d,%d)\n", (int) rect->x, (int) rect->y, (int) rect->w, (int) rect->h);
827 data->glTexSubImage2D(texturedata->type, 0, rect->x, rect->y, 1001 data->glTexSubImage2D(texturedata->type, 0, rect->x, rect->y,
828 rect->w, rect->h, texturedata->format, 1002 rect->w, rect->h, texturedata->format,
829 texturedata->formattype, pixels); 1003 texturedata->formattype, pixels);
830 } 1004 }
831 SDL_ClearDirtyRects(&texturedata->dirty); 1005 SDL_ClearDirtyRects(&texturedata->dirty);
900 break; 1074 break;
901 } 1075 }
902 data->scaleMode = texture->scaleMode; 1076 data->scaleMode = texture->scaleMode;
903 } 1077 }
904 1078
1079 if (texturedata->shader != 0) {
1080 data->glEnable(GL_FRAGMENT_PROGRAM_ARB);
1081 data->glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, texturedata->shader);
1082 }
1083
905 data->glBegin(GL_TRIANGLE_STRIP); 1084 data->glBegin(GL_TRIANGLE_STRIP);
906 data->glTexCoord2f(minu, minv); 1085 data->glTexCoord2f(minu, minv);
907 data->glVertex2i(minx, miny); 1086 data->glVertex2i(minx, miny);
908 data->glTexCoord2f(maxu, minv); 1087 data->glTexCoord2f(maxu, minv);
909 data->glVertex2i(maxx, miny); 1088 data->glVertex2i(maxx, miny);
911 data->glVertex2i(minx, maxy); 1090 data->glVertex2i(minx, maxy);
912 data->glTexCoord2f(maxu, maxv); 1091 data->glTexCoord2f(maxu, maxv);
913 data->glVertex2i(maxx, maxy); 1092 data->glVertex2i(maxx, maxy);
914 data->glEnd(); 1093 data->glEnd();
915 1094
1095 if (texturedata->shader != 0) {
1096 data->glDisable(GL_FRAGMENT_PROGRAM_ARB);
1097 }
916 return 0; 1098 return 0;
917 } 1099 }
918 1100
919 static void 1101 static void
920 GL_RenderPresent(SDL_Renderer * renderer) 1102 GL_RenderPresent(SDL_Renderer * renderer)
950 { 1132 {
951 GL_RenderData *data = (GL_RenderData *) renderer->driverdata; 1133 GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
952 1134
953 if (data) { 1135 if (data) {
954 if (data->context) { 1136 if (data->context) {
1137 if (data->GL_ARB_fragment_program_supported) {
1138 data->glDisable(GL_FRAGMENT_PROGRAM_ARB);
1139 data->glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, 0);
1140 if (data->fragment_program_UYVY != 0) {
1141 data->glDeleteProgramsARB(1, &data->fragment_program_UYVY);
1142 }
1143 }
1144
955 /* SDL_GL_MakeCurrent(0, NULL); *//* doesn't do anything */ 1145 /* SDL_GL_MakeCurrent(0, NULL); *//* doesn't do anything */
956 SDL_GL_DeleteContext(data->context); 1146 SDL_GL_DeleteContext(data->context);
957 } 1147 }
958 SDL_free(data); 1148 SDL_free(data);
959 } 1149 }