Skip to content

Commit

Permalink
Refactor: New mechanism for configuring render list texture units
Browse files Browse the repository at this point in the history
The previous implementation made texture unit configuration a function
of primitive writing, therefore every time one wanted to write a polygon
to the lists, the texture unit config had to be reconstructed.

This interface mechanic was a architectural bottleneck (not helped by
the fact that acquiring the config to construct the texture unit state
itself had some performance issues).

This commit addresses this bottleneck thus:

1) Render list primitive write interface was extended with a state
based texture unit configuration mechanic. It is also now possible
to configure this state once, before then writing multiple polygons
to the list(s).

2) Render list interface was extended with the ability to reference
directly prepared rtexmapunit_t states owned by another module.

3) World renderer was enhanced to take advantage of the new mechanics
of the render list inteface, mapping the preprocessed rtexmapunit_t
state (owned by MaterialSnapshot) when writing to the lists.

4) Added new logical texture units for shiny textures and their masks
and moved writing of the shiny polygons into the render list module.
The interface presented by the render list module now deals entirely
with "logical" texture units. Users of this module should not need to
be concerned with whether there are enough "physical" texture units
available. The render list module will itself dynamically determine
when insufficent units are available and use a new render pass as is
necessary. Therefore the primitive write for shiny textures belongs
in this module.

Cleanup of the Material type hierarchy.
  • Loading branch information
danij-deng committed Nov 24, 2011
1 parent 96a92be commit 5c78017
Show file tree
Hide file tree
Showing 31 changed files with 1,464 additions and 1,031 deletions.
18 changes: 18 additions & 0 deletions doomsday/engine/portable/include/materials.h
Expand Up @@ -34,6 +34,24 @@ struct materialsnapshot_s;

enum materialnamespaceid_t; // Defined in dd_share.h

/// Material (Usage) Context identifiers.
typedef enum {
MC_UNKNOWN = -1,
MATERIALCONTEXT_FIRST = 0,
MC_UI = MATERIALCONTEXT_FIRST,
MC_MAPSURFACE,
MC_SPRITE,
MC_MODELSKIN,
MC_PSPRITE,
MC_SKYSPHERE,
MATERIALCONTEXT_LAST = MC_SKYSPHERE
} materialcontext_t;

#define MATERIALCONTEXT_COUNT (MATERIALCONTEXT_LAST + 1 - MATERIALCONTEXT_FIRST )

/// @c true= val can be interpreted as a valid material context identifier.
#define VALID_MATERIALCONTEXT(val) ((val) >= MATERIALCONTEXT_FIRST && (val) <= MATERIALCONTEXT_LAST)

/// Components within a Material path hierarchy are delimited by this character.
#define MATERIALS_PATH_DELIMITER '/'

Expand Down
66 changes: 19 additions & 47 deletions doomsday/engine/portable/include/materialvariant.h
Expand Up @@ -24,27 +24,11 @@
#ifndef LIBDENG_MATERIALVARIANT_H
#define LIBDENG_MATERIALVARIANT_H

#include "texture.h"
#include "r_data.h"

struct texturevariant_s;
struct texturevariantspecification_s;

/// Material (Usage) Context identifiers.
typedef enum {
MC_UNKNOWN = -1,
MATERIALCONTEXT_FIRST = 0,
MC_UI = MATERIALCONTEXT_FIRST,
MC_MAPSURFACE,
MC_SPRITE,
MC_MODELSKIN,
MC_PSPRITE,
MC_SKYSPHERE,
MATERIALCONTEXT_LAST = MC_SKYSPHERE
} materialcontext_t;

#define MATERIALCONTEXT_COUNT (MATERIALCONTEXT_LAST + 1 - MATERIALCONTEXT_FIRST )

#define VALID_MATERIALCONTEXT(mc) ((mc) >= MATERIALCONTEXT_FIRST && (mc) <= MATERIALCONTEXT_LAST)

typedef struct materialvariantspecification_s {
materialcontext_t context;
struct texturevariantspecification_s* primarySpec;
Expand All @@ -61,35 +45,16 @@ enum {
NUM_MATERIAL_TEXTURE_UNITS
};

typedef struct material_textureunit_s {
struct material_textureunit_texture {
texture_t* texture;
const struct texturevariantspecification_s* spec;
DGLuint glName;
float s, t;
} tex;

int magMode;

/// Currently used only with reflection.
blendmode_t blendMode;

/// Material-space scale multiplier.
vec2_t scale;

/// Material-space origin translation.
vec2_t offset;

float alpha;
} material_textureunit_t;

typedef struct materialsnapshot_s {
/// "Virtual" texturing units.
material_textureunit_t units[NUM_MATERIAL_TEXTURE_UNITS];
/// @c true= this material is entirely opaque.
boolean isOpaque;

/// Dimensions in logical world units.
int width, height;

/// Glow strength multiplier.
float glowing;

/// Average colors (for lighting).
vec3_t color;
vec3_t colorAmplified;
Expand All @@ -100,17 +65,24 @@ typedef struct materialsnapshot_s {
/// Minimum sector light color for shiny texturing.
vec3_t shinyMinColor;

/// Glow strength multiplier.
float glowing;
/// Textures used on each texture unit.
const struct texturevariant_s* textures[NUM_MATERIAL_TEXTURE_UNITS];

boolean isOpaque;
/// Texture unit configuration.
rtexmapunit_t units[NUM_MATERIAL_TEXTURE_UNITS];
} materialsnapshot_t;

#define MSU(ms, u) ((ms)->units[u])
// Helper macros for accessing MaterialSnapshot data elements.
#define MST(ms, u) ((ms)->textures[u])
#define MSU(ms, u) ((ms)->units[u])

#define MSU_texture(ms, u) (MST(ms, u)? TextureVariant_GeneralCase(MST(ms, u)) : NULL)
#define MSU_gltexture(ms, u) (MST(ms, u)? TextureVariant_GLName(MST(ms, u)) : 0)
#define MSU_texturespec(ms, u) (MST(ms, u)? TextureVariant_Spec(MST(ms, u)) : NULL)

typedef struct materialvariant_layer_s {
int stage; // -1 => layer not in use.
texture_t* texture;
struct texture_s* texture;
float texOrigin[2]; /// Origin of the texture in material-space.
float glow;
short tics;
Expand Down
1 change: 0 additions & 1 deletion doomsday/engine/portable/include/p_mapdata.h
Expand Up @@ -130,7 +130,6 @@ typedef struct biassurface_s {

typedef void* blockmap_t;

#include "materialvariant.h"
#include "p_polyob.h"
#include "p_maptypes.h"

Expand Down
81 changes: 68 additions & 13 deletions doomsday/engine/portable/include/r_data.h
Expand Up @@ -29,6 +29,7 @@
#ifndef LIBDENG_REFRESH_DATA_H
#define LIBDENG_REFRESH_DATA_H

#include "dd_types.h"
#include "gl_main.h"
#include "dd_def.h"
#include "p_think.h"
Expand All @@ -53,13 +54,68 @@ struct font_s;
#define DTLF_PWAD 0x2 // Can use if from PWAD.
#define DTLF_EXTERNAL 0x4 // Can use if from external resource.

/**
* Texture unit state. POD.
*
* A simple Record data structure for storing properties used for
* configuring a GL texture unit during render.
*/
typedef struct rtexmapuint_s {
/// Texture used on this layer (if any).
DGLuint tex;

/// GL texture magnification filter.
int magMode;

/// Currently used only with reflection.
blendmode_t blendMode;

/// Opacity of this layer [0...1].
float opacity;

/// Texture-space scale multiplier.
vec2_t scale;

/// Texture-space origin translation (unscaled).
vec2_t offset;
} rtexmapunit_t;

/// Manipulators, for convenience.
void Rtu_Init(rtexmapunit_t* rtu);

/// Change the scale property.
void Rtu_SetScale(rtexmapunit_t* rtu, float s, float t);
void Rtu_SetScalev(rtexmapunit_t* rtu, float const st[2]);

/**
* Multiply the offset and scale properties by @a scalar.
* \note @a scalar is applied to both scale and offset properties
* however the offset remains independent from scale (i.e., it is
* still considered "unscaled").
*/
void Rtu_Scale(rtexmapunit_t* rtu, float scalar);
void Rtu_ScaleST(rtexmapunit_t* rtu, float const scalarST[2]);

/// Change the offset property.
void Rtu_SetOffset(rtexmapunit_t* rtu, float s, float t);
void Rtu_SetOffsetv(rtexmapunit_t* rtu, float const st[2]);

/// Translate the offset property.
void Rtu_TranslateOffset(rtexmapunit_t* rtu, float s, float t);
void Rtu_TranslateOffsetv(rtexmapunit_t* rtu, float const st[2]);

/**
* Logical texture unit indices.
*/
typedef enum {
TU_PRIMARY = 0,
TU_PRIMARY_DETAIL,
TU_INTER,
TU_INTER_DETAIL,
RTU_PRIMARY = 0,
RTU_PRIMARY_DETAIL,
RTU_INTER,
RTU_INTER_DETAIL,
RTU_REFLECTION,
RTU_REFLECTION_MASK,
NUM_TEXMAP_UNITS
} gltexunit_t;
} rtexmapunitid_t;

typedef struct glcommand_vertex_s {
float s, t;
Expand Down Expand Up @@ -226,14 +282,13 @@ void R_FreeRendColors(rcolor_t* rcolors);
void R_FreeRendTexCoords(rtexcoord_t* rtexcoords);
void R_InfoRendVerticesPool(void);

void R_DivVerts(rvertex_t* dst, const rvertex_t* src,
const walldiv_t* divs);
void R_DivVertColors(rcolor_t* dst, const rcolor_t* src,
const walldiv_t* divs, float bL, float tL,
float bR, float tR);
void R_DivTexCoords(rtexcoord_t* dst, const rtexcoord_t* src,
const walldiv_t* divs, float bL, float tL,
float bR, float tR);
void R_DivVerts(rvertex_t* dst, const rvertex_t* src, const walldiv_t* divs);

void R_DivVertColors(rcolor_t* dst, const rcolor_t* src, const walldiv_t* divs,
float bL, float tL, float bR, float tR);

void R_DivTexCoords(rtexcoord_t* dst, const rtexcoord_t* src, const walldiv_t* divs,
float bL, float tL, float bR, float tR);

void R_InitTranslationTables(void);
void R_UpdateTranslationTables(void);
Expand Down
2 changes: 2 additions & 0 deletions doomsday/engine/portable/include/r_draw.h
Expand Up @@ -29,6 +29,8 @@
#ifndef LIBDENG_REFRESH_DRAW_H
#define LIBDENG_REFRESH_DRAW_H

#include "texture.h"

void R_InitViewWindow(void);
void R_ShutdownViewWindow(void);

Expand Down
1 change: 0 additions & 1 deletion doomsday/engine/portable/include/r_things.h
Expand Up @@ -99,7 +99,6 @@ typedef struct rendspriteparams_s {
// Material:
material_t* mat;
int tMap, tClass;
float matOffset[2];
boolean matFlip[2]; // [S, T] Flip along the specified axis.

// Lighting/color:
Expand Down

0 comments on commit 5c78017

Please sign in to comment.