Fixed trilinear scaling so that it does not use stamp-filled mipmap image; fixes bug #929
git-svn-id: svn://svn.code.sf.net/p/sc2/code/trunk@2842 8092fc87-c524-0410-9efc-e669fe64eaf9
This commit is contained in:
@@ -1,4 +1,6 @@
|
||||
Changes towards version 0.7:
|
||||
- Fixed a problem with blue ships after Avatar's tractor beam,
|
||||
along with some other fill-stamp situations; bug #929 - Alex
|
||||
- Added TFB_Canvas_Lock(), TFB_Canvas_Unlock() and TFB_Canvas_GetStride()
|
||||
- SvdB
|
||||
- Scaling images with respect to their hotspots: stabilizes compound
|
||||
|
||||
@@ -110,7 +110,7 @@ typedef struct tfb_dc_setpal
|
||||
typedef struct tfb_dc_setmip
|
||||
{
|
||||
TFB_Image *image;
|
||||
TFB_Canvas mipmap;
|
||||
TFB_Image *mipmap;
|
||||
int hotx, hoty;
|
||||
} TFB_DrawCommand_SetMipmap;
|
||||
|
||||
|
||||
@@ -1037,7 +1037,6 @@ TFB_DrawCanvas_Rescale_Trilinear (TFB_Canvas src_canvas, TFB_Canvas src_mipmap,
|
||||
SDL_PixelFormat *mmfmt = mm->format;
|
||||
SDL_PixelFormat *dstfmt = dst->format;
|
||||
SDL_Color *srcpal = srcfmt->palette? srcfmt->palette->colors : 0;
|
||||
SDL_Color *mmpal = mmfmt->palette ? mmfmt->palette->colors : 0;
|
||||
const int sbpp = srcfmt->BytesPerPixel;
|
||||
const int mmbpp = mmfmt->BytesPerPixel;
|
||||
const int slen = src->pitch;
|
||||
@@ -1058,6 +1057,13 @@ TFB_DrawCanvas_Rescale_Trilinear (TFB_Canvas src_canvas, TFB_Canvas src_mipmap,
|
||||
int ssx0 = 0, ssy0 = 0, ssx1 = 0, ssy1 = 0;
|
||||
int x, y, w, h;
|
||||
|
||||
if (mmfmt->palette && !srcpal)
|
||||
{
|
||||
log_add (log_Warning, "TFB_DrawCanvas_Rescale_Trilinear: "
|
||||
"Mipmap is paletted, but source is not! Failing.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (scale > 0)
|
||||
{
|
||||
int fw, fh;
|
||||
@@ -1231,13 +1237,13 @@ TFB_DrawCanvas_Rescale_Trilinear (TFB_Canvas src_canvas, TFB_Canvas src_mipmap,
|
||||
Uint8 *mm_p = src_a1 + px1 * mmbpp;
|
||||
|
||||
p1[0].value = scale_read_pixel (mm_p, mmfmt,
|
||||
mmpal, mk1, ck1);
|
||||
srcpal, mk1, ck1);
|
||||
p1[1].value = scale_read_pixel (mm_p + mmbpp, mmfmt,
|
||||
mmpal, mk1, ck1);
|
||||
srcpal, mk1, ck1);
|
||||
p1[2].value = scale_read_pixel (mm_p + mmlen, mmfmt,
|
||||
mmpal, mk1, ck1);
|
||||
srcpal, mk1, ck1);
|
||||
p1[3].value = scale_read_pixel (mm_p + mmbpp + mmlen, mmfmt,
|
||||
mmpal, mk1, ck1);
|
||||
srcpal, mk1, ck1);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -692,11 +692,9 @@ TFB_FlushGraphics (void) // Only call from main thread!!
|
||||
switch (DC.Type)
|
||||
{
|
||||
case TFB_DRAWCOMMANDTYPE_SETMIPMAP:
|
||||
LockMutex (DC.data.setmipmap.image->mutex);
|
||||
DC.data.setmipmap.image->MipmapImg = DC.data.setmipmap.mipmap;
|
||||
DC.data.setmipmap.image->MipmapHs.x = DC.data.setmipmap.hotx;
|
||||
DC.data.setmipmap.image->MipmapHs.y = DC.data.setmipmap.hoty;
|
||||
UnlockMutex (DC.data.setmipmap.image->mutex);
|
||||
TFB_DrawImage_SetMipmap (DC.data.setmipmap.image,
|
||||
DC.data.setmipmap.mipmap,
|
||||
DC.data.setmipmap.hotx, DC.data.setmipmap.hoty);
|
||||
break;
|
||||
case TFB_DRAWCOMMANDTYPE_IMAGE:
|
||||
{
|
||||
|
||||
@@ -158,6 +158,20 @@ TFB_DrawScreen_Copy (RECT *r, SCREEN src, SCREEN dest)
|
||||
TFB_EnqueueDrawCommand (&DC);
|
||||
}
|
||||
|
||||
void
|
||||
TFB_DrawScreen_SetMipmap (TFB_Image *img, TFB_Image *mmimg, int hotx, int hoty)
|
||||
{
|
||||
TFB_DrawCommand DC;
|
||||
|
||||
DC.Type = TFB_DRAWCOMMANDTYPE_SETMIPMAP;
|
||||
DC.data.setmipmap.image = img;
|
||||
DC.data.setmipmap.mipmap = mmimg;
|
||||
DC.data.setmipmap.hotx = hotx;
|
||||
DC.data.setmipmap.hoty = hoty;
|
||||
|
||||
TFB_EnqueueDrawCommand (&DC);
|
||||
}
|
||||
|
||||
void
|
||||
TFB_DrawScreen_DeleteImage (TFB_Image *img)
|
||||
{
|
||||
@@ -358,6 +372,40 @@ TFB_DrawImage_New_Rotated (TFB_Image *img, int angle)
|
||||
return newimg;
|
||||
}
|
||||
|
||||
void
|
||||
TFB_DrawImage_SetMipmap (TFB_Image *img, TFB_Image *mmimg, int hotx, int hoty)
|
||||
{
|
||||
bool imgpal;
|
||||
bool mmpal;
|
||||
|
||||
if (!img || !mmimg)
|
||||
return;
|
||||
|
||||
LockMutex (img->mutex);
|
||||
LockMutex (mmimg->mutex);
|
||||
|
||||
// Either both images must be using the same colormap, or mipmap image
|
||||
// must not be paletted. This restriction is due to the current
|
||||
// implementation of fill-stamp, which replaces the palette with
|
||||
// fill color.
|
||||
imgpal = TFB_DrawCanvas_IsPaletted (img->NormalImg);
|
||||
mmpal = TFB_DrawCanvas_IsPaletted (mmimg->NormalImg);
|
||||
if (!mmpal || (mmpal && imgpal &&
|
||||
img->colormap_index == mmimg->colormap_index))
|
||||
{
|
||||
img->MipmapImg = mmimg->NormalImg;
|
||||
img->MipmapHs.x = hotx;
|
||||
img->MipmapHs.y = hoty;
|
||||
}
|
||||
else
|
||||
{
|
||||
img->MipmapImg = NULL;
|
||||
}
|
||||
|
||||
UnlockMutex (mmimg->mutex);
|
||||
UnlockMutex (img->mutex);
|
||||
}
|
||||
|
||||
void
|
||||
TFB_DrawImage_Delete (TFB_Image *image)
|
||||
{
|
||||
|
||||
@@ -95,6 +95,7 @@ void TFB_DrawScreen_FilledImage (TFB_Image *img, int x, int y, int scale, int r,
|
||||
void TFB_DrawScreen_FontChar (TFB_Char *, TFB_Image *backing, int x, int y, SCREEN dest);
|
||||
|
||||
void TFB_DrawScreen_CopyToImage (TFB_Image *img, RECT *lpRect, SCREEN src);
|
||||
void TFB_DrawScreen_SetMipmap (TFB_Image *img, TFB_Image *mmimg, int hotx, int hoty);
|
||||
void TFB_DrawScreen_DeleteImage (TFB_Image *img);
|
||||
void TFB_DrawScreen_DeleteData (void *);
|
||||
void TFB_DrawScreen_WaitForSignal (void);
|
||||
@@ -104,6 +105,7 @@ void TFB_DrawScreen_Callback (void (*callback) (void *arg), void *arg);
|
||||
TFB_Image *TFB_DrawImage_New (TFB_Canvas canvas);
|
||||
TFB_Image *TFB_DrawImage_CreateForScreen (int w, int h, BOOLEAN withalpha);
|
||||
TFB_Image *TFB_DrawImage_New_Rotated (TFB_Image *img, int angle);
|
||||
void TFB_DrawImage_SetMipmap (TFB_Image *img, TFB_Image *mmimg, int hotx, int hoty);
|
||||
void TFB_DrawImage_Delete (TFB_Image *image);
|
||||
void TFB_DrawImage_FixScaling (TFB_Image *image, int target, int type);
|
||||
|
||||
|
||||
+11
-15
@@ -932,23 +932,19 @@ PostProcessQueue (VIEW_STATE view_state, SIZE scroll_x,
|
||||
// (smaller) zoom level image as mipmap,
|
||||
// needed for trilinear scaling
|
||||
|
||||
FRAME frame =
|
||||
SetAbsFrameIndex (
|
||||
ElementPtr->next.image.farray[index + 1],
|
||||
GetFrameIndex (ElementPtr->next.image.frame));
|
||||
FRAME frame = ElementPtr->next.image.frame;
|
||||
FRAME mmframe = SetEquFrameIndex (
|
||||
ElementPtr->next.image.farray[
|
||||
index + 1], frame);
|
||||
|
||||
if (frame && frame->image)
|
||||
// TODO: This is currently hacky, this code
|
||||
// really should not dereference FRAME.
|
||||
// Perhaps make mipmap part of STAMP prim?
|
||||
if (frame && mmframe)
|
||||
{
|
||||
TFB_DrawCommand DC;
|
||||
TFB_Image *mmimg = frame->image;
|
||||
DC.Type = TFB_DRAWCOMMANDTYPE_SETMIPMAP;
|
||||
DC.data.setmipmap.image = (ElementPtr->next.image.frame)->image;
|
||||
DC.data.setmipmap.hotx = frame->HotSpot.x;
|
||||
DC.data.setmipmap.hoty = frame->HotSpot.y;
|
||||
LockMutex (mmimg->mutex);
|
||||
DC.data.setmipmap.mipmap = mmimg->NormalImg;
|
||||
UnlockMutex (mmimg->mutex);
|
||||
TFB_EnqueueDrawCommand (&DC);
|
||||
HOT_SPOT mmhs = GetFrameHot (mmframe);
|
||||
TFB_DrawScreen_SetMipmap (frame->image,
|
||||
mmframe->image, mmhs.x, mmhs.y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user