# HG changeset patch # User Sunny Sachanandani # Date 1280298377 -19800 # Node ID 05eb4a07e5e386bd1d171e4bd10648ff50a6e084 # Parent 789483a200814952e83b70938ad49d9fef5b2d08 Add support for texture modulation (both color and alpha). testsprite2 works now with --cyclealpha and --cyclecolor. diff -r 789483a20081 -r 05eb4a07e5e3 src/video/x11/SDL_x11render.c --- a/src/video/x11/SDL_x11render.c Thu Jul 22 16:00:18 2010 +0530 +++ b/src/video/x11/SDL_x11render.c Wed Jul 28 11:56:17 2010 +0530 @@ -39,6 +39,8 @@ static int X11_QueryTexturePixels(SDL_Renderer * renderer, SDL_Texture * texture, void **pixels, int *pitch); +static int X11_SetTextureRGBAMod(SDL_Renderer * renderer, + SDL_Texture * texture); static int X11_SetTextureBlendMode(SDL_Renderer * renderer, SDL_Texture * texture); static int X11_SetTextureScaleMode(SDL_Renderer * renderer, @@ -133,6 +135,8 @@ GC gc; #ifdef SDL_VIDEO_DRIVER_X11_XRENDER Picture picture; + Pixmap modulated_pixmap; + Picture modulated_picture; XRenderPictFormat* picture_fmt; int blend_op; const char* filter; @@ -309,10 +313,11 @@ else break; } - info->blend_modes = (SDL_BLENDMODE_BLEND | SDL_BLENDMODE_ADD | + info->blend_modes |= (SDL_BLENDMODE_BLEND | SDL_BLENDMODE_ADD | SDL_BLENDMODE_MOD | SDL_BLENDMODE_MASK); - info->scale_modes = (SDL_TEXTURESCALEMODE_FAST | SDL_TEXTURESCALEMODE_SLOW | + info->scale_modes |= (SDL_TEXTURESCALEMODE_FAST | SDL_TEXTURESCALEMODE_SLOW | SDL_TEXTURESCALEMODE_BEST); + info->mod_modes |= (SDL_TEXTUREMODULATE_COLOR | SDL_TEXTUREMODULATE_ALPHA); } #endif @@ -357,6 +362,8 @@ renderer->DisplayModeChanged = X11_DisplayModeChanged; renderer->CreateTexture = X11_CreateTexture; renderer->QueryTexturePixels = X11_QueryTexturePixels; + renderer->SetTextureAlphaMod = X11_SetTextureRGBAMod; + renderer->SetTextureColorMod = X11_SetTextureRGBAMod; renderer->SetTextureBlendMode = X11_SetTextureBlendMode; renderer->SetTextureScaleMode = X11_SetTextureScaleMode; renderer->UpdateTexture = X11_UpdateTexture; @@ -788,6 +795,23 @@ return NULL; } + +static XRenderColor +SDLColorToXRenderColor(Uint8 r, Uint8 g, Uint8 b, Uint8 a) { + double rd, gd, bd, ad; + XRenderColor ret; + rd = r / 255.0; + gd = g / 255.0; + bd = b / 255.0; + ad = a / 255.0; + + ret.red = (unsigned short) (rd * ad * 0xFFFF); + ret.green = (unsigned short) (gd * ad * 0xFFFF); + ret.blue = (unsigned short) (bd * ad * 0xFFFF); + ret.alpha = (unsigned short) (ad * 0xFFFF); + + return ret; +} #endif static int @@ -965,6 +989,22 @@ SDL_SetError("XRenderCreatePicture() failed"); return -1; } + data->modulated_pixmap = + XCreatePixmap(renderdata->display, renderdata->xwindow, + texture->w, texture->h, data->depth); + if (!data->modulated_pixmap) { + X11_DestroyTexture(renderer, texture); + SDL_SetError("XCreatePixmap() failed"); + return -1; + } + data->modulated_picture = + XRenderCreatePicture(renderdata->display, data->modulated_pixmap, + data->picture_fmt, 0, NULL); + if (!data->modulated_picture) { + X11_DestroyTexture(renderer, texture); + SDL_SetError("XRenderCreatePicture() failed"); + return -1; + } texture->blendMode = SDL_BLENDMODE_NONE; data->blend_op = PictOpSrc; } @@ -988,6 +1028,63 @@ } static int +X11_SetTextureRGBAMod(SDL_Renderer * renderer, SDL_Texture * texture) +{ + + X11_TextureData *data = (X11_TextureData *) texture->driverdata; + X11_RenderData *renderdata = (X11_RenderData *) renderer->driverdata; + + if (renderdata->use_xrender) { + + Uint8 r = 0xFF, g = 0xFF, b = 0xFF, a = 0xFF; + + if (texture->modMode & SDL_TEXTUREMODULATE_ALPHA) { + a = texture->a; + } + + if (texture->modMode & SDL_TEXTUREMODULATE_COLOR) { + r = texture->r; + g = texture->g; + b = texture->b; + } + + if (texture->modMode != SDL_TEXTUREMODULATE_NONE) { + XRenderColor mod_color = + SDLColorToXRenderColor(r, g, b, a); + XRenderFillRectangle(renderdata->display, PictOpSrc, + renderdata->brush_pict, &mod_color, + 0, 0, 1, 1); + } + + XRenderPictureAttributes attr; + if (texture->modMode & SDL_TEXTUREMODULATE_COLOR) { + attr.component_alpha = True; + XRenderChangePicture(renderdata->display, renderdata->brush_pict, + CPComponentAlpha, &attr); + } + + if (texture->modMode != SDL_TEXTUREMODULATE_NONE) { + XRenderComposite(renderdata->display, PictOpSrc, + data->picture, renderdata->brush_pict, + data->modulated_picture, + 0, 0, 0, 0, 0, 0, texture->w, texture->h); + } + + if (texture->modMode & SDL_TEXTUREMODULATE_COLOR) { + attr.component_alpha = False; + XRenderChangePicture(renderdata->display, renderdata->brush_pict, + CPComponentAlpha, &attr); + } + + return 0; + } + else { + SDL_Unsupported(); + return -1; + } +} + +static int X11_SetTextureBlendMode(SDL_Renderer * renderer, SDL_Texture * texture) { X11_TextureData *data = (X11_TextureData *) texture->driverdata; @@ -1203,23 +1300,15 @@ static XRenderColor xrenderdrawcolor(SDL_Renderer *renderer) { - // Premultiply the color channels as well as modulate them to a 16 bit color space XRenderColor xrender_color; - double alphad; - if(renderer->blendMode == SDL_BLENDMODE_NONE) - alphad = 1.0; - else - alphad = (renderer->a) / 255.0; - - xrender_color.alpha = (unsigned short) ((renderer->a / 255.0) * 0xFFFF); - - xrender_color.red = - (unsigned short) ((renderer->r / 255.0) * alphad * 0xFFFF); - xrender_color.green = - (unsigned short) ((renderer->g / 255.0) * alphad * 0xFFFF); - xrender_color.blue = - (unsigned short) ((renderer->b / 255.0) * alphad * 0xFFFF); - + if(renderer->blendMode == SDL_BLENDMODE_NONE) { + xrender_color = + SDLColorToXRenderColor(renderer->r, renderer->g, renderer->b, 0xFF); + } + else { + xrender_color = + SDLColorToXRenderColor(renderer->r, renderer->g, renderer->b, renderer->a); + } return xrender_color; } @@ -1758,9 +1847,17 @@ } XSync(data->display, False); } - Picture mask; + Picture src, mask; XRenderPictureAttributes attr; const SDL_Rect *mrect; + + if (texture->modMode == SDL_TEXTUREMODULATE_NONE) { + src = texturedata->picture; + } + else { + src = texturedata->modulated_picture; + } + if(texture->blendMode == SDL_BLENDMODE_NONE) { mask = None; @@ -1776,18 +1873,19 @@ mask = texturedata->picture; mrect = srcrect; } + if(srcrect->w == dstrect->w && srcrect->h == dstrect->h) { if (texture->blendMode == SDL_BLENDMODE_MOD) { XRenderComposite(data->display, PictOpSrc, data->drawable_pict, - texturedata->picture, data->stencil_pict, + src, data->stencil_pict, dstrect->x, dstrect->y, srcrect->x, srcrect->y, dstrect->x, dstrect->y, dstrect->w, dstrect->h); attr.component_alpha = True; XRenderChangePicture(data->display, data->stencil_pict, CPComponentAlpha, &attr); } - XRenderComposite(data->display, texturedata->blend_op, texturedata->picture, - mask, data->drawable_pict, srcrect->x, srcrect->y, + XRenderComposite(data->display, texturedata->blend_op, + src, mask, data->drawable_pict, srcrect->x, srcrect->y, mrect->x, mrect->y, dstrect->x, dstrect->y, dstrect->w, dstrect->h); } else { @@ -1797,11 +1895,11 @@ {XDoubleToFixed(xscale), XDoubleToFixed(0), XDoubleToFixed(0)}, {XDoubleToFixed(0), XDoubleToFixed(yscale), XDoubleToFixed(0)}, {XDoubleToFixed(0), XDoubleToFixed(0), XDoubleToFixed(xscale * yscale)}}}; - XRenderSetPictureTransform(data->display, texturedata->picture, &xform); + XRenderSetPictureTransform(data->display, src, &xform); if (texture->blendMode == SDL_BLENDMODE_MOD) { XRenderComposite(data->display, PictOpSrc, data->drawable_pict, - texturedata->picture, data->stencil_pict, + src, data->stencil_pict, dstrect->x, dstrect->y, srcrect->x, srcrect->y, dstrect->x, dstrect->y, dstrect->w, dstrect->h); attr.component_alpha = True; @@ -1809,11 +1907,11 @@ CPComponentAlpha, &attr); } - XRenderSetPictureFilter(data->display, texturedata->picture, + XRenderSetPictureFilter(data->display, src, texturedata->filter, 0, 0); XRenderComposite(data->display, texturedata->blend_op, - texturedata->picture, mask, data->drawable_pict, + src, mask, data->drawable_pict, srcrect->x, srcrect->y, mrect->x, mrect->y, dstrect->x, dstrect->y, dstrect->w, dstrect->h); @@ -1821,7 +1919,7 @@ {XDoubleToFixed(1), XDoubleToFixed(0), XDoubleToFixed(0)}, {XDoubleToFixed(0), XDoubleToFixed(1), XDoubleToFixed(0)}, {XDoubleToFixed(0), XDoubleToFixed(0), XDoubleToFixed(1)}}}; - XRenderSetPictureTransform(data->display, texturedata->picture, &identity); + XRenderSetPictureTransform(data->display, src, &identity); } if (renderer->blendMode == SDL_BLENDMODE_MOD) { attr.component_alpha = False; @@ -2081,6 +2179,12 @@ if (data->picture) { XRenderFreePicture(renderdata->display, data->picture); } + if (data->modulated_pixmap) { + XFreePixmap(renderdata->display, data->modulated_pixmap); + } + if (data->modulated_picture) { + XRenderFreePicture(renderdata->display, data->modulated_picture); + } } #endif if (data->scaling_image) {