Compare commits

...

1 Commits

Author SHA1 Message Date
Nico de Poel 0c0de31b78 Experimenting with tessellation subdivision formula: 3 years ago
  1. 7
      qmath.h
  2. BIN
      test.ps1bsp
  3. 42
      world.c

7
qmath.h

@ -17,4 +17,11 @@ INLINE short m_pointPlaneDist2(const VECTOR point2, const SVECTOR normal12, int
return (short)(x + y + z - dist2);
}
INLINE void m_lightColor(const CVECTOR *color, short light, CVECTOR *outColor)
{
outColor->r = (uint8_t)((light * color->r) >> 8);
outColor->g = (uint8_t)((light * color->g) >> 8);
outColor->b = (uint8_t)((light * color->b) >> 8);
}
#endif // __QMATH_H__

BIN
test.ps1bsp

42
world.c

@ -22,6 +22,8 @@ static CVECTOR colors[] =
};
static const int numColors = sizeof(colors) / sizeof(CVECTOR);
CVECTOR color_white = { 255, 255, 255 };
// Set data pointers directly from an in-memory byte buffer
#define LOAD_CHUNK(type, dst, num, src, entry) \
dst = (type*)((src) + (entry).offset); \
@ -49,7 +51,7 @@ void world_load(const u_long *data, world_t *world)
LOAD_CHUNK(u_char, world->visData, world->numVisData, bytes, header->visData);
}
static INLINE void drawface_triangle_fan(const ps1bsp_face_t *face, SVECTOR *vecs)
static INLINE void drawface_triangle_fan(const ps1bsp_face_t *face, SVECTOR *vecs, CVECTOR *color)
{
int p;
@ -80,16 +82,16 @@ static INLINE void drawface_triangle_fan(const ps1bsp_face_t *face, SVECTOR *vec
setPolyG3(poly);
gte_stsxy3_g3(poly);
poly->r0 = poly->g0 = poly->b0 = (uint8_t)v0->pad;
poly->r1 = poly->g1 = poly->b1 = (uint8_t)v1->pad;
poly->r2 = poly->g2 = poly->b2 = (uint8_t)v2->pad;
m_lightColor(color, v0->pad, (CVECTOR*)&poly->r0);
m_lightColor(color, v1->pad, (CVECTOR*)&poly->r1);
m_lightColor(color, v2->pad, (CVECTOR*)&poly->r2);
addPrim(curOT + depth, poly);
++polyCount;
}
}
static INLINE void drawface_triangle_strip(const ps1bsp_face_t *face, SVECTOR *vecs)
static INLINE void drawface_triangle_strip(const ps1bsp_face_t *face, SVECTOR *vecs, CVECTOR *color)
{
int p;
@ -136,16 +138,16 @@ static INLINE void drawface_triangle_strip(const ps1bsp_face_t *face, SVECTOR *v
setPolyG3(poly);
gte_stsxy3_g3(poly);
poly->r0 = poly->g0 = poly->b0 = (uint8_t)v0->pad;
poly->r1 = poly->g1 = poly->b1 = (uint8_t)v1->pad;
poly->r2 = poly->g2 = poly->b2 = (uint8_t)v2->pad;
m_lightColor(color, v0->pad, (CVECTOR*)&poly->r0);
m_lightColor(color, v1->pad, (CVECTOR*)&poly->r1);
m_lightColor(color, v2->pad, (CVECTOR*)&poly->r2);
addPrim(curOT + depth, poly);
++polyCount;
}
}
static INLINE void drawface_quad_strip(const ps1bsp_face_t *face, SVECTOR *vecs)
static INLINE void drawface_quad_strip(const ps1bsp_face_t *face, SVECTOR *vecs, CVECTOR *color)
{
int p;
@ -193,10 +195,10 @@ static INLINE void drawface_quad_strip(const ps1bsp_face_t *face, SVECTOR *vecs)
gte_rtps();
gte_stsxy(&poly->x3);
poly->r0 = poly->g0 = poly->b0 = (uint8_t)v0->pad;
poly->r1 = poly->g1 = poly->b1 = (uint8_t)v1->pad;
poly->r2 = poly->g2 = poly->b2 = (uint8_t)v2->pad;
poly->r3 = poly->g3 = poly->b3 = (uint8_t)v3->pad;
m_lightColor(color, v0->pad, (CVECTOR*)&poly->r0);
m_lightColor(color, v1->pad, (CVECTOR*)&poly->r1);
m_lightColor(color, v2->pad, (CVECTOR*)&poly->r2);
m_lightColor(color, v3->pad, (CVECTOR*)&poly->r3);
addPrim(curOT + depth, poly);
++polyCount;
@ -237,6 +239,16 @@ static void world_drawface(const world_t *world, const ps1bsp_face_t *face)
if ((dot >= 0) ^ face->side)
return;
// Experimenting with tessellation levels
dot = abs(dot) / center.pad;// for a more stable albeit less accurate result, divide by a fixed value of 160
char tess;
if (dot < 4)
tess = 0;
else if (dot < 12)
tess = 1;
else
tess = 2;
SVECTOR *vecs = (SVECTOR*)(scratchpad + 256);
// Copy this face's vertices into scratch RAM for fast reuse
@ -250,9 +262,9 @@ static void world_drawface(const world_t *world, const ps1bsp_face_t *face)
}
if (face->numFaceVertices == 3) // Special case: draw single triangles using the simplest method
drawface_triangle_fan(face, vecs);
drawface_triangle_fan(face, vecs, &colors[tess]);
else
drawface_quad_strip(face, vecs);
drawface_quad_strip(face, vecs, &colors[tess]);
}
static void world_drawnode(const world_t *world, short nodeIdx, u_char *pvs)

Loading…
Cancel
Save