Skip to content

Commit

Permalink
Refactor|Resources: Continued cleaning up Sprite resource initialization
Browse files Browse the repository at this point in the history
  • Loading branch information
danij-deng committed Nov 20, 2013
1 parent e846b9b commit fd39368
Show file tree
Hide file tree
Showing 7 changed files with 106 additions and 83 deletions.
13 changes: 8 additions & 5 deletions doomsday/client/include/resource/sprite.h
Expand Up @@ -48,13 +48,13 @@ class Sprite
public:
static int const max_angles = 8;

public:
byte _rotate; ///< 0= no rotations, 1= only front, 2= more...
Material *_mats[8]; ///< Material to use for view angles 0-7
byte _flip[8]; ///< Flip (1 = flip) to use for view angles 0-7

public:
Sprite();
Sprite(Sprite const &other);

Sprite &operator = (Sprite const &other);

void newViewAngle(Material *material, uint rotation, bool flipped);

/**
* Select an appropriate material for visualizing the sprite given a mobj's
Expand Down Expand Up @@ -99,6 +99,9 @@ class Sprite
*/
Lumobj *generateLumobj() const;
#endif

private:
DENG2_PRIVATE(d)
};

#endif // DENG_RESOURCE_SPRITE_H
6 changes: 3 additions & 3 deletions doomsday/client/src/render/api_render.cpp
Expand Up @@ -55,16 +55,16 @@ DENG_EXTERN_C boolean R_GetSpriteInfo(int spriteId, int frame, spriteinfo_t *inf
}

de::zapPtr(info);
info->flip = sprite->_flip[0];
bool flip;
info->material = sprite->material(0, &flip);
info->flip = flip;

if(novideo)
{
// We can't prepare the material.
return true;
}

info->material = sprite->_mats[0];

#ifdef __CLIENT__
/// @todo fixme: We should not be using the PSprite spec here. -ds
de::MaterialVariantSpec const &spec =
Expand Down
7 changes: 4 additions & 3 deletions doomsday/client/src/render/billboard.cpp
Expand Up @@ -210,12 +210,13 @@ static void setupPSpriteParams(rendpspriteparams_t *params, vispsprite_t *spr)

Sprite const *sprite = &App_ResourceSystem().sprite(spriteIdx, frameIdx);

boolean flip = sprite->_flip[0];
bool flip;
Material *material = sprite->material(0, &flip);

MaterialVariantSpec const &spec =
App_Materials().variantSpec(PSpriteContext, 0, 1, 0, 0, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE,
0, -2, 0, false, true, true, false);
MaterialSnapshot const &ms = sprite->_mats[0]->prepare(spec);
MaterialSnapshot const &ms = material->prepare(spec);

Texture const &tex = ms.texture(MTU_PRIMARY).generalCase();
variantspecification_t const &texSpec = TS_GENERAL(ms.texture(MTU_PRIMARY).spec());
Expand All @@ -233,7 +234,7 @@ static void setupPSpriteParams(rendpspriteparams_t *params, vispsprite_t *spr)
params->texFlip[0] = flip;
params->texFlip[1] = false;

params->mat = sprite->_mats[0];
params->mat = material;
params->ambientColor[CA] = spr->data.sprite.alpha;

if(spr->data.sprite.isFullBright)
Expand Down
26 changes: 11 additions & 15 deletions doomsday/client/src/render/r_main.cpp
Expand Up @@ -1553,16 +1553,16 @@ static int findSpriteOwner(thinker_t *th, void *context)
return false; // Continue iteration.
}

static void cacheSpritesForState(int stateIdx, MaterialVariantSpec const &spec)
static void cacheSpriteSet(int spriteId, MaterialVariantSpec const &spec)
{
state_t *state = toState(stateIdx);
DENG2_ASSERT(state != 0);

ResourceSystem::SpriteSet const &sprites = App_ResourceSystem().spriteSet(state->sprite);
ResourceSystem::SpriteSet const &sprites = App_ResourceSystem().spriteSet(spriteId);
foreach(Sprite *sprite, sprites)
for(int i = 0; i < Sprite::max_angles; ++i)
{
App_Materials().cache(*sprite->_mats[i], spec);
if(Material *material = sprite->material(i))
{
App_Materials().cache(*material, spec);
}
}
}

Expand All @@ -1583,7 +1583,10 @@ DENG_EXTERN_C void Rend_CacheForMobjType(int num)

if(precacheSprites)
{
cacheSpritesForState(i, spec);
state_t *state = toState(i);
DENG2_ASSERT(state != 0);

cacheSpriteSet(state->sprite, spec);
}
/// @todo What about sounds?
}
Expand Down Expand Up @@ -1644,14 +1647,7 @@ void Rend_CacheForMap()
findSpriteOwner, &i))
{
// This sprite is used by some state of at least one mobj.

// Precache all angles for all frames.
ResourceSystem::SpriteSet const &sprites = App_ResourceSystem().spriteSet(i);
foreach(Sprite *sprite, sprites)
for(int k = 0; k < Sprite::max_angles; ++k)
{
App_Materials().cache(*sprite->_mats[k], spec);
}
cacheSpriteSet(i, spec);
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion doomsday/client/src/resource/models.cpp
Expand Up @@ -951,7 +951,7 @@ static void scaleModelToSprite(modeldef_t &mf, int spriteIdx, int frameIdx)
Sprite *sprite = App_ResourceSystem().spritePtr(spriteIdx, frameIdx);
if(!sprite) return;

MaterialSnapshot const &ms = sprite->_mats[0]->prepare(Rend_SpriteMaterialSpec());
MaterialSnapshot const &ms = sprite->material(0)->prepare(Rend_SpriteMaterialSpec());
Texture const &tex = ms.texture(MTU_PRIMARY).generalCase();
int off = de::max(0, -tex.origin().y - ms.height());
scaleModel(mf, ms.height(), off);
Expand Down
72 changes: 23 additions & 49 deletions doomsday/client/src/resource/resourcesystem.cpp
Expand Up @@ -1423,36 +1423,6 @@ static SpriteDefs generateSpriteDefs()
return spriteDefs;
}

static void setupSpriteViewAngle(Sprite *sprTemp, int *maxFrame,
Material *mat, uint frame, uint rotation, bool flipped)
{
if(frame >= 30) return;
if(rotation > 8) return;

if((signed) frame > *maxFrame)
{
*maxFrame = frame;
}

if(rotation == 0)
{
// This frame should be used for all rotations.
sprTemp[frame]._rotate = false;
for(int r = 0; r < 8; ++r)
{
sprTemp[frame]._mats[r] = mat;
sprTemp[frame]._flip[r] = byte( flipped );
}
return;
}

rotation--; // Make 0 based.

sprTemp[frame]._rotate = true;
sprTemp[frame]._mats[rotation] = mat;
sprTemp[frame]._flip[rotation] = byte( flipped );
}

void ResourceSystem::initSprites()
{
Time begunAt;
Expand All @@ -1470,7 +1440,6 @@ void ResourceSystem::initSprites()
//groups.reserve(spriteNameCount);

// Build the final sprites.
Sprite sprTemp[128];
int customIdx = 0;
foreach(SpriteDef const &def, defs)
{
Expand All @@ -1481,25 +1450,38 @@ void ResourceSystem::initSprites()
DENG2_ASSERT(!d->spriteGroups.contains(spriteId)); // sanity check.
Instance::SpriteGroup &group = d->spriteGroups.insert(spriteId, Instance::SpriteGroup()).value();

std::memset(sprTemp, -1, sizeof(sprTemp));
//std::memset(sprTemp, -1, sizeof(sprTemp));
Sprite sprTemp[128];

int maxSprite = -1;
foreach(SpriteFrameDef const &frameDef, def.frames)
{
setupSpriteViewAngle(sprTemp, &maxSprite, frameDef.mat,
frameDef.frame[0] - 1, frameDef.rotation[0],
false);
int frame = frameDef.frame[0] - 1;
if(frame < 30)
{
sprTemp[frame].newViewAngle(frameDef.mat, frameDef.rotation[0], false);
if(frame > maxSprite)
{
maxSprite = frame;
}
}

if(frameDef.frame[1])
{
setupSpriteViewAngle(sprTemp, &maxSprite, frameDef.mat,
frameDef.frame[1] - 1, frameDef.rotation[1],
true);
frame = frameDef.frame[1] - 1;
if(frame < 30)
{
sprTemp[frame].newViewAngle(frameDef.mat, frameDef.rotation[1], true);
if(frame > maxSprite)
{
maxSprite = frame;
}
}
}
}
++maxSprite;

for(int k = 0; k < maxSprite; ++k)
/*for(int k = 0; k < maxSprite; ++k)
{
if(int(sprTemp[k]._rotate) == -1) // Ahem!
{
Expand All @@ -1520,19 +1502,11 @@ void ResourceSystem::initSprites()
}
}
}
}
}*/

for(int k = 0; k < maxSprite; ++k)
{
Sprite const &tmpSprite = sprTemp[k];

Sprite *sprite = new Sprite;

sprite->_rotate = tmpSprite._rotate;
std::memcpy(sprite->_mats, tmpSprite._mats, sizeof(sprite->_mats));
std::memcpy(sprite->_flip, tmpSprite._flip, sizeof(sprite->_flip));

group.sprites.append(sprite);
group.sprites.append(new Sprite(sprTemp[k]));
}
}
}
Expand Down
63 changes: 56 additions & 7 deletions doomsday/client/src/resource/sprite.cpp
Expand Up @@ -34,11 +34,60 @@

using namespace de;

Sprite::Sprite()
: _rotate(0)
DENG2_PIMPL_NOREF(Sprite)
{
zap(_mats);
zap(_flip);
byte rotate; ///< 0= no rotations, 1= only front, 2= more...
Material *mats[8]; ///< Material to use for view angles 0-7
byte flip[8]; ///< Flip (1 = flip) to use for view angles 0-7

Instance()
: rotate(0)
{
zap(mats);
zap(flip);
}

Instance(Instance const &other)
: rotate(other.rotate)
{
std::memcpy(mats, other.mats, sizeof(mats));
std::memcpy(flip, other.flip, sizeof(flip));
}
};

Sprite::Sprite() : d(new Instance)
{}

Sprite::Sprite(Sprite const &other) : d(new Instance(*other.d))
{}

Sprite &Sprite::operator = (Sprite const &other)
{
d.reset(new Instance(*other.d));
return *this;
}

void Sprite::newViewAngle(Material *material, uint rotation, bool flipped)
{
if(rotation > 8) return;

if(rotation == 0)
{
// This frame should be used for all rotations.
d->rotate = false;
for(int r = 0; r < 8; ++r)
{
d->mats[r] = material;
d->flip[r] = byte( flipped );
}
return;
}

rotation--; // Make 0 based.

d->rotate = true;
d->mats[rotation] = material;
d->flip[rotation] = byte( flipped );
}

Material *Sprite::material(int rotation, bool *flipX, bool *flipY) const
Expand All @@ -51,17 +100,17 @@ Material *Sprite::material(int rotation, bool *flipX, bool *flipY) const
return 0;
}

if(flipX) *flipX = CPP_BOOL(_flip[rotation]);
if(flipX) *flipX = CPP_BOOL(d->flip[rotation]);

return _mats[rotation];
return d->mats[rotation];
}

Material *Sprite::material(angle_t mobjAngle, angle_t angleToEye,
bool noRotation, bool *flipX, bool *flipY) const
{
int rotation = 0; // Use single rotation for all viewing angles (default).

if(!noRotation && _rotate)
if(!noRotation && d->rotate)
{
// Rotation is determined by the relative angle to the viewer.
rotation = (angleToEye - mobjAngle + (unsigned) (ANG45 / 2) * 9) >> 29;
Expand Down

0 comments on commit fd39368

Please sign in to comment.