- 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 "a_sharedglobal.h"
#include "r_sky.h"
#include "portal.h"
#include "gl/system/gl_interface.h"
#include "gl/system/gl_framebuffer.h"
@ -959,14 +960,14 @@ int GLMirrorPortal::ClipSubsector(subsector_t *sub)
// this seg is completely behind the mirror!
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;
}
int GLMirrorPortal::ClipPoint(fixed_t x, fixed_t y)
{
if (P_PointOnLineSide(x, y, linedef))
if (P_PointOnLineSidePrecise(x, y, linedef))
{
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;
viewx += l2l->xDisplacement;
viewy += l2l->yDisplacement;
viewx = l2l->viewx;
viewy = l2l->viewy;
viewz = l2l->viewz;
viewangle = l2l->viewangle;
SaveMapSection();
for (unsigned i = 0; i < lines.Size(); i++)
{
ASkyViewpoint *pt = lines[i].seg->linedef->skybox;
int mapsection = lines[i].seg->Subsector->mapsection;
int mapsection = lines[i].seg->linedef->getPortalDestination()->frontsector->subsectors[0]->mapsection;
currentmapsection[mapsection >> 3] |= 1 << (mapsection & 7);
}
@ -1023,10 +1066,13 @@ void GLLineToLinePortal::DrawContents()
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
if (P_PointOnLineSide(seg->v1->x, seg->v1->y, masterline) &&
P_PointOnLineSide(seg->v2->x, seg->v2->y, masterline))
//we cannot use P_PointOnLineSide here because it loses the special meaning of 0 == 'on the line'.
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;
}
@ -1039,7 +1085,7 @@ int GLLineToLinePortal::ClipSubsector(subsector_t *sub)
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;
}
@ -1047,7 +1093,7 @@ int GLLineToLinePortal::ClipSubsector(subsector_t *sub)
int GLLineToLinePortal::ClipPoint(fixed_t x, fixed_t y)
{
line_t *masterline = lines[0].seg->linedef->getPortalDestination();
if (P_PointOnLineSide(x, y, masterline))
if (P_PointOnLineSidePrecise(x, y, masterline))
{
return PClip_InFront;
}

View file

@ -53,12 +53,13 @@ struct GLHorizonInfo
struct GLLineToLineInfo
{
fixed_t xDisplacement;
fixed_t yDisplacement;
fixed_t turnangle;
fixed_t angle;
fixed_t x0;
fixed_t y0;
angle_t viewangle;
fixed_t viewx;
fixed_t viewy;
fixed_t viewz;
fixed_t x0, y0;
angle_t lineangle;
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

View file

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