You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
162 lines
5.2 KiB
162 lines
5.2 KiB
#ifndef __PS1BSP_H__
|
|
#define __PS1BSP_H__
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
/*
|
|
Probable rendering process:
|
|
- Determine visible leaves based on PVS and frustum culling, the usual.
|
|
- Chain together faces/polygons to be drawn. Possibly grouped by texture ID?
|
|
Texture chaining might improve performance by making better use of texture cache, but we'll still be separating polygons based on depth anyway, so the advantage is questionable.
|
|
Texture chaining should probably be the last optimization we try.
|
|
- Tessellate polygons close to the camera by recursively cutting edges in two, up to X times based on camera distance/screen size. Possibly GTE can aid with averaging coordinates? => look at GPF/GPL (general purpose interpolation)
|
|
- Collect all vertices that need to be transformed, put them through GTE, update lighting values if needed, and cache the results.
|
|
(It may not be worth it to collect and precalculate vertices, as keeping track of all the administration also comes at a considerable cost.)
|
|
- Draw all the (tessellated) polygons using the precalculated vertex positions. Use GTE to calculate average depth and order polygons.
|
|
Note: we may not have to calculate average depth for BSP polygons, as the leafs already provide an ordering, and leafs are convex so there is no need to sort the polygons within.
|
|
We do however need some kind of depth value per leaf to insert alias models at the correct positions in the ordering table.
|
|
*/
|
|
typedef struct
|
|
{
|
|
unsigned int offset;
|
|
unsigned int size;
|
|
} ps1bsp_dentry_t;
|
|
|
|
typedef struct
|
|
{
|
|
u_short version;
|
|
|
|
ps1bsp_dentry_t textures;
|
|
ps1bsp_dentry_t vertices;
|
|
ps1bsp_dentry_t polygons;
|
|
ps1bsp_dentry_t polyVertices;
|
|
ps1bsp_dentry_t faces;
|
|
ps1bsp_dentry_t faceVertices;
|
|
ps1bsp_dentry_t planes;
|
|
ps1bsp_dentry_t nodes;
|
|
ps1bsp_dentry_t leaves;
|
|
ps1bsp_dentry_t leafFaces;
|
|
ps1bsp_dentry_t visData;
|
|
} ps1bsp_header_t;
|
|
|
|
typedef struct
|
|
{
|
|
unsigned char w, h; // These may be necessary for scaling UVs, especially since we use a mix of mip0 and mip1 textures
|
|
unsigned char uoffs, voffs; // Texture coordinate offset within the texture page
|
|
unsigned short tpage; // Texture page in PS1 VRAM (precalculated when generating the texture atlas)
|
|
unsigned short nextframe; // If non-zero, the texture is animated and this points to the next texture in the sequence
|
|
} ps1bsp_texture_t;
|
|
|
|
// This matches the SVECTOR data type; we can use the extra padding to store some more data.
|
|
typedef struct
|
|
{
|
|
short x, y, z;
|
|
short pad;
|
|
} ps1bsp_vertex_t;
|
|
|
|
// Texture UV and lighting data for a vertex on a particular polygon.
|
|
typedef struct
|
|
{
|
|
unsigned short index;
|
|
unsigned short light; // Can be made into u_char if we need to store more data; currently u_short for 32-bit alignment purposes
|
|
unsigned short u, v; // Can be made into u_char if we need to store more data; currently u_short for 32-bit alignment purposes
|
|
} ps1bsp_polyvertex_t;
|
|
|
|
// Faces are broken up into one or more polygons, each of which can be drawn as a quad/triangle strip with a single texture.
|
|
// This ahead-of-time tesselation is done to deal with the fact that the PS1 can't do texture wrapping, meaning tiling textures have to be broken up into separate polygons.
|
|
typedef struct
|
|
{
|
|
unsigned short firstPolyVertex;
|
|
unsigned short numPolyVertices;
|
|
} ps1bsp_polygon_t;
|
|
|
|
typedef struct
|
|
{
|
|
unsigned short index;
|
|
|
|
// Sampled texture color * light, for untextured gouraud shaded drawing at range
|
|
unsigned char a : 1;
|
|
unsigned char r : 5;
|
|
unsigned char g : 5;
|
|
unsigned char b : 5;
|
|
} ps1bsp_facevertex_t;
|
|
|
|
// High quality: Face -> polygons -> polygon vertex indices (index + UV + light) -> vertices
|
|
// Low quality: Face -> face vertex indices (index + color) -> vertices
|
|
typedef struct
|
|
{
|
|
unsigned short planeId;
|
|
unsigned char side;
|
|
|
|
// Used for high-quality tesselated textured drawing
|
|
unsigned short firstPolygon;
|
|
unsigned char numPolygons;
|
|
|
|
// Used for low-quality untextured vertex colored drawing
|
|
unsigned short firstFaceVertex;
|
|
unsigned char numFaceVertices;
|
|
|
|
unsigned char textureId;
|
|
|
|
// Used for backface culling
|
|
SVECTOR center;
|
|
|
|
// Which frame was this face last drawn on? Used to check if this face should be drawn.
|
|
u_long drawFrame;
|
|
|
|
u_short pad; // For 32-bit alignment
|
|
} ps1bsp_face_t;
|
|
|
|
typedef struct
|
|
{
|
|
SVECTOR normal;
|
|
short dist;
|
|
short type;
|
|
} ps1bsp_plane_t;
|
|
|
|
typedef struct
|
|
{
|
|
int planeId;
|
|
short children[2];
|
|
|
|
// TODO: add bounding box for frustum culling (or bounding sphere, might be cheaper)
|
|
|
|
u_short firstFace;
|
|
u_short numFaces;
|
|
} ps1bsp_node_t;
|
|
|
|
typedef struct
|
|
{
|
|
int type;
|
|
int vislist;
|
|
|
|
// TODO: add bounding box for frustum culling (or do we? could save half the number of bounds checks if we only check nodes)
|
|
//SVECTOR center;
|
|
|
|
u_short firstLeafFace;
|
|
u_short numLeafFaces;
|
|
} ps1bsp_leaf_t;
|
|
|
|
// Pre-parsed and encoded entity data (this runs the risk of becoming too bloated)
|
|
typedef struct
|
|
{
|
|
unsigned short classtype; // Hash of the original classname
|
|
short angle[3]; // Can store both mangle (all axes) and just angle (Z-axis rotation only)
|
|
int origin[3]; // In 12-bit fixed point coordinates
|
|
unsigned int spawnflags;
|
|
unsigned short messageId; // Index into a pool of pre-defined messages
|
|
} ps1bsp_entity_t;
|
|
|
|
typedef struct
|
|
{
|
|
unsigned short length;
|
|
char message[1];
|
|
} ps1bsp_message_t;
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif // __PS1BSP_H__
|