- 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++) for (j = startwall, wal = &wall[startwall]; j < endwall; j++, wal++)
{ {
if (wal->nextwall >= 0) continue; 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]) if ((g_gameType & GAMEFLAG_SW) && !gFullMap && !show2dwall[j])
continue; continue;
@ -588,7 +588,7 @@ void renderDrawMapView(int cposx, int cposy, int czoom, int cang)
int picnum = sector[i].floorpicnum; int picnum = sector[i].floorpicnum;
if ((unsigned)picnum >= (unsigned)MAXTILES) continue; 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()); vertices.Resize(mesh->vertices.Size());
for (unsigned j = 0; j < mesh->vertices.Size(); j++) for (unsigned j = 0; j < mesh->vertices.Size(); j++)
{ {

View file

@ -47,6 +47,19 @@ struct MapRecord;
extern cycle_t drawtime, actortime, thinktime, gameupdatetime; 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 struct GameInterface
{ {
virtual const char* Name() { return "$"; } virtual const char* Name() { return "$"; }
@ -107,6 +120,7 @@ struct GameInterface
virtual void UpdateCameras(double smoothratio) {} virtual void UpdateCameras(double smoothratio) {}
virtual void EnterPortal(spritetype* viewer, int type) {} virtual void EnterPortal(spritetype* viewer, int type) {}
virtual void LeavePortal(spritetype* viewer, int type) {} virtual void LeavePortal(spritetype* viewer, int type) {}
virtual bool GetGeoEffect(GeoEffect* eff, int viewsector) { return false; }
virtual FString statFPS() virtual FString statFPS()
{ {

View file

@ -6,7 +6,7 @@
// //
// This program is free software: you can redistribute it and/or modify // 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 // 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. // (at your option) any later version.
// //
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,

View file

@ -384,6 +384,8 @@ void HWDrawInfo::CreateScene()
screen->mLights->Map(); screen->mLights->Map();
spritesortcnt = 0; spritesortcnt = 0;
ingeo = false;
geoofs = { 0,0 };
vec2_t view = { int(vp.Pos.X * 16), int(vp.Pos.Y * -16) }; vec2_t view = { int(vp.Pos.X * 16), int(vp.Pos.Y * -16) };
mDrawer.Init(this, mClipper, view); mDrawer.Init(this, mClipper, view);
@ -397,6 +399,79 @@ void HWDrawInfo::CreateScene()
DispatchSprites(); DispatchSprites();
SetupSprite.Unclock(); 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->mLights->Unmap();
screen->mVertexData->Unmap(); screen->mVertexData->Unmap();

View file

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

View file

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

View file

@ -101,7 +101,7 @@ void HWFlat::MakeVertices()
bool canvas = texture->isHardwareCanvas(); bool canvas = texture->isHardwareCanvas();
if (sprite == nullptr) if (sprite == nullptr)
{ {
auto mesh = sectorGeometry.get(sec - sector, plane); auto mesh = sectorGeometry.get(sec - sector, plane, geoofs);
if (!mesh) return; if (!mesh) return;
auto ret = screen->mVertexData->AllocVertices(mesh->vertices.Size()); auto ret = screen->mVertexData->AllocVertices(mesh->vertices.Size());
auto vp = ret.first; auto vp = ret.first;
@ -161,7 +161,7 @@ void HWFlat::DrawFlat(HWDrawInfo *di, FRenderState &state, bool translucent)
if (!sprite) if (!sprite)
{ {
auto mesh = sectorGeometry.get(sec - sector, plane); auto mesh = sectorGeometry.get(sec - sector, plane, geoofs);
state.SetNormal(mesh->normal); state.SetNormal(mesh->normal);
} }
else else
@ -231,7 +231,7 @@ void HWFlat::PutFlat(HWDrawInfo *di, int whichplane)
{ {
vertcount = 0; vertcount = 0;
plane = whichplane; 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 0
if (di->Level->HasDynamicLights && texture != nullptr && !di->isFullbrightScene() && !(hacktype & (SSRF_PLANEHACK | SSRF_FLOODHACK))) 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); visibility = sectorVisibility(frontsector);
sec = frontsector; sec = frontsector;
sprite = nullptr; sprite = nullptr;
geoofs = di->geoofs;
// //
// //

View file

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

View file

@ -69,6 +69,7 @@ struct GameInterface : public ::GameInterface
void UpdateCameras(double smoothratio) override; void UpdateCameras(double smoothratio) override;
void EnterPortal(spritetype* viewer, int type) override; void EnterPortal(spritetype* viewer, int type) override;
void LeavePortal(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--; 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 // RRRA's drug distortion effect