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