Browse Source

First implementation of dynamic world object (model) rendering.

Still very basic, with plenty of sorting and clipping issues.
master
Nico de Poel 3 years ago
parent
commit
fd77b80afc
  1. 4
      ps1bsp.h
  2. 79
      world.c

4
ps1bsp.h

@ -163,8 +163,8 @@ typedef struct ps1bsp_model_s
u_short nodeId0; u_short nodeId0;
u_short nodeId1; u_short nodeId1;
u_short nodeId2;
u_short nodeId3;
u_short firstFace;
u_short numFaces;
// Run-time data // Run-time data
const struct ps1bsp_model_s* nextModel; const struct ps1bsp_model_s* nextModel;

79
world.c

@ -144,12 +144,12 @@ static void world_drawface_textured(const world_t *world, const ps1bsp_face_t *f
const ps1bsp_texture_t *texture = &world->textures[face->textureId]; const ps1bsp_texture_t *texture = &world->textures[face->textureId];
const ps1bsp_polygon_t* poly = &world->polygons[face->firstPolygon]; const ps1bsp_polygon_t* poly = &world->polygons[face->firstPolygon];
u_char tess = face->flags & 3;
if (tess)
{
world_drawface_flat(world, face, &colors[tess - 1], ot);
return;
}
// u_char tess = face->flags & 3;
// if (tess)
// {
// world_drawface_flat(world, face, &colors[tess - 1], ot);
// return;
// }
if (face->flags & SURF_DRAWLIQUID) if (face->flags & SURF_DRAWLIQUID)
{ {
@ -232,11 +232,56 @@ static ps1bsp_face_t *world_sortFaces(const world_t *world, const ps1bsp_leaf_t
face->nextFace = firstFace; face->nextFace = firstFace;
firstFace = face; firstFace = face;
} }
// Draw models in this leaf
for (const ps1bsp_model_t* model = leaf->models; model != NULL; model = model->nextModel)
{
// Hmmm... either just draw all the faces in this model, or do the whole BSP sorting thing
// Guess we could call sortLeafs from here
// If we don't, things like tech doors which are concave might render improperly
ps1bsp_face_t* face = &world->faces[model->firstFace];
for (u_short faceIdx = 0; faceIdx < model->numFaces; ++faceIdx, ++face)
{
if (face->drawFrame == frameNum)
continue;
face->drawFrame = frameNum;
if (!world_cull_backface(world, face))
continue;
face->nextFace = firstFace;
firstFace = face;
}
}
} }
return firstFace; return firstFace;
} }
static void world_sortModels(const world_t *world)
{
for (u_short modelIdx = 1; modelIdx < world->numModels; ++modelIdx)
{
ps1bsp_model_t* model = (ps1bsp_model_t*)&world->models[modelIdx];
// TODO: refence leaf in model, update only when model moves
VECTOR pos;
pos.vx = model->origin.vx + model->boundingSphere.vx;
pos.vy = model->origin.vy + model->boundingSphere.vy;
pos.vz = model->origin.vz + model->boundingSphere.vz;
short leafIdx = world_leafAtPoint(world, &pos);
if (leafIdx >= 0)
{
ps1bsp_leaf_t *leaf = (ps1bsp_leaf_t*)&world->leaves[leafIdx];
model->nextModel = leaf->models;
leaf->models = model;
}
}
}
static ps1bsp_leaf_t *world_sortLeafs(const world_t *world, short startNode, u_char *pvs) static ps1bsp_leaf_t *world_sortLeafs(const world_t *world, short startNode, u_char *pvs)
{ {
short *nodeStack = (short*)(scratchpad + 256); // Place the node stack in fast RAM after the PVS data short *nodeStack = (short*)(scratchpad + 256); // Place the node stack in fast RAM after the PVS data
@ -266,6 +311,7 @@ static ps1bsp_leaf_t *world_sortLeafs(const world_t *world, short startNode, u_c
// Since we're traversing the BSP tree front-to-back, adding each leaf at the start sorts the list in back-to-front order // Since we're traversing the BSP tree front-to-back, adding each leaf at the start sorts the list in back-to-front order
ps1bsp_leaf_t *leaf = (ps1bsp_leaf_t*)&world->leaves[leafIdx]; ps1bsp_leaf_t *leaf = (ps1bsp_leaf_t*)&world->leaves[leafIdx];
leaf->nextLeaf = firstLeaf; leaf->nextLeaf = firstLeaf;
leaf->models = NULL;
firstLeaf = leaf; firstLeaf = leaf;
continue; continue;
} }
@ -333,21 +379,6 @@ static u_char *world_noVisData(const world_t *world, u_char **buffer)
return head; return head;
} }
static u_short world_leafAtPoint(const world_t *world, const VECTOR *point)
{
short nodeIdx = 0;
while (nodeIdx >= 0)
{
const ps1bsp_node_t *node = &world->nodes[nodeIdx];
const ps1bsp_plane_t *plane = &world->planes[node->planeId];
short dist = world_pointPlaneDist(point, plane);
nodeIdx = node->children[(dist > 0) ^ 1];
}
return ~nodeIdx;
}
void world_draw(const world_t *world) void world_draw(const world_t *world)
{ {
// The world doesn't move, so we just set the camera view-projection matrix // The world doesn't move, so we just set the camera view-projection matrix
@ -360,12 +391,14 @@ void world_draw(const world_t *world)
u_char *pvs = world_loadVisData(world, cam_leaf, &pvsbuf); u_char *pvs = world_loadVisData(world, cam_leaf, &pvsbuf);
//u_char *pvs = world_noVisData(world, &pvsbuf); //u_char *pvs = world_noVisData(world, &pvsbuf);
ps1bsp_leaf_t *firstLeaf = world_sortLeafs(world, world->models[0].nodeId0, pvs);
world_sortModels(world);
ps1bsp_face_t *firstFace = world_sortFaces(world, firstLeaf);
if (enableTexturing) if (enableTexturing)
world_drawface = &world_drawface_textured; world_drawface = &world_drawface_textured;
else else
world_drawface = &world_drawface_lit; world_drawface = &world_drawface_lit;
ps1bsp_leaf_t *firstLeaf = world_sortLeafs(world, world->models[0].nodeId0, pvs);
ps1bsp_face_t *firstFace = world_sortFaces(world, firstLeaf);
world_drawFaces(world, firstFace); world_drawFaces(world, firstFace);
} }
Loading…
Cancel
Save