brender-1997/softrend/rend.h
2022-05-03 14:31:40 -07:00

309 lines
7.4 KiB
C

/*
* Copyright (c) 1993-1995 Argonaut Technologies Limited. All rights reserved.
*
* $Id: rend.h 2.13 1997/05/22 14:45:07 jon Exp $
* $Locker: $
*
* Static scratch area for renderer
*/
#ifndef _REND_H_
#define _REND_H_
#ifdef __cplusplus
extern "C" {
#endif
/*
* Flags for vertices
*/
#define TVDIR_FRONT 0x80000000
#define TVDIR_BACK 0x40000000
#define TV_CLIPPED 0x20000000
struct temp_face {
/*
* Combined outcodes of face
*/
br_uint_16 codes;
/*
* Flag describing visiblity of face
*/
br_uint_8 flag;
br_uint_8 _pad[1];
};
/*
* Values for temp_face.flag
*/
#define TFF_VISIBLE 4
#define TFF_CLIPPED 2
#define TFF_REVERSED 1
/*
* Workspace for renderer functions
*/
typedef struct rend_block {
/*
* Pointers into scratch buffer
*/
void *scratch;
struct temp_face *temp_faces;
br_int_8 *vertex_counts;
union brp_vertex *temp_vertices;
union brp_vertex **vertex_heap_pointers;
br_int_8 *vertex_flags;
br_int_8 *edge_flags;
br_int_32 nvisible_faces;
br_boolean faces_clipped;
struct v11face *faces;
struct fmt_vertex *vertices;
br_colour *face_colours;
br_colour *vertex_colours;
br_uint_8 *face_flags;
br_int_32 nfaces;
br_int_32 nvertices;
br_int_32 nedges;
/*
* Index of the current face during face ops
*/
br_uint_32 current_face;
br_vector3 eye_l;
struct brp_block *block;
br_boolean block_changed;
br_boolean range_changed;
/*
* Current renderer
*/
struct br_renderer *renderer;
struct br_geometry *geometry;
/*
* Current subdivion limit
*/
br_scalar subdivide_threshold;
} _rend;
/*
* Cached info that is based on current state
*/
struct active_light {
br_token type;
br_vector3 position;
br_vector3 direction;
br_vector3 half;
br_scalar intensity;
void (*accumulate_index)(br_renderer *self, br_vector3 *p, br_vector3 *n, struct active_light *alp, br_scalar *comp);
void (*accumulate_colour)(br_renderer *self, br_vector3 *p, br_vector3 *n, br_colour colour, struct active_light *alp, br_scalar *comp);
struct state_light *s;
};
typedef struct static_cache {
br_matrix4 model_to_screen;
br_matrix34 view_to_model;
br_matrix34 model_to_environment;
/*
* model_to_screen with viewport transform multiplied in
*/
br_matrix4 model_to_viewport;
#if BASED_FIXED
/*
* High words of bottom row of matrix
*/
br_scalar model_to_viewport_hi[4];
#endif
/*
* Combined surface colour & opacity
*/
br_colour colour;
#if BASED_FIXED
br_uint_32 loop_count;
/*
* Local copies of X,Y,Z scale and offset for ASM transform & project
*/
br_scalar scale_x,scale_y,scale_z;
br_scalar offset_x,offset_y,offset_z;
#endif
/*
* Local copy of bounds
*/
br_vector2 min;
br_vector2 max;
br_vector4 eye_m;
br_vector3 eye_m_normalised;
br_boolean user_clip_active;
/*
* Current lighting info.
*/
br_boolean light_1md;
struct active_light lights[MAX_STATE_LIGHTS];
br_int_32 nlights_model;
br_int_32 nlights_view;
/*
* Flags indicating what needs to be updated
*/
br_boolean valid_v2m;
br_boolean valid_m2s;
br_boolean valid_per_model;
br_boolean valid_per_scene;
} _static_cache;
extern _rend BR_ASM_DATA rend;
extern _static_cache BR_ASM_DATA scache;
/*
* Generates outcodes for a homogenous point
*/
#define OUTCODE_POINT(outcode,screen)\
{ \
/* \
* The 6 planes of the view volume... \
*/ \
if((screen)->v[X] >= (screen)->v[W]) \
(outcode) ^= (OUTCODE_RIGHT | OUTCODE_N_RIGHT); \
if((screen)->v[X] < -(screen)->v[W]) \
(outcode) ^= (OUTCODE_LEFT | OUTCODE_N_LEFT); \
\
if((screen)->v[Y] >= (screen)->v[W]) \
(outcode) ^= (OUTCODE_TOP | OUTCODE_N_TOP); \
if((screen)->v[Y] < -(screen)->v[W]) \
(outcode) ^= (OUTCODE_BOTTOM | OUTCODE_N_BOTTOM); \
\
if((screen)->v[Z] >= (screen)->v[W]) \
(outcode) ^= (OUTCODE_HITHER | OUTCODE_N_HITHER); \
if((screen)->v[Z] < -(screen)->v[W]) \
(outcode) ^= (OUTCODE_YON | OUTCODE_N_YON); \
\
/* \
* Any user defined clip planes... \
*/ \
if(scache.user_clip_active) { \
int c; \
for(c = 0; c < MAX_STATE_CLIP_PLANES; c++) \
if(renderer->state.clip[c].type == BRT_PLANE && \
BrVector4Dot((screen),&renderer->state.clip[c].plane) < S0) \
(outcode) ^= (OUTCODE_USER | OUTCODE_N_USER) << c; \
} \
}
/*
* Generic macro for projecting a vertex from homogenous coordinates
*/
#define PROJECT_VERTEX(tvp,sx,sy,sz,sw) \
{ \
float q = BR_DIV(S1,(sw)); \
(tvp)->comp[C_SX] = renderer->state.cache.comp_offsets[C_SX] + \
BR_MUL(renderer->state.cache.comp_scales[C_SX], \
BR_MUL((sx),q)); \
(tvp)->comp[C_SY] = renderer->state.cache.comp_offsets[C_SY] + \
BR_MUL(renderer->state.cache.comp_scales[C_SY], \
BR_MUL((sy),q)); \
(tvp)->comp[C_SZ] = renderer->state.cache.comp_offsets[C_SZ] + \
BR_MUL(renderer->state.cache.comp_scales[C_SZ], \
BR_MUL((sz),q)); \
}
#define PROJECT_VERTEX_WRITE_Q(tvp,sx,sy,sz,sw) \
{ \
(tvp)->comp[C_Q] = BR_DIV(S1,(sw)); \
(tvp)->comp[C_SX] = renderer->state.cache.comp_offsets[C_SX] + \
BR_MUL(renderer->state.cache.comp_scales[C_SX], \
BR_MUL((sx),(tvp)->comp[C_Q])); \
(tvp)->comp[C_SY] = renderer->state.cache.comp_offsets[C_SY] + \
BR_MUL(renderer->state.cache.comp_scales[C_SY], \
BR_MUL((sy),(tvp)->comp[C_Q])); \
(tvp)->comp[C_SZ] = renderer->state.cache.comp_offsets[C_SZ] + \
BR_MUL(renderer->state.cache.comp_scales[C_SZ], \
BR_MUL((sz),(tvp)->comp[C_Q])); \
}
/*
* Transform into screen space - Inline expanded BrMatrix4ApplyP()
*/
#define TRANSFORM_VERTEX(dest,src,mat) {\
(dest)->v[X] = BR_MAC3( \
(src)->v[X],(mat)->m[0][0], \
(src)->v[Y],(mat)->m[1][0], \
(src)->v[Z],(mat)->m[2][0]) + \
(mat)->m[3][0]; \
\
(dest)->v[Y] = BR_MAC3( \
(src)->v[X],(mat)->m[0][1], \
(src)->v[Y],(mat)->m[1][1], \
(src)->v[Z],(mat)->m[2][1]) + \
(mat)->m[3][1]; \
\
(dest)->v[Z] = BR_MAC3( \
(src)->v[X],(mat)->m[0][2], \
(src)->v[Y],(mat)->m[1][2], \
(src)->v[Z],(mat)->m[2][2]) + \
(mat)->m[3][2]; \
\
(dest)->v[W] = BR_MAC3( \
(src)->v[X],(mat)->m[0][3], \
(src)->v[Y],(mat)->m[1][3], \
(src)->v[Z],(mat)->m[2][3]) + \
(mat)->m[3][3]; \
}
/*
* Alignment for block in scratch area
*/
#define SCRATCH_BOUNDARY 16
#define SCRATCH_ALIGN(x) (((x)+(SCRATCH_BOUNDARY-1)) & ~(SCRATCH_BOUNDARY-1))
/*
* Update MIN and MAX vertices' x,y
*/
#define UPDATE_BOUNDS(tv) { \
if((tv)->comp[C_SX] > scache.max.v[X]) scache.max.v[X] = (tv)->comp[C_SX]; \
if((tv)->comp[C_SX] < scache.min.v[X]) scache.min.v[X] = (tv)->comp[C_SX]; \
if((tv)->comp[C_SY] > scache.max.v[Y]) scache.max.v[Y] = (tv)->comp[C_SY]; \
if((tv)->comp[C_SY] < scache.min.v[Y]) scache.min.v[Y] = (tv)->comp[C_SY]; \
}
#if BASED_FIXED
#define PrimitiveStateRangesQuery PrimitiveStateRangesQueryX
#endif
#if BASED_FLOAT
#define PrimitiveStateRangesQuery PrimitiveStateRangesQueryF
#endif
/*
* The level below which the fixed specular power function is zero
*/
#define SPECULARPOW_CUTOFF BR_SCALAR(0.6172)
#ifdef __cplusplus
};
#endif
#endif