- implemented RR's geometry effect.

The grossest of all gross render hack that were ever done with Build...
This commit is contained in:
Christoph Oelckers 2021-04-02 22:52:46 +02:00
parent 54eee347a6
commit dc234ea72d
11 changed files with 131 additions and 18 deletions

View file

@ -478,7 +478,7 @@ static void drawwhitelines(int cposx, int cposy, int czoom, int cang)
for (j = startwall, wal = &wall[startwall]; j < endwall; j++, wal++)
{
if (wal->nextwall >= 0) continue;
if (!tileGetTexture(wal->picnum)->isValid()) continue;
if (!gFullMap && !tileGetTexture(wal->picnum)->isValid()) continue;
if ((g_gameType & GAMEFLAG_SW) && !gFullMap && !show2dwall[j])
continue;
@ -588,7 +588,7 @@ void renderDrawMapView(int cposx, int cposy, int czoom, int cang)
int picnum = sector[i].floorpicnum;
if ((unsigned)picnum >= (unsigned)MAXTILES) continue;
auto mesh = sectorGeometry.get(i, 0);
auto mesh = sectorGeometry.get(i, 0, { 0.f,0.f });
vertices.Resize(mesh->vertices.Size());
for (unsigned j = 0; j < mesh->vertices.Size(); j++)
{

View file

@ -47,6 +47,19 @@ struct MapRecord;
extern cycle_t drawtime, actortime, thinktime, gameupdatetime;
struct GeoEffect
{
int* geosectorwarp;
int* geosectorwarp2;
int* geosector;
int* geox;
int* geoy;
int* geox2;
int* geoy2;
int geocnt;
};
struct GameInterface
{
virtual const char* Name() { return "$"; }
@ -107,6 +120,7 @@ struct GameInterface
virtual void UpdateCameras(double smoothratio) {}
virtual void EnterPortal(spritetype* viewer, int type) {}
virtual void LeavePortal(spritetype* viewer, int type) {}
virtual bool GetGeoEffect(GeoEffect* eff, int viewsector) { return false; }
virtual FString statFPS()
{

View file

@ -6,7 +6,7 @@
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 2 of the License, or
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,

View file

@ -384,6 +384,8 @@ void HWDrawInfo::CreateScene()
screen->mLights->Map();
spritesortcnt = 0;
ingeo = false;
geoofs = { 0,0 };
vec2_t view = { int(vp.Pos.X * 16), int(vp.Pos.Y * -16) };
mDrawer.Init(this, mClipper, view);
@ -397,6 +399,79 @@ void HWDrawInfo::CreateScene()
DispatchSprites();
SetupSprite.Unclock();
GeoEffect eff;
int effsect = vp.SectNums ? vp.SectNums[0] : vp.SectCount;
int drawsect = effsect;
// RR geometry hack. Ugh...
// This just adds to the existing render list, so we must offset the effect areas to the same xy-space as the main one as we cannot change the view matrix.
if (gi->GetGeoEffect(&eff, effsect))
{
ingeo = true;
geoofs = { (float)eff.geox[0], (float)eff.geoy[0] };
// process the first layer.
for (int i = 0; i < eff.geocnt; i++)
{
auto sect = &sector[eff.geosectorwarp[i]];
for (auto w = 0; w < sect->wallnum; w++)
{
auto wal = &wall[sect->wallptr + w];
wal->x += eff.geox[i];
wal->y += eff.geoy[i];
}
sect->dirty = 255;
if (eff.geosector[i] == effsect) drawsect = eff.geosectorwarp[i];
}
mClipper->Clear();
mClipper->SafeAddClipRange(bamang(vp.RotAngle + a1), bamang(vp.RotAngle - a1));
mDrawer.Init(this, mClipper, view);
mDrawer.RenderScene(&drawsect, 1);
for (int i = 0; i < eff.geocnt; i++)
{
auto sect = &sector[eff.geosectorwarp[i]];
for (auto w = 0; w < sect->wallnum; w++)
{
auto wal = &wall[sect->wallptr + w];
wal->x -= eff.geox[i];
wal->y -= eff.geoy[i];
}
}
// Now the second layer. Same shit, different arrays.
geoofs = { (float)eff.geox2[0], (float)eff.geoy2[0] };
for (int i = 0; i < eff.geocnt; i++)
{
auto sect = &sector[eff.geosectorwarp2[i]];
for (auto w = 0; w < sect->wallnum; w++)
{
auto wal = &wall[sect->wallptr + w];
wal->x += eff.geox2[i];
wal->y += eff.geoy2[i];
}
sect->dirty = 255;
if (eff.geosector[i] == effsect) drawsect = eff.geosectorwarp2[i];
}
mClipper->Clear();
mClipper->SafeAddClipRange(bamang(vp.RotAngle + a1), bamang(vp.RotAngle - a1));
mDrawer.Init(this, mClipper, view);
mDrawer.RenderScene(&drawsect, 1);
for (int i = 0; i < eff.geocnt; i++)
{
auto sect = &sector[eff.geosectorwarp2[i]];
for (auto w = 0; w < sect->wallnum; w++)
{
auto wal = &wall[sect->wallptr + w];
wal->x -= eff.geox2[i];
wal->y -= eff.geoy2[i];
}
}
ingeo = false;
}
screen->mLights->Unmap();
screen->mVertexData->Unmap();

View file

@ -109,10 +109,12 @@ struct HWDrawInfo
HWViewpointUniforms VPUniforms; // per-viewpoint uniform state
TArray<HWPortal *> Portals;
spritetype tsprite[MAXSPRITESONSCREEN];
int spritesortcnt = 0;
int spritesortcnt;
// This is needed by the BSP traverser.
bool multithread;
bool ingeo;
FVector2 geoofs;
private:
bool inview;

View file

@ -258,6 +258,7 @@ public:
FRenderStyle RenderStyle;
int iboindex;
bool stack;
FVector2 geoofs;
//int vboheight;
int plane;

View file

@ -101,7 +101,7 @@ void HWFlat::MakeVertices()
bool canvas = texture->isHardwareCanvas();
if (sprite == nullptr)
{
auto mesh = sectorGeometry.get(sec - sector, plane);
auto mesh = sectorGeometry.get(sec - sector, plane, geoofs);
if (!mesh) return;
auto ret = screen->mVertexData->AllocVertices(mesh->vertices.Size());
auto vp = ret.first;
@ -161,7 +161,7 @@ void HWFlat::DrawFlat(HWDrawInfo *di, FRenderState &state, bool translucent)
if (!sprite)
{
auto mesh = sectorGeometry.get(sec - sector, plane);
auto mesh = sectorGeometry.get(sec - sector, plane, geoofs);
state.SetNormal(mesh->normal);
}
else
@ -231,7 +231,7 @@ void HWFlat::PutFlat(HWDrawInfo *di, int whichplane)
{
vertcount = 0;
plane = whichplane;
if (!screen->BuffersArePersistent() || sprite) // should be made static buffer content later (when the logic is working)
if (!screen->BuffersArePersistent() || sprite || di->ingeo) // should be made static buffer content later (when the logic is working)
{
#if 0
if (di->Level->HasDynamicLights && texture != nullptr && !di->isFullbrightScene() && !(hacktype & (SSRF_PLANEHACK | SSRF_FLOODHACK)))
@ -273,6 +273,7 @@ void HWFlat::ProcessSector(HWDrawInfo *di, sectortype * frontsector, int which)
visibility = sectorVisibility(frontsector);
sec = frontsector;
sprite = nullptr;
geoofs = di->geoofs;
//
//

View file

@ -99,17 +99,19 @@ class UVCalculator
FGameTexture* tex;
float xpanning, ypanning;
float xscaled, yscaled;
FVector2 offset;
public:
// Moved in from pragmas.h
UVCalculator(sectortype* sec, int plane, FGameTexture* tx)
UVCalculator(sectortype* sec, int plane, FGameTexture* tx, const FVector2& off)
{
float xpan, ypan;
sect = sec;
tex = tx;
myplane = plane;
offset = off;
auto firstwall = &wall[sec->wallptr];
ix1 = firstwall->x;
@ -188,8 +190,8 @@ public:
}
else
{
tu = x;
tv = -y;
tu = x - offset.X;
tv = -y - offset.Y;
}
if (stat & CSTAT_SECTOR_SWAPXY)
@ -212,7 +214,7 @@ public:
//
//==========================================================================
void SectorGeometry::MakeVertices(unsigned int secnum, int plane)
void SectorGeometry::MakeVertices(unsigned int secnum, int plane, const FVector2& offset)
{
auto sec = &sector[secnum];
int numvertices = sec->wallnum;
@ -297,7 +299,7 @@ void SectorGeometry::MakeVertices(unsigned int secnum, int plane)
auto texture = tileGetTexture(plane ? sec->ceilingpicnum : sec->floorpicnum);
UVCalculator uvcalc(sec, plane, texture);
UVCalculator uvcalc(sec, plane, texture, offset);
for(unsigned i = 0; i < entry.vertices.Size(); i++)
{
@ -317,7 +319,7 @@ void SectorGeometry::MakeVertices(unsigned int secnum, int plane)
//
//==========================================================================
void SectorGeometry::ValidateSector(unsigned int secnum, int plane)
void SectorGeometry::ValidateSector(unsigned int secnum, int plane, const FVector2& offset)
{
auto sec = &sector[secnum];
auto compare = &data[secnum].compare[plane];
@ -350,5 +352,5 @@ void SectorGeometry::ValidateSector(unsigned int secnum, int plane)
*compare = *sec;
data[secnum].poscompare[plane] = wall[sec->wallptr].pos;
data[secnum].poscompare2[plane] = wall[wall[sec->wallptr].point2].pos;
MakeVertices(secnum, plane);
MakeVertices(secnum, plane, offset);
}

View file

@ -23,14 +23,14 @@ class SectorGeometry
{
TArray<SectorGeometryData> data;
void ValidateSector(unsigned sectnum, int plane);
void MakeVertices(unsigned sectnum, int plane);
void ValidateSector(unsigned sectnum, int plane, const FVector2& offset);
void MakeVertices(unsigned sectnum, int plane, const FVector2& offset);
public:
SectorGeometryPlane* get(unsigned sectnum, int plane)
SectorGeometryPlane* get(unsigned sectnum, int plane, const FVector2& offset)
{
if (sectnum >= data.Size()) return nullptr;
ValidateSector(sectnum, plane);
ValidateSector(sectnum, plane, offset);
return &data[sectnum].planes[plane];
}

View file

@ -69,6 +69,7 @@ struct GameInterface : public ::GameInterface
void UpdateCameras(double smoothratio) override;
void EnterPortal(spritetype* viewer, int type) override;
void LeavePortal(spritetype* viewer, int type) override;
bool GetGeoEffect(GeoEffect* eff, int viewsector) override;
};

View file

@ -144,6 +144,23 @@ void GameInterface::LeavePortal(spritetype* viewer, int type)
if (type == PORTAL_WALL_MIRROR) display_mirror--;
}
bool GameInterface::GetGeoEffect(GeoEffect* eff, int viewsector)
{
if (!isRR() || sector[viewsector].lotag == 848)
{
eff->geocnt = geocnt;
eff->geosector = geosector;
eff->geosectorwarp = geosectorwarp;
eff->geosectorwarp2 = geosectorwarp2;
eff->geox = geox;
eff->geoy = geoy;
eff->geox2 = geox2;
eff->geoy2 = geoy2;
return true;
}
return false;
}
//---------------------------------------------------------------------------
//
// RRRA's drug distortion effect