Skip to content

PolymostTexManagement

jonof edited this page Jan 4, 2011 · 4 revisions

PolymostTex Management improvements

Objectives

  1. Remove redundant copies of texture data in memory when a single texture is used by more than one Hightile replacement.
  2. Integrate model skin loading with the rest of the texture handling framework.

The current process

When a polygon is to be rendered for a sprite, wall, ceiling, or floor, Polymost requests from PolymostTex a PTHead structure based on the picnum, palnum, and some additional flags. PolymostTex will try this sequence of actions to try and fulfill this request:

  1. It looks for a Hightile replacement for the exact combination of picnum and palnum.
  2. Otherwise, it looks for a Hightile replacement for the picnum and palnum 0.
  3. Otherwise, it tries to load a texture from the 8-bit ART file.
  4. Otherwise, bummer.

Currently PolymostTex supports up to six 'layers' of texture, however only three are defined (base, glow/fullbright, detail) and two implemented. For the special skybox case, each of the six layers is one face of the cube. Only the base layer is implemented for Hightile textures, though the fullbright layer is used for ART tiles with fullbright pixels. The detail layer is unimplemented.

This is the current PTHead structure used by Polymost:

    struct PTHead_typ {
        GLuint glpic[PTHGLPIC_SIZE];    // OpenGL texture ids
        
        int32 picnum;
        int32 palnum;
        uint16 flags;
        
        hicreplctyp *repldef;   // pointer to the HighTile replacement definition
        
        int32 sizx, sizy;        // padded texture dimensions
        int32 tsizx, tsizy;      // true texture dimensions
        float scalex, scaley;   // scale factor between texture and ART tile
    };

Model rendering is completely independent from the rest of the world rendering. Textures for model skins are handled in the model code and this duplicates a certain amount of functionality.

The proposed solution

We need to rationalise the loading of textures so that it happens in one place only for world and model drawing. Model skins can be thought of as the same as a regular Hightile texture.

A new module of PolymostTex is suggested to abstract one layer further the handling of loading textures off disk and into the graphics hardware, and through this abstraction we can eliminate duplicate copies of textures in memory.

The PTHead structure would change to this:

    struct PTHead_typ {
        PTMHead *pic[PTHPIC_SIZE];    // pointers to managed texture headers
        
        int32 picnum;
        int32 palnum;
        uint16 flags;   // clamped, etc
        
        hicreplctyp *repldef;   // pointer to the HighTile replacement definition
        
        float scalex, scaley;   // scale factor between texture and ART tile
    };

The new PTMHead structure would look like this:

    struct PTMHead_typ {
        GLuint glpic;
        
        md4hash id;           // unique identifier (see below)
        
        int32 sizx, sizy;        // padded texture dimensions
        int32 tsizx, tsizy;      // true texture dimensions
    };

The interesting part here is the MD4 hash which maps many identical definitions of a texture into a single object to be loaded up to the graphics hardware. id is the MD4 of one these structures based on the source of the texture:

    struct arthash {
        int16  type;    // = 0
        uint16 flags;
        int32  palnum;
        int32  picnum;
    };
    struct hightilehash {
        int16  type;    // = 1
        uint16 flags;
        uint16 effects;
        char   filename[];
    };

Fitting mdsprite into all this

The structures for each model format mdsprite supports (VOX, MD2, MD3) begin with a common header:

    typedef struct {
        long mdnum; //VOX=1, MD2=2, MD3=3. NOTE: must be first in structure!
        long shadeoff;
        float scale, bscale, zadd;
        GLuint *texid;	// skins
    } mdmodel;

MD3-format models also have skin map structures that look like this:

    typedef struct _mdskinmap_t {
        unsigned char palette, filler[3]; // Build palette number
        int skinnum, surfnum;   // Skin identifier, surface number
        char *fn;   // Skin filename
        GLuint texid[HICEFFECTMASK+1];   // OpenGL texture numbers for effect variations
        struct _mdskinmap_t *next;
    } mdskinmap_t;

The GLuints would become pointers to PTMHeads and the specialised versions of the skin loading code in mdsprite should be removed and reworked to use the functionality of PolymostTex.

Wildcards

  1. In-memory textures generated by rendering into a tile.
  2. VOX model skins generated at runtime.
  3. Flags like PTH_DIRTY should be pushed into the PTMHead.