Skip to content

Commit

Permalink
Material: Share material animation states
Browse files Browse the repository at this point in the history
Rather than store per-usage context animation states in the variant,
it is better to manage this information separately, with a state for
each usage context (see render/materialcontext.h) at material level.
  • Loading branch information
danij-deng committed Mar 3, 2013
1 parent 1dcbf36 commit bc72466
Show file tree
Hide file tree
Showing 26 changed files with 689 additions and 449 deletions.
3 changes: 3 additions & 0 deletions doomsday/client/client.pro
Expand Up @@ -137,6 +137,7 @@ DENG_HEADERS += \
include/MapElement \
include/Material \
include/MaterialArchive \
include/MaterialContext \
include/MaterialManifest \
include/Materials \
include/MaterialScheme \
Expand Down Expand Up @@ -286,6 +287,7 @@ DENG_HEADERS += \
include/network/ui_mpi.h \
include/r_util.h \
include/render/lumobj.h \
include/render/materialcontext.h \
include/render/r_draw.h \
include/render/r_main.h \
include/render/r_lgrid.h \
Expand Down Expand Up @@ -598,6 +600,7 @@ SOURCES += \
src/resource/hq2x.cpp \
src/resource/image.cpp \
src/resource/material.cpp \
src/resource/materialanimation.cpp \
src/resource/materialarchive.cpp \
src/resource/materialmanifest.cpp \
src/resource/materials.cpp \
Expand Down
1 change: 1 addition & 0 deletions doomsday/client/include/MaterialContext
@@ -0,0 +1 @@
#include "render/materialcontext.h"
2 changes: 1 addition & 1 deletion doomsday/client/include/gl/gl_texmanager.h
Expand Up @@ -197,7 +197,7 @@ int GL_LogicalAnisoLevelForVariantSpec(variantspecification_t const &spec);
*
* @return A rationalized and valid TextureVariantSpecification.
*/
texturevariantspecification_t &GL_TextureVariantSpecificationForContext(
texturevariantspecification_t &GL_TextureVariantSpec(
texturevariantusagecontext_t tc, int flags, byte border, int tClass,
int tMap, int wrapS, int wrapT, int minFilter, int magFilter, int anisoFilter,
boolean mipmapped, boolean gammaCorrection, boolean noStretch, boolean toAlpha);
Expand Down
41 changes: 41 additions & 0 deletions doomsday/client/include/render/materialcontext.h
@@ -0,0 +1,41 @@
/** @file render/materialcontext.h Material render-contexts
*
* @authors Copyright © 2009-2013 Daniel Swanson <danij@dengine.net>
*
* @par License
* GPL: http://www.gnu.org/licenses/gpl.html
*
* <small>This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. This program is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details. You should have received a copy of the GNU
* General Public License along with this program; if not, see:
* http://www.gnu.org/licenses</small>
*/

#ifndef LIBDENG_RENDER_MATERIALCONTEXT_H
#define LIBDENG_RENDER_MATERIALCONTEXT_H

/**
* Material render-context identifiers:
*
* @ingroup render
*/
enum MaterialContextId
{
FirstMaterialContextId = 0,

UiContext = FirstMaterialContextId,
MapSurfaceContext,
SpriteContext,
ModelSkinContext,
PSpriteContext,
SkySphereContext,

LastMaterialContextId = SkySphereContext
};

#endif // LIBDENG_RENDER_MATERIALCONTEXT_H
195 changes: 131 additions & 64 deletions doomsday/client/include/resource/material.h
Expand Up @@ -25,6 +25,9 @@
#include "def_data.h"
#include "audio/s_environ.h"
#include "map/p_dmu.h" // setargs_t
#ifdef __CLIENT__
# include "MaterialContext"
#endif
#include "uri.hh"
#include <de/Error>
#include <de/Vector>
Expand Down Expand Up @@ -406,20 +409,16 @@ class Material : public de::MapElement
typedef QList<Decoration *> Decorations;

/**
* Context-specialized variant. Encapsulates all context variant values
* and logics pertaining to a specialized version of the @em superior
* material instance.
*
* Variant instances are only created by the superior material when asked
* to @ref Material::prepare() for render using a context specialization
* specification which it cannot fulfill/match.
*
* @see MaterialVariantSpec
* Animation (state).
*/
class Variant
class Animation
{
private:
Animation(Material &material, MaterialContextId context);
~Animation();

public:
/// Current state of a material layer animation.
/// Current state of a layer animation.
struct LayerState
{
/// Animation stage else @c -1 => layer not in use.
Expand All @@ -432,7 +431,7 @@ class Material : public de::MapElement
float inter;
};

/// Current state of a material (light) decoration animation.
/// Current state of a (light) decoration animation.
struct DecorationState
{
/// Animation stage else @c -1 => decoration not in use.
Expand All @@ -445,23 +444,89 @@ class Material : public de::MapElement
float inter;
};

private:
/**
* @param generalCase Material from which the variant is to be derived.
* @param spec Specification used to derive the variant.
* Returns the logical usage context identifier for the animation.
*/
Variant(Material &generalCase, VariantSpec const &spec);
~Variant();
MaterialContextId context() const;

/**
* Process a system tick event. If not currently paused and still valid;
* the variant material's layers and decorations are animated.
* the material's layers and decorations are animated.
*
* @param ticLength Length of the tick in seconds.
*
* @see isPaused()
*/
void ticker(timespan_t ticLength);
void animate(timespan_t ticLength);

/**
* Returns @c true if animation is currently paused (e.g., this state
* is for use with a context driven by the game timer (and the client
* has paused the game)).
*/
bool isPaused() const;

/**
* Restart the animation, resetting the staged animation point. The
* state of all layers and decorations will be rewound to the beginning.
*/
void restart();

/**
* Returns the current state of layer @a layerNum for the animation.
*/
LayerState const &layer(int layerNum) const;

/**
* Returns the current state of the detail layer for the animation.
*
* @see Material::isDetailed()
*/
LayerState const &detailLayer() const;

/**
* Returns the current state of the shine layer for the animation.
*
* @see Material::isShiny()
*/
LayerState const &shineLayer() const;

/**
* Returns the current state of (light) decoration @a decorNum for
* the animation.
*/
DecorationState const &decoration(int decorNum) const;

friend class Material;
friend struct Material::Instance;

private:
DENG2_PRIVATE(d)
};

/// An animation state for each usage context.
typedef QMap<MaterialContextId, Animation *> Animations;

/**
* Context-specialized variant. Encapsulates all context variant values
* and logics pertaining to a specialized version of the @em superior
* material instance.
*
* Variant instances are only created by the superior material when asked
* to @ref Material::prepare() for render using a context specialization
* specification which it cannot fulfill/match.
*
* @see MaterialVariantSpec
*/
class Variant
{
private:
/**
* @param generalCase Material from which the variant is to be derived.
* @param spec Specification used to derive the variant.
*/
Variant(Material &generalCase, VariantSpec const &spec);
~Variant();

public:
/**
Expand All @@ -481,11 +546,13 @@ class Material : public de::MapElement
VariantSpec const &spec() const;

/**
* Returns @c true if animation of the variant is currently paused
* (e.g., the variant is for use with an in-game render context and
* the client has paused the game).
* Returns the usage context for this variant (from the spec).
*
* Same as @c spec().context
*
* @see spec()
*/
bool isPaused() const;
MaterialContextId context() const;

/**
* Prepare the context variant for render (if necessary, uploading
Expand All @@ -502,45 +569,6 @@ class Material : public de::MapElement
*/
Snapshot const &prepare(bool forceSnapshotUpdate = false);

/**
* Returns the MaterialSnapshot data for the variant.
*/
Snapshot &snapshot() const;

/**
* Reset the staged animation point for the material. The animation
* states of all layers and decorations will be rewound to the beginning.
*/
void restartAnimation();

/**
* Returns the current state of the layer animation @a layerNum for
* the variant.
*/
LayerState const &layer(int layerNum) const;

/**
* Returns the current state of the detail layer animation for the
* variant.
*
* @see Material::isDetailed()
*/
LayerState const &detailLayer() const;

/**
* Returns the current state of the shine layer animation for the
* variant.
*
* @see Material::isShiny()
*/
LayerState const &shineLayer() const;

/**
* Returns the current state of the (light) decoration animation
* @a decorNum for the variant.
*/
DecorationState const &decoration(int decorNum) const;

friend class Material;
friend struct Material::Instance;

Expand Down Expand Up @@ -611,7 +639,7 @@ class Material : public de::MapElement
*
* @see isValid()
*/
void ticker(timespan_t time);
void ticker(timespan_t ticLength);

/// Returns @c true if the material has at least one animated layer.
bool isAnimated() const;
Expand Down Expand Up @@ -645,6 +673,30 @@ class Material : public de::MapElement
/// Returns @c true if one or more of the material's layers are glowing.
bool hasGlow() const;

#ifdef __CLIENT__

inline bool Material::hasAnimatedLayers() const
{
foreach(Layer *layer, layers())
{
if(layer->isAnimated()) return true;
}
if(isDetailed() && detailLayer().isAnimated()) return true;
if(isShiny() && shineLayer().isAnimated()) return true;
return false;
}

inline bool Material::hasAnimatedDecorations() const
{
foreach(Decoration *decor, decorations())
{
if(decor->isAnimated()) return true;
}
return false;
}

#endif // __CLIENT__

/**
* Returns the dimensions of the material in map coordinate space units.
*/
Expand Down Expand Up @@ -805,6 +857,20 @@ class Material : public de::MapElement
*/
Decorations const &decorations() const;

/**
* Retrieve the animation state for the specified render @a context.
*/
inline Animation *animation(MaterialContextId context) const
{
return animations()[context];
}

/**
* Provides access to the set of usage context animation states,
* for efficient traversal.
*/
Animations const &animations() const;

/**
* Returns the number of context variants for the material.
*/
Expand Down Expand Up @@ -847,7 +913,7 @@ class Material : public de::MapElement
*
* @return Snapshot for the chosen and prepared variant of Material.
*
* @see Materials::variantSpecForContext(), chooseVariant(), Variant::prepare()
* @see Materials::variantSpec(), chooseVariant(), Variant::prepare()
*/
inline Snapshot const &prepare(VariantSpec const &spec, bool forceSnapshotUpdate = false)
{
Expand Down Expand Up @@ -880,6 +946,7 @@ Q_DECLARE_OPERATORS_FOR_FLAGS(Material::Flags)

// Aliases.
#ifdef __CLIENT__
typedef Material::Animation MaterialAnimation;
typedef Material::Decoration MaterialDecoration;
typedef Material::Variant MaterialVariant;
#endif
Expand Down
10 changes: 5 additions & 5 deletions doomsday/client/include/resource/materials.h
Expand Up @@ -272,9 +272,9 @@ class Materials
inline void restartAllAnimations() const
{
foreach(Material *material, all())
foreach(MaterialVariant *variant, material->variants())
foreach(MaterialAnimation *animation, material->animations())
{
variant->restartAnimation();
animation->restart();
}
}

Expand All @@ -283,7 +283,7 @@ class Materials
* usage context. If incomplete context information is supplied, suitable
* default values will be chosen in their place.
*
* @param materialContext Material (usage) context identifier.
* @param contextId Usage context identifier.
* @param flags @ref textureVariantSpecificationFlags
* @param border Border size in pixels (all edges).
* @param tClass Color palette translation class.
Expand All @@ -300,8 +300,8 @@ class Materials
*
* @return Rationalized (and interned) copy of the final specification.
*/
VariantSpec const &variantSpecForContext(materialcontext_t materialContext,
int flags, byte border, int tClass, int tMap, int wrapS, int wrapT,
VariantSpec const &variantSpec(MaterialContextId contextId, int flags,
byte border, int tClass, int tMap, int wrapS, int wrapT,
int minFilter, int magFilter, int anisoFilter,
bool mipmapped, bool gammaCorrection, bool noStretch, bool toAlpha);

Expand Down

0 comments on commit bc72466

Please sign in to comment.