brender-1997/3dfx/RENDFUNC.C
2022-05-03 14:31:40 -07:00

425 lines
10 KiB
C

/*
* Copyright (c) 1993-1995 Argonaut Technologies Limited. All rights reserved.
*
* Rendering hooks
*/
#include <math.h>
#include "drv.h"
#include "shortcut.h"
#include "brassert.h"
/* 1/w values don't need to be calculated in non-textured renderers if fogging
* isn't on. Since this saves 3 divides, even with the test it should be faster */
extern int fog_enabled;
/* Glide Vertex Structures: Notes
*
* All modes: x, y, 0 to screen resolution
* Gouraud or lit textures: r, g, b 0 to 255
* Alpha (blend or test) a 0 to 255
* Texture mapping sow, tow 0-255.0 on primary axis, aspect ratio on secondary, * oow
* Texture mapping oow 1.0 for non-perspective, else see below
* Fogging (by table) oow Not Clearly Defined. Doesn't Really Matter I think
* Z-buffer ooz 1.0 to 65535.0 (I think)
*
* BRender ignores scales for W, which goes from camera hither to yon
*/
/* Fixed vertex snapping: uses knowledge that BRender fixed point is 16.16 */
//#define FAST_SNAP_VERT(x) (BrFixedToFloat((x) & 0xfffff000))
/* Floating point vertex snapping */
// #define SNAP_VERT(v) ((float)((long)((v)*16))/16.0f)
/* Faster floating point vertex snapping: uses prescaling in match ranges */
#define SNAP_RECIP (0.0625f)
#ifndef WIN32
/* Have to use this for DOS */
#define SNAP_VERT(v) ((float)((long)(v)) * SNAP_RECIP)
#else
/* Even faster; a function that casts to int MUCH faster than MSVC's. This should
* probably subtract 0.5 to correct the result, but the accuracy is good enough
* anyway without it and it saves a couple of cycles. */
#pragma warning( disable : 4035 )
__inline int intCast(float f)
{
int result;
__asm{
fld f
fistp result
mov eax,dword ptr result
}
}
#pragma warning( default : 4035 )
#define SNAP_VERT(v) ((float)(intCast(v)) * SNAP_RECIP)
#endif
#define DEPTH_CONVERT(v) ((v)->comp_f[C_SZ])
#define FAST_W_DEPTH_CONVERT(v) ((v)->comp_f[C_Q])
//#define FAST_W_DEPTH_CONVERT(v) (1.0f / ((v)->comp_f[C_W]) )
extern float alpha_value;
void BR_ASM_CALL PointRender(brp_block *block, brp_vertex *a)
{
GrVertex vtx[1];
float oow;
vtx[0].x = SNAP_VERT(a->comp_f[C_SX]);
vtx[0].y = SNAP_VERT(a->comp_f[C_SY]);
vtx[0].ooz = DEPTH_CONVERT(a);
oow = FAST_W_DEPTH_CONVERT(a);
vtx[0].oow = oow;
vtx[0].tmuvtx[0].sow = a->comp_f[C_U]*oow;
vtx[0].tmuvtx[0].tow = a->comp_f[C_V]*oow;
/* Cover this both ways - inefficient, but simple */
vtx[0].r = a->comp_f[C_R];
vtx[0].g = a->comp_f[C_G];
vtx[0].b = a->comp_f[C_B];
grConstantColorValue4(alpha_value, a->comp_f[C_R], a->comp_f[C_G], a->comp_f[C_B]);
grDrawPoint(vtx+0);
}
void BR_ASM_CALL LineRender_Flat(brp_block *block, brp_vertex *a,brp_vertex *b)
{
GrVertex vtx[2];
float oow;
vtx[0].x = SNAP_VERT(a->comp_f[C_SX]);
vtx[0].y = SNAP_VERT(a->comp_f[C_SY]);
vtx[0].ooz = DEPTH_CONVERT(a);
oow = FAST_W_DEPTH_CONVERT(a);
vtx[0].oow = oow;
vtx[0].tmuvtx[0].sow = a->comp_f[C_U]*oow;
vtx[0].tmuvtx[0].tow = a->comp_f[C_V]*oow;
vtx[1].x = SNAP_VERT(b->comp_f[C_SX]);
vtx[1].y = SNAP_VERT(b->comp_f[C_SY]);
vtx[1].ooz = DEPTH_CONVERT(b);
oow = FAST_W_DEPTH_CONVERT(b);
vtx[1].oow = oow;
vtx[1].tmuvtx[0].sow = b->comp_f[C_U]*oow;
vtx[1].tmuvtx[0].tow = b->comp_f[C_V]*oow;
grConstantColorValue4(alpha_value, a->comp_f[C_R], a->comp_f[C_G], a->comp_f[C_B]);
grDrawLine(vtx+0, vtx+1);
}
void BR_ASM_CALL LineRender_Smooth(brp_block *block, brp_vertex *a,brp_vertex *b)
{
GrVertex vtx[2];
float oow;
vtx[0].x = SNAP_VERT(a->comp_f[C_SX]);
vtx[0].y = SNAP_VERT(a->comp_f[C_SY]);
vtx[0].ooz = DEPTH_CONVERT(a);
oow = FAST_W_DEPTH_CONVERT(a);
vtx[0].oow = oow;
vtx[0].tmuvtx[0].sow = a->comp_f[C_U]*oow;
vtx[0].tmuvtx[0].tow = a->comp_f[C_V]*oow;
vtx[0].r = a->comp_f[C_R];
vtx[0].g = a->comp_f[C_G];
vtx[0].b = a->comp_f[C_B];
vtx[1].x = SNAP_VERT(b->comp_f[C_SX]);
vtx[1].y = SNAP_VERT(b->comp_f[C_SY]);
vtx[1].ooz = DEPTH_CONVERT(b);
oow = FAST_W_DEPTH_CONVERT(b);
vtx[1].oow = oow;
vtx[1].tmuvtx[0].sow = b->comp_f[C_U]*oow;
vtx[1].tmuvtx[0].tow = b->comp_f[C_V]*oow;
vtx[1].r = b->comp_f[C_R];
vtx[1].g = b->comp_f[C_G];
vtx[1].b = b->comp_f[C_B];
grDrawLine(vtx+0, vtx+1);
}
/*
* Untextured, flat shaded
*/
void BR_ASM_CALL TriangleRender_Flat(brp_block *block, brp_vertex *a,brp_vertex *b,brp_vertex *c)
{
GrVertex vtx[3];
vtx[0].x = SNAP_VERT(a->comp_f[C_SX]);
vtx[0].y = SNAP_VERT(a->comp_f[C_SY]);
vtx[0].ooz = DEPTH_CONVERT(a);
vtx[1].x = SNAP_VERT(b->comp_f[C_SX]);
vtx[1].y = SNAP_VERT(b->comp_f[C_SY]);
vtx[1].ooz = DEPTH_CONVERT(b);
vtx[2].x = SNAP_VERT(c->comp_f[C_SX]);
vtx[2].y = SNAP_VERT(c->comp_f[C_SY]);
vtx[2].ooz = DEPTH_CONVERT(c);
if (fog_enabled) {
vtx[0].oow = FAST_W_DEPTH_CONVERT(a);
vtx[1].oow = FAST_W_DEPTH_CONVERT(b);
vtx[2].oow = FAST_W_DEPTH_CONVERT(c);
}
grConstantColorValue4(alpha_value, a->comp_f[C_R], a->comp_f[C_G], a->comp_f[C_B]);
grDrawTriangle(vtx+0, vtx+1, vtx+2);
}
/*
* Untextured, gouraud shaded
*/
void BR_ASM_CALL TriangleRender_Smooth(brp_block *block, brp_vertex *a,brp_vertex *b,brp_vertex *c)
{
GrVertex vtx[3];
vtx[0].x = SNAP_VERT(a->comp_f[C_SX]);
vtx[0].y = SNAP_VERT(a->comp_f[C_SY]);
vtx[0].ooz = DEPTH_CONVERT(a);
vtx[0].r = a->comp_f[C_R];
vtx[0].g = a->comp_f[C_G];
vtx[0].b = a->comp_f[C_B];
vtx[1].x = SNAP_VERT(b->comp_f[C_SX]);
vtx[1].y = SNAP_VERT(b->comp_f[C_SY]);
vtx[1].ooz = DEPTH_CONVERT(b);
vtx[1].r = b->comp_f[C_R];
vtx[1].g = b->comp_f[C_G];
vtx[1].b = b->comp_f[C_B];
vtx[2].x = SNAP_VERT(c->comp_f[C_SX]);
vtx[2].y = SNAP_VERT(c->comp_f[C_SY]);
vtx[2].ooz = DEPTH_CONVERT(c);
vtx[2].r = c->comp_f[C_R];
vtx[2].g = c->comp_f[C_G];
vtx[2].b = c->comp_f[C_B];
if (fog_enabled) {
vtx[0].oow = FAST_W_DEPTH_CONVERT(a);
vtx[1].oow = FAST_W_DEPTH_CONVERT(b);
vtx[2].oow = FAST_W_DEPTH_CONVERT(c);
}
grDrawTriangle(vtx+0, vtx+1, vtx+2);
}
/*
* Textured, unlit
*/
void BR_ASM_CALL TriangleRender_UnlitTextured(brp_block *block, brp_vertex *a,brp_vertex *b,brp_vertex *c)
{
GrVertex vtx[3];
float oow;
vtx[0].x = SNAP_VERT(a->comp_f[C_SX]);
vtx[0].y = SNAP_VERT(a->comp_f[C_SY]);
vtx[0].ooz = DEPTH_CONVERT(a);
oow = FAST_W_DEPTH_CONVERT(a);
vtx[0].oow = oow;
vtx[0].tmuvtx[0].sow = a->comp_f[C_U] * oow;
vtx[0].tmuvtx[0].tow = a->comp_f[C_V] * oow;
vtx[1].x = SNAP_VERT(b->comp_f[C_SX]);
vtx[1].y = SNAP_VERT(b->comp_f[C_SY]);
vtx[1].ooz = DEPTH_CONVERT(b);
oow = FAST_W_DEPTH_CONVERT(b);
vtx[1].oow = oow;
vtx[1].tmuvtx[0].sow = b->comp_f[C_U] * oow;
vtx[1].tmuvtx[0].tow = b->comp_f[C_V] * oow;
vtx[2].x = SNAP_VERT(c->comp_f[C_SX]);
vtx[2].y = SNAP_VERT(c->comp_f[C_SY]);
vtx[2].ooz = DEPTH_CONVERT(c);
oow = FAST_W_DEPTH_CONVERT(c);
vtx[2].oow = oow;
vtx[2].tmuvtx[0].sow = c->comp_f[C_U] * oow;
vtx[2].tmuvtx[0].tow = c->comp_f[C_V] * oow;
grDrawTriangle(vtx+0, vtx+1, vtx+2);
}
/*
* Textured, flat shaded
*/
void BR_ASM_CALL TriangleRender_FlatTextured(brp_block *block, brp_vertex *a,brp_vertex *b,brp_vertex *c)
{
GrVertex vtx[3];
float oow;
vtx[0].x = SNAP_VERT(a->comp_f[C_SX]);
vtx[0].y = SNAP_VERT(a->comp_f[C_SY]);
vtx[0].ooz = DEPTH_CONVERT(a);
oow = FAST_W_DEPTH_CONVERT(a);
vtx[0].oow = oow;
vtx[0].tmuvtx[0].sow = a->comp_f[C_U] * oow;
vtx[0].tmuvtx[0].tow = a->comp_f[C_V] * oow;
vtx[1].x = SNAP_VERT(b->comp_f[C_SX]);
vtx[1].y = SNAP_VERT(b->comp_f[C_SY]);
vtx[1].ooz = DEPTH_CONVERT(b);
oow = FAST_W_DEPTH_CONVERT(b);
vtx[1].oow = oow;
vtx[1].tmuvtx[0].sow = b->comp_f[C_U] * oow;
vtx[1].tmuvtx[0].tow = b->comp_f[C_V] * oow;
vtx[2].x = SNAP_VERT(c->comp_f[C_SX]);
vtx[2].y = SNAP_VERT(c->comp_f[C_SY]);
vtx[2].ooz = DEPTH_CONVERT(c);
oow = FAST_W_DEPTH_CONVERT(c);
vtx[2].oow = oow;
vtx[2].tmuvtx[0].sow = c->comp_f[C_U] * oow;
vtx[2].tmuvtx[0].tow = c->comp_f[C_V] * oow;
grConstantColorValue4(alpha_value, a->comp_f[C_R], a->comp_f[C_G], a->comp_f[C_B]);
grDrawTriangle(vtx+0, vtx+1, vtx+2);
}
/*
* Textured, gouraud shaded
*/
#if 0
void BR_ASM_CALL TriangleRender_SmoothTextured(brp_block *block, brp_vertex *a,brp_vertex *b,brp_vertex *c)
{
GrVertex vtx[3];
float oow; /* 1/w */
float oowc;
oowc = 1.0 / (a->comp_f[C_W] * b->comp_f[C_W] * c->comp_f[C_W]);
vtx[0].x = SNAP_VERT(a->comp_f[C_SX]);
vtx[0].y = SNAP_VERT(a->comp_f[C_SY]);
vtx[0].ooz = DEPTH_CONVERT(a);
oow = oowc * b->comp_f[C_W] * c->comp_f[C_W];
vtx[0].oow = oow;
vtx[0].tmuvtx[0].sow = a->comp_f[C_U] * oow;
vtx[0].tmuvtx[0].tow = a->comp_f[C_V] * oow;
vtx[0].r = a->comp_f[C_R];
vtx[0].g = a->comp_f[C_G];
vtx[0].b = a->comp_f[C_B];
vtx[1].x = SNAP_VERT(b->comp_f[C_SX]);
vtx[1].y = SNAP_VERT(b->comp_f[C_SY]);
vtx[1].ooz = DEPTH_CONVERT(b);
oow = oowc * a->comp_f[C_W] * c->comp_f[C_W];
vtx[1].oow = oow;
vtx[1].tmuvtx[0].sow = b->comp_f[C_U] * oow;
vtx[1].tmuvtx[0].tow = b->comp_f[C_V] * oow;
vtx[1].r = b->comp_f[C_R];
vtx[1].g = b->comp_f[C_G];
vtx[1].b = b->comp_f[C_B];
vtx[2].x = SNAP_VERT(c->comp_f[C_SX]);
vtx[2].y = SNAP_VERT(c->comp_f[C_SY]);
vtx[2].ooz = DEPTH_CONVERT(c);
oow = oowc * a->comp_f[C_W] * b->comp_f[C_W];
vtx[2].oow = oow;
vtx[2].tmuvtx[0].sow = c->comp_f[C_U] * oow;
vtx[2].tmuvtx[0].tow = c->comp_f[C_V] * oow;
vtx[2].r = c->comp_f[C_R];
vtx[2].g = c->comp_f[C_G];
vtx[2].b = c->comp_f[C_B];
grDrawTriangle(vtx+0, vtx+1, vtx+2);
}
#else
void BR_ASM_CALL TriangleRender_SmoothTextured(brp_block *block, brp_vertex *a,brp_vertex *b,brp_vertex *c)
{
GrVertex vtx[3];
float oow; /* 1/w */
vtx[0].x = SNAP_VERT(a->comp_f[C_SX]);
vtx[0].y = SNAP_VERT(a->comp_f[C_SY]);
vtx[0].ooz = DEPTH_CONVERT(a);
oow = FAST_W_DEPTH_CONVERT(a);
vtx[0].oow = oow;
vtx[0].tmuvtx[0].sow = a->comp_f[C_U] * oow;
vtx[0].tmuvtx[0].tow = a->comp_f[C_V] * oow;
vtx[0].r = a->comp_f[C_R];
vtx[0].g = a->comp_f[C_G];
vtx[0].b = a->comp_f[C_B];
vtx[1].x = SNAP_VERT(b->comp_f[C_SX]);
vtx[1].y = SNAP_VERT(b->comp_f[C_SY]);
vtx[1].ooz = DEPTH_CONVERT(b);
oow = FAST_W_DEPTH_CONVERT(b);
vtx[1].oow = oow;
vtx[1].tmuvtx[0].sow = b->comp_f[C_U] * oow;
vtx[1].tmuvtx[0].tow = b->comp_f[C_V] * oow;
vtx[1].r = b->comp_f[C_R];
vtx[1].g = b->comp_f[C_G];
vtx[1].b = b->comp_f[C_B];
vtx[2].x = SNAP_VERT(c->comp_f[C_SX]);
vtx[2].y = SNAP_VERT(c->comp_f[C_SY]);
vtx[2].ooz = DEPTH_CONVERT(c);
oow = FAST_W_DEPTH_CONVERT(c);
vtx[2].oow = oow;
vtx[2].tmuvtx[0].sow = c->comp_f[C_U] * oow;
vtx[2].tmuvtx[0].tow = c->comp_f[C_V] * oow;
vtx[2].r = c->comp_f[C_R];
vtx[2].g = c->comp_f[C_G];
vtx[2].b = c->comp_f[C_B];
grDrawTriangle(vtx+0, vtx+1, vtx+2);
}
#endif