361 lines
9.4 KiB
C
361 lines
9.4 KiB
C
/*
|
|
* Copyright (c) 1993-1995 Argonaut Technologies Limited. All rights reserved.
|
|
*
|
|
* $Id: prepmatl.c 2.20 1997/07/03 11:13:23 ALISTAIR Exp ALISTAIR $
|
|
* $Locker: ALISTAIR $
|
|
*
|
|
* Precompute information for materials
|
|
Last change: TN 11 Apr 97 12:22 pm
|
|
*/
|
|
#include "v1db.h"
|
|
#include "brassert.h"
|
|
#include "shortcut.h"
|
|
|
|
BR_RCS_ID("$Id: prepmatl.c 2.20 1997/07/03 11:13:23 ALISTAIR Exp ALISTAIR $")
|
|
|
|
/*
|
|
* Mask of renderer state parts that materials are mapped to
|
|
*/
|
|
#define PARTS_MASK (BR_STATE_SURFACE | BR_STATE_PRIMITIVE | BR_STATE_CULL)
|
|
|
|
void BR_PUBLIC_ENTRY BrMaterialUpdate(br_material *mat, br_uint_16 flags)
|
|
{
|
|
br_token_value tva[64], *tvp;
|
|
br_token t;
|
|
br_int_32 c;
|
|
|
|
/*
|
|
* Make sure there is is renderer
|
|
*/
|
|
if(v1db.renderer == NULL)
|
|
return;
|
|
|
|
/*
|
|
* Save current state and setup default
|
|
*/
|
|
RendererStatePush(v1db.renderer, (br_uint_32)PARTS_MASK);
|
|
RendererStateDefault(v1db.renderer, (br_uint_32)PARTS_MASK);
|
|
|
|
/*
|
|
* If there is an existing state, restore it into renderer
|
|
*/
|
|
if(mat->stored)
|
|
RendererStateRestore(v1db.renderer, mat->stored, (br_uint_32)PARTS_MASK);
|
|
|
|
/*
|
|
* Translate material into state
|
|
*/
|
|
|
|
if(flags & BR_MATU_MAP_TRANSFORM)
|
|
RendererPartSet(v1db.renderer, BRT_SURFACE, 0, BRT_AS_MATRIX23_SCALAR(MAP_MATRIX), (br_uint_32)&mat->map_transform);
|
|
|
|
if(flags & BR_MATU_RENDERING) {
|
|
tvp = tva;
|
|
|
|
tvp->t = BRT_COLOUR_RGB;
|
|
tvp->v.rgb = mat->colour;
|
|
tvp++;
|
|
|
|
tvp->t = BRT_AS_SCALAR(OPACITY);
|
|
tvp->v.s = BR_DIV(BrIntToScalar(mat->opacity),BR_SCALAR(255.0));
|
|
tvp++;
|
|
|
|
tvp->t = BRT_MODULATE_B;
|
|
tvp->v.b = !!(mat->flags & (BR_MATF_LIGHT | BR_MATF_PRELIT));
|
|
tvp++;
|
|
|
|
tvp->t = BRT_BLEND_B;
|
|
tvp->v.b = (mat->opacity < 255);
|
|
tvp++;
|
|
|
|
tvp->t = BRT_SMOOTH_B;
|
|
#if 1 // Kludging flat shading for <REDACTEDGAME>
|
|
tvp->v.b = BR_TRUE;
|
|
#else
|
|
tvp->v.b = !!(mat->flags & BR_MATF_SMOOTH);
|
|
#endif
|
|
tvp++;
|
|
|
|
tvp->t = BRT_ZTRANSPARENCY_B;
|
|
tvp->v.b = !!(mat->flags & BR_MATF_ZTRANSPARENCY);
|
|
tvp++;
|
|
|
|
if((mat->flags & BR_MATF_SUBDIVIDE)){
|
|
tvp->t = BRT_PERSPECTIVE_T;
|
|
tvp->v.t = BRT_SUBDIVIDE;
|
|
tvp++;
|
|
tvp->t = BRT_SUBDIVIDE_TOLERANCE_I32;
|
|
tvp->v.i32 = mat->subdivide_tolerance;
|
|
tvp++;
|
|
} else {
|
|
tvp->t = BRT_PERSPECTIVE_B;
|
|
tvp->v.b = !!(mat->flags & BR_MATF_PERSPECTIVE);
|
|
tvp++;
|
|
}
|
|
|
|
tvp->t = BRT_DECAL_B;
|
|
tvp->v.b = !!(mat->flags & BR_MATF_DECAL);
|
|
tvp++;
|
|
|
|
tvp->t = BRT_DITHER_MAP_B;
|
|
tvp->v.b = !!(mat->flags & BR_MATF_DITHER);
|
|
tvp++;
|
|
|
|
tvp->t = BRT_DITHER_COLOUR_B;
|
|
tvp->v.b = !!(mat->flags & BR_MATF_DITHER);
|
|
tvp++;
|
|
|
|
tvp->t = BRT_INDEX_BASE_I32;
|
|
tvp->v.i32 = mat->index_base;
|
|
tvp++;
|
|
|
|
tvp->t = BRT_INDEX_RANGE_I32;
|
|
tvp->v.i32 = mat->index_range;
|
|
tvp++;
|
|
|
|
tvp->t = BRT_ANTIALIASING_T;
|
|
tvp->v.t = (mat->flags_ext & BR_MATFX_EDGE_ANTIALIASING)?BRT_DEFAULT:BRT_NONE;
|
|
tvp++;
|
|
|
|
tvp->t = BRT_MAP_ANTIALIASING_T;
|
|
tvp->v.t = (mat->flags & BR_MATF_MAP_ANTIALIASING)?BRT_LINEAR:BRT_NONE;
|
|
tvp++;
|
|
|
|
tvp->t = BRT_MAP_INTERPOLATION_T;
|
|
tvp->v.t = (mat->flags & BR_MATF_MAP_INTERPOLATION)?BRT_LINEAR:BRT_NONE;
|
|
tvp++;
|
|
|
|
tvp->t = BRT_MIP_INTERPOLATION_T;
|
|
tvp->v.t = (mat->flags & BR_MATF_MIP_INTERPOLATION)?BRT_LINEAR:BRT_NONE;
|
|
tvp++;
|
|
|
|
// Texture map wrapping.
|
|
tvp->t = BRT_MAP_WIDTH_LIMIT_T;
|
|
tvp->v.t = BRT_WRAP;
|
|
if (mat->flags_ext & BR_MATFX_TEXTURE0_MIRRORED_U) tvp->v.t = BRT_MIRROR;
|
|
if (mat->flags_ext & BR_MATFX_TEXTURE0_CLAMPED_U) tvp->v.t = BRT_CLAMP;
|
|
tvp++;
|
|
|
|
tvp->t = BRT_MAP_HEIGHT_LIMIT_T;
|
|
tvp->v.t = BRT_WRAP;
|
|
if (mat->flags_ext & BR_MATFX_TEXTURE0_MIRRORED_V) tvp->v.t = BRT_MIRROR;
|
|
if (mat->flags_ext & BR_MATFX_TEXTURE0_CLAMPED_V) tvp->v.t = BRT_CLAMP;
|
|
tvp++;
|
|
|
|
tvp->t = BRT_FOG_B;
|
|
tvp->v.b = !!(mat->flags & BR_MATF_FOG_LOCAL);
|
|
tvp++;
|
|
|
|
tvp->t = BRT_FOG_T;
|
|
tvp->v.t = (mat->flags & BR_MATF_FOG_LOCAL)?BRT_LINEAR:BRT_NONE;
|
|
tvp++;
|
|
|
|
if((mat->flags & BR_MATF_FOG_LOCAL)){
|
|
tvp->t = BRT_AS_SCALAR(FOG_MIN);
|
|
tvp->v.s = mat->fog_min;
|
|
tvp++;
|
|
tvp->t = BRT_AS_SCALAR(FOG_MAX);
|
|
tvp->v.s = mat->fog_max;
|
|
tvp++;
|
|
tvp->t = BRT_FOG_RGB;
|
|
tvp->v.rgb = mat->fog_colour;
|
|
tvp++;
|
|
tvp->t = BRT_FOG_SCALE_U8;
|
|
tvp->v.u8 = mat->opacity;
|
|
tvp++;
|
|
tvp->t = BRT_USE_CONSTANT_FOG_B;
|
|
tvp->v.b = !!(mat->flags_ext & BR_MATFX_CONSTANT_FOG);
|
|
tvp++;
|
|
}
|
|
|
|
tvp->t = BRT_Z_WRITE_T;
|
|
switch(mat->zbuffer_mode) {
|
|
case BR_MATZM_STANDARD: tvp->v.t = BRT_Z_WRITE_CONDITIONAL; break;
|
|
case BR_MATZM_ALWAYS_WRITE: tvp->v.t = BRT_Z_WRITE_ALWAYS; break;
|
|
case BR_MATZM_DONT_WRITE: tvp->v.t = BRT_Z_WRITE_CONDITIONAL_NO_Z; break;
|
|
case BR_MATZM_OFF: tvp->v.t = BRT_Z_WRITE_NEVER; break;
|
|
default: tvp->v.t = BRT_Z_WRITE_CONDITIONAL;
|
|
}
|
|
tvp++;
|
|
|
|
tvp->t = BRT_DEPTH_TEST_T;
|
|
switch(mat->zbuffer_compare) {
|
|
case BR_MATZC_LT: tvp->v.t = BRT_LESS; break;
|
|
case BR_MATZC_GT: tvp->v.t = BRT_GREATER; break;
|
|
case BR_MATZC_LE: tvp->v.t = BRT_LESS_OR_EQUAL; break;
|
|
case BR_MATZC_GE: tvp->v.t = BRT_GREATER_OR_EQUAL; break;
|
|
case BR_MATZC_EQ: tvp->v.t = BRT_EQUAL; break;
|
|
case BR_MATZC_NE: tvp->v.t = BRT_NOT_EQUAL; break;
|
|
default: tvp->v.t = BRT_LESS;
|
|
}
|
|
tvp++;
|
|
|
|
tvp->t = BRT_BLEND_MODE_T;
|
|
switch(mat->alpha_mode) {
|
|
case BR_MATB_NONE: tvp->v.t = BRT_NONE; break;
|
|
case BR_MATB_INTENSITY_REDUCTION: tvp->v.t = BRT_INTENSITY_REDUCTION; break;
|
|
case BR_MATB_COMPOSITING_WITH_REDUCTION: tvp->v.t = BRT_COMPOSITING_WITH_REDUCTION; break;
|
|
case BR_MATB_STANDARD_BLEND: tvp->v.t = BRT_STANDARD_BLEND; break;
|
|
case BR_MATB_COMPOSITING: tvp->v.t = BRT_COMPOSITING; break;
|
|
case BR_MATB_COMPOSITING_WITH_INCREASE: tvp->v.t = BRT_COMPOSITING_WITH_INCREASE; break;
|
|
default: tvp->v.t = BRT_NONE;
|
|
}
|
|
tvp++;
|
|
|
|
|
|
tvp->t = BR_NULL_TOKEN;
|
|
|
|
RendererPartSetMany(v1db.renderer, BRT_PRIMITIVE, 0, tva, &c);
|
|
|
|
t = BRT_ONE_SIDED;
|
|
|
|
if(mat->flags & BR_MATF_ALWAYS_VISIBLE)
|
|
t = BRT_NONE;
|
|
|
|
if(mat->flags & BR_MATF_TWO_SIDED)
|
|
t = BRT_TWO_SIDED;
|
|
|
|
RendererPartSet(v1db.renderer, BRT_CULL, 0, BRT_TYPE_T, t);
|
|
}
|
|
|
|
if(flags & BR_MATU_LIGHTING) {
|
|
tvp = tva;
|
|
|
|
tvp->t = BRT_COLOUR_RGB;
|
|
tvp->v.rgb = mat->colour;
|
|
tvp++;
|
|
|
|
tvp->t = BRT_AS_SCALAR(OPACITY);
|
|
tvp->v.s = BR_DIV(BrIntToScalar(mat->opacity),BR_SCALAR(255.0));
|
|
tvp++;
|
|
|
|
tvp->t = BRT_AS_SCALAR(AMBIENT);
|
|
tvp->v.s = BrUFractionToScalar(mat->ka);
|
|
tvp++;
|
|
|
|
tvp->t = BRT_AS_SCALAR(DIFFUSE);
|
|
tvp->v.s = BrUFractionToScalar(mat->kd);
|
|
tvp++;
|
|
|
|
tvp->t = BRT_AS_SCALAR(SPECULAR);
|
|
tvp->v.s = BrUFractionToScalar(mat->ks);
|
|
tvp++;
|
|
|
|
tvp->t = BRT_AS_SCALAR(SPECULAR_POWER);
|
|
tvp->v.s = mat->power;
|
|
tvp++;
|
|
|
|
tvp->t = BRT_AS_SCALAR(AMBIENT_R);
|
|
tvp->v.s = BR_MUL(BrFixedToScalar(BR_RED(mat->ambient_colour) << 8),BrFixedToScalar(BR_RED(mat->colour) << 8));
|
|
tvp++;
|
|
|
|
tvp->t = BRT_AS_SCALAR(AMBIENT_G);
|
|
tvp->v.s = BR_MUL(BrFixedToScalar(BR_GRN(mat->ambient_colour) << 8),BrFixedToScalar(BR_GRN(mat->colour) << 8));
|
|
tvp++;
|
|
|
|
tvp->t = BRT_AS_SCALAR(AMBIENT_B);
|
|
tvp->v.s = BR_MUL(BrFixedToScalar(BR_BLU(mat->ambient_colour) << 8),BrFixedToScalar(BR_BLU(mat->colour) << 8));
|
|
tvp++;
|
|
|
|
tvp->t = BRT_LIGHTING_B;
|
|
if(mat->flags & BR_MATF_PRELIT)
|
|
tvp->v.b = BR_FALSE;
|
|
else
|
|
tvp->v.b = !!(mat->flags & BR_MATF_LIGHT);
|
|
tvp++;
|
|
|
|
tvp->t = BRT_FORCE_FRONT_B;
|
|
tvp->v.b = !!(mat->flags & BR_MATF_FORCE_FRONT);
|
|
tvp++;
|
|
|
|
tvp->t = BRT_FORCE_BACK_B;
|
|
tvp->v.b = !!(mat->flags & BR_MATF_FORCE_BACK);
|
|
tvp++;
|
|
|
|
tvp->t = BRT_COLOUR_SOURCE_T;
|
|
tvp->v.t = (mat->flags & BR_MATF_PRELIT)?BRT_GEOMETRY:BRT_SURFACE;
|
|
tvp++;
|
|
|
|
tvp->t = BRT_MAPPING_SOURCE_T;
|
|
tvp->v.t = BRT_GEOMETRY_MAP;
|
|
|
|
if(mat->flags & (BR_MATF_ENVIRONMENT_L))
|
|
tvp->v.t = BRT_ENVIRONMENT_LOCAL;
|
|
|
|
if(mat->flags & (BR_MATF_ENVIRONMENT_I))
|
|
tvp->v.t = BRT_ENVIRONMENT_INFINITE;
|
|
|
|
if(mat->flags & (BR_MATF_QUAD_MAPPING))
|
|
tvp->v.t = BRT_QUAD;
|
|
|
|
tvp++;
|
|
|
|
tvp->t = BR_NULL_TOKEN;
|
|
|
|
RendererPartSetMany(v1db.renderer, BRT_SURFACE, 0, tva, &c);
|
|
}
|
|
|
|
if(flags & BR_MATU_COLOURMAP) {
|
|
tvp = tva;
|
|
|
|
tvp->t = BRT_COLOUR_MAP_O;
|
|
tvp->v.o = mat->colour_map?mat->colour_map->stored:NULL;
|
|
tvp++;
|
|
|
|
tvp->t = BRT_INDEX_SHADE_O;
|
|
tvp->v.o = mat->index_shade?mat->index_shade->stored:NULL;
|
|
tvp++;
|
|
|
|
tvp->t = BRT_INDEX_BLEND_O;
|
|
tvp->v.o = mat->index_blend?mat->index_blend->stored:NULL;
|
|
tvp++;
|
|
|
|
tvp->t = BRT_INDEX_FOG_O;
|
|
tvp->v.o = mat->index_fog?mat->index_fog->stored:NULL;
|
|
tvp++;
|
|
|
|
tvp->t = BR_NULL_TOKEN;
|
|
RendererPartSetMany(v1db.renderer, BRT_PRIMITIVE, 0, tva, &c);
|
|
}
|
|
|
|
if(flags & BR_MATU_SCREENDOOR) {
|
|
tvp = tva;
|
|
tvp->t = BRT_SCREEN_DOOR_O;
|
|
tvp->v.o = mat->screendoor?mat->screendoor->stored:NULL;
|
|
tvp++;
|
|
|
|
tvp->t = BR_NULL_TOKEN;
|
|
RendererPartSetMany(v1db.renderer, BRT_PRIMITIVE, 0, tva, &c);
|
|
}
|
|
|
|
if(flags & BR_MATU_EXTRA_SURF && mat->extra_surf)
|
|
RendererPartSetMany(v1db.renderer, BRT_SURFACE, 0, mat->extra_surf, &c);
|
|
|
|
if(flags & BR_MATU_EXTRA_PRIM && mat->extra_prim)
|
|
RendererPartSetMany(v1db.renderer, BRT_PRIMITIVE, 0, mat->extra_prim, &c);
|
|
|
|
/*
|
|
* If there was no previous state, create new one, otherwise, update existing state
|
|
*/
|
|
if(mat->stored)
|
|
RendererStateSave(v1db.renderer, mat->stored, (br_uint_32)PARTS_MASK);
|
|
else
|
|
RendererStateStoredNew(v1db.renderer, (br_renderer_state_stored **)&mat->stored, (br_uint_32)PARTS_MASK, NULL);
|
|
|
|
/*
|
|
* Restore previous state
|
|
*/
|
|
RendererStatePop(v1db.renderer, (br_uint_32)PARTS_MASK);
|
|
}
|
|
|
|
void BrMaterialClear(br_material *mat)
|
|
{
|
|
/*
|
|
* Free up an allocated state
|
|
*/
|
|
if(mat->stored == NULL)
|
|
return;
|
|
|
|
ObjectFree(mat->stored);
|
|
mat->stored = NULL;
|
|
}
|