/* ================ R_DrawSubmodelPolygons All in one leaf ================ */ void R_DrawSubmodelPolygons(mmodel_t *pmodel, int clipflags, mnode_t *topnode) { int i; vec_t dot; mface_t *psurf; int numsurfaces; cplane_t *pplane; // FIXME: use bounding-box-based frustum clipping info? psurf = pmodel->firstface; numsurfaces = pmodel->numfaces; for (i = 0; i < numsurfaces; i++, psurf++) { // find which side of the node we are on pplane = psurf->plane; dot = PlaneDiff(modelorg, pplane); // draw the polygon if (((psurf->drawflags & DSURF_PLANEBACK) && (dot < -BACKFACE_EPSILON)) || (!(psurf->drawflags & DSURF_PLANEBACK) && (dot > BACKFACE_EPSILON))) { r_currentkey = ((mleaf_t *)topnode)->key; // FIXME: use bounding-box-based frustum clipping info? R_RenderFace(psurf, clipflags); } } }
void R_DrawSubmodelPolygonsFPM (model_FPM_t *pmodel, int clipflags) { int i; fixedpoint_t dot; msurface_FPM_t *psurf; int numsurfaces; mplane_FPM_t *pplane; // FIXME: use bounding-box-based frustum clipping info? psurf = &pmodel->surfaces[pmodel->firstmodelsurface]; numsurfaces = pmodel->nummodelsurfaces; for (i=0 ; i<numsurfaces ; i++, psurf++) { // find which side of the node we are on pplane = psurf->plane; dot = FPM_SUB(DotProductFPM (modelorgFPM, pplane->normal), pplane->dist); // draw the polygon if (((psurf->flags & SURF_PLANEBACK) && (dot < -BACKFACE_EPSILON)) || (!(psurf->flags & SURF_PLANEBACK) && (dot > BACKFACE_EPSILON))) { r_currentkey = ((mleaf_FPM_t *)currententityFPM->topnode)->key; // FIXME: use bounding-box-based frustum clipping info? // R_RenderFaceFPM (psurf, clipflags); // FPM doesn't exist R_RenderFace (psurf, clipflags); } } }
/* ================ R_DrawSubmodelPolygons ================ */ void R_DrawSubmodelPolygons(const entity_t *e, model_t *pmodel, int clipflags) { int i; msurface_t *psurf; int numsurfaces; // FIXME: use bounding-box-based frustum clipping info? psurf = &pmodel->surfaces[pmodel->firstmodelsurface]; numsurfaces = pmodel->nummodelsurfaces; for (i = 0; i < numsurfaces; i++, psurf++) { if (psurf->clipflags == BMODEL_FULLY_CLIPPED) continue; r_currentkey = ((mleaf_t *)e->topnode)->key; R_RenderFace(e, psurf, clipflags); } }
/* ================ R_EmitSkyBox ================ */ qboolean R_EmitSkyBox (void) { int i, j; int oldkey; if (insubmodel) return false; if (r_skyframe == r_framecount) return true; if (!*skyname) return false; r_skyframe = r_framecount; for (i=0 ; i<8 ; i++) for (j=0 ; j<3 ; j++) r_skyverts[i].position[j] = r_origin[j] + box_verts[i][j]*128; for (i=0 ; i<6 ; i++) if (skybox_planes[i*2+1] > 0) r_skyplanes[i].dist = r_origin[skybox_planes[i*2]]+128; else r_skyplanes[i].dist = r_origin[skybox_planes[i*2]]-128; for (i=0 ; i<6 ; i++) { r_skytexinfo[i].vecs[0][3] = -DotProduct (r_origin, r_skytexinfo[i].vecs[0]); r_skytexinfo[i].vecs[1][3] = -DotProduct (r_origin, r_skytexinfo[i].vecs[1]); } oldkey = r_currentkey; r_currentkey = 0x7ffffff0; for (i=0 ; i<6 ; i++) { R_RenderFace (r_skyfaces + i, 15); } r_currentkey = oldkey; return true; }
/* ================ R_EmitSkyBox ================ */ void R_EmitSkyBox (void) { int i, j; int oldkey; if (insubmodel) return; // submodels should never have skies if (r_skyframe == r_framecount) return; // already set this frame r_skyframe = r_framecount; // set the eight fake vertexes for (i=0 ; i<8 ; i++) for (j=0 ; j<3 ; j++) r_skyverts[i].position[j] = r_origin[j] + box_verts[i][j]*128; // set the six fake planes for (i=0 ; i<6 ; i++) if (skybox_planes[i*2+1] > 0) r_skyplanes[i].dist = r_origin[skybox_planes[i*2]]+128; else r_skyplanes[i].dist = r_origin[skybox_planes[i*2]]-128; // fix texture offseets for (i=0 ; i<6 ; i++) { r_skytexinfo[i].vecs[0][3] = -DotProduct (r_origin, r_skytexinfo[i].vecs[0]); r_skytexinfo[i].vecs[1][3] = -DotProduct (r_origin, r_skytexinfo[i].vecs[1]); } // emit the six faces oldkey = r_currentkey; r_currentkey = 0x7ffffff0; for (i=0 ; i<6 ; i++) { R_RenderFace (r_skyfaces + i, 15); } r_currentkey = oldkey; // bsp sorting order }
/* ================ R_RecursiveWorldNode ================ */ static void R_RecursiveWorldNode(mnode_t *node, int clipflags) { int i, c, side, *pindex; vec3_t acceptpt, rejectpt; cplane_t *plane; mface_t *surf, **mark; float d, dot; mleaf_t *pleaf; while (node->visframe == r_visframecount) { // cull the clipping planes if not trivial accept // FIXME: the compiler is doing a lousy job of optimizing here; it could be // twice as fast in ASM if (clipflags) { for (i = 0; i < 4; i++) { if (!(clipflags & (1 << i))) continue; // don't need to clip against it // generate accept and reject points // FIXME: do with fast look-ups or integer tests based on the sign bit // of the floating point values pindex = pfrustum_indexes[i]; rejectpt[0] = (float)node->minmaxs[pindex[0]]; rejectpt[1] = (float)node->minmaxs[pindex[1]]; rejectpt[2] = (float)node->minmaxs[pindex[2]]; d = PlaneDiff(rejectpt, &view_clipplanes[i]); if (d <= 0) return; acceptpt[0] = (float)node->minmaxs[pindex[3 + 0]]; acceptpt[1] = (float)node->minmaxs[pindex[3 + 1]]; acceptpt[2] = (float)node->minmaxs[pindex[3 + 2]]; d = PlaneDiff(acceptpt, &view_clipplanes[i]); if (d >= 0) clipflags &= ~(1 << i); // node is entirely on screen } } c_drawnode++; // if a leaf node, draw stuff if (!node->plane) { pleaf = (mleaf_t *)node; if (pleaf->contents == CONTENTS_SOLID) return; // solid // check for door connected areas if (r_newrefdef.areabits) { if (! Q_IsBitSet(r_newrefdef.areabits, pleaf->area)) return; // not visible } mark = pleaf->firstleafface; c = pleaf->numleaffaces; if (c) { do { (*mark)->drawframe = r_framecount; mark++; } while (--c); } pleaf->key = r_currentkey; r_currentkey++; // all bmodels in a leaf share the same key return; } // node is just a decision point, so go down the apropriate sides // find which side of the node we are on plane = node->plane; dot = PlaneDiffFast(modelorg, plane); if (dot >= 0) side = 0; else side = 1; // recurse down the children, front side first R_RecursiveWorldNode(node->children[side], clipflags); // draw stuff c = node->numfaces; if (c) { surf = node->firstface; if (dot < -BACKFACE_EPSILON) { do { if ((surf->drawflags & DSURF_PLANEBACK) && (surf->drawframe == r_framecount)) { R_RenderFace(surf, clipflags); } surf++; } while (--c); } else if (dot > BACKFACE_EPSILON) { do { if (!(surf->drawflags & DSURF_PLANEBACK) && (surf->drawframe == r_framecount)) { R_RenderFace(surf, clipflags); } surf++; } while (--c); } // all surfaces on the same node share the same sequence number r_currentkey++; } // recurse down the back side node = node->children[side ^ 1]; } }
/* ================ R_RecursiveWorldNode ================ */ void R_RecursiveWorldNode (mnode_t *node, int clipflags) { int i, c, side, *pindex; mplane_t *plane; msurface_t *surf, **mark; mleaf_t *pleaf; double dot; #ifdef USE_PQ_OPT1 int d_fxp; #else double d; vec3_t acceptpt, rejectpt; #endif if (node->contents == CONTENTS_SOLID) return; // solid if (node->visframe != r_visframecount) return; // cull the clipping planes if not trivial accept // FIXME: the compiler is doing a lousy job of optimizing here; it could be // twice as fast in ASM if (clipflags) { for (i=0 ; i<4 ; i++) { if (! (clipflags & (1<<i)) ) continue; // don't need to clip against it // generate accept and reject points // FIXME: do with fast look-ups or integer tests based on the sign bit // of the floating point values pindex = pfrustum_indexes[i]; #ifdef USE_PQ_OPT1 d_fxp=node->minmaxs[pindex[0]]*clipplanes_fxp[i][0]+node->minmaxs[pindex[1]]*clipplanes_fxp[i][1]+node->minmaxs[pindex[2]]*clipplanes_fxp[i][2]; d_fxp-=clipdist_fxp[i]; if (d_fxp <= 0) return; d_fxp=node->minmaxs[pindex[3]]*clipplanes_fxp[i][0]+node->minmaxs[pindex[4]]*clipplanes_fxp[i][1]+node->minmaxs[pindex[5]]*clipplanes_fxp[i][2]; d_fxp-=clipdist_fxp[i]; if (d_fxp >= 0) clipflags &= ~(1<<i); // node is entirely on screen #else rejectpt[0] = (float)node->minmaxs[pindex[0]]; rejectpt[1] = (float)node->minmaxs[pindex[1]]; rejectpt[2] = (float)node->minmaxs[pindex[2]]; d = DotProduct (rejectpt, view_clipplanes[i].normal); d -= view_clipplanes[i].dist; if (d <= 0) return; acceptpt[0] = (float)node->minmaxs[pindex[3+0]]; acceptpt[1] = (float)node->minmaxs[pindex[3+1]]; acceptpt[2] = (float)node->minmaxs[pindex[3+2]]; d = DotProduct (acceptpt, view_clipplanes[i].normal); d -= view_clipplanes[i].dist; if (d >= 0) clipflags &= ~(1<<i); // node is entirely on screen #endif } } // if a leaf node, draw stuff if (node->contents < 0) { pleaf = (mleaf_t *)node; mark = pleaf->firstmarksurface; c = pleaf->nummarksurfaces; if (c) { do { (*mark)->visframe = r_framecount; mark++; } while (--c); } // deal with model fragments in this leaf if (pleaf->efrags) { R_StoreEfrags (&pleaf->efrags); } pleaf->key = r_currentkey; r_currentkey++; // all bmodels in a leaf share the same key } else { // node is just a decision point, so go down the apropriate sides // find which side of the node we are on plane = node->plane; switch (plane->type) { case PLANE_X: dot = modelorg[0] - plane->dist; break; case PLANE_Y: dot = modelorg[1] - plane->dist; break; case PLANE_Z: dot = modelorg[2] - plane->dist; break; default: dot = DotProduct (modelorg, plane->normal) - plane->dist; break; } if (dot >= 0) side = 0; else side = 1; // recurse down the children, front side first R_RecursiveWorldNode (node->children[side], clipflags); // draw stuff c = node->numsurfaces; if (c) { surf = cl.worldmodel->surfaces + node->firstsurface; if (dot < -BACKFACE_EPSILON) { do { if ((surf->flags & SURF_PLANEBACK) && (surf->visframe == r_framecount)) { if (r_drawpolys) { if (r_worldpolysbacktofront) { if (numbtofpolys < MAX_BTOFPOLYS) { pbtofpolys[numbtofpolys].clipflags = clipflags; pbtofpolys[numbtofpolys].psurf = surf; numbtofpolys++; } } else { R_RenderPoly (surf, clipflags); } } else { R_RenderFace (surf, clipflags); } } surf++; } while (--c); } else if (dot > BACKFACE_EPSILON) { do { if (!(surf->flags & SURF_PLANEBACK) && (surf->visframe == r_framecount)) { if (r_drawpolys) { if (r_worldpolysbacktofront) { if (numbtofpolys < MAX_BTOFPOLYS) { pbtofpolys[numbtofpolys].clipflags = clipflags; pbtofpolys[numbtofpolys].psurf = surf; numbtofpolys++; } } else { R_RenderPoly (surf, clipflags); } } else { R_RenderFace (surf, clipflags); } } surf++; } while (--c); } // all surfaces on the same node share the same sequence number r_currentkey++; } // recurse down the back side R_RecursiveWorldNode (node->children[!side], clipflags); } }
/* ================ R_RecursiveWorldNode ================ */ static void R_RecursiveWorldNode(const entity_t *e, mnode_t *node) { int count, side; mplane_t *plane; msurface_t *surf; mleaf_t *pleaf; vec_t dot; if (node->contents == CONTENTS_SOLID) return; if (node->visframe != r_visframecount) return; if (node->clipflags == BMODEL_FULLY_CLIPPED) return; /* if a leaf node, draw stuff */ if (node->contents < 0) { pleaf = (mleaf_t *)node; pleaf->key = r_currentkey; r_currentkey++; // all bmodels in a leaf share the same key return; } /* * The node is a decision point, so go down the apropriate sides. * Find which side of the node we are on. */ plane = node->plane; switch (plane->type) { case PLANE_X: dot = modelorg[0] - plane->dist; break; case PLANE_Y: dot = modelorg[1] - plane->dist; break; case PLANE_Z: dot = modelorg[2] - plane->dist; break; default: dot = DotProduct(modelorg, plane->normal) - plane->dist; break; } side = (dot >= 0) ? 0 : 1; /* recurse down the children, front side first */ R_RecursiveWorldNode(e, node->children[side]); /* draw stuff */ count = node->numsurfaces; if (count) { surf = cl.worldmodel->surfaces + node->firstsurface; for (count = node->numsurfaces; count; count--, surf++) { if (surf->visframe != r_visframecount) continue; if (surf->clipflags == BMODEL_FULLY_CLIPPED) continue; R_RenderFace(e, surf, surf->clipflags); } /* all surfaces on the same node share the same sequence number */ r_currentkey++; } /* recurse down the back side */ R_RecursiveWorldNode(e, node->children[!side]); }
void R_RecursiveWorldNode (mnode_t *node, int clipflags) { int i, c, side, *pindex; vec3_t acceptpt, rejectpt; mplane_t *plane; msurface_t *surf, **mark; mleaf_t *pleaf; double d, dot; if (node->contents == CONTENTS_SOLID) return; // solid if (node->visframe != r_visframecount) return; // cull the clipping planes if not trivial accept // FIXME: the compiler is doing a lousy job of optimizing here; it could be twice as fast in ASM if (clipflags) { for (i = 0; i < 4; i++) { if (!(clipflags & (1<<i)) ) continue; // don't need to clip against it // generate accept and reject points // FIXME: do with fast look-ups or integer tests based on the sign bit of the floating point values pindex = pfrustum_indexes[i]; rejectpt[0] = (float)node->minmaxs[pindex[0]]; rejectpt[1] = (float)node->minmaxs[pindex[1]]; rejectpt[2] = (float)node->minmaxs[pindex[2]]; d = DotProduct (rejectpt, view_clipplanes[i].normal); d -= view_clipplanes[i].dist; if (d <= 0) return; acceptpt[0] = (float)node->minmaxs[pindex[3+0]]; acceptpt[1] = (float)node->minmaxs[pindex[3+1]]; acceptpt[2] = (float)node->minmaxs[pindex[3+2]]; d = DotProduct (acceptpt, view_clipplanes[i].normal); d -= view_clipplanes[i].dist; if (d >= 0) clipflags &= ~(1<<i); // node is entirely on screen } } // if a leaf node, draw stuff if (node->contents < 0) { pleaf = (mleaf_t *)node; mark = pleaf->firstmarksurface; c = pleaf->nummarksurfaces; if (c) { do { (*mark)->visframe = r_framecount; mark++; } while (--c); } // deal with model fragments in this leaf if (pleaf->efrags) R_StoreEfrags (&pleaf->efrags); pleaf->key = r_currentkey; r_currentkey++; // all bmodels in a leaf share the same key } else { // node is just a decision point, so go down the apropriate sides // find which side of the node we are on plane = node->plane; dot = PlaneDiff (modelorg, plane); side = (dot < 0); // recurse down the children, front side first R_RecursiveWorldNode (node->children[side], clipflags); // draw stuff c = node->numsurfaces; if (c) { surf = cl.worldmodel->surfaces + node->firstsurface; if (dot < -BACKFACE_EPSILON) { do { if ((surf->flags & SURF_PLANEBACK) && surf->visframe == r_framecount) R_RenderFace (surf, clipflags); surf++; } while (--c); } else if (dot > BACKFACE_EPSILON) { do { if (!(surf->flags & SURF_PLANEBACK) && surf->visframe == r_framecount) R_RenderFace (surf, clipflags); surf++; } while (--c); } // all surfaces on the same node share the same sequence number r_currentkey++; } // recurse down the back side R_RecursiveWorldNode (node->children[!side], clipflags); } }