- implemented line-to-line portal rendering. So far working for two-sided portal lines - one-sided yet to come.

This commit is contained in:
Christoph Oelckers 2016-02-06 12:32:47 +01:00
parent 760db90d71
commit 3683a8ac58
4 changed files with 65 additions and 34 deletions

View file

@ -46,6 +46,7 @@
#include "doomstat.h" #include "doomstat.h"
#include "a_sharedglobal.h" #include "a_sharedglobal.h"
#include "r_sky.h" #include "r_sky.h"
#include "portal.h"
#include "gl/system/gl_interface.h" #include "gl/system/gl_interface.h"
#include "gl/system/gl_framebuffer.h" #include "gl/system/gl_framebuffer.h"
@ -959,14 +960,14 @@ int GLMirrorPortal::ClipSubsector(subsector_t *sub)
// this seg is completely behind the mirror! // this seg is completely behind the mirror!
for(unsigned int i=0;i<sub->numlines;i++) for(unsigned int i=0;i<sub->numlines;i++)
{ {
if (P_PointOnLineSide(sub->firstline[i].v1->x, sub->firstline[i].v1->y, linedef) == 0) return PClip_Inside; if (P_PointOnLineSidePrecise(sub->firstline[i].v1->x, sub->firstline[i].v1->y, linedef) == 0) return PClip_Inside;
} }
return PClip_InFront; return PClip_InFront;
} }
int GLMirrorPortal::ClipPoint(fixed_t x, fixed_t y) int GLMirrorPortal::ClipPoint(fixed_t x, fixed_t y)
{ {
if (P_PointOnLineSide(x, y, linedef)) if (P_PointOnLineSidePrecise(x, y, linedef))
{ {
return PClip_InFront; return PClip_InFront;
} }
@ -984,6 +985,47 @@ int GLMirrorPortal::ClipPoint(fixed_t x, fixed_t y)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
static void glTranslatePortal(line_t* src, line_t* dst, fixed_t& x, fixed_t& y, angle_t & angle)
{
// Get the angle between the two linedefs, for rotating
// orientation and velocity. Rotate 180 degrees, and flip
// the position across the exit linedef, if reversed.
double xangle = atan2(double(dst->dy), double(dst->dx)) - atan2(double(src->dy), double(src->dx)) + M_PI;
double s = sin(xangle);
double c = cos(xangle);
fixed_t nposx = x - src->v1->x;
fixed_t nposy = y - src->v1->y;
// Rotate position along normal to match exit linedef
x = xs_RoundToInt(nposx * c - nposy * s) + dst->v2->x;
y = xs_RoundToInt(nposy * c + nposx * s) + dst->v2->y;
angle += xs_CRoundToInt(xangle * (ANGLE_180 / M_PI));
}
void GLLineToLineInfo::init(line_t *line)
{
static const divline_t divlx = { 0, 0, 128 * FRACUNIT, 0 };
static const divline_t divly = { 0, 0, 0, 128 * FRACUNIT };
// store some info about the portal line
divline_t divl;
P_MakeDivline(line, &divl);
x0 = P_InterceptVector(&divlx, &divl);
y0 = P_InterceptVector(&divly, &divl);
lineangle = R_PointToAnglePrecise(line->v1->x, line->v1->y, line->v2->x, line->v2->y);
// and some info about the viewpoint translation
viewx = ::viewx;
viewy = ::viewy;
viewz = ::viewz;
viewangle = ::viewangle;
glTranslatePortal(line, line->getPortalDestination(), viewx, viewy, viewangle);
P_TranslatePortalZ(line, line->getPortalDestination(), viewz);
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// //
// //
@ -1000,14 +1042,15 @@ void GLLineToLinePortal::DrawContents()
GLRenderer->mCurrentPortal = this; GLRenderer->mCurrentPortal = this;
viewx += l2l->xDisplacement; viewx = l2l->viewx;
viewy += l2l->yDisplacement; viewy = l2l->viewy;
viewz = l2l->viewz;
viewangle = l2l->viewangle;
SaveMapSection(); SaveMapSection();
for (unsigned i = 0; i < lines.Size(); i++) for (unsigned i = 0; i < lines.Size(); i++)
{ {
ASkyViewpoint *pt = lines[i].seg->linedef->skybox; int mapsection = lines[i].seg->linedef->getPortalDestination()->frontsector->subsectors[0]->mapsection;
int mapsection = lines[i].seg->Subsector->mapsection;
currentmapsection[mapsection >> 3] |= 1 << (mapsection & 7); currentmapsection[mapsection >> 3] |= 1 << (mapsection & 7);
} }
@ -1023,10 +1066,13 @@ void GLLineToLinePortal::DrawContents()
int GLLineToLinePortal::ClipSeg(seg_t *seg) int GLLineToLinePortal::ClipSeg(seg_t *seg)
{ {
line_t *masterline = lines[0].seg->linedef->getPortalDestination(); line_t *linedef = lines[0].seg->linedef->getPortalDestination();
// this seg is completely behind the portal // this seg is completely behind the portal
if (P_PointOnLineSide(seg->v1->x, seg->v1->y, masterline) && //we cannot use P_PointOnLineSide here because it loses the special meaning of 0 == 'on the line'.
P_PointOnLineSide(seg->v2->x, seg->v2->y, masterline)) int side1 = DMulScale32(seg->v1->y - linedef->v1->y, linedef->dx, linedef->v1->x - seg->v1->x, linedef->dy);
int side2 = DMulScale32(seg->v2->y - linedef->v1->y, linedef->dx, linedef->v1->x - seg->v2->x, linedef->dy);
if (side1 >= 0 && side2 >= 0)
{ {
return PClip_InFront; return PClip_InFront;
} }
@ -1039,7 +1085,7 @@ int GLLineToLinePortal::ClipSubsector(subsector_t *sub)
for(unsigned int i=0;i<sub->numlines;i++) for(unsigned int i=0;i<sub->numlines;i++)
{ {
if (P_PointOnLineSide(sub->firstline[i].v1->x, sub->firstline[i].v1->y, masterline) == 0) return PClip_Inside; if (P_PointOnLineSidePrecise(sub->firstline[i].v1->x, sub->firstline[i].v1->y, masterline) == 0) return PClip_Inside;
} }
return PClip_InFront; return PClip_InFront;
} }
@ -1047,7 +1093,7 @@ int GLLineToLinePortal::ClipSubsector(subsector_t *sub)
int GLLineToLinePortal::ClipPoint(fixed_t x, fixed_t y) int GLLineToLinePortal::ClipPoint(fixed_t x, fixed_t y)
{ {
line_t *masterline = lines[0].seg->linedef->getPortalDestination(); line_t *masterline = lines[0].seg->linedef->getPortalDestination();
if (P_PointOnLineSide(x, y, masterline)) if (P_PointOnLineSidePrecise(x, y, masterline))
{ {
return PClip_InFront; return PClip_InFront;
} }

View file

@ -53,12 +53,13 @@ struct GLHorizonInfo
struct GLLineToLineInfo struct GLLineToLineInfo
{ {
fixed_t xDisplacement; angle_t viewangle;
fixed_t yDisplacement; fixed_t viewx;
fixed_t turnangle; fixed_t viewy;
fixed_t angle; fixed_t viewz;
fixed_t x0; fixed_t x0, y0;
fixed_t y0; angle_t lineangle;
void init(line_t *line); void init(line_t *line);
}; };

View file

@ -130,22 +130,6 @@ void GLSkyInfo::init(int sky1, PalEntry FadeColor)
} }
void GLLineToLineInfo::init(line_t *line)
{
/*
static const divline_t divlx = { 0, 0, 128 * FRACUNIT, 0 };
static const divline_t divly = { 0, 0, 0, 128 * FRACUNIT };
xDisplacement = line->skybox->scaleX;
yDisplacement = line->skybox->scaleY;
angle = R_PointToAnglePrecise(line->v1->x, line->v1->y, line->v2->x, line->v2->y);
divline_t divl;
P_MakeDivline(line, &divl);
x0 = P_InterceptVector(&divlx, &divl);
y0 = P_InterceptVector(&divly, &divl);
*/
}
//========================================================================== //==========================================================================
// //
// Calculate sky texture for ceiling or floor // Calculate sky texture for ceiling or floor

View file

@ -1595,7 +1595,7 @@ void GLWall::Process(seg_t *seg, sector_t * frontsector, sector_t * backsector)
zbottom[0] = FIXED2FLOAT(bfh1); zbottom[0] = FIXED2FLOAT(bfh1);
zbottom[1] = FIXED2FLOAT(bfh2); zbottom[1] = FIXED2FLOAT(bfh2);
//SkyLine(frontsector, seg->linedef); SkyLine(frontsector, seg->linedef);
} }
else if (backsector->e->XFloor.ffloors.Size() || frontsector->e->XFloor.ffloors.Size()) else if (backsector->e->XFloor.ffloors.Size() || frontsector->e->XFloor.ffloors.Size())
{ {