Skip to content

Commit

Permalink
Changed: When loading sprites add an additonal 1-pixel border around …
Browse files Browse the repository at this point in the history
…the graphic which is then scaled and clipped out at render time. This addresses various GL filtering issues where a sprite contains color information in the edge texels.
  • Loading branch information
danij-deng committed May 21, 2010
1 parent 63b078a commit 13e6367
Show file tree
Hide file tree
Showing 5 changed files with 24 additions and 17 deletions.
1 change: 1 addition & 0 deletions doomsday/engine/portable/include/r_data.h
Expand Up @@ -146,6 +146,7 @@ typedef struct flat_s {
typedef struct {
lumpnum_t lump; // Real lump number.
short width, height, offX, offY;
int extraOffset[2]; // Used on ALL sprites to hide edge filtering artefacts.
} spritetex_t;

// Model skin.
Expand Down
1 change: 1 addition & 0 deletions doomsday/engine/portable/include/r_things.h
Expand Up @@ -87,6 +87,7 @@ typedef struct rendspriteparams_s {
float center[3]; // The real center point.
float width, height;
float viewOffX; // View-aligned offset to center point.
float viewOffY;
float srvo[3]; // Short-range visual offset.
float distance; // Distance from viewer.
boolean viewAligned;
Expand Down
10 changes: 5 additions & 5 deletions doomsday/engine/portable/src/gl_texmanager.c
Expand Up @@ -1611,8 +1611,8 @@ byte GL_LoadSprite(image_t* image, const gltexture_inst_t* inst,
const lumppatch_t* patch;
void* tmp = NULL;

image->width = sprTex->width;
image->height = sprTex->height;
image->width = sprTex->width+abs(sprTex->extraOffset[0])*2;
image->height = sprTex->height+abs(sprTex->extraOffset[1])*2;
image->pixelSize = 1;
image->pixels = M_Calloc(2 * image->width * image->height);

Expand All @@ -1633,7 +1633,7 @@ byte GL_LoadSprite(image_t* image, const gltexture_inst_t* inst,
patch = W_CacheLumpNum(sprTex->lump, PU_STATIC);
}

image->isMasked = DrawRealPatch(image->pixels, image->width, image->height, patch, 0, 0, false, true);
image->isMasked = DrawRealPatch(image->pixels, image->width, image->height, patch, abs(sprTex->extraOffset[0]), abs(sprTex->extraOffset[1]), false, true);

if(freePatch)
M_Free(tmp);
Expand Down Expand Up @@ -2860,8 +2860,8 @@ if(!didDefer)
else
{
int pw = M_CeilPow2(image.width), ph = M_CeilPow2(image.height);
tc[0] = image.width / (float) pw;
tc[1] = image.height / (float) ph;
tc[0] = (image.width-1) / (float) pw;
tc[1] = (image.height-1) / (float) ph;
}
}

Expand Down
16 changes: 11 additions & 5 deletions doomsday/engine/portable/src/r_things.c
Expand Up @@ -499,6 +499,11 @@ void R_PreInitSprites(void)
sprTex->width = SHORT(patch->width);
sprTex->height = SHORT(patch->height);

// An extra offset is applied during drawing and the sprite
// loaded with an additional border to counteract GL edge
// filtering artefacts.
sprTex->extraOffset[0] = sprTex->extraOffset[1] = -1;

glTex = GL_CreateGLTexture(name, idx++, GLT_SPRITE);

// Create a new material for this sprite patch.
Expand Down Expand Up @@ -721,8 +726,8 @@ boolean R_GetSpriteInfo(int sprite, int frame, spriteinfo_t* info)
info->flip = sprFrame->flip[0];
info->offset = sprTex->offX;
info->topOffset = sprTex->offY;
info->width = ms.width;
info->height = ms.height;
info->width = ms.width + abs(sprTex->extraOffset[0])*2;
info->height = ms.height + abs(sprTex->extraOffset[1])*2;
info->texCoord[0] = ms.units[MTU_PRIMARY].texInst->data.sprite.texCoord[0];
info->texCoord[1] = ms.units[MTU_PRIMARY].texInst->data.sprite.texCoord[1];

Expand Down Expand Up @@ -970,8 +975,8 @@ static void setupSpriteParamsForVisSprite(rendspriteparams_t *params,

sprTex = spriteTextures[ms.units[MTU_PRIMARY].texInst->tex->ofTypeID];

params->width = ms.width;
params->height = ms.height;
params->width = ms.width + fabs(sprTex->extraOffset[0])*2;
params->height = ms.height + fabs(sprTex->extraOffset[1])*2;

params->center[VX] = x;
params->center[VY] = y;
Expand All @@ -980,7 +985,8 @@ static void setupSpriteParamsForVisSprite(rendspriteparams_t *params,
params->srvo[VY] = visOffY;
params->srvo[VZ] = visOffZ;
params->distance = distance;
params->viewOffX = (float) sprTex->offX - ms.width / 2.0f;
params->viewOffX = (float) sprTex->offX - ms.width / 2.0f - sprTex->extraOffset[0];
params->viewOffY = -sprTex->extraOffset[1];
params->subsector = ssec;
params->viewAligned = viewAligned;
params->noZWrite = noSpriteZWrite;
Expand Down
13 changes: 6 additions & 7 deletions doomsday/engine/portable/src/rend_sprite.c
Expand Up @@ -272,11 +272,10 @@ static void setupPSpriteParams(rendpspriteparams_t* params,
Material_Prepare(&ms, sprFrame->mats[0], true, &mparams);

sprTex = spriteTextures[ms.units[MTU_PRIMARY].texInst->tex->ofTypeID];
params->pos[VX] = psp->pos[VX] - sprTex->offX + pspOffset[VX];
params->pos[VX] = psp->pos[VX] - sprTex->offX + pspOffset[VX];
params->pos[VY] = offScaleY * (psp->pos[VY] - sprTex->offY) + pspOffset[VY];
params->width = ms.width;
params->height = ms.height;
params->pos[VX] = psp->pos[VX] - sprTex->offX + pspOffset[VX] + sprTex->extraOffset[0];
params->pos[VY] = offScaleY * (psp->pos[VY] - sprTex->offY) + pspOffset[VY] + sprTex->extraOffset[1];
params->width = ms.width + fabs(sprTex->extraOffset[0])*2;
params->height = ms.height + fabs(sprTex->extraOffset[1])*2;

// Calculate texture coordinates.
params->texOffset[0] = ms.units[MTU_PRIMARY].texInst->data.sprite.texCoord[VX];
Expand Down Expand Up @@ -914,8 +913,8 @@ void Rend_RenderSprite(const rendspriteparams_t* params)
v3[VX] = v4[VX];
v3[VY] = v4[VY];

v1[VZ] = v4[VZ] = spriteCenter[VZ] - params->height / 2;
v2[VZ] = v3[VZ] = spriteCenter[VZ] + params->height / 2;
v1[VZ] = v4[VZ] = spriteCenter[VZ] - params->height / 2 + params->viewOffY;
v2[VZ] = v3[VZ] = spriteCenter[VZ] + params->height / 2 + params->viewOffY;

// Calculate the surface normal.
M_PointCrossProduct(v2, v1, v3, surfaceNormal);
Expand Down

0 comments on commit 13e6367

Please sign in to comment.