mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-29 07:22:05 +00:00
- implemented line-to-line portal rendering. So far working for two-sided portal lines - one-sided yet to come.
This commit is contained in:
parent
760db90d71
commit
3683a8ac58
4 changed files with 65 additions and 34 deletions
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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())
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue