mirror of
https://github.com/ZDoom/Raze.git
synced 2025-01-18 22:51:50 +00:00
- ported my old Build-style renderer for Doom from 2008 and the wall renderer from GZDoom to work with Build data.
It renders walls, but y-panning is still broken.
This commit is contained in:
parent
9ebd8fd4a5
commit
b492cbcebb
15 changed files with 2353 additions and 55 deletions
|
@ -1072,6 +1072,8 @@ set (PCH_SOURCES
|
||||||
core/gi.cpp
|
core/gi.cpp
|
||||||
|
|
||||||
core/rendering/scene/hw_clipper.cpp
|
core/rendering/scene/hw_clipper.cpp
|
||||||
|
core/rendering/scene/hw_walls.cpp
|
||||||
|
core/rendering/render.cpp
|
||||||
|
|
||||||
core/console/c_notifybuffer.cpp
|
core/console/c_notifybuffer.cpp
|
||||||
core/console/d_event.cpp
|
core/console/d_event.cpp
|
||||||
|
|
|
@ -875,6 +875,19 @@ enum EHitBits
|
||||||
|
|
||||||
void updateModelInterpolation();
|
void updateModelInterpolation();
|
||||||
|
|
||||||
|
int32_t renderAddTsprite(int16_t z, int16_t sectnum);
|
||||||
|
|
||||||
|
inline void tileUpdatePicnum(int* const tileptr, int const obj, int stat)
|
||||||
|
{
|
||||||
|
auto& tile = *tileptr;
|
||||||
|
|
||||||
|
if (picanm[tile].sf & PICANM_ANIMTYPE_MASK)
|
||||||
|
tile += animateoffs(tile, obj);
|
||||||
|
|
||||||
|
if (((obj & 16384) == 16384) && (stat & CSTAT_WALL_ROTATE_90) && RotTile(tile).newtile != -1)
|
||||||
|
tile = RotTile(tile).newtile;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#include "iterators.h"
|
#include "iterators.h"
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,17 @@
|
||||||
// bits 12-15: reserved
|
// bits 12-15: reserved
|
||||||
|
|
||||||
//////////////////// Version 7 map format ////////////////////
|
//////////////////// Version 7 map format ////////////////////
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
CSTAT_SECTOR_SKY = 1,
|
||||||
|
CSTAT_SECTOR_SLOPE = 2,
|
||||||
|
CSTAT_SECTOR_SWAPXY = 4,
|
||||||
|
CSTAT_SECTOR_TEXHALF = 8,
|
||||||
|
CSTAT_SECTOR_XFLIP = 16,
|
||||||
|
CSTAT_SECTOR_YFLIP = 32,
|
||||||
|
CSTAT_SECTOR_ALIGN = 64,
|
||||||
|
CSTAT_SECTOR_METHOD = 384
|
||||||
|
};
|
||||||
|
|
||||||
//40 bytes
|
//40 bytes
|
||||||
struct sectortype
|
struct sectortype
|
||||||
|
@ -91,6 +102,7 @@ struct walltype
|
||||||
int16_t hitag;
|
int16_t hitag;
|
||||||
int16_t extra;
|
int16_t extra;
|
||||||
float xpan_, ypan_;
|
float xpan_, ypan_;
|
||||||
|
angle_t clipangle;
|
||||||
|
|
||||||
int xpan() const { return int(xpan_); }
|
int xpan() const { return int(xpan_); }
|
||||||
int ypan() const { return int(ypan_); }
|
int ypan() const { return int(ypan_); }
|
||||||
|
|
|
@ -1419,7 +1419,7 @@ int32_t hitscan(const vec3_t *sv, int16_t sectnum, int32_t vx, int32_t vy, int32
|
||||||
{
|
{
|
||||||
if (picanm[tilenum].sf&PICANM_TEXHITSCAN_BIT)
|
if (picanm[tilenum].sf&PICANM_TEXHITSCAN_BIT)
|
||||||
{
|
{
|
||||||
tileUpdatePicnum(&tilenum, 0);
|
tileUpdatePicnum(&tilenum, 0, 0);
|
||||||
|
|
||||||
if (tileLoad(tilenum))
|
if (tileLoad(tilenum))
|
||||||
{
|
{
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
#include "inputstate.h"
|
#include "inputstate.h"
|
||||||
#include "printf.h"
|
#include "printf.h"
|
||||||
#include "gamecontrol.h"
|
#include "gamecontrol.h"
|
||||||
|
#include "render.h"
|
||||||
|
|
||||||
#ifdef USE_OPENGL
|
#ifdef USE_OPENGL
|
||||||
# include "mdsprite.h"
|
# include "mdsprite.h"
|
||||||
|
@ -38,6 +39,7 @@
|
||||||
#include "gl_renderer.h"
|
#include "gl_renderer.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
float rollang;
|
||||||
|
|
||||||
int32_t r_rortexture = 0;
|
int32_t r_rortexture = 0;
|
||||||
int32_t r_rortexturerange = 0;
|
int32_t r_rortexturerange = 0;
|
||||||
|
@ -909,9 +911,32 @@ void set_globalang(fixed_t const ang)
|
||||||
// drawrooms
|
// drawrooms
|
||||||
//
|
//
|
||||||
EXTERN_CVAR(Int, gl_fogmode)
|
EXTERN_CVAR(Int, gl_fogmode)
|
||||||
|
CVAR(Bool, testnewrenderer, true, 0)
|
||||||
|
|
||||||
int32_t renderDrawRoomsQ16(int32_t daposx, int32_t daposy, int32_t daposz,
|
int32_t renderDrawRoomsQ16(int32_t daposx, int32_t daposy, int32_t daposz,
|
||||||
fixed_t daang, fixed_t dahoriz, int16_t dacursectnum)
|
fixed_t daang, fixed_t dahoriz, int16_t dacursectnum)
|
||||||
{
|
{
|
||||||
|
for (int i = 0; i < numwalls; ++i)
|
||||||
|
{
|
||||||
|
if (wall[i].cstat & CSTAT_WALL_ROTATE_90)
|
||||||
|
{
|
||||||
|
auto& w = wall[i];
|
||||||
|
auto& tile = RotTile(w.picnum + animateoffs(w.picnum, 16384));
|
||||||
|
|
||||||
|
if (tile.newtile == -1 && tile.owner == -1)
|
||||||
|
{
|
||||||
|
auto owner = w.picnum + animateoffs(w.picnum, 16384);
|
||||||
|
|
||||||
|
tile.newtile = TileFiles.tileCreateRotated(owner);
|
||||||
|
assert(tile.newtile != -1);
|
||||||
|
|
||||||
|
RotTile(tile.newtile).owner = w.picnum + animateoffs(w.picnum, 16384);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int32_t i;
|
int32_t i;
|
||||||
|
|
||||||
if (gl_fogmode == 1) gl_fogmode = 2; // only radial fog works with Build's screwed up coordinate system.
|
if (gl_fogmode == 1) gl_fogmode = 2; // only radial fog works with Build's screwed up coordinate system.
|
||||||
|
@ -931,26 +956,6 @@ int32_t renderDrawRoomsQ16(int32_t daposx, int32_t daposy, int32_t daposz,
|
||||||
|
|
||||||
i = xdimen-1;
|
i = xdimen-1;
|
||||||
|
|
||||||
for (int i = 0; i < numwalls; ++i)
|
|
||||||
{
|
|
||||||
if (wall[i].cstat & CSTAT_WALL_ROTATE_90)
|
|
||||||
{
|
|
||||||
auto &w = wall[i];
|
|
||||||
auto &tile = RotTile(w.picnum+animateoffs(w.picnum,16384));
|
|
||||||
|
|
||||||
if (tile.newtile == -1 && tile.owner == -1)
|
|
||||||
{
|
|
||||||
auto owner = w.picnum + animateoffs(w.picnum, 16384);
|
|
||||||
|
|
||||||
tile.newtile = TileFiles.tileCreateRotated(owner);
|
|
||||||
assert(tile.newtile != -1);
|
|
||||||
|
|
||||||
RotTile(tile.newtile).owner = w.picnum+animateoffs(w.picnum,16384);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update starting sector number (common to classic and Polymost).
|
// Update starting sector number (common to classic and Polymost).
|
||||||
// ADJUST_GLOBALCURSECTNUM.
|
// ADJUST_GLOBALCURSECTNUM.
|
||||||
if (globalcursectnum >= MAXSECTORS)
|
if (globalcursectnum >= MAXSECTORS)
|
||||||
|
@ -967,7 +972,15 @@ int32_t renderDrawRoomsQ16(int32_t daposx, int32_t daposy, int32_t daposz,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Polymost::polymost_drawrooms();
|
if (!testnewrenderer)
|
||||||
|
{
|
||||||
|
Polymost::polymost_drawrooms();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vec3_t pos = { daposx, daposy, daposz };
|
||||||
|
render_drawrooms(pos, globalcursectnum, daang, dahoriz, rollang, r_fov, false, false);
|
||||||
|
}
|
||||||
|
|
||||||
return inpreparemirror;
|
return inpreparemirror;
|
||||||
}
|
}
|
||||||
|
@ -1560,9 +1573,11 @@ void renderDrawMapView(int32_t dax, int32_t day, int32_t zoome, int16_t ang)
|
||||||
|
|
||||||
globalfloorpal = globalpal = sec->floorpal;
|
globalfloorpal = globalpal = sec->floorpal;
|
||||||
|
|
||||||
globalpicnum = sec->floorpicnum;
|
int _globalpicnum = sec->floorpicnum;
|
||||||
if ((unsigned)globalpicnum >= (unsigned)MAXTILES) globalpicnum = 0;
|
if ((unsigned)_globalpicnum >= (unsigned)MAXTILES) globalpicnum = 0;
|
||||||
tileUpdatePicnum(&globalpicnum, s);
|
tileUpdatePicnum(&_globalpicnum, s, 0);
|
||||||
|
globalpicnum = _globalpicnum;
|
||||||
|
|
||||||
setgotpic(globalpicnum);
|
setgotpic(globalpicnum);
|
||||||
if ((tileWidth(globalpicnum) <= 0) || (tileHeight(globalpicnum) <= 0)) continue;
|
if ((tileWidth(globalpicnum) <= 0) || (tileHeight(globalpicnum) <= 0)) continue;
|
||||||
|
|
||||||
|
@ -1679,8 +1694,12 @@ void renderDrawMapView(int32_t dax, int32_t day, int32_t zoome, int16_t ang)
|
||||||
|
|
||||||
globalpicnum = spr->picnum;
|
globalpicnum = spr->picnum;
|
||||||
globalpal = spr->pal; // GL needs this, software doesn't
|
globalpal = spr->pal; // GL needs this, software doesn't
|
||||||
if ((unsigned)globalpicnum >= (unsigned)MAXTILES) globalpicnum = 0;
|
|
||||||
tileUpdatePicnum(&globalpicnum, s);
|
int _globalpicnum = sec->floorpicnum;
|
||||||
|
if ((unsigned)_globalpicnum >= (unsigned)MAXTILES) globalpicnum = 0;
|
||||||
|
tileUpdatePicnum(&_globalpicnum, s, 0);
|
||||||
|
globalpicnum = _globalpicnum;
|
||||||
|
|
||||||
setgotpic(globalpicnum);
|
setgotpic(globalpicnum);
|
||||||
if ((tileWidth(globalpicnum) <= 0) || (tileHeight(globalpicnum) <= 0)) continue;
|
if ((tileWidth(globalpicnum) <= 0) || (tileHeight(globalpicnum) <= 0)) continue;
|
||||||
|
|
||||||
|
@ -2981,6 +3000,7 @@ void alignflorslope(int16_t dasect, int32_t x, int32_t y, int32_t z)
|
||||||
void renderSetRollAngle(float rolla)
|
void renderSetRollAngle(float rolla)
|
||||||
{
|
{
|
||||||
Polymost::gtang = rolla * BAngRadian;
|
Polymost::gtang = rolla * BAngRadian;
|
||||||
|
rollang = rolla * (BAngRadian * 180 / pi::pif());
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,8 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "cmdlib.h"
|
||||||
|
|
||||||
#ifndef ENGINE_PRIV_H
|
#ifndef ENGINE_PRIV_H
|
||||||
#define ENGINE_PRIV_H
|
#define ENGINE_PRIV_H
|
||||||
|
|
||||||
|
@ -96,10 +98,6 @@ static FORCE_INLINE int32_t getpalookup(int32_t davis, int32_t dashade)
|
||||||
|
|
||||||
static FORCE_INLINE int32_t getpalookupsh(int32_t davis) { return getpalookup(davis, globalshade) << 8; }
|
static FORCE_INLINE int32_t getpalookupsh(int32_t davis) { return getpalookup(davis, globalshade) << 8; }
|
||||||
|
|
||||||
////// yax'y stuff //////
|
|
||||||
int32_t renderAddTsprite(int16_t z, int16_t sectnum);
|
|
||||||
|
|
||||||
|
|
||||||
static FORCE_INLINE void setgotpic(int32_t tilenume)
|
static FORCE_INLINE void setgotpic(int32_t tilenume)
|
||||||
{
|
{
|
||||||
gotpic[tilenume>>3] |= pow2char[tilenume&7];
|
gotpic[tilenume>>3] |= pow2char[tilenume&7];
|
||||||
|
@ -117,16 +115,6 @@ static FORCE_INLINE void set_globalpos(int32_t const x, int32_t const y, int32_t
|
||||||
globalposz = z, fglobalposz = (float)z;
|
globalposz = z, fglobalposz = (float)z;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> static FORCE_INLINE void tileUpdatePicnum(T * const tileptr, int const obj)
|
|
||||||
{
|
|
||||||
auto &tile = *tileptr;
|
|
||||||
|
|
||||||
if (picanm[tile].sf & PICANM_ANIMTYPE_MASK)
|
|
||||||
tile += animateoffs(tile, obj);
|
|
||||||
|
|
||||||
if (((obj & 16384) == 16384) && (globalorientation & CSTAT_WALL_ROTATE_90) && RotTile(tile).newtile != -1)
|
|
||||||
tile = RotTile(tile).newtile;
|
|
||||||
}
|
|
||||||
|
|
||||||
// x1, y1: in/out
|
// x1, y1: in/out
|
||||||
// rest x/y: out
|
// rest x/y: out
|
||||||
|
@ -196,22 +184,12 @@ static inline void get_floorspr_points(T const * const spr, int32_t px, int32_t
|
||||||
|
|
||||||
inline int widthBits(int num)
|
inline int widthBits(int num)
|
||||||
{
|
{
|
||||||
int w = tileWidth(num);
|
return sizeToBits(tileWidth(num));
|
||||||
int j = 15;
|
|
||||||
|
|
||||||
while ((j > 1) && ((1 << j) > w))
|
|
||||||
j--;
|
|
||||||
return j;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int heightBits(int num)
|
inline int heightBits(int num)
|
||||||
{
|
{
|
||||||
int w = tileHeight(num);
|
return sizeToBits(tileHeight(num));
|
||||||
int j = 15;
|
|
||||||
|
|
||||||
while ((j > 1) && ((1 << j) > w))
|
|
||||||
j--;
|
|
||||||
return j;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -114,13 +114,24 @@ static inline float polymost_invsqrt_approximation(float x)
|
||||||
return 1.f / sqrtf(x);
|
return 1.f / sqrtf(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
float sectorVisibility(int sectnum)
|
static float sectorVisibility(int sectnum)
|
||||||
{
|
{
|
||||||
// Beware of wraparound madness...
|
// Beware of wraparound madness...
|
||||||
int v = sector[sectnum].visibility;
|
int v = sector[sectnum].visibility;
|
||||||
return v? ((uint8_t)(v + 16)) / 16.f : 1.f;
|
return v? ((uint8_t)(v + 16)) / 16.f : 1.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T> static FORCE_INLINE void tileUpdatePicnum(T* const tileptr, int const obj)
|
||||||
|
{
|
||||||
|
auto& tile = *tileptr;
|
||||||
|
|
||||||
|
if (picanm[tile].sf & PICANM_ANIMTYPE_MASK)
|
||||||
|
tile += animateoffs(tile, obj);
|
||||||
|
|
||||||
|
if (((obj & 16384) == 16384) && (globalorientation & CSTAT_WALL_ROTATE_90) && RotTile(tile).newtile != -1)
|
||||||
|
tile = RotTile(tile).newtile;
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
//Use this for both initialization and uninitialization of OpenGL.
|
//Use this for both initialization and uninitialization of OpenGL.
|
||||||
|
|
|
@ -103,4 +103,14 @@ inline void fillshort(void* buff, size_t count, uint16_t clear)
|
||||||
template<typename T> inline constexpr T Sgn(const T& val) { return (val > 0) - (val < 0); }
|
template<typename T> inline constexpr T Sgn(const T& val) { return (val > 0) - (val < 0); }
|
||||||
|
|
||||||
|
|
||||||
|
inline int sizeToBits(int w)
|
||||||
|
{
|
||||||
|
int j = 15;
|
||||||
|
|
||||||
|
while ((j > 1) && ((1 << j) > w))
|
||||||
|
j--;
|
||||||
|
return j;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
688
source/core/rendering/render.cpp
Normal file
688
source/core/rendering/render.cpp
Normal file
|
@ -0,0 +1,688 @@
|
||||||
|
// renderer draft. This code is not for release!
|
||||||
|
#include "glbackend/glbackend.h"
|
||||||
|
#include "build.h"
|
||||||
|
#include "hw_vrmodes.h"
|
||||||
|
#include "v_draw.h"
|
||||||
|
#include "gamecvars.h"
|
||||||
|
#include "binaryangle.h"
|
||||||
|
#include "automap.h"
|
||||||
|
#include "hw_clipper.h"
|
||||||
|
#include "hw_drawstructs.h"
|
||||||
|
#include "hw_clock.h"
|
||||||
|
#include "render.h"
|
||||||
|
#include "printf.h"
|
||||||
|
#include "v_video.h"
|
||||||
|
#include "flatvertices.h"
|
||||||
|
|
||||||
|
angle_t FrustumAngle(float ratio, float fov, float pitch)
|
||||||
|
{
|
||||||
|
float tilt = fabs(pitch);
|
||||||
|
|
||||||
|
// If the pitch is larger than this you can look all around at a FOV of 90°
|
||||||
|
if (tilt > 46.0f) return 0xffffffff;
|
||||||
|
|
||||||
|
// ok, this is a gross hack that barely works...
|
||||||
|
// but at least it doesn't overestimate too much...
|
||||||
|
// todo: integrate roll into the calculation
|
||||||
|
double floatangle = 2.0 + (45.0 + ((tilt / 1.9))) * fov * 48.0 / AspectMultiplier(ratio) / 90.0;
|
||||||
|
angle_t a1 = DAngle(floatangle).BAMs();
|
||||||
|
if (a1 >= ANGLE_180) return 0xffffffff;
|
||||||
|
return a1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// note that these return values in renderer coordinate space with inverted sign!
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
float CeilingAtPoint(sectortype* sec, float dax, float day)
|
||||||
|
{
|
||||||
|
if (!(sec->ceilingstat & CSTAT_SECTOR_SLOPE))
|
||||||
|
return float(sec->ceilingz);
|
||||||
|
|
||||||
|
auto wal = &wall[sec->wallptr];
|
||||||
|
auto wal2 = &wall[wal->point2];
|
||||||
|
|
||||||
|
vec2_t d = { wal2->x - wal->x, wal2->y - wal->y };
|
||||||
|
|
||||||
|
int i = ksqrt(uhypsq(d.x, d.y)) << 5;
|
||||||
|
if (i == 0) return sec->ceilingz;
|
||||||
|
|
||||||
|
float const j = (d.x * (day - wal->y) - d.y * (dax - wal->x)) * (1.f / 8.f);
|
||||||
|
return -float(sec->ceilingz) + (sec->ceilingheinum * j) / i;
|
||||||
|
}
|
||||||
|
|
||||||
|
float FloorAtPoint(usectorptr_t sec, float dax, float day)
|
||||||
|
{
|
||||||
|
if (!(sec->floorstat & CSTAT_SECTOR_SLOPE))
|
||||||
|
return float(sec->floorz);
|
||||||
|
|
||||||
|
auto wal = &wall[sec->wallptr];
|
||||||
|
auto wal2 = &wall[wal->point2];
|
||||||
|
|
||||||
|
vec2_t d = { wal2->x - wal->x, wal2->y - wal->y };
|
||||||
|
|
||||||
|
int i = ksqrt(uhypsq(d.x, d.y)) << 5;
|
||||||
|
if (i == 0) return sec->floorz;
|
||||||
|
|
||||||
|
float const j = (d.x * (day - wal->y) - d.y * (dax - wal->x)) * (1.f / 8.f);
|
||||||
|
return -float(sec->floorz) + (sec->floorheinum * j) / i;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PlanesAtPoint(usectorptr_t sec, float dax, float day, float* pceilz, float* pflorz)
|
||||||
|
{
|
||||||
|
float ceilz = float(sec->ceilingz);
|
||||||
|
float florz = float(sec->floorz);
|
||||||
|
|
||||||
|
if (((sec->ceilingstat | sec->floorstat) & CSTAT_SECTOR_SLOPE) == CSTAT_SECTOR_SLOPE)
|
||||||
|
{
|
||||||
|
auto wal = &wall[sec->wallptr];
|
||||||
|
auto wal2 = &wall[wal->point2];
|
||||||
|
|
||||||
|
vec2_t d = { wal2->x - wal->x, wal2->y - wal->y };
|
||||||
|
|
||||||
|
int i = ksqrt(uhypsq(d.x, d.y)) << 5;
|
||||||
|
if (i != 0)
|
||||||
|
{
|
||||||
|
float const j = (d.x * (day - wal->y) - d.y * (dax - wal->x)) * (1.f / 8.f);
|
||||||
|
if (sec->ceilingstat & CSTAT_SECTOR_SLOPE) ceilz += (sec->ceilingheinum * j) / i;
|
||||||
|
if (sec->floorstat & CSTAT_SECTOR_SLOPE) florz += (sec->floorheinum * j) / i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Scale to render coordinates.
|
||||||
|
*pceilz = ceilz * -(1.f / 256.f);
|
||||||
|
*pflorz = florz * -(1.f / 256.f);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define NS namespace Newrender { // auto-format blocking #define.
|
||||||
|
NS
|
||||||
|
|
||||||
|
struct FBunch
|
||||||
|
{
|
||||||
|
int sectnum;
|
||||||
|
int startline;
|
||||||
|
int endline;
|
||||||
|
angle_t startangle; // in pseudo angles for the clipper
|
||||||
|
angle_t endangle;
|
||||||
|
};
|
||||||
|
|
||||||
|
const float aspect_factor = (1.28f / 1.333333f); // this factor gets applied by the original code - must check if needed or just an artifact of the weird math.
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Bunches are groups of continuous lines
|
||||||
|
// This array stores the amount of points per bunch,
|
||||||
|
// the view angles for each point and the line index for the starting line
|
||||||
|
//
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
class BunchDrawer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Clipper &clipper;
|
||||||
|
int LastBunch;
|
||||||
|
int StartTime;
|
||||||
|
TArray<FBunch> Bunches;
|
||||||
|
TArray<int> CompareData;
|
||||||
|
double viewx, viewy;
|
||||||
|
FixedBitArray<MAXSECTORS> gotsector;
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
public:
|
||||||
|
BunchDrawer(Clipper& c, vec2_t& view) : clipper(c)
|
||||||
|
{
|
||||||
|
viewx = view.x * (1/ 16.f);
|
||||||
|
viewy = view.y * -(1/ 16.f);
|
||||||
|
StartScene();
|
||||||
|
clipper.SetViewpoint(DVector2(viewx, viewy));
|
||||||
|
for (int i = 0; i < numwalls; i++)
|
||||||
|
{
|
||||||
|
// Precalculate the clip angles to avoid doing this repeatedly during level traversal.
|
||||||
|
// Reverse the orientation so that startangle and endangle are properly ordered.
|
||||||
|
wall[i].clipangle = 0 - clipper.PointToPseudoAngle(wall[i].x * (1 / 16.f), wall[i].y * (-1 / 16.f));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
private:
|
||||||
|
void StartScene()
|
||||||
|
{
|
||||||
|
LastBunch = 0;
|
||||||
|
StartTime = I_msTime();
|
||||||
|
Bunches.Clear();
|
||||||
|
CompareData.Clear();
|
||||||
|
gotsector.Zero();
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
void StartBunch(int sectnum, int linenum, angle_t startan, angle_t endan)
|
||||||
|
{
|
||||||
|
FBunch* bunch = &Bunches[LastBunch = Bunches.Reserve(1)];
|
||||||
|
|
||||||
|
bunch->sectnum = sectnum;
|
||||||
|
bunch->startline = bunch->endline = linenum;
|
||||||
|
bunch->startangle = startan;
|
||||||
|
bunch->endangle = endan;
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
void AddLineToBunch(int line, int newan)
|
||||||
|
{
|
||||||
|
Bunches[LastBunch].endline++;
|
||||||
|
Bunches[LastBunch].endangle = newan;
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
void DeleteBunch(int index)
|
||||||
|
{
|
||||||
|
Bunches[index] = Bunches.Last();
|
||||||
|
Bunches.Pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CheckClip(walltype* wal)
|
||||||
|
{
|
||||||
|
auto pt2 = &wall[wal->point2];
|
||||||
|
sectortype* backsector = §or[wal->nextsector];
|
||||||
|
sectortype* frontsector = §or[wall[wal->nextwall].nextsector];
|
||||||
|
float bs_floorheight1;
|
||||||
|
float bs_floorheight2;
|
||||||
|
float bs_ceilingheight1;
|
||||||
|
float bs_ceilingheight2;
|
||||||
|
float fs_floorheight1;
|
||||||
|
float fs_floorheight2;
|
||||||
|
float fs_ceilingheight1;
|
||||||
|
float fs_ceilingheight2;
|
||||||
|
|
||||||
|
// Mirrors and horizons always block the view
|
||||||
|
//if (linedef->special==Line_Mirror || linedef->special==Line_Horizon) return true;
|
||||||
|
|
||||||
|
PlanesAtPoint(frontsector, wal->x, wal->y, &fs_ceilingheight1, &fs_floorheight1);
|
||||||
|
PlanesAtPoint(frontsector, pt2->x, pt2->y, &fs_ceilingheight2, &fs_floorheight2);
|
||||||
|
|
||||||
|
PlanesAtPoint(backsector, wal->x, wal->y, &bs_ceilingheight1, &bs_floorheight1);
|
||||||
|
PlanesAtPoint(backsector, pt2->x, pt2->y, &bs_ceilingheight2, &bs_floorheight2);
|
||||||
|
|
||||||
|
// now check for closed sectors! No idea if we really need the sky checks. We'll see.
|
||||||
|
if (bs_ceilingheight1 <= fs_floorheight1 && bs_ceilingheight2 <= fs_floorheight2)
|
||||||
|
{
|
||||||
|
// backsector's ceiling is below frontsector's floor.
|
||||||
|
if (frontsector->ceilingstat & backsector->ceilingstat & CSTAT_SECTOR_SKY) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fs_ceilingheight1 <= bs_floorheight1 && fs_ceilingheight2 <= bs_floorheight2)
|
||||||
|
{
|
||||||
|
// backsector's floor is above frontsector's ceiling
|
||||||
|
if (frontsector->floorstat & backsector->floorstat & CSTAT_SECTOR_SKY) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bs_ceilingheight1 <= bs_floorheight1 && bs_ceilingheight2 <= bs_floorheight2)
|
||||||
|
{
|
||||||
|
// backsector is closed
|
||||||
|
if (frontsector->ceilingstat & backsector->ceilingstat & CSTAT_SECTOR_SKY) return false;
|
||||||
|
if (frontsector->floorstat & backsector->floorstat & CSTAT_SECTOR_SKY) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// ClipLine
|
||||||
|
// Clips the given segment
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
CL_Skip = 0,
|
||||||
|
CL_Draw = 1,
|
||||||
|
CL_Pass = 2,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
int ClipLine(int line)
|
||||||
|
{
|
||||||
|
angle_t startAngle, endAngle;
|
||||||
|
auto wal = &wall[line];
|
||||||
|
|
||||||
|
startAngle = wal->clipangle;
|
||||||
|
endAngle = wall[wal->point2].clipangle;
|
||||||
|
|
||||||
|
// Back side, i.e. backface culling - read: endAngle >= startAngle!
|
||||||
|
if (startAngle - endAngle < ANGLE_180)
|
||||||
|
{
|
||||||
|
return CL_Skip;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!clipper.SafeCheckRange(startAngle, endAngle))
|
||||||
|
{
|
||||||
|
return CL_Skip;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wal->nextwall == -1 || (wal->cstat & CSTAT_WALL_1WAY) || CheckClip(wal))
|
||||||
|
{
|
||||||
|
// one-sided
|
||||||
|
clipper.SafeAddClipRange(startAngle, endAngle);
|
||||||
|
return CL_Draw;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return CL_Draw | CL_Pass;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
void ProcessBunch(int bnch)
|
||||||
|
{
|
||||||
|
FBunch* bunch = &Bunches[bnch];
|
||||||
|
|
||||||
|
ClipWall.Clock();
|
||||||
|
for (int i = bunch->startline; i <= bunch->endline; i++)
|
||||||
|
{
|
||||||
|
int clipped = ClipLine(i);
|
||||||
|
|
||||||
|
if (clipped & CL_Draw)
|
||||||
|
{
|
||||||
|
show2dwall.Set(i);
|
||||||
|
|
||||||
|
//if (gl_render_walls)
|
||||||
|
{
|
||||||
|
SetupWall.Clock();
|
||||||
|
|
||||||
|
HWWall hwwall;
|
||||||
|
//Printf("Rendering wall %d\n", i);
|
||||||
|
hwwall.Process(nullptr, &wall[i], §or[bunch->sectnum], wall[i].nextsector<0? nullptr : §or[wall[i].nextsector]);
|
||||||
|
rendered_lines++;
|
||||||
|
|
||||||
|
SetupWall.Unclock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (clipped & CL_Pass)
|
||||||
|
{
|
||||||
|
ClipWall.Unclock();
|
||||||
|
ProcessSector(wall[i].nextsector);
|
||||||
|
ClipWall.Clock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ClipWall.Unclock();
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
int WallInFront(int wall1, int wall2)
|
||||||
|
{
|
||||||
|
double x1s = WallStartX(wall1);
|
||||||
|
double y1s = WallStartY(wall1);
|
||||||
|
double x1e = WallEndX(wall1);
|
||||||
|
double y1e = WallEndY(wall1);
|
||||||
|
double x2s = WallStartX(wall2);
|
||||||
|
double y2s = WallStartY(wall2);
|
||||||
|
double x2e = WallEndX(wall2);
|
||||||
|
double y2e = WallEndY(wall2);
|
||||||
|
|
||||||
|
double dx = x1e - x1s;
|
||||||
|
double dy = y1e - y1s;
|
||||||
|
|
||||||
|
double t1 = PointOnLineSide(x2s, y2s, x1s, y1s, dx, dy);
|
||||||
|
double t2 = PointOnLineSide(x2e, y2e, x1s, y1s, dx, dy);
|
||||||
|
if (t1 == 0)
|
||||||
|
{
|
||||||
|
if (t2 == 0) return(-1);
|
||||||
|
t1 = t2;
|
||||||
|
}
|
||||||
|
if (t2 == 0) t2 = t1;
|
||||||
|
|
||||||
|
if ((t1 * t2) >= 0)
|
||||||
|
{
|
||||||
|
t2 = PointOnLineSide(viewx, viewy, x1s, y1s, dx, dy);
|
||||||
|
return((t2 * t1) < 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
dx = x2e - x2s;
|
||||||
|
dy = y2e - y2s;
|
||||||
|
t1 = PointOnLineSide(x1s, y1s, x2s, y2s, dx, dy);
|
||||||
|
t2 = PointOnLineSide(x1e, y1e, x2s, y2s, dx, dy);
|
||||||
|
if (t1 == 0)
|
||||||
|
{
|
||||||
|
if (t2 == 0) return(-1);
|
||||||
|
t1 = t2;
|
||||||
|
}
|
||||||
|
if (t2 == 0) t2 = t1;
|
||||||
|
if ((t1 * t2) >= 0)
|
||||||
|
{
|
||||||
|
t2 = PointOnLineSide(viewx, viewy, x2s, y2s, dx, dy);
|
||||||
|
return((t2 * t1) >= 0);
|
||||||
|
}
|
||||||
|
return(-2);
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// This is a bit more complicated than it looks because angles can wrap
|
||||||
|
// around so we can only compare angle differences.
|
||||||
|
//
|
||||||
|
// Rules:
|
||||||
|
// 1. Any bunch can span at most 180°.
|
||||||
|
// 2. 2 bunches can never overlap at both ends
|
||||||
|
// 3. if there is an overlap one of the 2 starting points must be in the
|
||||||
|
// overlapping area.
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
int BunchInFront(FBunch* b1, FBunch* b2)
|
||||||
|
{
|
||||||
|
angle_t anglecheck, endang;
|
||||||
|
|
||||||
|
if (b2->startangle - b1->startangle < b1->endangle - b1->startangle)
|
||||||
|
{
|
||||||
|
// we have an overlap at b2->startangle
|
||||||
|
anglecheck = b2->startangle - b1->startangle;
|
||||||
|
|
||||||
|
// Find the wall in b1 that overlaps b2->startangle
|
||||||
|
for (int i = b1->startline; i <= b1->endline; i++)
|
||||||
|
{
|
||||||
|
endang = wall[wall[i].point2].clipangle - b1->startangle;
|
||||||
|
if (endang > anglecheck)
|
||||||
|
{
|
||||||
|
// found a line
|
||||||
|
int ret = WallInFront(b2->startline, i);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (b1->startangle - b2->startangle < b2->endangle - b2->startangle)
|
||||||
|
{
|
||||||
|
// we have an overlap at b1->startangle
|
||||||
|
anglecheck = b1->startangle - b2->startangle;
|
||||||
|
|
||||||
|
// Find the wall in b2 that overlaps b1->startangle
|
||||||
|
for (int i = b2->startline; i <= b2->endline; i++)
|
||||||
|
{
|
||||||
|
endang = wall[wall[i].point2].clipangle - b2->startangle;
|
||||||
|
if (endang > anglecheck)
|
||||||
|
{
|
||||||
|
// found a line
|
||||||
|
int ret = WallInFront(i, b1->startline);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// we have no overlap
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
int FindClosestBunch()
|
||||||
|
{
|
||||||
|
int closest = 0; //Almost works, but not quite :(
|
||||||
|
|
||||||
|
CompareData.Clear();
|
||||||
|
for (unsigned i = 1; i < Bunches.Size(); i++)
|
||||||
|
{
|
||||||
|
switch (BunchInFront(&Bunches[i], &Bunches[closest]))
|
||||||
|
{
|
||||||
|
case 0: // i is in front
|
||||||
|
closest = i;
|
||||||
|
continue;
|
||||||
|
|
||||||
|
case 1: // i is behind
|
||||||
|
continue;
|
||||||
|
|
||||||
|
default: // can't determine
|
||||||
|
CompareData.Push(i); // mark for later comparison
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// we need to do a second pass to see how the marked bunches relate to the currently closest one.
|
||||||
|
for (unsigned i = 0; i < CompareData.Size(); i++)
|
||||||
|
{
|
||||||
|
switch (BunchInFront(&Bunches[CompareData[i]], &Bunches[closest]))
|
||||||
|
{
|
||||||
|
case 0: // is in front
|
||||||
|
closest = CompareData[i];
|
||||||
|
CompareData[i] = CompareData.Last();
|
||||||
|
CompareData.Pop();
|
||||||
|
i = 0; // we need to recheck everything that's still marked.
|
||||||
|
continue;
|
||||||
|
|
||||||
|
case 1: // is behind
|
||||||
|
CompareData[i] = CompareData.Last();
|
||||||
|
CompareData.Pop();
|
||||||
|
i--;
|
||||||
|
continue;
|
||||||
|
|
||||||
|
default:
|
||||||
|
continue;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return closest;
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
void ProcessSector(int sectnum)
|
||||||
|
{
|
||||||
|
if (gotsector[sectnum]) return;
|
||||||
|
gotsector.Set(sectnum);
|
||||||
|
|
||||||
|
Bsp.Clock();
|
||||||
|
|
||||||
|
auto sect = §or[sectnum];
|
||||||
|
bool inbunch;
|
||||||
|
angle_t startangle;
|
||||||
|
|
||||||
|
//if (sect->validcount == StartTime) return;
|
||||||
|
//sect->validcount = StartTime;
|
||||||
|
|
||||||
|
#if 0//ndef BUILD_TEST
|
||||||
|
DoSector(sectnum, false);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//Todo: process subsectors
|
||||||
|
inbunch = false;
|
||||||
|
for (int i = 0; i < sect->wallnum; i++)
|
||||||
|
{
|
||||||
|
auto thiswall = &wall[sect->wallptr + i];
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
// For displaying positions in debugger
|
||||||
|
DVector2 start = { WallStartX(thiswall), WallStartY(thiswall) };
|
||||||
|
DVector2 end = { WallStartX(thiswall->point2), WallStartY(thiswall->point2) };
|
||||||
|
#endif
|
||||||
|
angle_t ang1 = thiswall->clipangle;
|
||||||
|
angle_t ang2 = wall[thiswall->point2].clipangle;
|
||||||
|
|
||||||
|
if (ang1 - ang2 < ANGLE_180)
|
||||||
|
{
|
||||||
|
// Backside
|
||||||
|
inbunch = false;
|
||||||
|
}
|
||||||
|
else if (!clipper.SafeCheckRange(ang1, ang2))
|
||||||
|
{
|
||||||
|
// is it visible?
|
||||||
|
inbunch = false;
|
||||||
|
}
|
||||||
|
else if (!inbunch || ang2 - startangle >= ANGLE_180)
|
||||||
|
{
|
||||||
|
// don't let a bunch span more than 180° to avoid problems.
|
||||||
|
// This limitation ensures that the combined range of 2
|
||||||
|
// bunches will always be less than 360° which simplifies
|
||||||
|
// the distance comparison code because it prevents a
|
||||||
|
// situation where 2 bunches may overlap at both ends.
|
||||||
|
|
||||||
|
startangle = ang1;
|
||||||
|
StartBunch(sectnum, sect->wallptr + i, ang1, ang2);
|
||||||
|
inbunch = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AddLineToBunch(sect->wallptr + i, ang2);
|
||||||
|
}
|
||||||
|
if (thiswall->point2 != sect->wallptr + i + 1) inbunch = false;
|
||||||
|
}
|
||||||
|
Bsp.Unclock();
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
public:
|
||||||
|
void RenderScene(int viewsector)
|
||||||
|
{
|
||||||
|
ProcessSector(viewsector);
|
||||||
|
while (Bunches.Size() > 0)
|
||||||
|
{
|
||||||
|
int closest = FindClosestBunch();
|
||||||
|
ProcessBunch(closest);
|
||||||
|
DeleteBunch(closest);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// R_FrustumAngle
|
||||||
|
//
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
static void SetProjection(const FRotator& rotation, FAngle fov)
|
||||||
|
{
|
||||||
|
auto vrmode = VRMode::GetVRMode(false);
|
||||||
|
const int eyeCount = vrmode->mEyeCount;
|
||||||
|
const auto& eye = vrmode->mEyes[0];
|
||||||
|
|
||||||
|
int width = (windowxy2.x - windowxy1.x + 1);
|
||||||
|
int height = (windowxy2.y - windowxy1.y + 1);
|
||||||
|
float ratio = ActiveRatio(width, height, nullptr);
|
||||||
|
float fovratio;
|
||||||
|
|
||||||
|
if (ratio >= 1.3f)
|
||||||
|
{
|
||||||
|
fovratio = 1.333333f;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fovratio = ratio;
|
||||||
|
}
|
||||||
|
ratio *= aspect_factor; // this factor gets applied by the original code - must check if needed or just an artifact of the weird math.
|
||||||
|
fovratio *= aspect_factor;
|
||||||
|
auto rotmat = eye.GetProjection(fov.Degrees, ratio, fovratio);
|
||||||
|
renderSetProjectionMatrix(rotmat.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SetViewMatrix(const FRotator& angles, float vx, float vy, float vz, bool mirror, bool planemirror)
|
||||||
|
{
|
||||||
|
float mult = mirror ? -1.f : 1.f;
|
||||||
|
float planemult = planemirror ? -aspect_factor : aspect_factor;// Level->info->pixelstretch : Level->info->pixelstretch;
|
||||||
|
VSMatrix mViewMatrix;
|
||||||
|
|
||||||
|
mViewMatrix.loadIdentity();
|
||||||
|
mViewMatrix.rotate(angles.Roll.Degrees, 0.0f, 0.0f, 1.0f);
|
||||||
|
mViewMatrix.rotate(angles.Pitch.Degrees, 1.0f, 0.0f, 0.0f);
|
||||||
|
mViewMatrix.rotate(angles.Yaw.Degrees, 0.0f, mult, 0.0f);
|
||||||
|
mViewMatrix.translate(vx * mult, -vz * planemult, -vy);
|
||||||
|
mViewMatrix.scale(-mult, planemult, 1);
|
||||||
|
renderSetViewMatrix(mViewMatrix.get());
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
using namespace Newrender;
|
||||||
|
|
||||||
|
void render_drawrooms(vec3_t& position, int sectnum, fixed_t q16angle, fixed_t q16horizon, float rollang, float fov, bool mirror, bool planemirror)
|
||||||
|
{
|
||||||
|
GLInterface.ClearDepth();
|
||||||
|
GLInterface.EnableBlend(false);
|
||||||
|
GLInterface.EnableAlphaTest(false);
|
||||||
|
GLInterface.EnableDepthTest(true);
|
||||||
|
GLInterface.SetDepthFunc(DF_LEqual);
|
||||||
|
GLInterface.SetRenderStyle(LegacyRenderStyles[STYLE_Translucent]);
|
||||||
|
|
||||||
|
|
||||||
|
FRotator rotation;
|
||||||
|
rotation.Yaw = -90.f + q16ang(q16angle).asdeg();
|
||||||
|
rotation.Pitch = -HorizToPitch(q16horizon);
|
||||||
|
rotation.Roll = rollang;
|
||||||
|
SetProjection(rotation, fov);
|
||||||
|
SetViewMatrix(rotation, position.x / 16.f, -position.y / 16.f, -position.z / 256.f, mirror, planemirror);
|
||||||
|
|
||||||
|
renderSetViewpoint(position.x / 16.f, -position.y / 16.f, -position.z / 256.f);
|
||||||
|
renderSetVisibility((1.f / (65536.f * 65536.f)) * g_visibility / r_ambientlight);// MulScale(g_visibility, MulScale(xdimenscale * viewingrangerecip * fviewingrange / r_ambientlight);
|
||||||
|
renderBeginScene();
|
||||||
|
|
||||||
|
Clipper clipper;
|
||||||
|
// fixme: This does not consider the roll angle yet. Pitch disabled to get consistent values during testing.
|
||||||
|
auto fa = FrustumAngle(16.f / 9, r_fov, 0);// rotation.Pitch.Degrees);
|
||||||
|
|
||||||
|
angle_t rotang = q16ang(q16angle).asbam();
|
||||||
|
clipper.SafeAddClipRangeRealAngles(rotang + fa, rotang - fa);
|
||||||
|
|
||||||
|
BunchDrawer drawer(clipper, position.vec2);
|
||||||
|
|
||||||
|
drawer.RenderScene(sectnum);
|
||||||
|
|
||||||
|
renderFinishScene();
|
||||||
|
|
||||||
|
GLInterface.SetDepthFunc(DF_LEqual);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
68
source/core/rendering/render.h
Normal file
68
source/core/rendering/render.h
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
#pragma once
|
||||||
|
#include "build.h"
|
||||||
|
|
||||||
|
|
||||||
|
// y is negated so that the orientation is the same as in GZDoom, in order to use its utilities.
|
||||||
|
// The render code should NOT use Build coordinates for anything!
|
||||||
|
|
||||||
|
inline double WallStartX(int wallnum)
|
||||||
|
{
|
||||||
|
return wall[wallnum].x * (1 / 16.);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline double WallStartY(int wallnum)
|
||||||
|
{
|
||||||
|
return wall[wallnum].y * (1 / -16.);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline double WallEndX(int wallnum)
|
||||||
|
{
|
||||||
|
return wall[wall[wallnum].point2].x * (1 / 16.);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline double WallEndY(int wallnum)
|
||||||
|
{
|
||||||
|
return wall[wall[wallnum].point2].y * (1 / -16.);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline double WallStartX(const walltype* wallnum)
|
||||||
|
{
|
||||||
|
return wallnum->x * (1 / 16.);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline double WallStartY(const walltype* wallnum)
|
||||||
|
{
|
||||||
|
return wallnum->y * (1 / -16.);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline double WallEndX(const walltype* wallnum)
|
||||||
|
{
|
||||||
|
return wall[wallnum->point2].x * (1 / 16.);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline double WallEndY(const walltype* wallnum)
|
||||||
|
{
|
||||||
|
return wall[wallnum->point2].y * (1 / -16.);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline double SpriteX(int wallnum)
|
||||||
|
{
|
||||||
|
return sprite[wallnum].x * (1 / 16.);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline double SpriteY(int wallnum)
|
||||||
|
{
|
||||||
|
return sprite[wallnum].y * (1 / -16.);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline double PointOnLineSide(double x, double y, double linex, double liney, double deltax, double deltay)
|
||||||
|
{
|
||||||
|
return (x - linex) * deltay - (y - liney) * deltax;
|
||||||
|
}
|
||||||
|
|
||||||
|
float CeilingAtPoint(sectortype* sec, float dax, float day);
|
||||||
|
float FloorAtPoint(usectorptr_t sec, float dax, float day);
|
||||||
|
void PlanesAtPoint(usectorptr_t sec, float dax, float day, float* ceilz, float* florz);
|
||||||
|
|
||||||
|
void render_drawrooms(vec3_t& position, int sectnum, fixed_t q16angle, fixed_t q16horizon, float rollang, float fov, bool mirror, bool planemirror);
|
||||||
|
|
|
@ -32,7 +32,6 @@ class Clipper
|
||||||
DVector2 viewpoint;
|
DVector2 viewpoint;
|
||||||
bool blocked = false;
|
bool blocked = false;
|
||||||
|
|
||||||
static angle_t AngleToPseudo(angle_t ang);
|
|
||||||
bool IsRangeVisible(angle_t startangle, angle_t endangle);
|
bool IsRangeVisible(angle_t startangle, angle_t endangle);
|
||||||
void RemoveRange(ClipNode * cn);
|
void RemoveRange(ClipNode * cn);
|
||||||
void AddClipRange(angle_t startangle, angle_t endangle);
|
void AddClipRange(angle_t startangle, angle_t endangle);
|
||||||
|
@ -44,6 +43,7 @@ public:
|
||||||
Clipper();
|
Clipper();
|
||||||
|
|
||||||
void Clear();
|
void Clear();
|
||||||
|
static angle_t AngleToPseudo(angle_t ang);
|
||||||
|
|
||||||
void Free(ClipNode *node)
|
void Free(ClipNode *node)
|
||||||
{
|
{
|
||||||
|
|
392
source/core/rendering/scene/hw_drawstructs.h
Normal file
392
source/core/rendering/scene/hw_drawstructs.h
Normal file
|
@ -0,0 +1,392 @@
|
||||||
|
#pragma once
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// One wall segment in the draw list
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
#include "renderstyle.h"
|
||||||
|
#include "textures.h"
|
||||||
|
#include "fcolormap.h"
|
||||||
|
#include "build.h"
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(disable:4244)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct HWHorizonInfo;
|
||||||
|
struct HWSkyInfo;
|
||||||
|
class FMaterial;
|
||||||
|
struct FTexCoordInfo;
|
||||||
|
struct FSectorPortalGroup;
|
||||||
|
struct FFlatVertex;
|
||||||
|
struct FLinePortalSpan;
|
||||||
|
struct FDynLightData;
|
||||||
|
class VSMatrix;
|
||||||
|
struct FSpriteModelFrame;
|
||||||
|
class FRenderState;
|
||||||
|
struct HWDecal;
|
||||||
|
|
||||||
|
struct HWSectorPlane
|
||||||
|
{
|
||||||
|
FTextureID texture;
|
||||||
|
//secplane_t plane;
|
||||||
|
float Texheight;
|
||||||
|
float Angle;
|
||||||
|
FVector2 Offs;
|
||||||
|
FVector2 Scale;
|
||||||
|
|
||||||
|
void GetFromSector(sectortype* sec, int ceiling)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Offs.X = (float)sec->GetXOffset(ceiling);
|
||||||
|
Offs.Y = (float)sec->GetYOffset(ceiling);
|
||||||
|
Scale.X = (float)sec->GetXScale(ceiling);
|
||||||
|
Scale.Y = (float)sec->GetYScale(ceiling);
|
||||||
|
Angle = (float)sec->GetAngle(ceiling).Degrees;
|
||||||
|
texture = sec->GetTexture(ceiling);
|
||||||
|
plane = sec->GetSecPlane(ceiling);
|
||||||
|
Texheight = (float)((ceiling == sector_t::ceiling) ? plane.fD() : -plane.fD());
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
enum HWRenderStyle
|
||||||
|
{
|
||||||
|
STYLEHW_Normal, // default
|
||||||
|
STYLEHW_Solid, // drawn solid (needs special treatment for sprites)
|
||||||
|
STYLEHW_NoAlphaTest, // disable alpha test
|
||||||
|
};
|
||||||
|
|
||||||
|
enum WallTypes
|
||||||
|
{
|
||||||
|
RENDERWALL_NONE,
|
||||||
|
RENDERWALL_TOP,
|
||||||
|
RENDERWALL_M1S,
|
||||||
|
RENDERWALL_M2S,
|
||||||
|
RENDERWALL_BOTTOM,
|
||||||
|
RENDERWALL_FOGBOUNDARY,
|
||||||
|
RENDERWALL_MIRRORSURFACE,
|
||||||
|
RENDERWALL_M2SNF,
|
||||||
|
RENDERWALL_COLOR,
|
||||||
|
// Insert new types at the end!
|
||||||
|
};
|
||||||
|
|
||||||
|
enum PortalTypes
|
||||||
|
{
|
||||||
|
PORTALTYPE_SKY,
|
||||||
|
PORTALTYPE_HORIZON,
|
||||||
|
PORTALTYPE_SKYBOX,
|
||||||
|
PORTALTYPE_SECTORSTACK,
|
||||||
|
PORTALTYPE_PLANEMIRROR,
|
||||||
|
PORTALTYPE_MIRROR,
|
||||||
|
PORTALTYPE_LINETOLINE,
|
||||||
|
};
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// One sector plane, still in fixed point
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
struct HWSeg
|
||||||
|
{
|
||||||
|
float x1,x2;
|
||||||
|
float y1,y2;
|
||||||
|
float fracleft, fracright;
|
||||||
|
|
||||||
|
FVector3 Normal() const
|
||||||
|
{
|
||||||
|
// we do not use the vector math inlines here because they are not optimized for speed but accuracy in the playsim and this is called quite frequently.
|
||||||
|
float x = y2 - y1;
|
||||||
|
float y = x1 - x2;
|
||||||
|
float ilength = 1.f / sqrtf(x*x + y*y);
|
||||||
|
return FVector3(x * ilength, 0, y * ilength);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct texcoord
|
||||||
|
{
|
||||||
|
float u,v;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct HWDrawInfo;
|
||||||
|
|
||||||
|
class HWWall
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static const char passflag[];
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
HWF_CLAMPX=1,
|
||||||
|
HWF_CLAMPY=2,
|
||||||
|
HWF_SKYHACK=4,
|
||||||
|
HWF_NOSPLIT=64,
|
||||||
|
HWF_TRANSLUCENT = 128,
|
||||||
|
HWF_NOSLICE = 256
|
||||||
|
};
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
RWF_BLANK = 0,
|
||||||
|
RWF_TEXTURED = 1, // actually not being used anymore because with buffers it's even less efficient not writing the texture coordinates - but leave it here
|
||||||
|
RWF_NORENDER = 8,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
LOLFT,
|
||||||
|
UPLFT,
|
||||||
|
UPRGT,
|
||||||
|
LORGT,
|
||||||
|
};
|
||||||
|
|
||||||
|
friend struct HWDrawList;
|
||||||
|
friend class HWPortal;
|
||||||
|
|
||||||
|
FGameTexture *texture;
|
||||||
|
|
||||||
|
HWSeg glseg;
|
||||||
|
float ztop[2],zbottom[2];
|
||||||
|
texcoord tcs[4];
|
||||||
|
float alpha;
|
||||||
|
|
||||||
|
ERenderStyle RenderStyle;
|
||||||
|
|
||||||
|
float ViewDistance;
|
||||||
|
float visibility;
|
||||||
|
short shade, palette, floorpal;
|
||||||
|
|
||||||
|
uint16_t flags;
|
||||||
|
uint8_t type;
|
||||||
|
|
||||||
|
int dynlightindex;
|
||||||
|
|
||||||
|
/*
|
||||||
|
union
|
||||||
|
{
|
||||||
|
// it's either one of them but never more!
|
||||||
|
FSectorPortal *secportal; // sector portal (formerly skybox)
|
||||||
|
HWSkyInfo * sky; // for normal sky
|
||||||
|
HWHorizonInfo * horizon; // for horizon information
|
||||||
|
FSectorPortalGroup * portal; // stacked sector portals
|
||||||
|
secplane_t * planemirror; // for plane mirrors
|
||||||
|
FLinePortalSpan *lineportal; // line-to-line portals
|
||||||
|
};
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// these are not the same as ytop and ybottom!!!
|
||||||
|
float zceil[2];
|
||||||
|
float zfloor[2];
|
||||||
|
|
||||||
|
unsigned int vertindex;
|
||||||
|
unsigned int vertcount;
|
||||||
|
|
||||||
|
public:
|
||||||
|
walltype * seg;
|
||||||
|
sectortype *frontsector, *backsector;
|
||||||
|
//private:
|
||||||
|
|
||||||
|
void PutWall(HWDrawInfo *di, bool translucent);
|
||||||
|
void PutPortal(HWDrawInfo *di, int ptype, int plane);
|
||||||
|
void CheckTexturePosition();
|
||||||
|
|
||||||
|
void SetupLights(HWDrawInfo *di, FDynLightData &lightdata);
|
||||||
|
|
||||||
|
void MakeVertices(HWDrawInfo *di, bool nosplit);
|
||||||
|
|
||||||
|
void SkyPlane(HWDrawInfo *di, sectortype *sector, int plane, bool allowmirror);
|
||||||
|
void SkyLine(HWDrawInfo *di, sectortype *sec, walltype *line);
|
||||||
|
void SkyNormal(HWDrawInfo* di, sectortype* fs, FVector2& v1, FVector2& v2) {}
|
||||||
|
void SkyTop(HWDrawInfo *di, walltype * seg,sectortype * fs,sectortype * bs, FVector2& v1, FVector2& v2) {}
|
||||||
|
void SkyBottom(HWDrawInfo *di, walltype * seg,sectortype * fs,sectortype * bs, FVector2& v1, FVector2& v2) {}
|
||||||
|
|
||||||
|
bool DoHorizon(HWDrawInfo *di, walltype * seg,sectortype * fs, DVector2& v1, DVector2& v2);
|
||||||
|
|
||||||
|
bool SetWallCoordinates(walltype* seg, float topleft, float topright, float bottomleft, float bottomright);
|
||||||
|
|
||||||
|
void DoTexture(HWDrawInfo* di, walltype* wal, walltype* refwall, float yref, float topleft, float topright, float bottomleft, float bottomright);
|
||||||
|
void DoOneSidedTexture(HWDrawInfo *di, walltype * seg, sectortype* frontsector, sectortype* backsector, float topleft,float topright, float bottomleft,float bottomright);
|
||||||
|
void DoUpperTexture(HWDrawInfo* di, walltype* seg, sectortype* frontsector, sectortype* backsector, float topleft, float topright, float bottomleft, float bottomright);
|
||||||
|
void DoLowerTexture(HWDrawInfo* di, walltype* seg, sectortype* frontsector, sectortype* backsector, float topleft, float topright, float bottomleft, float bottomright);
|
||||||
|
|
||||||
|
void DoMidTexture(HWDrawInfo *di, walltype * seg,
|
||||||
|
sectortype * front, sectortype * back,
|
||||||
|
float fch1, float fch2, float ffh1, float ffh2,
|
||||||
|
float bch1, float bch2, float bfh1, float bfh2);
|
||||||
|
|
||||||
|
//void ProcessDecal(HWDrawInfo *di, DBaseDecal *decal, const FVector3 &normal);
|
||||||
|
//void ProcessDecals(HWDrawInfo *di);
|
||||||
|
|
||||||
|
int CreateVertices(FFlatVertex *&ptr, bool nosplit);
|
||||||
|
|
||||||
|
//int CountVertices();
|
||||||
|
|
||||||
|
void RenderWall(HWDrawInfo *di, FRenderState &state, int textured);
|
||||||
|
void RenderFogBoundary(HWDrawInfo *di, FRenderState &state);
|
||||||
|
void RenderMirrorSurface(HWDrawInfo *di, FRenderState &state);
|
||||||
|
void RenderTexturedWall(HWDrawInfo *di, FRenderState &state, int rflags);
|
||||||
|
void RenderTranslucentWall(HWDrawInfo *di, FRenderState &state);
|
||||||
|
|
||||||
|
public:
|
||||||
|
void Process(HWDrawInfo* di, walltype* seg, sectortype* frontsector, sectortype* backsector);
|
||||||
|
|
||||||
|
float PointOnSide(float x,float y)
|
||||||
|
{
|
||||||
|
return -((y-glseg.y1)*(glseg.x2-glseg.x1)-(x-glseg.x1)*(glseg.y2-glseg.y1));
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawWall(HWDrawInfo *di, FRenderState &state, bool translucent);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// One flat plane in the draw list
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
class HWFlat
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
sectortype * sector;
|
||||||
|
FGameTexture *texture;
|
||||||
|
|
||||||
|
float z; // the z position of the flat (only valid for non-sloped planes)
|
||||||
|
FColormap Colormap; // light and fog
|
||||||
|
PalEntry FlatColor;
|
||||||
|
PalEntry AddColor;
|
||||||
|
ERenderStyle renderstyle;
|
||||||
|
|
||||||
|
float alpha;
|
||||||
|
HWSectorPlane plane;
|
||||||
|
int lightlevel;
|
||||||
|
bool stack;
|
||||||
|
bool ceiling;
|
||||||
|
uint8_t renderflags;
|
||||||
|
uint8_t hacktype;
|
||||||
|
int iboindex;
|
||||||
|
//int vboheight;
|
||||||
|
|
||||||
|
int dynlightindex;
|
||||||
|
|
||||||
|
void CreateSkyboxVertices(FFlatVertex *buffer);
|
||||||
|
//void SetupLights(HWDrawInfo *di, FLightNode *head, FDynLightData &lightdata, int portalgroup);
|
||||||
|
|
||||||
|
void PutFlat(HWDrawInfo *di, bool fog = false);
|
||||||
|
void Process(HWDrawInfo *di, sectortype * model, int whichplane, bool notexture);
|
||||||
|
void ProcessSector(HWDrawInfo *di, sectortype * frontsector, int which = 7 /*SSRF_RENDERALL*/); // cannot use constant due to circular dependencies.
|
||||||
|
|
||||||
|
void DrawSubsectors(HWDrawInfo *di, FRenderState &state);
|
||||||
|
void DrawFlat(HWDrawInfo *di, FRenderState &state, bool translucent);
|
||||||
|
|
||||||
|
void DrawOtherPlanes(HWDrawInfo *di, FRenderState &state);
|
||||||
|
void DrawFloodPlanes(HWDrawInfo *di, FRenderState &state);
|
||||||
|
};
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// One sprite in the draw list
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
|
||||||
|
class HWSprite
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
int lightlevel;
|
||||||
|
uint8_t foglevel;
|
||||||
|
uint8_t hw_styleflags;
|
||||||
|
bool fullbright;
|
||||||
|
bool polyoffset;
|
||||||
|
FColormap Colormap;
|
||||||
|
FSpriteModelFrame * modelframe;
|
||||||
|
FRenderStyle RenderStyle;
|
||||||
|
int OverrideShader;
|
||||||
|
|
||||||
|
int translation;
|
||||||
|
int index;
|
||||||
|
float depth;
|
||||||
|
int vertexindex;
|
||||||
|
|
||||||
|
float topclip;
|
||||||
|
float bottomclip;
|
||||||
|
|
||||||
|
float x,y,z; // needed for sorting!
|
||||||
|
|
||||||
|
float ul,ur;
|
||||||
|
float vt,vb;
|
||||||
|
float x1,y1,z1;
|
||||||
|
float x2,y2,z2;
|
||||||
|
float trans;
|
||||||
|
int dynlightindex;
|
||||||
|
|
||||||
|
FGameTexture *texture;
|
||||||
|
spritetype * actor;
|
||||||
|
//TArray<lightlist_t> *lightlist;
|
||||||
|
DRotator Angles;
|
||||||
|
|
||||||
|
|
||||||
|
void SplitSprite(HWDrawInfo *di, sectortype * frontsector, bool translucent);
|
||||||
|
void PerformSpriteClipAdjustment(AActor *thing, const DVector2 &thingpos, float spriteheight);
|
||||||
|
bool CalculateVertices(HWDrawInfo *di, FVector3 *v, DVector3 *vp);
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
void CreateVertices(HWDrawInfo *di);
|
||||||
|
void PutSprite(HWDrawInfo *di, bool translucent);
|
||||||
|
void Process(HWDrawInfo *di, AActor* thing,sectortype * sector, int thruportal = false);
|
||||||
|
|
||||||
|
void DrawSprite(HWDrawInfo *di, FRenderState &state, bool translucent);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
struct DecalVertex
|
||||||
|
{
|
||||||
|
float x, y, z;
|
||||||
|
float u, v;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
struct HWDecal
|
||||||
|
{
|
||||||
|
FGameTexture *texture;
|
||||||
|
TArray<lightlist_t> *lightlist;
|
||||||
|
DBaseDecal *decal;
|
||||||
|
DecalVertex dv[4];
|
||||||
|
float zcenter;
|
||||||
|
unsigned int vertindex;
|
||||||
|
|
||||||
|
FRenderStyle renderstyle;
|
||||||
|
int lightlevel;
|
||||||
|
int rellight;
|
||||||
|
float alpha;
|
||||||
|
FColormap Colormap;
|
||||||
|
int dynlightindex;
|
||||||
|
sectortype *frontsector;
|
||||||
|
FVector3 Normal;
|
||||||
|
|
||||||
|
void DrawDecal(HWDrawInfo *di, FRenderState &state);
|
||||||
|
|
||||||
|
};
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
inline float Dist2(float x1,float y1,float x2,float y2)
|
||||||
|
{
|
||||||
|
return sqrtf((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool hw_SetPlaneTextureRotation(const HWSectorPlane * secplane, FGameTexture * gltexture, VSMatrix &mat);
|
||||||
|
void hw_GetDynModelLight(AActor *self, FDynLightData &modellightdata);
|
||||||
|
|
||||||
|
extern const float LARGE_VALUE;
|
||||||
|
|
||||||
|
struct FDynLightData;
|
||||||
|
struct FDynamicLight;
|
||||||
|
bool GetLight(FDynLightData& dld, int group, Plane& p, FDynamicLight* light, bool checkside);
|
||||||
|
void AddLightToList(FDynLightData &dld, int group, FDynamicLight* light, bool forceAttenuate);
|
1098
source/core/rendering/scene/hw_walls.cpp
Normal file
1098
source/core/rendering/scene/hw_walls.cpp
Normal file
File diff suppressed because it is too large
Load diff
|
@ -389,6 +389,11 @@ void renderSetVisibility(float vis)
|
||||||
vp.mGlobVis = vis;
|
vp.mGlobVis = vis;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void renderSetViewpoint(float x, float y, float z)
|
||||||
|
{
|
||||||
|
vp.mCameraPos = {x, y, z, 0};
|
||||||
|
}
|
||||||
|
|
||||||
void renderBeginScene()
|
void renderBeginScene()
|
||||||
{
|
{
|
||||||
assert(BufferLock == 0);
|
assert(BufferLock == 0);
|
||||||
|
|
|
@ -345,6 +345,7 @@ extern F2DDrawer twodpsp;
|
||||||
void renderSetProjectionMatrix(const float* p);
|
void renderSetProjectionMatrix(const float* p);
|
||||||
void renderSetViewMatrix(const float* p);
|
void renderSetViewMatrix(const float* p);
|
||||||
void renderSetVisibility(float v);
|
void renderSetVisibility(float v);
|
||||||
|
void renderSetViewpoint(float x, float y, float z);
|
||||||
void renderBeginScene();
|
void renderBeginScene();
|
||||||
void renderFinishScene();
|
void renderFinishScene();
|
||||||
void DrawRateStuff();
|
void DrawRateStuff();
|
||||||
|
|
Loading…
Reference in a new issue