comparison libvo/gl_common.c @ 18655:6aa0b26d584b

Add yuv to rgb conversion using a 3D lookup texture
author reimar
date Thu, 08 Jun 2006 19:02:56 +0000
parents 5af43a16abc3
children e813d4014acd
comparison
equal deleted inserted replaced
18654:9fb5e9cdcae8 18655:6aa0b26d584b
721 "TEX result.color.g, res.gaaa, texture[%c], 2D;" 721 "TEX result.color.g, res.gaaa, texture[%c], 2D;"
722 "ADD res.a, res.a, 0.25;" 722 "ADD res.a, res.a, 0.25;"
723 "TEX result.color.b, res.baaa, texture[%c], 2D;" 723 "TEX result.color.b, res.baaa, texture[%c], 2D;"
724 "END"; 724 "END";
725 725
726 static const char *yuv_lookup3d_prog_template =
727 "TEX result.color, yuv, texture[%c], 3D;"
728 "END";
729
726 static void create_scaler_textures(int scaler, int *texu, char *texs) { 730 static void create_scaler_textures(int scaler, int *texu, char *texs) {
727 switch (scaler) { 731 switch (scaler) {
728 case YUV_SCALER_BILIN: 732 case YUV_SCALER_BILIN:
729 break; 733 break;
730 case YUV_SCALER_BICUB: 734 case YUV_SCALER_BICUB:
735 default: 739 default:
736 mp_msg(MSGT_VO, MSGL_ERR, "[gl] unknown scaler type %i\n", scaler); 740 mp_msg(MSGT_VO, MSGL_ERR, "[gl] unknown scaler type %i\n", scaler);
737 } 741 }
738 } 742 }
739 743
744 static void gen_yuv2rgb_map(unsigned char *map, int size, float brightness,
745 float contrast, float uvcos, float uvsin,
746 float rgamma, float ggamma, float bgamma) {
747 int i, j, k;
748 float step = 1.0 / size;
749 float y, u, v, u_, v_;
750 float r, g, b;
751 v = -0.5;
752 for (i = -1; i <= size; i++) {
753 u = -0.5;
754 for (j = -1; j <= size; j++) {
755 y = -(16.0 / 255.0);
756 for (k = -1; k <= size; k++) {
757 u_ = uvcos * u + uvsin * v;
758 v_ = uvcos * v + uvsin * u;
759 r = 1.164 * y + 1.596 * v_;
760 g = 1.164 * y - 0.391 * u_ - 0.813 * v_;
761 b = 1.164 * y + 2.018 * u_ ;
762 r = pow(contrast * (r - 0.5) + 0.5 + brightness, 1.0 / rgamma);
763 g = pow(contrast * (g - 0.5) + 0.5 + brightness, 1.0 / ggamma);
764 b = pow(contrast * (b - 0.5) + 0.5 + brightness, 1.0 / bgamma);
765 if (r > 1) r = 1;
766 if (r < 0) r = 0;
767 if (g > 1) g = 1;
768 if (g < 0) g = 0;
769 if (b > 1) b = 1;
770 if (b < 0) b = 0;
771 *map++ = 255 * r;
772 *map++ = 255 * g;
773 *map++ = 255 * b;
774 y += (k == -1 || k == size - 1) ? step / 2 : step;
775 }
776 u += (j == -1 || j == size - 1) ? step / 2 : step;
777 }
778 v += (i == -1 || i == size - 1) ? step / 2 : step;
779 }
780 }
781
740 static void gen_gamma_map(unsigned char *map, int size, float gamma); 782 static void gen_gamma_map(unsigned char *map, int size, float gamma);
741 783
742 //! resolution of texture for gamma lookup table 784 //! resolution of texture for gamma lookup table
743 #define LOOKUP_RES 512 785 #define LOOKUP_RES 512
786 //! resolution for 3D yuv->rgb conversion lookup table
787 #define LOOKUP_3DRES 32
744 static void create_conv_textures(int conv, int *texu, char *texs, 788 static void create_conv_textures(int conv, int *texu, char *texs,
745 int brightness, int contrast, int uvcos, int uvsin, 789 int brightness, int contrast, int uvcos, int uvsin,
746 int rgamma, int ggamma, int bgamma) { 790 int rgamma, int ggamma, int bgamma) {
747 unsigned char *lookup_data = NULL; 791 unsigned char *lookup_data = NULL;
748 switch (conv) { 792 switch (conv) {
760 LOOKUP_RES, 4, 0); 804 LOOKUP_RES, 4, 0);
761 glUploadTex(GL_TEXTURE_2D, GL_LUMINANCE, GL_UNSIGNED_BYTE, lookup_data, 805 glUploadTex(GL_TEXTURE_2D, GL_LUMINANCE, GL_UNSIGNED_BYTE, lookup_data,
762 LOOKUP_RES, 0, 0, LOOKUP_RES, 4, 0); 806 LOOKUP_RES, 0, 0, LOOKUP_RES, 4, 0);
763 ActiveTexture(GL_TEXTURE0); 807 ActiveTexture(GL_TEXTURE0);
764 texs[0] += '0'; 808 texs[0] += '0';
809 break;
810 case YUV_CONVERSION_FRAGMENT_LOOKUP3D:
811 {
812 int sz = LOOKUP_3DRES + 2; // texture size including borders
813 if (!TexImage3D) {
814 mp_msg(MSGT_VO, MSGL_ERR, "[gl] Missing 3D texture function!\n");
815 break;
816 }
817 texs[0] = (*texu)++;
818 ActiveTexture(GL_TEXTURE0 + texs[0]);
819 lookup_data = malloc(3 * sz * sz * sz);
820 gen_yuv2rgb_map(lookup_data, LOOKUP_3DRES, brightness, contrast,
821 uvcos, uvsin, rgamma, ggamma, bgamma);
822 glAdjustAlignment(sz);
823 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
824 TexImage3D(GL_TEXTURE_3D, 0, 3, sz, sz, sz, 1,
825 GL_RGB, GL_UNSIGNED_BYTE, lookup_data);
826 glTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_PRIORITY, 1.0);
827 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
828 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
829 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP);
830 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP);
831 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP);
832 ActiveTexture(GL_TEXTURE0);
833 texs[0] += '0';
834 }
765 break; 835 break;
766 default: 836 default:
767 mp_msg(MSGT_VO, MSGL_ERR, "[gl] unknown conversion type %i\n", conv); 837 mp_msg(MSGT_VO, MSGL_ERR, "[gl] unknown conversion type %i\n", conv);
768 } 838 }
769 if (lookup_data) 839 if (lookup_data)
927 case YUV_CONVERSION_FRAGMENT_LOOKUP: 997 case YUV_CONVERSION_FRAGMENT_LOOKUP:
928 snprintf(prog_pos, prog_remain, yuv_lookup_prog_template, 998 snprintf(prog_pos, prog_remain, yuv_lookup_prog_template,
929 ry, gy, by, ru, gu, bu, rv, gv, bv, rc, gc, bc, 999 ry, gy, by, ru, gu, bu, rv, gv, bv, rc, gc, bc,
930 conv_texs[0], conv_texs[0], conv_texs[0]); 1000 conv_texs[0], conv_texs[0], conv_texs[0]);
931 break; 1001 break;
1002 case YUV_CONVERSION_FRAGMENT_LOOKUP3D:
1003 snprintf(prog_pos, prog_remain, yuv_lookup3d_prog_template, conv_texs[0]);
1004 break;
932 default: 1005 default:
933 mp_msg(MSGT_VO, MSGL_ERR, "[gl] unknown conversion type %i\n", YUV_CONVERSION(type)); 1006 mp_msg(MSGT_VO, MSGL_ERR, "[gl] unknown conversion type %i\n", YUV_CONVERSION(type));
934 break; 1007 break;
935 } 1008 }
936 mp_msg(MSGT_VO, MSGL_V, "[gl] generated fragment program:\n%s\n", yuv_prog); 1009 mp_msg(MSGT_VO, MSGL_V, "[gl] generated fragment program:\n%s\n", yuv_prog);
981 break; 1054 break;
982 case YUV_CONVERSION_COMBINERS_ATI: 1055 case YUV_CONVERSION_COMBINERS_ATI:
983 glSetupYUVCombinersATI(uvcos, uvsin); 1056 glSetupYUVCombinersATI(uvcos, uvsin);
984 break; 1057 break;
985 case YUV_CONVERSION_FRAGMENT_LOOKUP: 1058 case YUV_CONVERSION_FRAGMENT_LOOKUP:
1059 case YUV_CONVERSION_FRAGMENT_LOOKUP3D:
986 case YUV_CONVERSION_FRAGMENT: 1060 case YUV_CONVERSION_FRAGMENT:
987 case YUV_CONVERSION_FRAGMENT_POW: 1061 case YUV_CONVERSION_FRAGMENT_POW:
988 glSetupYUVFragprog(brightness, contrast, uvcos, uvsin, 1062 glSetupYUVFragprog(brightness, contrast, uvcos, uvsin,
989 rgamma, ggamma, bgamma, type, 1063 rgamma, ggamma, bgamma, type,
990 target == GL_TEXTURE_RECTANGLE, 1064 target == GL_TEXTURE_RECTANGLE,
1018 ActiveTexture(GL_TEXTURE2); 1092 ActiveTexture(GL_TEXTURE2);
1019 glEnable(target); 1093 glEnable(target);
1020 ActiveTexture(GL_TEXTURE0); 1094 ActiveTexture(GL_TEXTURE0);
1021 glEnable(GL_FRAGMENT_SHADER_ATI); 1095 glEnable(GL_FRAGMENT_SHADER_ATI);
1022 break; 1096 break;
1097 case YUV_CONVERSION_FRAGMENT_LOOKUP3D:
1023 case YUV_CONVERSION_FRAGMENT_LOOKUP: 1098 case YUV_CONVERSION_FRAGMENT_LOOKUP:
1024 case YUV_CONVERSION_FRAGMENT_POW: 1099 case YUV_CONVERSION_FRAGMENT_POW:
1025 case YUV_CONVERSION_FRAGMENT: 1100 case YUV_CONVERSION_FRAGMENT:
1026 glEnable(GL_FRAGMENT_PROGRAM); 1101 glEnable(GL_FRAGMENT_PROGRAM);
1027 break; 1102 break;
1051 ActiveTexture(GL_TEXTURE2); 1126 ActiveTexture(GL_TEXTURE2);
1052 glDisable(target); 1127 glDisable(target);
1053 ActiveTexture(GL_TEXTURE0); 1128 ActiveTexture(GL_TEXTURE0);
1054 glDisable(GL_FRAGMENT_SHADER_ATI); 1129 glDisable(GL_FRAGMENT_SHADER_ATI);
1055 break; 1130 break;
1131 case YUV_CONVERSION_FRAGMENT_LOOKUP3D:
1056 case YUV_CONVERSION_FRAGMENT_LOOKUP: 1132 case YUV_CONVERSION_FRAGMENT_LOOKUP:
1057 case YUV_CONVERSION_FRAGMENT_POW: 1133 case YUV_CONVERSION_FRAGMENT_POW:
1058 case YUV_CONVERSION_FRAGMENT: 1134 case YUV_CONVERSION_FRAGMENT:
1059 glDisable(GL_FRAGMENT_PROGRAM); 1135 glDisable(GL_FRAGMENT_PROGRAM);
1060 break; 1136 break;