// // R_RenderPlanePortal // static void R_RenderPlanePortal(pwindow_t *window) { visplane_t *vplane; int x; float angle; portal_t *portal = window->portal; portalrender.curwindow = window; if(portal->type != R_PLANE) return; if(window->maxx < window->minx) return; // haleyjd 01/05/08: flat angle angle = *portal->data.plane.baseangle + *portal->data.plane.angle; vplane = R_FindPlane(*portal->data.plane.delta + viewz, *portal->data.plane.pic, *portal->data.plane.lightlevel, *portal->data.plane.xoff, *portal->data.plane.yoff, angle, NULL, 0, 255, NULL); vplane = R_CheckPlane(vplane, window->minx, window->maxx); for(x = window->minx; x <= window->maxx; x++) { if(window->top[x] < window->bottom[x]) { vplane->top[x] = (int)window->top[x]; vplane->bottom[x] = (int)window->bottom[x]; } } if(window->head == window && window->portal->poverlay) R_PushPost(false, window->portal->poverlay); if(window->child) R_RenderPlanePortal(window->child); }
static void R_RenderLinkedPortal(pwindow_t *window) { fixed_t lastx, lasty, lastz; float lastxf, lastyf, lastzf; portal_t *portal = window->portal; // ioanch 20160123: keep track of window portalrender.curwindow = window; if(portal->type != R_LINKED || window->maxx < window->minx) return; // haleyjd: temporary debug if(portal->tainted > 6) { if(showtainted) R_ShowTainted(window); portal->tainted++; C_Printf(FC_ERROR "Refused to draw portal (line=%i) (t=%d)", portal->data.link.maker, portal->tainted); return; } #ifdef RANGECHECK for(int i = 0; i < video.width; i++) { if(window->bottom[i] > window->top[i] && (window->bottom[i] < -1 || window->bottom[i] > viewwindow.height || window->top[i] < -1 || window->top[i] > viewwindow.height)) { I_Error("R_RenderAnchoredPortal: clipping array contained invalid " "information:\n" " x:%i, ytop:%f, ybottom:%f\n", i, window->top[i], window->bottom[i]); } } #endif if(!R_SetupPortalClipsegs(window->minx, window->maxx, window->top, window->bottom)) return; R_ClearSlopeMark(window->minx, window->maxx, window->type); // haleyjd: temporary debug portal->tainted++; floorclip = window->bottom; ceilingclip = window->top; R_ClearOverlayClips(); portalrender.minx = window->minx; portalrender.maxx = window->maxx; ++validcount; R_SetMaskedSilhouette(ceilingclip, floorclip); lastx = viewx; lasty = viewy; lastz = viewz; lastxf = view.x; lastyf = view.y; lastzf = view.z; // SoM 3/10/2005: Use the coordinates stored in the portal struct viewx = window->vx + portal->data.link.deltax; viewy = window->vy + portal->data.link.deltay; viewz = window->vz + portal->data.link.deltaz; view.x = M_FixedToFloat(viewx); view.y = M_FixedToFloat(viewy); view.z = M_FixedToFloat(viewz); R_IncrementFrameid(); R_RenderBSPNode(numnodes - 1); // Only push the overlay if this is the head window R_PushPost(true, window->head == window ? window->portal->poverlay : NULL); floorclip = floorcliparray; ceilingclip = ceilingcliparray; viewx = lastx; viewy = lasty; viewz = lastz; view.x = lastxf; view.y = lastyf; view.z = lastzf; if(window->child) R_RenderLinkedPortal(window->child); }
// // R_RenderSkyboxPortal // static void R_RenderSkyboxPortal(pwindow_t *window) { fixed_t lastx, lasty, lastz, lastangle; float lastxf, lastyf, lastzf, lastanglef; portal_t *portal = window->portal; portalrender.curwindow = window; if(portal->type != R_SKYBOX) return; if(window->maxx < window->minx) return; #ifdef RANGECHECK for(int i = 0; i < video.width; i++) { if(window->bottom[i] > window->top[i] && (window->bottom[i] < -1 || window->bottom[i] > viewwindow.height || window->top[i] < -1 || window->top[i] > viewwindow.height)) { I_Error("R_RenderSkyboxPortal: clipping array contained invalid " "information:\n" " x:%i, ytop:%f, ybottom:%f\n", i, window->top[i], window->bottom[i]); } } #endif if(!R_SetupPortalClipsegs(window->minx, window->maxx, window->top, window->bottom)) return; R_ClearSlopeMark(window->minx, window->maxx, window->type); floorclip = window->bottom; ceilingclip = window->top; R_ClearOverlayClips(); portalrender.minx = window->minx; portalrender.maxx = window->maxx; ++validcount; R_SetMaskedSilhouette(ceilingclip, floorclip); lastx = viewx; lasty = viewy; lastz = viewz; lastangle = viewangle; lastxf = view.x; lastyf = view.y; lastzf = view.z; lastanglef = view.angle; viewx = portal->data.camera->x; viewy = portal->data.camera->y; viewz = portal->data.camera->z; view.x = M_FixedToFloat(viewx); view.y = M_FixedToFloat(viewy); view.z = M_FixedToFloat(viewz); // SoM: The viewangle should also be offset by the skybox camera angle. viewangle += portal->data.camera->angle; viewsin = finesine[viewangle>>ANGLETOFINESHIFT]; viewcos = finecosine[viewangle>>ANGLETOFINESHIFT]; view.angle = (ANG90 - viewangle) * PI / ANG180; view.sin = (float)sin(view.angle); view.cos = (float)cos(view.angle); R_IncrementFrameid(); R_RenderBSPNode(numnodes - 1); // Only push the overlay if this is the head window R_PushPost(true, window->head == window ? window->portal->poverlay : NULL); floorclip = floorcliparray; ceilingclip = ceilingcliparray; // SoM: "pop" the view state. viewx = lastx; viewy = lasty; viewz = lastz; viewangle = lastangle; view.x = lastxf; view.y = lastyf; view.z = lastzf; view.angle = lastanglef; viewsin = finesine[viewangle>>ANGLETOFINESHIFT]; viewcos = finecosine[viewangle>>ANGLETOFINESHIFT]; view.sin = (float)sin(view.angle); view.cos = (float)cos(view.angle); if(window->child) R_RenderSkyboxPortal(window->child); }
// // R_RenderHorizonPortal // static void R_RenderHorizonPortal(pwindow_t *window) { fixed_t lastx, lasty, lastz; // SoM 3/10/2005 float lastxf, lastyf, lastzf, floorangle, ceilingangle; visplane_t *topplane, *bottomplane; int x; portal_t *portal = window->portal; portalrender.curwindow = window; if(portal->type != R_HORIZON) return; if(window->maxx < window->minx) return; // haleyjd 01/05/08: angles floorangle = *portal->data.horizon.floorbaseangle + *portal->data.horizon.floorangle; ceilingangle = *portal->data.horizon.ceilingbaseangle + *portal->data.horizon.ceilingangle; topplane = R_FindPlane(*portal->data.horizon.ceilingz, *portal->data.horizon.ceilingpic, *portal->data.horizon.ceilinglight, *portal->data.horizon.ceilingxoff, *portal->data.horizon.ceilingyoff, ceilingangle, NULL, 0, 255, NULL); bottomplane = R_FindPlane(*portal->data.horizon.floorz, *portal->data.horizon.floorpic, *portal->data.horizon.floorlight, *portal->data.horizon.floorxoff, *portal->data.horizon.flooryoff, floorangle, NULL, 0, 255, NULL); topplane = R_CheckPlane(topplane, window->minx, window->maxx); bottomplane = R_CheckPlane(bottomplane, window->minx, window->maxx); for(x = window->minx; x <= window->maxx; x++) { if(window->top[x] > window->bottom[x]) continue; if(window->top[x] <= view.ycenter - 1.0f && window->bottom[x] >= view.ycenter) { topplane->top[x] = (int)window->top[x]; topplane->bottom[x] = centery - 1; bottomplane->top[x] = centery; bottomplane->bottom[x] = (int)window->bottom[x]; } else if(window->top[x] <= view.ycenter - 1.0f) { topplane->top[x] = (int)window->top[x]; topplane->bottom[x] = (int)window->bottom[x]; } else if(window->bottom[x] > view.ycenter - 1.0f) { bottomplane->top[x] = (int)window->top[x]; bottomplane->bottom[x] = (int)window->bottom[x]; } } lastx = viewx; lasty = viewy; lastz = viewz; lastxf = view.x; lastyf = view.y; lastzf = view.z; viewx = window->vx; viewy = window->vy; viewz = window->vz; view.x = M_FixedToFloat(viewx); view.y = M_FixedToFloat(viewy); view.z = M_FixedToFloat(viewz); if(window->head == window && window->portal->poverlay) R_PushPost(false, window->portal->poverlay); if(window->child) R_RenderHorizonPortal(window->child); viewx = lastx; viewy = lasty; viewz = lastz; view.x = lastxf; view.y = lastyf; view.z = lastzf; }
static void R_RenderLinkedPortal(pwindow_t *window) { fixed_t lastx, lasty, lastz; float lastxf, lastyf, lastzf; portal_t *portal = window->portal; // ioanch 20160123: keep track of window portalrender.curwindow = window; if(portal->type != R_LINKED || window->maxx < window->minx) return; // haleyjd: temporary debug if(portal->tainted > PORTAL_RECURSION_LIMIT) { R_ShowTainted(window); portal->tainted++; return; } #ifdef RANGECHECK for(int i = 0; i < video.width; i++) { if(window->bottom[i] > window->top[i] && (window->bottom[i] < -1 || window->bottom[i] > viewwindow.height || window->top[i] < -1 || window->top[i] > viewwindow.height)) { I_Error("R_RenderAnchoredPortal: clipping array contained invalid " "information:\n" " x:%i, ytop:%f, ybottom:%f\n", i, window->top[i], window->bottom[i]); } } #endif if(!R_SetupPortalClipsegs(window->minx, window->maxx, window->top, window->bottom)) return; R_ClearSlopeMark(window->minx, window->maxx, window->type); // haleyjd: temporary debug portal->tainted++; floorclip = window->bottom; ceilingclip = window->top; R_ClearOverlayClips(); portalrender.minx = window->minx; portalrender.maxx = window->maxx; ++validcount; R_SetMaskedSilhouette(ceilingclip, floorclip); lastx = viewx; lasty = viewy; lastz = viewz; lastxf = view.x; lastyf = view.y; lastzf = view.z; // SoM 3/10/2005: Use the coordinates stored in the portal struct viewx = window->vx + portal->data.link.deltax; viewy = window->vy + portal->data.link.deltay; viewz = window->vz + portal->data.link.deltaz; // ioanch 20160227: microscopic adjustment for line portals to make sure // the edge textures in the buffer sectors are seen in case of polyobject // portals //if(window->line && window->line->portal->data.link.polyportalpartner) //{ // if(window->line->dx > 0) // --viewy; // else if(window->line->dx < 0) // ++viewy; // if(window->line->dy > 0) // ++viewx; // else if(window->line->dy < 0) // --viewx; //} view.x = M_FixedToFloat(viewx); view.y = M_FixedToFloat(viewy); view.z = M_FixedToFloat(viewz); R_IncrementFrameid(); R_RenderBSPNode(numnodes - 1); // Only push the overlay if this is the head window R_PushPost(true, window->head == window ? window->portal->poverlay : NULL); floorclip = floorcliparray; ceilingclip = ceilingcliparray; viewx = lastx; viewy = lasty; viewz = lastz; view.x = lastxf; view.y = lastyf; view.z = lastzf; if(window->child) R_RenderLinkedPortal(window->child); }