Mercurial > sdl-ios-xcode
comparison src/video/x11/SDL_x11render.c @ 4616:05eb4a07e5e3
Add support for texture modulation (both color and alpha). testsprite2 works now with --cyclealpha and --cyclecolor.
author | Sunny Sachanandani <sunnysachanandani@gmail.com> |
---|---|
date | Wed, 28 Jul 2010 11:56:17 +0530 |
parents | 789483a20081 |
children | cfbb1ff4b8ec |
comparison
equal
deleted
inserted
replaced
4615:789483a20081 | 4616:05eb4a07e5e3 |
---|---|
37 static int X11_DisplayModeChanged(SDL_Renderer * renderer); | 37 static int X11_DisplayModeChanged(SDL_Renderer * renderer); |
38 static int X11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture); | 38 static int X11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture); |
39 static int X11_QueryTexturePixels(SDL_Renderer * renderer, | 39 static int X11_QueryTexturePixels(SDL_Renderer * renderer, |
40 SDL_Texture * texture, void **pixels, | 40 SDL_Texture * texture, void **pixels, |
41 int *pitch); | 41 int *pitch); |
42 static int X11_SetTextureRGBAMod(SDL_Renderer * renderer, | |
43 SDL_Texture * texture); | |
42 static int X11_SetTextureBlendMode(SDL_Renderer * renderer, | 44 static int X11_SetTextureBlendMode(SDL_Renderer * renderer, |
43 SDL_Texture * texture); | 45 SDL_Texture * texture); |
44 static int X11_SetTextureScaleMode(SDL_Renderer * renderer, | 46 static int X11_SetTextureScaleMode(SDL_Renderer * renderer, |
45 SDL_Texture * texture); | 47 SDL_Texture * texture); |
46 static int X11_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, | 48 static int X11_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, |
131 int depth; | 133 int depth; |
132 Visual *visual; | 134 Visual *visual; |
133 GC gc; | 135 GC gc; |
134 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER | 136 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER |
135 Picture picture; | 137 Picture picture; |
138 Pixmap modulated_pixmap; | |
139 Picture modulated_picture; | |
136 XRenderPictFormat* picture_fmt; | 140 XRenderPictFormat* picture_fmt; |
137 int blend_op; | 141 int blend_op; |
138 const char* filter; | 142 const char* filter; |
139 #endif | 143 #endif |
140 XImage *image; | 144 XImage *image; |
307 } | 311 } |
308 } | 312 } |
309 else | 313 else |
310 break; | 314 break; |
311 } | 315 } |
312 info->blend_modes = (SDL_BLENDMODE_BLEND | SDL_BLENDMODE_ADD | | 316 info->blend_modes |= (SDL_BLENDMODE_BLEND | SDL_BLENDMODE_ADD | |
313 SDL_BLENDMODE_MOD | SDL_BLENDMODE_MASK); | 317 SDL_BLENDMODE_MOD | SDL_BLENDMODE_MASK); |
314 info->scale_modes = (SDL_TEXTURESCALEMODE_FAST | SDL_TEXTURESCALEMODE_SLOW | | 318 info->scale_modes |= (SDL_TEXTURESCALEMODE_FAST | SDL_TEXTURESCALEMODE_SLOW | |
315 SDL_TEXTURESCALEMODE_BEST); | 319 SDL_TEXTURESCALEMODE_BEST); |
320 info->mod_modes |= (SDL_TEXTUREMODULATE_COLOR | SDL_TEXTUREMODULATE_ALPHA); | |
316 } | 321 } |
317 #endif | 322 #endif |
318 | 323 |
319 for (i = 0; i < _this->num_displays; ++i) { | 324 for (i = 0; i < _this->num_displays; ++i) { |
320 SDL_AddRenderDriver(&_this->displays[i], &X11_RenderDriver); | 325 SDL_AddRenderDriver(&_this->displays[i], &X11_RenderDriver); |
355 data->xwindow = windowdata->xwindow; | 360 data->xwindow = windowdata->xwindow; |
356 | 361 |
357 renderer->DisplayModeChanged = X11_DisplayModeChanged; | 362 renderer->DisplayModeChanged = X11_DisplayModeChanged; |
358 renderer->CreateTexture = X11_CreateTexture; | 363 renderer->CreateTexture = X11_CreateTexture; |
359 renderer->QueryTexturePixels = X11_QueryTexturePixels; | 364 renderer->QueryTexturePixels = X11_QueryTexturePixels; |
365 renderer->SetTextureAlphaMod = X11_SetTextureRGBAMod; | |
366 renderer->SetTextureColorMod = X11_SetTextureRGBAMod; | |
360 renderer->SetTextureBlendMode = X11_SetTextureBlendMode; | 367 renderer->SetTextureBlendMode = X11_SetTextureBlendMode; |
361 renderer->SetTextureScaleMode = X11_SetTextureScaleMode; | 368 renderer->SetTextureScaleMode = X11_SetTextureScaleMode; |
362 renderer->UpdateTexture = X11_UpdateTexture; | 369 renderer->UpdateTexture = X11_UpdateTexture; |
363 renderer->LockTexture = X11_LockTexture; | 370 renderer->LockTexture = X11_LockTexture; |
364 renderer->UnlockTexture = X11_UnlockTexture; | 371 renderer->UnlockTexture = X11_UnlockTexture; |
785 return ret[0].visual; | 792 return ret[0].visual; |
786 } | 793 } |
787 } | 794 } |
788 | 795 |
789 return NULL; | 796 return NULL; |
797 } | |
798 | |
799 static XRenderColor | |
800 SDLColorToXRenderColor(Uint8 r, Uint8 g, Uint8 b, Uint8 a) { | |
801 double rd, gd, bd, ad; | |
802 XRenderColor ret; | |
803 rd = r / 255.0; | |
804 gd = g / 255.0; | |
805 bd = b / 255.0; | |
806 ad = a / 255.0; | |
807 | |
808 ret.red = (unsigned short) (rd * ad * 0xFFFF); | |
809 ret.green = (unsigned short) (gd * ad * 0xFFFF); | |
810 ret.blue = (unsigned short) (bd * ad * 0xFFFF); | |
811 ret.alpha = (unsigned short) (ad * 0xFFFF); | |
812 | |
813 return ret; | |
790 } | 814 } |
791 #endif | 815 #endif |
792 | 816 |
793 static int | 817 static int |
794 X11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) | 818 X11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) |
963 if (!data->picture) { | 987 if (!data->picture) { |
964 X11_DestroyTexture(renderer, texture); | 988 X11_DestroyTexture(renderer, texture); |
965 SDL_SetError("XRenderCreatePicture() failed"); | 989 SDL_SetError("XRenderCreatePicture() failed"); |
966 return -1; | 990 return -1; |
967 } | 991 } |
992 data->modulated_pixmap = | |
993 XCreatePixmap(renderdata->display, renderdata->xwindow, | |
994 texture->w, texture->h, data->depth); | |
995 if (!data->modulated_pixmap) { | |
996 X11_DestroyTexture(renderer, texture); | |
997 SDL_SetError("XCreatePixmap() failed"); | |
998 return -1; | |
999 } | |
1000 data->modulated_picture = | |
1001 XRenderCreatePicture(renderdata->display, data->modulated_pixmap, | |
1002 data->picture_fmt, 0, NULL); | |
1003 if (!data->modulated_picture) { | |
1004 X11_DestroyTexture(renderer, texture); | |
1005 SDL_SetError("XRenderCreatePicture() failed"); | |
1006 return -1; | |
1007 } | |
968 texture->blendMode = SDL_BLENDMODE_NONE; | 1008 texture->blendMode = SDL_BLENDMODE_NONE; |
969 data->blend_op = PictOpSrc; | 1009 data->blend_op = PictOpSrc; |
970 } | 1010 } |
971 #endif | 1011 #endif |
972 return 0; | 1012 return 0; |
982 return SDL_SW_QueryYUVTexturePixels(data->yuv, pixels, pitch); | 1022 return SDL_SW_QueryYUVTexturePixels(data->yuv, pixels, pitch); |
983 } else { | 1023 } else { |
984 *pixels = data->pixels; | 1024 *pixels = data->pixels; |
985 *pitch = data->pitch; | 1025 *pitch = data->pitch; |
986 return 0; | 1026 return 0; |
1027 } | |
1028 } | |
1029 | |
1030 static int | |
1031 X11_SetTextureRGBAMod(SDL_Renderer * renderer, SDL_Texture * texture) | |
1032 { | |
1033 | |
1034 X11_TextureData *data = (X11_TextureData *) texture->driverdata; | |
1035 X11_RenderData *renderdata = (X11_RenderData *) renderer->driverdata; | |
1036 | |
1037 if (renderdata->use_xrender) { | |
1038 | |
1039 Uint8 r = 0xFF, g = 0xFF, b = 0xFF, a = 0xFF; | |
1040 | |
1041 if (texture->modMode & SDL_TEXTUREMODULATE_ALPHA) { | |
1042 a = texture->a; | |
1043 } | |
1044 | |
1045 if (texture->modMode & SDL_TEXTUREMODULATE_COLOR) { | |
1046 r = texture->r; | |
1047 g = texture->g; | |
1048 b = texture->b; | |
1049 } | |
1050 | |
1051 if (texture->modMode != SDL_TEXTUREMODULATE_NONE) { | |
1052 XRenderColor mod_color = | |
1053 SDLColorToXRenderColor(r, g, b, a); | |
1054 XRenderFillRectangle(renderdata->display, PictOpSrc, | |
1055 renderdata->brush_pict, &mod_color, | |
1056 0, 0, 1, 1); | |
1057 } | |
1058 | |
1059 XRenderPictureAttributes attr; | |
1060 if (texture->modMode & SDL_TEXTUREMODULATE_COLOR) { | |
1061 attr.component_alpha = True; | |
1062 XRenderChangePicture(renderdata->display, renderdata->brush_pict, | |
1063 CPComponentAlpha, &attr); | |
1064 } | |
1065 | |
1066 if (texture->modMode != SDL_TEXTUREMODULATE_NONE) { | |
1067 XRenderComposite(renderdata->display, PictOpSrc, | |
1068 data->picture, renderdata->brush_pict, | |
1069 data->modulated_picture, | |
1070 0, 0, 0, 0, 0, 0, texture->w, texture->h); | |
1071 } | |
1072 | |
1073 if (texture->modMode & SDL_TEXTUREMODULATE_COLOR) { | |
1074 attr.component_alpha = False; | |
1075 XRenderChangePicture(renderdata->display, renderdata->brush_pict, | |
1076 CPComponentAlpha, &attr); | |
1077 } | |
1078 | |
1079 return 0; | |
1080 } | |
1081 else { | |
1082 SDL_Unsupported(); | |
1083 return -1; | |
987 } | 1084 } |
988 } | 1085 } |
989 | 1086 |
990 static int | 1087 static int |
991 X11_SetTextureBlendMode(SDL_Renderer * renderer, SDL_Texture * texture) | 1088 X11_SetTextureBlendMode(SDL_Renderer * renderer, SDL_Texture * texture) |
1201 } | 1298 } |
1202 | 1299 |
1203 static XRenderColor | 1300 static XRenderColor |
1204 xrenderdrawcolor(SDL_Renderer *renderer) | 1301 xrenderdrawcolor(SDL_Renderer *renderer) |
1205 { | 1302 { |
1206 // Premultiply the color channels as well as modulate them to a 16 bit color space | |
1207 XRenderColor xrender_color; | 1303 XRenderColor xrender_color; |
1208 double alphad; | 1304 if(renderer->blendMode == SDL_BLENDMODE_NONE) { |
1209 if(renderer->blendMode == SDL_BLENDMODE_NONE) | 1305 xrender_color = |
1210 alphad = 1.0; | 1306 SDLColorToXRenderColor(renderer->r, renderer->g, renderer->b, 0xFF); |
1211 else | 1307 } |
1212 alphad = (renderer->a) / 255.0; | 1308 else { |
1213 | 1309 xrender_color = |
1214 xrender_color.alpha = (unsigned short) ((renderer->a / 255.0) * 0xFFFF); | 1310 SDLColorToXRenderColor(renderer->r, renderer->g, renderer->b, renderer->a); |
1215 | 1311 } |
1216 xrender_color.red = | |
1217 (unsigned short) ((renderer->r / 255.0) * alphad * 0xFFFF); | |
1218 xrender_color.green = | |
1219 (unsigned short) ((renderer->g / 255.0) * alphad * 0xFFFF); | |
1220 xrender_color.blue = | |
1221 (unsigned short) ((renderer->b / 255.0) * alphad * 0xFFFF); | |
1222 | |
1223 return xrender_color; | 1312 return xrender_color; |
1224 } | 1313 } |
1225 | 1314 |
1226 static int | 1315 static int |
1227 X11_RenderDrawPoints(SDL_Renderer * renderer, const SDL_Point * points, | 1316 X11_RenderDrawPoints(SDL_Renderer * renderer, const SDL_Point * points, |
1756 texturedata->image, srcrect->x, srcrect->y, srcrect->x, | 1845 texturedata->image, srcrect->x, srcrect->y, srcrect->x, |
1757 srcrect->y, srcrect->w, srcrect->h); | 1846 srcrect->y, srcrect->w, srcrect->h); |
1758 } | 1847 } |
1759 XSync(data->display, False); | 1848 XSync(data->display, False); |
1760 } | 1849 } |
1761 Picture mask; | 1850 Picture src, mask; |
1762 XRenderPictureAttributes attr; | 1851 XRenderPictureAttributes attr; |
1763 const SDL_Rect *mrect; | 1852 const SDL_Rect *mrect; |
1853 | |
1854 if (texture->modMode == SDL_TEXTUREMODULATE_NONE) { | |
1855 src = texturedata->picture; | |
1856 } | |
1857 else { | |
1858 src = texturedata->modulated_picture; | |
1859 } | |
1860 | |
1764 if(texture->blendMode == SDL_BLENDMODE_NONE) | 1861 if(texture->blendMode == SDL_BLENDMODE_NONE) |
1765 { | 1862 { |
1766 mask = None; | 1863 mask = None; |
1767 mrect = srcrect; | 1864 mrect = srcrect; |
1768 } | 1865 } |
1774 else | 1871 else |
1775 { | 1872 { |
1776 mask = texturedata->picture; | 1873 mask = texturedata->picture; |
1777 mrect = srcrect; | 1874 mrect = srcrect; |
1778 } | 1875 } |
1876 | |
1779 if(srcrect->w == dstrect->w && srcrect->h == dstrect->h) { | 1877 if(srcrect->w == dstrect->w && srcrect->h == dstrect->h) { |
1780 if (texture->blendMode == SDL_BLENDMODE_MOD) { | 1878 if (texture->blendMode == SDL_BLENDMODE_MOD) { |
1781 XRenderComposite(data->display, PictOpSrc, data->drawable_pict, | 1879 XRenderComposite(data->display, PictOpSrc, data->drawable_pict, |
1782 texturedata->picture, data->stencil_pict, | 1880 src, data->stencil_pict, |
1783 dstrect->x, dstrect->y, srcrect->x, srcrect->y, | 1881 dstrect->x, dstrect->y, srcrect->x, srcrect->y, |
1784 dstrect->x, dstrect->y, dstrect->w, dstrect->h); | 1882 dstrect->x, dstrect->y, dstrect->w, dstrect->h); |
1785 attr.component_alpha = True; | 1883 attr.component_alpha = True; |
1786 XRenderChangePicture(data->display, data->stencil_pict, | 1884 XRenderChangePicture(data->display, data->stencil_pict, |
1787 CPComponentAlpha, &attr); | 1885 CPComponentAlpha, &attr); |
1788 } | 1886 } |
1789 XRenderComposite(data->display, texturedata->blend_op, texturedata->picture, | 1887 XRenderComposite(data->display, texturedata->blend_op, |
1790 mask, data->drawable_pict, srcrect->x, srcrect->y, | 1888 src, mask, data->drawable_pict, srcrect->x, srcrect->y, |
1791 mrect->x, mrect->y, dstrect->x, dstrect->y, | 1889 mrect->x, mrect->y, dstrect->x, dstrect->y, |
1792 dstrect->w, dstrect->h); | 1890 dstrect->w, dstrect->h); |
1793 } else { | 1891 } else { |
1794 double xscale = ((double) dstrect->w) / srcrect->w; | 1892 double xscale = ((double) dstrect->w) / srcrect->w; |
1795 double yscale = ((double) dstrect->h) / srcrect->h; | 1893 double yscale = ((double) dstrect->h) / srcrect->h; |
1796 XTransform xform = {{ | 1894 XTransform xform = {{ |
1797 {XDoubleToFixed(xscale), XDoubleToFixed(0), XDoubleToFixed(0)}, | 1895 {XDoubleToFixed(xscale), XDoubleToFixed(0), XDoubleToFixed(0)}, |
1798 {XDoubleToFixed(0), XDoubleToFixed(yscale), XDoubleToFixed(0)}, | 1896 {XDoubleToFixed(0), XDoubleToFixed(yscale), XDoubleToFixed(0)}, |
1799 {XDoubleToFixed(0), XDoubleToFixed(0), XDoubleToFixed(xscale * yscale)}}}; | 1897 {XDoubleToFixed(0), XDoubleToFixed(0), XDoubleToFixed(xscale * yscale)}}}; |
1800 XRenderSetPictureTransform(data->display, texturedata->picture, &xform); | 1898 XRenderSetPictureTransform(data->display, src, &xform); |
1801 | 1899 |
1802 if (texture->blendMode == SDL_BLENDMODE_MOD) { | 1900 if (texture->blendMode == SDL_BLENDMODE_MOD) { |
1803 XRenderComposite(data->display, PictOpSrc, data->drawable_pict, | 1901 XRenderComposite(data->display, PictOpSrc, data->drawable_pict, |
1804 texturedata->picture, data->stencil_pict, | 1902 src, data->stencil_pict, |
1805 dstrect->x, dstrect->y, srcrect->x, srcrect->y, | 1903 dstrect->x, dstrect->y, srcrect->x, srcrect->y, |
1806 dstrect->x, dstrect->y, dstrect->w, dstrect->h); | 1904 dstrect->x, dstrect->y, dstrect->w, dstrect->h); |
1807 attr.component_alpha = True; | 1905 attr.component_alpha = True; |
1808 XRenderChangePicture(data->display, data->stencil_pict, | 1906 XRenderChangePicture(data->display, data->stencil_pict, |
1809 CPComponentAlpha, &attr); | 1907 CPComponentAlpha, &attr); |
1810 } | 1908 } |
1811 | 1909 |
1812 XRenderSetPictureFilter(data->display, texturedata->picture, | 1910 XRenderSetPictureFilter(data->display, src, |
1813 texturedata->filter, 0, 0); | 1911 texturedata->filter, 0, 0); |
1814 | 1912 |
1815 XRenderComposite(data->display, texturedata->blend_op, | 1913 XRenderComposite(data->display, texturedata->blend_op, |
1816 texturedata->picture, mask, data->drawable_pict, | 1914 src, mask, data->drawable_pict, |
1817 srcrect->x, srcrect->y, mrect->x, mrect->y, | 1915 srcrect->x, srcrect->y, mrect->x, mrect->y, |
1818 dstrect->x, dstrect->y, dstrect->w, dstrect->h); | 1916 dstrect->x, dstrect->y, dstrect->w, dstrect->h); |
1819 | 1917 |
1820 XTransform identity = {{ | 1918 XTransform identity = {{ |
1821 {XDoubleToFixed(1), XDoubleToFixed(0), XDoubleToFixed(0)}, | 1919 {XDoubleToFixed(1), XDoubleToFixed(0), XDoubleToFixed(0)}, |
1822 {XDoubleToFixed(0), XDoubleToFixed(1), XDoubleToFixed(0)}, | 1920 {XDoubleToFixed(0), XDoubleToFixed(1), XDoubleToFixed(0)}, |
1823 {XDoubleToFixed(0), XDoubleToFixed(0), XDoubleToFixed(1)}}}; | 1921 {XDoubleToFixed(0), XDoubleToFixed(0), XDoubleToFixed(1)}}}; |
1824 XRenderSetPictureTransform(data->display, texturedata->picture, &identity); | 1922 XRenderSetPictureTransform(data->display, src, &identity); |
1825 } | 1923 } |
1826 if (renderer->blendMode == SDL_BLENDMODE_MOD) { | 1924 if (renderer->blendMode == SDL_BLENDMODE_MOD) { |
1827 attr.component_alpha = False; | 1925 attr.component_alpha = False; |
1828 XRenderChangePicture(data->display, data->stencil_pict, | 1926 XRenderChangePicture(data->display, data->stencil_pict, |
1829 CPComponentAlpha, &attr); | 1927 CPComponentAlpha, &attr); |
2079 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER | 2177 #ifdef SDL_VIDEO_DRIVER_X11_XRENDER |
2080 if (renderdata->use_xrender) { | 2178 if (renderdata->use_xrender) { |
2081 if (data->picture) { | 2179 if (data->picture) { |
2082 XRenderFreePicture(renderdata->display, data->picture); | 2180 XRenderFreePicture(renderdata->display, data->picture); |
2083 } | 2181 } |
2182 if (data->modulated_pixmap) { | |
2183 XFreePixmap(renderdata->display, data->modulated_pixmap); | |
2184 } | |
2185 if (data->modulated_picture) { | |
2186 XRenderFreePicture(renderdata->display, data->modulated_picture); | |
2187 } | |
2084 } | 2188 } |
2085 #endif | 2189 #endif |
2086 if (data->scaling_image) { | 2190 if (data->scaling_image) { |
2087 SDL_free(data->scaling_image->data); | 2191 SDL_free(data->scaling_image->data); |
2088 data->scaling_image->data = NULL; | 2192 data->scaling_image->data = NULL; |