From a14c0c80636728e022ae80cdba8e6bdee3495739 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Wed, 27 Apr 2016 00:10:29 -0500 Subject: [PATCH 01/30] Fix a couple missing structs in vissprite_t --- src/r_things.h | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/r_things.h b/src/r_things.h index 97010713a..60cc17366 100644 --- a/src/r_things.h +++ b/src/r_things.h @@ -41,8 +41,14 @@ struct vissprite_t FVector3 gpos; // origin in world coordinates union { - float gzb, gzt; // global bottom / top for silhouette clipping - int y1, y2; // top / bottom of particle on screen + struct + { + float gzb, gzt; // global bottom / top for silhouette clipping + }; + struct + { + int y1, y2; // top / bottom of particle on screen + }; }; angle_t angle; fixed_t xscale; From 3fd0d27efa16f8149d5be585fb8ab276ef149205 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 27 Apr 2016 15:34:13 +0200 Subject: [PATCH 02/30] - removed some leftover fixed point handling from PType. --- src/dobjtype.cpp | 8 +------- src/dobjtype.h | 2 -- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/src/dobjtype.cpp b/src/dobjtype.cpp index e707c7711..febcad0b5 100644 --- a/src/dobjtype.cpp +++ b/src/dobjtype.cpp @@ -438,7 +438,7 @@ void PType::SkipValue(FArchive &ar, int tag) ar.Read(buff, 2); break; - case VAL_Int32: case VAL_UInt32: case VAL_Float32: case VAL_Fixed: case VAL_BAM: + case VAL_Int32: case VAL_UInt32: case VAL_Float32: ar.Read(buff, 4); break; @@ -936,10 +936,8 @@ bool PInt::ReadValue(FArchive &ar, void *addr) const BYTE val8; WORD val16; DWORD val32; - fixed_t fix; float single; double dbl; - angle_t ang; }; ar << tag; @@ -955,8 +953,6 @@ bool PInt::ReadValue(FArchive &ar, void *addr) const case VAL_UInt32: ar << val32; uval = val32; break; case VAL_Int64: ar << sval; break; case VAL_UInt64: ar << uval; break; - case VAL_Fixed: ar << fix; sval = fix >> FRACBITS; break; // fixed -> int - case VAL_BAM: ar << ang; uval = ang / ANGLE_1; break; // BAM -> degrees case VAL_Float32: ar << single; sval = (SQWORD)single; break; case VAL_Float64: ar << dbl; sval = (SQWORD)dbl; break; default: SkipValue(ar, tag); return false; // Incompatible type @@ -1317,8 +1313,6 @@ static bool ReadValueDbl(FArchive &ar, double *addr, unsigned tag) case VAL_UInt32: ar << val32; val = val32; break; case VAL_Int64: ar << val64; val = (double)(SQWORD)val64; break; case VAL_UInt64: ar << val64; val = (double)val64; break; - case VAL_Fixed: ar << fix; val = FIXED2DBL(fix); break; - case VAL_BAM: ar << ang; val = ang * (90.0 / ANGLE_90); break; // BAM -> degrees case VAL_Float32: ar << single; val = single; break; case VAL_Float64: ar << val; break; default: PType::SkipValue(ar, tag); return false; // Incompatible type diff --git a/src/dobjtype.h b/src/dobjtype.h index 3c7481751..7edf8ca6a 100644 --- a/src/dobjtype.h +++ b/src/dobjtype.h @@ -904,8 +904,6 @@ enum ETypeVal : BYTE VAL_One, VAL_Float32, VAL_Float64, - VAL_Fixed, - VAL_BAM, VAL_String, VAL_Name, VAL_Struct, From 38d92b23b96bd20c35fd41affa26332feb5a43d7 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 27 Apr 2016 15:41:22 +0200 Subject: [PATCH 03/30] - fixed: ACS's GetSectorCeilingZ and GetSectorFloorZ expected integer coordinates. --- src/p_acs.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/p_acs.cpp b/src/p_acs.cpp index 088612e2a..003138211 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -8750,23 +8750,24 @@ scriptwait: { int tag = STACK(3); int secnum; - DVector2 pos(ACSToDouble(STACK(2)), ACSToDouble(STACK(1))); + double x = double(STACK(2)); + double y = double(STACK(1)); double z = 0; if (tag != 0) secnum = P_FindFirstSectorFromTag (tag); else - secnum = int(P_PointInSector (pos) - sectors); + secnum = int(P_PointInSector (x, y) - sectors); if (secnum >= 0) { if (pcd == PCD_GETSECTORFLOORZ) { - z = sectors[secnum].floorplane.ZatPoint (pos); + z = sectors[secnum].floorplane.ZatPoint (x, y); } else { - z = sectors[secnum].ceilingplane.ZatPoint (pos); + z = sectors[secnum].ceilingplane.ZatPoint (x, y); } } sp -= 2; From 0fc7055f5113c5fd53e03ed98a8a32bd7ab57562 Mon Sep 17 00:00:00 2001 From: MajorCooke Date: Wed, 27 Apr 2016 10:13:30 -0500 Subject: [PATCH 04/30] - Fixed: Quakes with rolling were not unique; they borrowed from any other quakes that didn't have rolling, thus preventing the rolling from falling off properly. --- src/g_shared/a_quake.cpp | 8 +++++--- src/g_shared/a_sharedglobal.h | 2 +- src/r_utility.cpp | 4 ++-- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/g_shared/a_quake.cpp b/src/g_shared/a_quake.cpp index f2f2e9b57..d02b12890 100644 --- a/src/g_shared/a_quake.cpp +++ b/src/g_shared/a_quake.cpp @@ -283,7 +283,8 @@ int DEarthquake::StaticGetQuakeIntensities(AActor *victim, FQuakeJiggers &jigger double dist = quake->m_Spot->Distance2D (victim, true); if (dist < quake->m_TremorRadius) { - double falloff = quake->GetFalloff(dist); + const double falloff = quake->GetFalloff(dist); + const double rfalloff = (quake->m_RollIntensity != 0) ? falloff : 0.; ++count; double x = quake->GetModIntensity(quake->m_Intensity.X); double y = quake->GetModIntensity(quake->m_Intensity.Y); @@ -293,6 +294,7 @@ int DEarthquake::StaticGetQuakeIntensities(AActor *victim, FQuakeJiggers &jigger if (!(quake->m_Flags & QF_WAVE)) { jiggers.Falloff = MAX(falloff, jiggers.Falloff); + jiggers.RFalloff = MAX(rfalloff, jiggers.RFalloff); jiggers.RollIntensity = MAX(r, jiggers.RollIntensity); if (quake->m_Flags & QF_RELATIVE) { @@ -310,11 +312,11 @@ int DEarthquake::StaticGetQuakeIntensities(AActor *victim, FQuakeJiggers &jigger else { jiggers.WFalloff = MAX(falloff, jiggers.WFalloff); - double mr = r * quake->GetModWave(quake->m_RollWave); + jiggers.RWFalloff = MAX(rfalloff, jiggers.RWFalloff); + jiggers.RollWave = r * quake->GetModWave(quake->m_RollWave); double mx = x * quake->GetModWave(quake->m_WaveSpeed.X); double my = y * quake->GetModWave(quake->m_WaveSpeed.Y); double mz = z * quake->GetModWave(quake->m_WaveSpeed.Z); - jiggers.RollWave = r * quake->GetModWave(quake->m_RollWave); // [RH] This only gives effect to the last sine quake. I would // prefer if some way was found to make multiples coexist diff --git a/src/g_shared/a_sharedglobal.h b/src/g_shared/a_sharedglobal.h index e3a30fc67..783abc87f 100644 --- a/src/g_shared/a_sharedglobal.h +++ b/src/g_shared/a_sharedglobal.h @@ -153,7 +153,7 @@ struct FQuakeJiggers DVector3 RelIntensity; DVector3 Offset; DVector3 RelOffset; - double Falloff, WFalloff; + double Falloff, WFalloff, RFalloff, RWFalloff; double RollIntensity, RollWave; }; diff --git a/src/r_utility.cpp b/src/r_utility.cpp index 20f3d506c..9e82906da 100644 --- a/src/r_utility.cpp +++ b/src/r_utility.cpp @@ -872,9 +872,9 @@ void R_SetupFrame (AActor *actor) double quakefactor = r_quakeintensity; DAngle an; - if (jiggers.RollIntensity != 0 || jiggers.RollWave != 0) + if (jiggers.RollIntensity != 0) { - ViewRoll += QuakePower(quakefactor, jiggers.RollIntensity, jiggers.RollWave, jiggers.Falloff, jiggers.WFalloff); + ViewRoll += QuakePower(quakefactor, jiggers.RollIntensity, jiggers.RollWave, jiggers.RFalloff, jiggers.RWFalloff); } if (jiggers.RelIntensity.X != 0 || jiggers.RelOffset.X != 0) { From 64d01a3bb1177beb389b2aebd2d58ca5e2a20900 Mon Sep 17 00:00:00 2001 From: MajorCooke Date: Wed, 27 Apr 2016 10:26:06 -0500 Subject: [PATCH 05/30] Forgot to undo this. --- src/r_utility.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/r_utility.cpp b/src/r_utility.cpp index 9e82906da..1dd4e5e40 100644 --- a/src/r_utility.cpp +++ b/src/r_utility.cpp @@ -872,7 +872,7 @@ void R_SetupFrame (AActor *actor) double quakefactor = r_quakeintensity; DAngle an; - if (jiggers.RollIntensity != 0) + if (jiggers.RollIntensity != 0 || jiggers.RollWave != 0) { ViewRoll += QuakePower(quakefactor, jiggers.RollIntensity, jiggers.RollWave, jiggers.RFalloff, jiggers.RWFalloff); } From 6f11a658932807cd20c381f8d3bb421da0b975e5 Mon Sep 17 00:00:00 2001 From: MajorCooke Date: Wed, 27 Apr 2016 12:58:18 -0500 Subject: [PATCH 06/30] - Converted rollIntensity from int to double. - It was already a double in the save version serialization so nothing had to be changed there. --- src/g_shared/a_quake.cpp | 6 +++--- src/g_shared/a_sharedglobal.h | 2 +- src/p_spec.h | 2 +- src/thingdef/thingdef_codeptr.cpp | 2 +- wadsrc/static/actors/actor.txt | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/g_shared/a_quake.cpp b/src/g_shared/a_quake.cpp index d02b12890..1d1117125 100644 --- a/src/g_shared/a_quake.cpp +++ b/src/g_shared/a_quake.cpp @@ -37,8 +37,8 @@ DEarthquake::DEarthquake() DEarthquake::DEarthquake(AActor *center, int intensityX, int intensityY, int intensityZ, int duration, int damrad, int tremrad, FSoundID quakesound, int flags, - double waveSpeedX, double waveSpeedY, double waveSpeedZ, int falloff, int highpoint, int rollIntensity, - double rollWave) + double waveSpeedX, double waveSpeedY, double waveSpeedZ, int falloff, int highpoint, + double rollIntensity, double rollWave) : DThinker(STAT_EARTHQUAKE) { m_QuakeSFX = quakesound; @@ -351,7 +351,7 @@ int DEarthquake::StaticGetQuakeIntensities(AActor *victim, FQuakeJiggers &jigger bool P_StartQuakeXYZ(AActor *activator, int tid, int intensityX, int intensityY, int intensityZ, int duration, int damrad, int tremrad, FSoundID quakesfx, int flags, double waveSpeedX, double waveSpeedY, double waveSpeedZ, int falloff, int highpoint, - int rollIntensity, double rollWave) + double rollIntensity, double rollWave) { AActor *center; bool res = false; diff --git a/src/g_shared/a_sharedglobal.h b/src/g_shared/a_sharedglobal.h index 783abc87f..f873ab0b7 100644 --- a/src/g_shared/a_sharedglobal.h +++ b/src/g_shared/a_sharedglobal.h @@ -164,7 +164,7 @@ class DEarthquake : public DThinker public: DEarthquake(AActor *center, int intensityX, int intensityY, int intensityZ, int duration, int damrad, int tremrad, FSoundID quakesfx, int flags, - double waveSpeedX, double waveSpeedY, double waveSpeedZ, int falloff, int highpoint, int rollIntensity, double rollWave); + double waveSpeedX, double waveSpeedY, double waveSpeedZ, int falloff, int highpoint, double rollIntensity, double rollWave); void Serialize (FArchive &arc); void Tick (); diff --git a/src/p_spec.h b/src/p_spec.h index 28c73914e..125b2374e 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -698,7 +698,7 @@ void P_DoDeferedScripts (void); // // [RH] p_quake.c // -bool P_StartQuakeXYZ(AActor *activator, int tid, int intensityX, int intensityY, int intensityZ, int duration, int damrad, int tremrad, FSoundID quakesfx, int flags, double waveSpeedX, double waveSpeedY, double waveSpeedZ, int falloff, int highpoint, int rollIntensity, double rollWave); +bool P_StartQuakeXYZ(AActor *activator, int tid, int intensityX, int intensityY, int intensityZ, int duration, int damrad, int tremrad, FSoundID quakesfx, int flags, double waveSpeedX, double waveSpeedY, double waveSpeedZ, int falloff, int highpoint, double rollIntensity, double rollWave); bool P_StartQuake(AActor *activator, int tid, int intensity, int duration, int damrad, int tremrad, FSoundID quakesfx); #endif diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index fe464b137..34a9cf02c 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -4985,7 +4985,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_QuakeEx) PARAM_FLOAT_OPT(mulWaveZ) { mulWaveZ = 1.; } PARAM_INT_OPT(falloff) { falloff = 0; } PARAM_INT_OPT(highpoint) { highpoint = 0; } - PARAM_INT_OPT(rollIntensity) { rollIntensity = 0; } + PARAM_FLOAT_OPT(rollIntensity) { rollIntensity = 0.; } PARAM_FLOAT_OPT(rollWave) { rollWave = 0.; } P_StartQuakeXYZ(self, 0, intensityX, intensityY, intensityZ, duration, damrad, tremrad, sound, flags, mulWaveX, mulWaveY, mulWaveZ, falloff, highpoint, rollIntensity, rollWave); diff --git a/wadsrc/static/actors/actor.txt b/wadsrc/static/actors/actor.txt index b6543cd7e..8b35be30d 100644 --- a/wadsrc/static/actors/actor.txt +++ b/wadsrc/static/actors/actor.txt @@ -281,7 +281,7 @@ ACTOR Actor native //: Thinker native void A_SetUserArrayFloat(name varname, int index, float value); native void A_SetSpecial(int spec, int arg0 = 0, int arg1 = 0, int arg2 = 0, int arg3 = 0, int arg4 = 0); native void A_Quake(int intensity, int duration, int damrad, int tremrad, sound sfx = "world/quake"); - native void A_QuakeEx(int intensityX, int intensityY, int intensityZ, int duration, int damrad, int tremrad, sound sfx = "world/quake", int flags = 0, float mulWaveX = 1, float mulWaveY = 1, float mulWaveZ = 1, int falloff = 0, int highpoint = 0, int rollIntensity = 0, float rollWave = 0); + native void A_QuakeEx(int intensityX, int intensityY, int intensityZ, int duration, int damrad, int tremrad, sound sfx = "world/quake", int flags = 0, float mulWaveX = 1, float mulWaveY = 1, float mulWaveZ = 1, int falloff = 0, int highpoint = 0, float rollIntensity = 0, float rollWave = 0); action native A_SetTics(int tics); native void A_SetDamageType(name damagetype); native void A_DropItem(class item, int dropamount = -1, int chance = 256); From ee7a4daa8c3548931e43061f1f68e4fe272968e0 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 27 Apr 2016 23:19:54 +0200 Subject: [PATCH 07/30] - preparations for textured dynamic lights. --- src/gl/scene/gl_drawinfo.cpp | 25 +++++++++++++++++++------ src/gl/scene/gl_drawinfo.h | 29 +++++++++++++++++++++++++++++ src/win32/win32gliface.cpp | 4 +++- 3 files changed, 51 insertions(+), 7 deletions(-) diff --git a/src/gl/scene/gl_drawinfo.cpp b/src/gl/scene/gl_drawinfo.cpp index 386dc6a4a..a444dbe62 100644 --- a/src/gl/scene/gl_drawinfo.cpp +++ b/src/gl/scene/gl_drawinfo.cpp @@ -991,10 +991,15 @@ static FDrawInfoList di_list; FDrawInfo::FDrawInfo() { next = NULL; + if (gl.lightmethod == LM_SOFTWARE) + { + dldrawlists = new GLDrawList[GLLDL_TYPES]; + } } FDrawInfo::~FDrawInfo() { + if (dldrawlists != NULL) delete[] dldrawlists; ClearBuffers(); } @@ -1018,13 +1023,17 @@ void FDrawInfo::StartScene() ss_renderflags.Resize(numsubsectors); no_renderflags.Resize(numsubsectors); - memset(§orrenderflags[0], 0, numsectors*sizeof(sectorrenderflags[0])); - memset(&ss_renderflags[0], 0, numsubsectors*sizeof(ss_renderflags[0])); - memset(&no_renderflags[0], 0, numnodes*sizeof(no_renderflags[0])); + memset(§orrenderflags[0], 0, numsectors * sizeof(sectorrenderflags[0])); + memset(&ss_renderflags[0], 0, numsubsectors * sizeof(ss_renderflags[0])); + memset(&no_renderflags[0], 0, numnodes * sizeof(no_renderflags[0])); - next=gl_drawinfo; - gl_drawinfo=this; - for(int i=0;idrawlists[i].Reset(); + if (di->dldrawlists != NULL) + { + for (int i = 0; i < GLLDL_TYPES; i++) di->dldrawlists[i].Reset(); + } gl_drawinfo=di->next; di_list.Release(di); } diff --git a/src/gl/scene/gl_drawinfo.h b/src/gl/scene/gl_drawinfo.h index 8cb6a412a..1eb4882ef 100644 --- a/src/gl/scene/gl_drawinfo.h +++ b/src/gl/scene/gl_drawinfo.h @@ -25,6 +25,28 @@ enum DrawListType GLDL_TYPES, }; +// more lists for handling of dynamic lights +enum DLDrawListType +{ + // These are organized so that the various multipass rendering modes have to be set as few times as possible + GLLDL_WALLS_PLAIN, // dynamic lights on normal walls + GLLDL_WALLS_BRIGHT, // dynamic lights on brightmapped walls + GLLDL_WALLS_MASKED, // dynamic lights on masked midtextures + + GLLDL_FLATS_PLAIN, // dynamic lights on normal flats + GLLDL_FLATS_BRIGHT, // dynamic lights on brightmapped flats + GLLDL_FLATS_MASKED, // dynamic lights on masked flats + + GLLDL_WALLS_FOG, // lights on fogged walls + GLLDL_WALLS_FOGMASKED, // lights on fogged masked midtextures + + GLLDL_FLATS_FOG, // lights on fogged walls + GLLDL_FLATS_FOGMASKED, // lights on fogged masked midtextures + + GLLDL_TYPES, +}; + + enum Drawpasses { GLPASS_ALL, // Main pass with dynamic lights @@ -32,6 +54,12 @@ enum Drawpasses GLPASS_PLAIN, // Main pass without dynamic lights GLPASS_DECALS, // Draws a decal GLPASS_TRANSLUCENT, // Draws translucent objects + + // these are only used with texture based dynamic lights + GLPASS_BASE, // untextured base for dynamic lights + GLPASS_LIGHTTEX, // lighttexture pass + GLPASS_TEXONLY // finishing texture pass + }; //========================================================================== @@ -199,6 +227,7 @@ struct FDrawInfo FDrawInfo * next; GLDrawList drawlists[GLDL_TYPES]; + GLDrawList *dldrawlists; // only gets allocated when needed. FDrawInfo(); ~FDrawInfo(); diff --git a/src/win32/win32gliface.cpp b/src/win32/win32gliface.cpp index 76099babb..625bda2a7 100644 --- a/src/win32/win32gliface.cpp +++ b/src/win32/win32gliface.cpp @@ -804,6 +804,8 @@ bool Win32GLVideo::InitHardware (HWND Window, int multisample) 0 }; + //Printf("Trying to create an OpenGL %d.%d %s profile context\n", versions[i] / 10, versions[i] % 10, prof == WGL_CONTEXT_CORE_PROFILE_BIT_ARB ? "Core" : "Compatibility"); + m_hRC = myWglCreateContextAttribsARB(m_hDC, 0, ctxAttribs); if (m_hRC != NULL) break; } @@ -832,7 +834,7 @@ bool Win32GLVideo::InitHardware (HWND Window, int multisample) } } // We get here if the driver doesn't support the modern context creation API which always means an old driver. - I_Error ("R_OPENGL: Unable to create an OpenGL render context.\n"); + I_Error ("R_OPENGL: Unable to create an OpenGL render context. Insufficient driver support for context creation\n"); return false; } From d4806f82cafa8c2aae27aa84dab310866c26abbb Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 28 Apr 2016 00:58:44 +0200 Subject: [PATCH 08/30] - reinstated some texturing-based dynamic light code. Not active yet and not tested yet. --- src/gl/compatibility/gl_20.cpp | 200 ++++++++++++++++++++++++++++++ src/gl/dynlights/gl_dynlight1.cpp | 92 -------------- src/gl/renderer/gl_renderer.h | 1 + src/gl/scene/gl_drawinfo.h | 4 +- src/gl/scene/gl_scene.cpp | 6 +- src/win32/win32gliface.cpp | 9 +- 6 files changed, 214 insertions(+), 98 deletions(-) diff --git a/src/gl/compatibility/gl_20.cpp b/src/gl/compatibility/gl_20.cpp index 5498c0b0a..280affa1a 100644 --- a/src/gl/compatibility/gl_20.cpp +++ b/src/gl/compatibility/gl_20.cpp @@ -45,10 +45,19 @@ #include "i_system.h" #include "v_text.h" #include "r_utility.h" +#include "gl/dynlights/gl_dynlight.h" +#include "gl/utility/gl_geometric.h" +#include "gl/renderer/gl_renderer.h" #include "gl/system/gl_interface.h" #include "gl/system/gl_cvars.h" #include "gl/renderer/gl_renderstate.h" +#include "gl/scene/gl_drawinfo.h" +//========================================================================== +// +// +// +//========================================================================== void gl_SetTextureMode(int type) { @@ -190,6 +199,11 @@ BYTE *gl_WarpBuffer(BYTE *buffer, int Width, int Height, int warp, float Speed) return (BYTE*)out; } +//========================================================================== +// +// +// +//========================================================================== static int ffTextureMode; static bool ffTextureEnabled; @@ -322,6 +336,12 @@ void FRenderState::ApplyFixedFunction() } +//========================================================================== +// +// +// +//========================================================================== + void gl_FillScreen(); void FRenderState::DrawColormapOverlay() @@ -375,4 +395,184 @@ void FRenderState::DrawColormapOverlay() gl_RenderState.BlendFunc(GL_DST_COLOR, GL_ZERO); gl_FillScreen(); gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); +} + +//========================================================================== +// +// Sets up the parameters to render one dynamic light onto one plane +// +//========================================================================== +bool gl_SetupLight(int group, Plane & p, ADynamicLight * light, Vector & nearPt, Vector & up, Vector & right, + float & scale, int desaturation, bool checkside, bool forceadditive) +{ + Vector fn, pos; + + DVector3 lpos = light->PosRelative(group); + + float dist = fabsf(p.DistToPoint(lpos.X, lpos.Z, lpos.Y)); + float radius = (light->GetRadius() * gl_lights_size); + + if (radius <= 0.f) return false; + if (dist > radius) return false; + if (checkside && gl_lights_checkside && p.PointOnSide(lpos.X, lpos.Z, lpos.Y)) + { + return false; + } + if (light->owned && light->target != NULL && !light->target->IsVisibleToPlayer()) + { + return false; + } + + scale = 1.0f / ((2.f * radius) - dist); + + // project light position onto plane (find closest point on plane) + + + pos.Set(lpos.X, lpos.Z, lpos.Y); + fn = p.Normal(); + fn.GetRightUp(right, up); + +#ifdef _MSC_VER + nearPt = pos + fn * dist; +#else + Vector tmpVec = fn * dist; + nearPt = pos + tmpVec; +#endif + + float cs = 1.0f - (dist / radius); + if (gl_lights_additive || light->flags4&MF4_ADDITIVE || forceadditive) cs *= 0.2f; // otherwise the light gets too strong. + float r = light->GetRed() / 255.0f * cs * gl_lights_intensity; + float g = light->GetGreen() / 255.0f * cs * gl_lights_intensity; + float b = light->GetBlue() / 255.0f * cs * gl_lights_intensity; + + if (light->IsSubtractive()) + { + Vector v; + + gl_RenderState.BlendEquation(GL_FUNC_REVERSE_SUBTRACT); + v.Set(r, g, b); + r = v.Length() - r; + g = v.Length() - g; + b = v.Length() - b; + } + else + { + gl_RenderState.BlendEquation(GL_FUNC_ADD); + } + if (desaturation > 0 && gl.glslversion > 0) // no-shader excluded because no desaturated textures. + { + float gray = (r * 77 + g * 143 + b * 37) / 257; + + r = (r*(32 - desaturation) + gray*desaturation) / 32; + g = (g*(32 - desaturation) + gray*desaturation) / 32; + b = (b*(32 - desaturation) + gray*desaturation) / 32; + } + glColor3f(r, g, b); + return true; +} + +//========================================================================== +// +// +// +//========================================================================== + +bool gl_SetupLightTexture() +{ + if (GLRenderer->gllight == NULL) return false; + FMaterial * pat = FMaterial::ValidateTexture(GLRenderer->gllight, false); + pat->Bind(CLAMP_XY, 0); + return true; +} + +//========================================================================== +// +// +// +//========================================================================== + +void FGLRenderer::RenderMultipassStuff() +{ + return; + // First pass: empty background with sector light only + + // Part 1: solid geometry. This is set up so that there are no transparent parts + + // remove any remaining texture bindings and shaders whick may get in the way. + gl_RenderState.EnableTexture(false); + gl_RenderState.EnableBrightmap(false); + gl_RenderState.Apply(); + gl_drawinfo->dldrawlists[GLLDL_WALLS_PLAIN].DrawWalls(GLPASS_BASE); + gl_drawinfo->dldrawlists[GLLDL_FLATS_PLAIN].DrawFlats(GLPASS_BASE); + + // Part 2: masked geometry. This is set up so that only pixels with alpha>0.5 will show + // This creates a blank surface that only fills the nontransparent parts of the texture + gl_RenderState.EnableTexture(true); + gl_RenderState.SetTextureMode(TM_MASK); + gl_RenderState.EnableBrightmap(true); + gl_drawinfo->dldrawlists[GLLDL_WALLS_BRIGHT].DrawWalls(GLPASS_BASE_MASKED); + gl_drawinfo->dldrawlists[GLLDL_WALLS_MASKED].DrawWalls(GLPASS_BASE_MASKED); + gl_drawinfo->dldrawlists[GLLDL_FLATS_BRIGHT].DrawFlats(GLPASS_BASE_MASKED); + gl_drawinfo->dldrawlists[GLLDL_FLATS_MASKED].DrawFlats(GLPASS_BASE_MASKED); + + // Part 3: The base of fogged surfaces, including the texture + gl_RenderState.EnableBrightmap(false); + gl_RenderState.SetTextureMode(TM_MODULATE); + gl_drawinfo->dldrawlists[GLLDL_WALLS_FOG].DrawWalls(GLPASS_PLAIN); + gl_drawinfo->dldrawlists[GLLDL_WALLS_FOGMASKED].DrawWalls(GLPASS_PLAIN); + gl_drawinfo->dldrawlists[GLLDL_FLATS_FOG].DrawFlats(GLPASS_PLAIN); + gl_drawinfo->dldrawlists[GLLDL_FLATS_FOGMASKED].DrawFlats(GLPASS_PLAIN); + + // second pass: draw lights + glDepthMask(false); + if (mLightCount && !gl_fixedcolormap) + { + if (gl_SetupLightTexture()) + { + gl_RenderState.BlendFunc(GL_ONE, GL_ONE); + glDepthFunc(GL_EQUAL); + if (glset.lightmode == 8) gl_RenderState.SetSoftLightLevel(255); + gl_drawinfo->dldrawlists[GLLDL_WALLS_PLAIN].DrawWalls(GLPASS_LIGHTTEX); + gl_drawinfo->dldrawlists[GLLDL_WALLS_BRIGHT].DrawWalls(GLPASS_LIGHTTEX); + gl_drawinfo->dldrawlists[GLLDL_WALLS_MASKED].DrawWalls(GLPASS_LIGHTTEX); + gl_drawinfo->dldrawlists[GLLDL_FLATS_PLAIN].DrawFlats(GLPASS_LIGHTTEX); + gl_drawinfo->dldrawlists[GLLDL_FLATS_BRIGHT].DrawFlats(GLPASS_LIGHTTEX); + gl_drawinfo->dldrawlists[GLLDL_FLATS_MASKED].DrawFlats(GLPASS_LIGHTTEX); + gl_RenderState.BlendEquation(GL_FUNC_ADD); + } + else gl_lights = false; + } + + // third pass: modulated texture + gl_RenderState.SetColor(0xffffffff); + gl_RenderState.BlendFunc(GL_DST_COLOR, GL_ZERO); + gl_RenderState.EnableFog(false); + gl_RenderState.AlphaFunc(GL_GEQUAL, 0); + glDepthFunc(GL_LEQUAL); + gl_drawinfo->dldrawlists[GLLDL_WALLS_PLAIN].DrawWalls(GLPASS_TEXONLY); + gl_drawinfo->dldrawlists[GLLDL_FLATS_PLAIN].DrawFlats(GLPASS_TEXONLY); + gl_drawinfo->dldrawlists[GLLDL_WALLS_BRIGHT].DrawWalls(GLPASS_TEXONLY); + gl_drawinfo->dldrawlists[GLLDL_FLATS_BRIGHT].DrawFlats(GLPASS_TEXONLY); + gl_RenderState.AlphaFunc(GL_GREATER, gl_mask_threshold); + gl_drawinfo->dldrawlists[GLLDL_WALLS_MASKED].DrawWalls(GLPASS_TEXONLY); + gl_drawinfo->dldrawlists[GLLDL_FLATS_MASKED].DrawFlats(GLPASS_TEXONLY); + + // fourth pass: additive lights + gl_RenderState.EnableFog(true); + gl_RenderState.BlendFunc(GL_ONE, GL_ONE); + glDepthFunc(GL_EQUAL); + if (gl_SetupLightTexture()) + { + gl_drawinfo->dldrawlists[GLLDL_WALLS_PLAIN].DrawWalls(GLPASS_LIGHTTEX_ADDITIVE); + gl_drawinfo->dldrawlists[GLLDL_WALLS_BRIGHT].DrawWalls(GLPASS_LIGHTTEX_ADDITIVE); + gl_drawinfo->dldrawlists[GLLDL_WALLS_MASKED].DrawWalls(GLPASS_LIGHTTEX_ADDITIVE); + gl_drawinfo->dldrawlists[GLLDL_FLATS_PLAIN].DrawFlats(GLPASS_LIGHTTEX_ADDITIVE); + gl_drawinfo->dldrawlists[GLLDL_FLATS_BRIGHT].DrawFlats(GLPASS_LIGHTTEX_ADDITIVE); + gl_drawinfo->dldrawlists[GLLDL_FLATS_MASKED].DrawFlats(GLPASS_LIGHTTEX_ADDITIVE); + gl_drawinfo->dldrawlists[GLLDL_WALLS_FOG].DrawWalls(GLPASS_LIGHTTEX_ADDITIVE); + gl_drawinfo->dldrawlists[GLLDL_WALLS_FOGMASKED].DrawWalls(GLPASS_LIGHTTEX_ADDITIVE); + gl_drawinfo->dldrawlists[GLLDL_FLATS_FOG].DrawFlats(GLPASS_LIGHTTEX_ADDITIVE); + gl_drawinfo->dldrawlists[GLLDL_FLATS_FOGMASKED].DrawFlats(GLPASS_LIGHTTEX_ADDITIVE); + } + else gl_lights = false; } \ No newline at end of file diff --git a/src/gl/dynlights/gl_dynlight1.cpp b/src/gl/dynlights/gl_dynlight1.cpp index b8fbfc24a..361b94618 100644 --- a/src/gl/dynlights/gl_dynlight1.cpp +++ b/src/gl/dynlights/gl_dynlight1.cpp @@ -140,95 +140,3 @@ bool gl_GetLight(int group, Plane & p, ADynamicLight * light, bool checkside, bo return true; } - - - -//========================================================================== -// -// Sets up the parameters to render one dynamic light onto one plane -// -//========================================================================== -bool gl_SetupLight(int group, Plane & p, ADynamicLight * light, Vector & nearPt, Vector & up, Vector & right, - float & scale, int desaturation, bool checkside, bool forceadditive) -{ - Vector fn, pos; - - DVector3 lpos = light->PosRelative(group); - - float dist = fabsf(p.DistToPoint(lpos.X, lpos.Z, lpos.Y)); - float radius = (light->GetRadius() * gl_lights_size); - - if (radius <= 0.f) return false; - if (dist > radius) return false; - if (checkside && gl_lights_checkside && p.PointOnSide(lpos.X, lpos.Z, lpos.Y)) - { - return false; - } - if (light->owned && light->target != NULL && !light->target->IsVisibleToPlayer()) - { - return false; - } - - scale = 1.0f / ((2.f * radius) - dist); - - // project light position onto plane (find closest point on plane) - - - pos.Set(lpos.X, lpos.Z, lpos.Y); - fn = p.Normal(); - fn.GetRightUp(right, up); - -#ifdef _MSC_VER - nearPt = pos + fn * dist; -#else - Vector tmpVec = fn * dist; - nearPt = pos + tmpVec; -#endif - - float cs = 1.0f - (dist / radius); - if (gl_lights_additive || light->flags4&MF4_ADDITIVE || forceadditive) cs *= 0.2f; // otherwise the light gets too strong. - float r = light->GetRed() / 255.0f * cs * gl_lights_intensity; - float g = light->GetGreen() / 255.0f * cs * gl_lights_intensity; - float b = light->GetBlue() / 255.0f * cs * gl_lights_intensity; - - if (light->IsSubtractive()) - { - Vector v; - - gl_RenderState.BlendEquation(GL_FUNC_REVERSE_SUBTRACT); - v.Set(r, g, b); - r = v.Length() - r; - g = v.Length() - g; - b = v.Length() - b; - } - else - { - gl_RenderState.BlendEquation(GL_FUNC_ADD); - } - if (desaturation > 0 && gl.glslversion > 0) // no-shader excluded because no desaturated textures. - { - float gray = (r * 77 + g * 143 + b * 37) / 257; - - r = (r*(32 - desaturation) + gray*desaturation) / 32; - g = (g*(32 - desaturation) + gray*desaturation) / 32; - b = (b*(32 - desaturation) + gray*desaturation) / 32; - } - glColor3f(r, g, b); - return true; -} - - -//========================================================================== -// -// -// -//========================================================================== - -bool gl_SetupLightTexture() -{ - - if (GLRenderer->gllight == NULL) return false; - FMaterial * pat = FMaterial::ValidateTexture(GLRenderer->gllight, true); - pat->Bind(CLAMP_XY, 0); - return true; -} diff --git a/src/gl/renderer/gl_renderer.h b/src/gl/renderer/gl_renderer.h index cc5aa9d53..d09ac1948 100644 --- a/src/gl/renderer/gl_renderer.h +++ b/src/gl/renderer/gl_renderer.h @@ -101,6 +101,7 @@ public: void Initialize(); void CreateScene(); + void RenderMultipassStuff(); void RenderScene(int recursion); void RenderTranslucent(); void DrawScene(bool toscreen = false); diff --git a/src/gl/scene/gl_drawinfo.h b/src/gl/scene/gl_drawinfo.h index 1eb4882ef..9745ade88 100644 --- a/src/gl/scene/gl_drawinfo.h +++ b/src/gl/scene/gl_drawinfo.h @@ -57,8 +57,10 @@ enum Drawpasses // these are only used with texture based dynamic lights GLPASS_BASE, // untextured base for dynamic lights + GLPASS_BASE_MASKED, // same but with active texture GLPASS_LIGHTTEX, // lighttexture pass - GLPASS_TEXONLY // finishing texture pass + GLPASS_TEXONLY, // finishing texture pass + GLPASS_LIGHTTEX_ADDITIVE, // lighttexture pass (additive) }; diff --git a/src/gl/scene/gl_scene.cpp b/src/gl/scene/gl_scene.cpp index 658a816a5..a745f7307 100644 --- a/src/gl/scene/gl_scene.cpp +++ b/src/gl/scene/gl_scene.cpp @@ -382,10 +382,10 @@ void FGLRenderer::RenderScene(int recursion) } else { - // Todo: Draw lights with multipass rendering. - // RenderMultpassStuff(); + // process everything that needs to handle textured dynamic lights. + if (haslights) RenderMultipassStuff(); - // The remaining stuff which is unaffected by dynamic lights is just processed as normal. + // The remaining lists which are unaffected by dynamic lights are just processed as normal. pass = GLPASS_PLAIN; } diff --git a/src/win32/win32gliface.cpp b/src/win32/win32gliface.cpp index 625bda2a7..11c359a32 100644 --- a/src/win32/win32gliface.cpp +++ b/src/win32/win32gliface.cpp @@ -813,8 +813,13 @@ bool Win32GLVideo::InitHardware (HWND Window, int multisample) if (m_hRC == NULL && prof == WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB) { - I_Error ("R_OPENGL: Unable to create an OpenGL render context.\n"); - return false; + + m_hRC = wglCreateContext(m_hDC); + if (m_hRC == NULL) + { + I_Error("R_OPENGL: Unable to create an OpenGL render context.\n"); + return false; + } } if (m_hRC != NULL) From ac69ed3361097719477695bad36a62ecc0e95191 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Wed, 27 Apr 2016 17:13:56 -0500 Subject: [PATCH 09/30] Minimal wallmost changes - Add comments - Fixed: When WallMost() finds a line entirely above the screen, it should set the most array to 0, not -1. --- src/r_segs.cpp | 37 ++++++++++++++++++------------------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/src/r_segs.cpp b/src/r_segs.cpp index 87b5f15a2..546544f81 100644 --- a/src/r_segs.cpp +++ b/src/r_segs.cpp @@ -2670,53 +2670,51 @@ int OWallMost (short *mostbuf, double z, const FWallCoords *wallc) s3 = globaldclip * wallc->sz1; s4 = globaldclip * wallc->sz2; bad = (zs3)<<2)+((z>s4)<<3); -#if 1 if ((bad&3) == 3) - { + { // entire line is above the screen memset (&mostbuf[wallc->sx1], 0, (wallc->sx2 - wallc->sx1)*sizeof(mostbuf[0])); return bad; } if ((bad&12) == 12) - { + { // entire line is below the screen clearbufshort (&mostbuf[wallc->sx1], wallc->sx2 - wallc->sx1, viewheight); return bad; } -#endif ix1 = wallc->sx1; iy1 = wallc->sz1; ix2 = wallc->sx2; iy2 = wallc->sz2; #if 1 if (bad & 3) - { + { // the line intersects the top of the screen double t = (z-s1) / (s2-s1); double inty = wallc->sz1 + t * (wallc->sz2 - wallc->sz1); int xcross = xs_RoundToInt(wallc->sx1 + (t * wallc->sz2 * (wallc->sx2 - wallc->sx1)) / inty); if ((bad & 3) == 2) - { + { // the right side is above the screen if (wallc->sx1 <= xcross) { iy2 = inty; ix2 = xcross; } if (wallc->sx2 > xcross) memset (&mostbuf[xcross], 0, (wallc->sx2-xcross)*sizeof(mostbuf[0])); } else - { + { // the left side is above the screen if (xcross <= wallc->sx2) { iy1 = inty; ix1 = xcross; } if (xcross > wallc->sx1) memset (&mostbuf[wallc->sx1], 0, (xcross-wallc->sx1)*sizeof(mostbuf[0])); } } if (bad & 12) - { + { // the line intersects the bottom of the screen double t = (z-s3) / (s4-s3); double inty = wallc->sz1 + t * (wallc->sz2 - wallc->sz1); int xcross = xs_RoundToInt(wallc->sx1 + (t * wallc->sz2 * (wallc->sx2 - wallc->sx1)) / inty); if ((bad & 12) == 8) - { + { // the right side is below the screen if (wallc->sx1 <= xcross) { iy2 = inty; ix2 = xcross; } if (wallc->sx2 > xcross) clearbufshort (&mostbuf[xcross], wallc->sx2 - xcross, viewheight); } else - { + { // the left side is below the screen if (xcross <= wallc->sx2) { iy1 = inty; ix1 = xcross; } if (xcross > wallc->sx1) clearbufshort (&mostbuf[wallc->sx1], xcross - wallc->sx1, viewheight); } @@ -2779,6 +2777,7 @@ int WallMost (short *mostbuf, const secplane_t &plane, const FWallCoords *wallc) int bad, ix1, ix2; double iy1, iy2; + // Get Z coordinates at both ends of the line if (MirrorFlags & RF_XFLIP) { x = curline->v2->fX(); @@ -2847,20 +2846,20 @@ int WallMost (short *mostbuf, const secplane_t &plane, const FWallCoords *wallc) oz1 = z1; oz2 = z2; if ((bad&3) == 3) - { - memset (&mostbuf[ix1], -1, (ix2-ix1)*sizeof(mostbuf[0])); + { // The entire line is above the screen + memset (&mostbuf[ix1], 0, (ix2-ix1)*sizeof(mostbuf[0])); return bad; } if ((bad&12) == 12) - { + { // The entire line is below the screen clearbufshort (&mostbuf[ix1], ix2-ix1, viewheight); return bad; } if (bad&3) - { + { // The line intersects the top of the screen //inty = intz / (globaluclip>>16) double t = (oz1-s1) / (s2-s1+oz1-oz2); double inty = wallc->sz1 + t * (wallc->sz2-wallc->sz1); @@ -2872,19 +2871,19 @@ int WallMost (short *mostbuf, const secplane_t &plane, const FWallCoords *wallc) //intz = z1 + mulscale30(z2-z1,t); if ((bad&3) == 2) - { + { // The right side of the line is above the screen if (wallc->sx1 <= xcross) { z2 = intz; iy2 = inty; ix2 = xcross; } memset (&mostbuf[xcross], 0, (wallc->sx2-xcross)*sizeof(mostbuf[0])); } else - { + { // The left side of the line is above the screen if (xcross <= wallc->sx2) { z1 = intz; iy1 = inty; ix1 = xcross; } memset (&mostbuf[wallc->sx1], 0, (xcross-wallc->sx1)*sizeof(mostbuf[0])); } } if (bad&12) - { + { // The line intersects the bottom of the screen //inty = intz / (globaldclip>>16) double t = (oz1-s3) / (s4-s3+oz1-oz2); double inty = wallc->sz1 + t * (wallc->sz2-wallc->sz1); @@ -2896,12 +2895,12 @@ int WallMost (short *mostbuf, const secplane_t &plane, const FWallCoords *wallc) //intz = z1 + mulscale30(z2-z1,t); if ((bad&12) == 8) - { + { // The right side of the line is below the screen if (wallc->sx1 <= xcross) { z2 = intz; iy2 = inty; ix2 = xcross; } if (wallc->sx2 > xcross) clearbufshort (&mostbuf[xcross], wallc->sx2-xcross, viewheight); } else - { + { // The left side of the line is below the screen if (xcross <= wallc->sx2) { z1 = intz; iy1 = inty; ix1 = xcross; } if (xcross > wallc->sx1) clearbufshort (&mostbuf[wallc->sx1], xcross-wallc->sx1, viewheight); } From 31d842a89416375a2e970b36a0cad177982fa910 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Wed, 27 Apr 2016 22:08:19 -0500 Subject: [PATCH 10/30] Store FTransform in visplanes instead of converting to fixed_t --- src/r_plane.cpp | 122 +++++++++++++++++++----------------------------- src/r_plane.h | 13 +++--- 2 files changed, 55 insertions(+), 80 deletions(-) diff --git a/src/r_plane.cpp b/src/r_plane.cpp index a3877010f..30e11a123 100644 --- a/src/r_plane.cpp +++ b/src/r_plane.cpp @@ -582,29 +582,21 @@ static visplane_t *new_visplane (unsigned hash) //========================================================================== visplane_t *R_FindPlane (const secplane_t &height, FTextureID picnum, int lightlevel, double Alpha, bool additive, - const FTransform &xform, + const FTransform &xxform, int sky, FSectorPortal *portal) { secplane_t plane; visplane_t *check; unsigned hash; // killough bool isskybox; - fixed_t xoffs = FLOAT2FIXED(xform.xOffs); - fixed_t yoffs = FLOAT2FIXED(xform.yOffs + xform.baseyOffs); - fixed_t xscale = FLOAT2FIXED(xform.xScale); - fixed_t yscale = FLOAT2FIXED(xform.yScale); + const FTransform *xform = &xxform; fixed_t alpha = FLOAT2FIXED(Alpha); - angle_t angle = (xform.Angle + xform.baseAngle).BAMs(); + //angle_t angle = (xform.Angle + xform.baseAngle).BAMs(); if (picnum == skyflatnum) // killough 10/98 { // most skies map together lightlevel = 0; - xoffs = 0; - yoffs = 0; - xscale = 0; - yscale = 0; - angle = 0; - alpha = 0; + xform = NULL; additive = false; // [RH] Map floor skies and ceiling skies to separate visplanes. This isn't // always necessary, but it is needed if a floor and ceiling sky are in the @@ -656,13 +648,10 @@ visplane_t *R_FindPlane (const secplane_t &height, FTextureID picnum, int lightl (plane == check->height && picnum == check->picnum && lightlevel == check->lightlevel && - - xoffs == check->xoffs && // killough 2/28/98: Add offset checks - yoffs == check->yoffs && basecolormap == check->colormap && // [RH] Add more checks - xscale == check->xscale && - yscale == check->yscale && - angle == check->angle + + (xform == check->xform || + (xform != NULL && check->xform != NULL && *xform == *check->xform)) ) ) && check->viewangle == stacked_angle @@ -683,12 +672,9 @@ visplane_t *R_FindPlane (const secplane_t &height, FTextureID picnum, int lightl if (plane == check->height && picnum == check->picnum && lightlevel == check->lightlevel && - xoffs == check->xoffs && // killough 2/28/98: Add offset checks - yoffs == check->yoffs && basecolormap == check->colormap && // [RH] Add more checks - xscale == check->xscale && - yscale == check->yscale && - angle == check->angle && + (xform == check->xform || + (xform != NULL && check->xform != NULL && *xform == *check->xform)) && sky == check->sky && CurrentPortalUniq == check->CurrentPortalUniq && MirrorFlags == check->MirrorFlags && @@ -705,11 +691,7 @@ visplane_t *R_FindPlane (const secplane_t &height, FTextureID picnum, int lightl check->height = plane; check->picnum = picnum; check->lightlevel = lightlevel; - check->xoffs = xoffs; // killough 2/28/98: Save offsets - check->yoffs = yoffs; - check->xscale = xscale; - check->yscale = yscale; - check->angle = angle; + check->xform = xform; check->colormap = basecolormap; // [RH] Save colormap check->sky = sky; check->portal = portal; @@ -794,11 +776,7 @@ visplane_t *R_CheckPlane (visplane_t *pl, int start, int stop) new_pl->height = pl->height; new_pl->picnum = pl->picnum; new_pl->lightlevel = pl->lightlevel; - new_pl->xoffs = pl->xoffs; // killough 2/28/98 - new_pl->yoffs = pl->yoffs; - new_pl->xscale = pl->xscale; // [RH] copy these, too - new_pl->yscale = pl->yscale; - new_pl->angle = pl->angle; + new_pl->xform = pl->xform; new_pl->colormap = pl->colormap; new_pl->portal = pl->portal; new_pl->extralight = pl->extralight; @@ -1117,8 +1095,8 @@ void R_DrawSinglePlane (visplane_t *pl, fixed_t alpha, bool additive, bool maske masked = false; } R_SetupSpanBits(tex); - pl->xscale = fixed_t(pl->xscale * tex->Scale.X); - pl->yscale = fixed_t(pl->yscale * tex->Scale.Y); + double xscale = pl->xform->xScale * tex->Scale.X; + double yscale = pl->xform->yScale * tex->Scale.Y; ds_source = tex->GetPixels (); basecolormap = pl->colormap; @@ -1126,11 +1104,11 @@ void R_DrawSinglePlane (visplane_t *pl, fixed_t alpha, bool additive, bool maske if (r_drawflat || (!pl->height.isSlope() && !tilt)) { - R_DrawNormalPlane (pl, alpha, additive, masked); + R_DrawNormalPlane(pl, xscale, yscale, alpha, additive, masked); } else { - R_DrawTiltedPlane (pl, alpha, additive, masked); + R_DrawTiltedPlane(pl, xscale, yscale, alpha, additive, masked); } } NetUpdate (); @@ -1502,7 +1480,7 @@ void R_DrawSkyPlane (visplane_t *pl) // //========================================================================== -void R_DrawNormalPlane (visplane_t *pl, fixed_t alpha, bool additive, bool masked) +void R_DrawNormalPlane (visplane_t *pl, double _xscale, double _yscale, fixed_t alpha, bool additive, bool masked) { #ifdef X86_ASM if (ds_source != ds_cursource) @@ -1516,31 +1494,29 @@ void R_DrawNormalPlane (visplane_t *pl, fixed_t alpha, bool additive, bool maske return; } - angle_t planeang = pl->angle; - xscale = pl->xscale << (16 - ds_xbits); - yscale = pl->yscale << (16 - ds_ybits); + DAngle planeang = pl->xform->Angle + pl->xform->baseAngle; + xscale = xs_ToFixed(32 - ds_xbits, _xscale); + yscale = xs_ToFixed(32 - ds_ybits, _yscale); if (planeang != 0) { - double rad = planeang * (M_PI / ANGLE_180); - double cosine = cos(rad), sine = sin(rad); - - pviewx = xs_RoundToInt(pl->xoffs + FLOAT2FIXED(ViewPos.X * cosine - ViewPos.Y * sine)); - pviewy = xs_RoundToInt(pl->yoffs - FLOAT2FIXED(ViewPos.X * sine - ViewPos.Y * cosine)); + double cosine = planeang.Cos(), sine = planeang.Sin(); + pviewx = FLOAT2FIXED(pl->xform->xOffs + ViewPos.X * cosine - ViewPos.Y * sine); + pviewy = FLOAT2FIXED(pl->xform->yOffs - ViewPos.X * sine - ViewPos.Y * cosine); } else { - pviewx = pl->xoffs + FLOAT2FIXED(ViewPos.X); - pviewy = pl->yoffs - FLOAT2FIXED(ViewPos.Y); + pviewx = FLOAT2FIXED(pl->xform->xOffs + ViewPos.X); + pviewy = FLOAT2FIXED(pl->xform->yOffs - ViewPos.Y); } pviewx = FixedMul (xscale, pviewx); pviewy = FixedMul (yscale, pviewy); // left to right mapping - planeang = (ViewAngle.BAMs() - ANG90 + planeang) >> ANGLETOFINESHIFT; + planeang = ViewAngle - 90 + planeang; // Scale will be unit scale at FocalLengthX (normally SCREENWIDTH/2) distance - xstepscale = fixed_t(FixedMul(xscale, finecosine[planeang]) / FocalLengthX); - ystepscale = fixed_t(FixedMul(yscale, -finesine[planeang]) / FocalLengthX); + xstepscale = xs_RoundToInt(xscale * planeang.Cos() / FocalLengthX); + ystepscale = xs_RoundToInt(yscale * -planeang.Sin() / FocalLengthX); // [RH] flip for mirrors if (MirrorFlags & RF_XFLIP) @@ -1550,9 +1526,9 @@ void R_DrawNormalPlane (visplane_t *pl, fixed_t alpha, bool additive, bool maske } int x = pl->right - halfviewwidth - 1; - planeang = (planeang + (ANG90 >> ANGLETOFINESHIFT)) & FINEMASK; - basexfrac = FixedMul (xscale, finecosine[planeang]) + x*xstepscale; - baseyfrac = FixedMul (yscale, -finesine[planeang]) + x*ystepscale; + planeang += 90; + basexfrac = xs_RoundToInt(xscale * planeang.Cos()) + x*xstepscale; + baseyfrac = xs_RoundToInt(yscale * -planeang.Sin()) + x*ystepscale; planeheight = fabs(pl->height.Zat0() - ViewPos.Z); @@ -1620,7 +1596,7 @@ void R_DrawNormalPlane (visplane_t *pl, fixed_t alpha, bool additive, bool maske // //========================================================================== -void R_DrawTiltedPlane (visplane_t *pl, fixed_t alpha, bool additive, bool masked) +void R_DrawTiltedPlane (visplane_t *pl, double _xscale, double _yscale, fixed_t alpha, bool additive, bool masked) { static const float ifloatpow2[16] = { @@ -1634,7 +1610,7 @@ void R_DrawTiltedPlane (visplane_t *pl, fixed_t alpha, bool additive, bool maske double lxscale, lyscale; double xscale, yscale; FVector3 p, m, n; - double ang; + DAngle ang; double zeroheight; if (alpha <= 0) @@ -1642,44 +1618,44 @@ void R_DrawTiltedPlane (visplane_t *pl, fixed_t alpha, bool additive, bool maske return; } - lxscale = FIXED2DBL(pl->xscale) * ifloatpow2[ds_xbits]; - lyscale = FIXED2DBL(pl->yscale) * ifloatpow2[ds_ybits]; + lxscale = _xscale * ifloatpow2[ds_xbits]; + lyscale = _yscale * ifloatpow2[ds_ybits]; xscale = 64.f / lxscale; yscale = 64.f / lyscale; zeroheight = pl->height.ZatPoint(ViewPos); - pviewx = MulScale (pl->xoffs, pl->xscale, ds_xbits); - pviewy = MulScale (pl->yoffs, pl->yscale, ds_ybits); + pviewx = xs_ToFixed(32 - ds_xbits, pl->xform->xOffs * pl->xform->xScale); + pviewy = xs_ToFixed(32 - ds_ybits, pl->xform->yOffs * pl->xform->yScale); // p is the texture origin in view space // Don't add in the offsets at this stage, because doing so can result in // errors if the flat is rotated. - ang = (DAngle(270.) - ViewAngle).Radians(); - p[0] = ViewPos.X * cos(ang) - ViewPos.Y * sin(ang); - p[2] = ViewPos.X * sin(ang) + ViewPos.Y * cos(ang); + ang = DAngle(270.) - ViewAngle; + p[0] = ViewPos.X * ang.Cos() - ViewPos.Y * ang.Sin(); + p[2] = ViewPos.X * ang.Sin() + ViewPos.Y * ang.Cos(); p[1] = pl->height.ZatPoint(0.0, 0.0) - ViewPos.Z; // m is the v direction vector in view space - ang = (DAngle(180.) - ViewAngle).Radians(); - m[0] = yscale * cos(ang); - m[2] = yscale * sin(ang); + ang = DAngle(180.) - ViewAngle; + m[0] = yscale * ang.Cos(); + m[2] = yscale * ang.Sin(); // m[1] = pl->height.ZatPointF (0, iyscale) - pl->height.ZatPointF (0,0)); // VectorScale2 (m, 64.f/VectorLength(m)); // n is the u direction vector in view space - ang += PI/2; - n[0] = -xscale * cos(ang); - n[2] = -xscale * sin(ang); + ang += 90; + n[0] = -xscale * ang.Cos(); + n[2] = -xscale * ang.Sin(); // n[1] = pl->height.ZatPointF (ixscale, 0) - pl->height.ZatPointF (0,0)); // VectorScale2 (n, 64.f/VectorLength(n)); // This code keeps the texture coordinates constant across the x,y plane no matter // how much you slope the surface. Use the commented-out code above instead to keep // the textures a constant size across the surface's plane instead. - ang = pl->angle * (M_PI / ANGLE_180); - m[1] = pl->height.ZatPoint(ViewPos.X + yscale * sin(ang), ViewPos.Y + yscale * cos(ang)) - zeroheight; - ang += PI/2; - n[1] = pl->height.ZatPoint(ViewPos.X + xscale * sin(ang), ViewPos.Y + xscale * cos(ang)) - zeroheight; + ang = pl->xform->Angle + pl->xform->baseAngle; + m[1] = pl->height.ZatPoint(ViewPos.X + yscale * ang.Sin(), ViewPos.Y + yscale * ang.Cos()) - zeroheight; + ang += 90; + n[1] = pl->height.ZatPoint(ViewPos.X + xscale * ang.Sin(), ViewPos.Y + xscale * ang.Cos()) - zeroheight; plane_su = p ^ m; plane_sv = p ^ n; diff --git a/src/r_plane.h b/src/r_plane.h index 25e46de98..006885db3 100644 --- a/src/r_plane.h +++ b/src/r_plane.h @@ -34,16 +34,15 @@ struct visplane_s { struct visplane_s *next; // Next visplane in hash chain -- killough + const FTransform *xform; + FDynamicColormap *colormap; // [RH] Support multiple colormaps + FSectorPortal *portal; // [RH] Support sky boxes + secplane_t height; FTextureID picnum; int lightlevel; - fixed_t xoffs, yoffs; // killough 2/28/98: Support scrolling flats int left, right; - FDynamicColormap *colormap; // [RH] Support multiple colormaps - fixed_t xscale, yscale; // [RH] Support flat scaling - angle_t angle; // [RH] Support flat rotation int sky; - FSectorPortal *portal; // [RH] Support sky boxes // [RH] This set of variables copies information from the time when the // visplane is created. They are only used by stacks so that you can @@ -90,8 +89,8 @@ void R_ClearPlanes (bool fullclear); int R_DrawPlanes (); void R_DrawPortals (); void R_DrawSkyPlane (visplane_t *pl); -void R_DrawNormalPlane (visplane_t *pl, fixed_t alpha, bool additive, bool masked); -void R_DrawTiltedPlane (visplane_t *pl, fixed_t alpha, bool additive, bool masked); +void R_DrawNormalPlane (visplane_t *pl, double xscale, double yscale, fixed_t alpha, bool additive, bool masked); +void R_DrawTiltedPlane (visplane_t *pl, double xscale, double yscale, fixed_t alpha, bool additive, bool masked); void R_MapVisPlane (visplane_t *pl, void (*mapfunc)(int y, int x1)); visplane_t *R_FindPlane From 44adff459abb6d49581db91ad99e913be4c33ced Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Wed, 27 Apr 2016 22:49:36 -0500 Subject: [PATCH 11/30] Remove halfviewwidth - Why I thought I needed this variable in addition to centerx has long ago left my memory. --- src/doomstat.h | 1 - src/r_draw.cpp | 1 - src/r_main.cpp | 1 - src/r_plane.cpp | 2 +- 4 files changed, 1 insertion(+), 4 deletions(-) diff --git a/src/doomstat.h b/src/doomstat.h index b7b922aca..cfdca5e5a 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -121,7 +121,6 @@ extern int viewwindowx; extern int viewwindowy; extern "C" int viewheight; extern "C" int viewwidth; -extern "C" int halfviewwidth; // [RH] Half view width, for plane drawing diff --git a/src/r_draw.cpp b/src/r_draw.cpp index c58175912..80b91ed2d 100644 --- a/src/r_draw.cpp +++ b/src/r_draw.cpp @@ -60,7 +60,6 @@ extern int ST_Y; BYTE* viewimage; extern "C" { -int halfviewwidth; int ylookup[MAXHEIGHT]; BYTE *dc_destorg; } diff --git a/src/r_main.cpp b/src/r_main.cpp index b87119b88..0249544eb 100644 --- a/src/r_main.cpp +++ b/src/r_main.cpp @@ -351,7 +351,6 @@ void R_SWRSetWindow(int windowSize, int fullWidth, int fullHeight, int stHeight, } fuzzviewheight = viewheight - 2; // Maximum row the fuzzer can draw to - halfviewwidth = (viewwidth >> 1) - 1; lastcenteryfrac = 1<<30; CenterX = centerx; diff --git a/src/r_plane.cpp b/src/r_plane.cpp index 30e11a123..61ada5243 100644 --- a/src/r_plane.cpp +++ b/src/r_plane.cpp @@ -1525,7 +1525,7 @@ void R_DrawNormalPlane (visplane_t *pl, double _xscale, double _yscale, fixed_t ystepscale = (DWORD)(-(SDWORD)ystepscale); } - int x = pl->right - halfviewwidth - 1; + int x = pl->right - centerx; planeang += 90; basexfrac = xs_RoundToInt(xscale * planeang.Cos()) + x*xstepscale; baseyfrac = xs_RoundToInt(yscale * -planeang.Sin()) + x*ystepscale; From ae7d0480577ab67c167dfa53862e3f3bc64325f8 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Wed, 27 Apr 2016 23:07:25 -0500 Subject: [PATCH 12/30] Store FTransform in visplane_t, not just a pointer - The transform values passed to R_CheckPlane might live on the stack, so it's not safe to only store a pointer to them. --- src/r_plane.cpp | 35 ++++++++++++++++++----------------- src/r_plane.h | 2 +- 2 files changed, 19 insertions(+), 18 deletions(-) diff --git a/src/r_plane.cpp b/src/r_plane.cpp index 61ada5243..46b5098e1 100644 --- a/src/r_plane.cpp +++ b/src/r_plane.cpp @@ -595,8 +595,12 @@ visplane_t *R_FindPlane (const secplane_t &height, FTextureID picnum, int lightl if (picnum == skyflatnum) // killough 10/98 { // most skies map together + FTransform nulltransform; lightlevel = 0; - xform = NULL; + xform = &nulltransform; + nulltransform.xOffs = nulltransform.yOffs = nulltransform.baseyOffs = 0; + nulltransform.xScale = nulltransform.yScale = 1; + nulltransform.Angle = nulltransform.baseAngle = 0.0; additive = false; // [RH] Map floor skies and ceiling skies to separate visplanes. This isn't // always necessary, but it is needed if a floor and ceiling sky are in the @@ -649,9 +653,7 @@ visplane_t *R_FindPlane (const secplane_t &height, FTextureID picnum, int lightl picnum == check->picnum && lightlevel == check->lightlevel && basecolormap == check->colormap && // [RH] Add more checks - - (xform == check->xform || - (xform != NULL && check->xform != NULL && *xform == *check->xform)) + *xform == check->xform ) ) && check->viewangle == stacked_angle @@ -673,8 +675,7 @@ visplane_t *R_FindPlane (const secplane_t &height, FTextureID picnum, int lightl picnum == check->picnum && lightlevel == check->lightlevel && basecolormap == check->colormap && // [RH] Add more checks - (xform == check->xform || - (xform != NULL && check->xform != NULL && *xform == *check->xform)) && + *xform == check->xform && sky == check->sky && CurrentPortalUniq == check->CurrentPortalUniq && MirrorFlags == check->MirrorFlags && @@ -691,7 +692,7 @@ visplane_t *R_FindPlane (const secplane_t &height, FTextureID picnum, int lightl check->height = plane; check->picnum = picnum; check->lightlevel = lightlevel; - check->xform = xform; + check->xform = *xform; check->colormap = basecolormap; // [RH] Save colormap check->sky = sky; check->portal = portal; @@ -1095,8 +1096,8 @@ void R_DrawSinglePlane (visplane_t *pl, fixed_t alpha, bool additive, bool maske masked = false; } R_SetupSpanBits(tex); - double xscale = pl->xform->xScale * tex->Scale.X; - double yscale = pl->xform->yScale * tex->Scale.Y; + double xscale = pl->xform.xScale * tex->Scale.X; + double yscale = pl->xform.yScale * tex->Scale.Y; ds_source = tex->GetPixels (); basecolormap = pl->colormap; @@ -1494,19 +1495,19 @@ void R_DrawNormalPlane (visplane_t *pl, double _xscale, double _yscale, fixed_t return; } - DAngle planeang = pl->xform->Angle + pl->xform->baseAngle; + DAngle planeang = pl->xform.Angle + pl->xform.baseAngle; xscale = xs_ToFixed(32 - ds_xbits, _xscale); yscale = xs_ToFixed(32 - ds_ybits, _yscale); if (planeang != 0) { double cosine = planeang.Cos(), sine = planeang.Sin(); - pviewx = FLOAT2FIXED(pl->xform->xOffs + ViewPos.X * cosine - ViewPos.Y * sine); - pviewy = FLOAT2FIXED(pl->xform->yOffs - ViewPos.X * sine - ViewPos.Y * cosine); + pviewx = FLOAT2FIXED(pl->xform.xOffs + ViewPos.X * cosine - ViewPos.Y * sine); + pviewy = FLOAT2FIXED(pl->xform.yOffs - ViewPos.X * sine - ViewPos.Y * cosine); } else { - pviewx = FLOAT2FIXED(pl->xform->xOffs + ViewPos.X); - pviewy = FLOAT2FIXED(pl->xform->yOffs - ViewPos.Y); + pviewx = FLOAT2FIXED(pl->xform.xOffs + ViewPos.X); + pviewy = FLOAT2FIXED(pl->xform.yOffs - ViewPos.Y); } pviewx = FixedMul (xscale, pviewx); @@ -1624,8 +1625,8 @@ void R_DrawTiltedPlane (visplane_t *pl, double _xscale, double _yscale, fixed_t yscale = 64.f / lyscale; zeroheight = pl->height.ZatPoint(ViewPos); - pviewx = xs_ToFixed(32 - ds_xbits, pl->xform->xOffs * pl->xform->xScale); - pviewy = xs_ToFixed(32 - ds_ybits, pl->xform->yOffs * pl->xform->yScale); + pviewx = xs_ToFixed(32 - ds_xbits, pl->xform.xOffs * pl->xform.xScale); + pviewy = xs_ToFixed(32 - ds_ybits, pl->xform.yOffs * pl->xform.yScale); // p is the texture origin in view space // Don't add in the offsets at this stage, because doing so can result in @@ -1652,7 +1653,7 @@ void R_DrawTiltedPlane (visplane_t *pl, double _xscale, double _yscale, fixed_t // This code keeps the texture coordinates constant across the x,y plane no matter // how much you slope the surface. Use the commented-out code above instead to keep // the textures a constant size across the surface's plane instead. - ang = pl->xform->Angle + pl->xform->baseAngle; + ang = pl->xform.Angle + pl->xform.baseAngle; m[1] = pl->height.ZatPoint(ViewPos.X + yscale * ang.Sin(), ViewPos.Y + yscale * ang.Cos()) - zeroheight; ang += 90; n[1] = pl->height.ZatPoint(ViewPos.X + xscale * ang.Sin(), ViewPos.Y + xscale * ang.Cos()) - zeroheight; diff --git a/src/r_plane.h b/src/r_plane.h index 006885db3..fcd02ed68 100644 --- a/src/r_plane.h +++ b/src/r_plane.h @@ -34,10 +34,10 @@ struct visplane_s { struct visplane_s *next; // Next visplane in hash chain -- killough - const FTransform *xform; FDynamicColormap *colormap; // [RH] Support multiple colormaps FSectorPortal *portal; // [RH] Support sky boxes + FTransform xform; secplane_t height; FTextureID picnum; int lightlevel; From 8171637a575d7a35220e6f2dc5df03e475a9a9ac Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 28 Apr 2016 11:37:02 +0200 Subject: [PATCH 13/30] - removed the last remaining uses of the finesine table from the rendering code. --- src/r_things.cpp | 18 +++++++++--------- src/r_things.h | 4 ++-- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/r_things.cpp b/src/r_things.cpp index b930a1e92..427e61b06 100644 --- a/src/r_things.cpp +++ b/src/r_things.cpp @@ -678,7 +678,7 @@ void R_DrawVisVoxel(vissprite_t *spr, int minslabz, int maxslabz, short *cliptop } // Render the voxel, either directly to the screen or offscreen. - R_DrawVoxel(spr->pa.vpos, spr->pa.vang, spr->gpos, spr->angle, + R_DrawVoxel(spr->pa.vpos, spr->pa.vang, spr->gpos, spr->Angle, spr->xscale, FLOAT2FIXED(spr->yscale), spr->voxel, spr->Style.colormap, cliptop, clipbot, minslabz, maxslabz, flags); @@ -994,7 +994,7 @@ void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor vis->texturemid = tex->TopOffset - (ViewPos.Z - pos.Z + thing->Floorclip) / yscale; vis->x1 = x1 < WindowLeft ? WindowLeft : x1; vis->x2 = x2 > WindowRight ? WindowRight : x2; - vis->angle = thing->Angles.Yaw.BAMs(); + vis->Angle = thing->Angles.Yaw; if (renderflags & RF_XFLIP) { @@ -1024,13 +1024,13 @@ void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor pos.Z -= thing->Floorclip; - vis->angle = thing->Angles.Yaw.BAMs() + voxel->AngleOffset.BAMs(); + vis->Angle = thing->Angles.Yaw + voxel->AngleOffset; int voxelspin = (thing->flags & MF_DROPPED) ? voxel->DroppedSpin : voxel->PlacedSpin; if (voxelspin != 0) { DAngle ang = double(I_FPSTime()) * voxelspin / 1000; - vis->angle -= ang.BAMs(); + vis->Angle -= ang; } vis->pa.vpos = { (float)ViewPos.X, (float)ViewPos.Y, (float)ViewPos.Z }; @@ -2664,7 +2664,7 @@ void R_DrawParticle (vissprite_t *vis) extern double BaseYaspectMul;; void R_DrawVoxel(const FVector3 &globalpos, FAngle viewangle, - const FVector3 &dasprpos, angle_t dasprang, + const FVector3 &dasprpos, DAngle dasprang, fixed_t daxscale, fixed_t dayscale, FVoxel *voxobj, lighttable_t *colormap, short *daumost, short *dadmost, int minslabz, int maxslabz, int flags) { @@ -2698,10 +2698,10 @@ void R_DrawVoxel(const FVector3 &globalpos, FAngle viewangle, dayscale = dayscale / (0xC000 >> 6); angle_t viewang = viewangle.BAMs(); - cosang = finecosine[viewang >> ANGLETOFINESHIFT] >> 2; - sinang = -finesine[viewang >> ANGLETOFINESHIFT] >> 2; - sprcosang = finecosine[dasprang >> ANGLETOFINESHIFT] >> 2; - sprsinang = -finesine[dasprang >> ANGLETOFINESHIFT] >> 2; + cosang = FLOAT2FIXED(viewangle.Cos()) >> 2; + sinang = FLOAT2FIXED(-viewangle.Sin()) >> 2; + sprcosang = FLOAT2FIXED(dasprang.Cos()) >> 2; + sprsinang = FLOAT2FIXED(-dasprang.Sin()) >> 2; R_SetupDrawSlab(colormap); diff --git a/src/r_things.h b/src/r_things.h index 60cc17366..1cf9b0200 100644 --- a/src/r_things.h +++ b/src/r_things.h @@ -50,7 +50,7 @@ struct vissprite_t int y1, y2; // top / bottom of particle on screen }; }; - angle_t angle; + DAngle Angle; fixed_t xscale; float yscale; float depth; @@ -141,7 +141,7 @@ void R_CheckOffscreenBuffer(int width, int height, bool spansonly); enum { DVF_OFFSCREEN = 1, DVF_SPANSONLY = 2, DVF_MIRRORED = 4 }; void R_DrawVoxel(const FVector3 &viewpos, FAngle viewangle, - const FVector3 &sprpos, angle_t dasprang, + const FVector3 &sprpos, DAngle dasprang, fixed_t daxscale, fixed_t dayscale, struct FVoxel *voxobj, lighttable_t *colormap, short *daumost, short *dadmost, int minslabz, int maxslabz, int flags); From 26f54b0ba49d3f32b95d9849f066d835ff18003a Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 28 Apr 2016 12:18:33 +0200 Subject: [PATCH 14/30] - eliminated tantoangle and cleaned up r_tables.h --- src/r_main.cpp | 6 ++++-- src/r_utility.cpp | 24 +---------------------- src/tables.cpp | 2 -- src/tables.h | 50 ----------------------------------------------- 4 files changed, 5 insertions(+), 77 deletions(-) diff --git a/src/r_main.cpp b/src/r_main.cpp index 0249544eb..072b03887 100644 --- a/src/r_main.cpp +++ b/src/r_main.cpp @@ -221,7 +221,6 @@ void R_InitTextureMapping () const int t1 = MAX(int(CenterX - FocalLengthX), 0); const int t2 = MIN(int(CenterX + FocalLengthX), viewwidth); - const fixed_t dfocus = FLOAT2FIXED(FocalLengthX) >> DBITS; for (i = 0, x = t2; x >= t1; --x) { @@ -233,7 +232,10 @@ void R_InitTextureMapping () } for (x = t2 + 1; x <= viewwidth; ++x) { - xtoviewangle[x] = ANGLE_270 + tantoangle[dfocus / (x - centerx)]; + double f = atan2((FocalLengthX / (x - centerx)), 1) / (2*M_PI); + xtoviewangle[x] = ANGLE_270 + (angle_t)(0xffffffff * f); + + //xtoviewangle[x] = ANGLE_270 + tantoangle[i]; } for (x = 0; x < t1; ++x) { diff --git a/src/r_utility.cpp b/src/r_utility.cpp index 1dd4e5e40..2374c9eea 100644 --- a/src/r_utility.cpp +++ b/src/r_utility.cpp @@ -158,27 +158,6 @@ DAngle viewpitch; // CODE -------------------------------------------------------------------- static void R_Shutdown (); -//========================================================================== -// -// R_InitPointToAngle -// -//========================================================================== - -void R_InitPointToAngle (void) -{ - double f; - int i; -// -// slope (tangent) to angle lookup -// - for (i = 0; i <= SLOPERANGE; i++) - { - f = g_atan2 ((double)i, (double)SLOPERANGE) / (6.28318530718 /* 2*pi */); - tantoangle[i] = (angle_t)(0xffffffff*f); - } -} - - //========================================================================== // // R_InitTables @@ -188,7 +167,7 @@ void R_InitPointToAngle (void) void R_InitTables (void) { int i; - const double pimul = PI*2/FINEANGLES; + const double pimul = M_PI*2/FINEANGLES; // viewangle tangent table finetangent[0] = (fixed_t)(FRACUNIT*g_tan ((0.5-FINEANGLES/4)*pimul)+0.5); @@ -410,7 +389,6 @@ void R_Init () //R_InitColormaps (); //StartScreen->Progress(); - R_InitPointToAngle (); R_InitTables (); R_InitTranslationTables (); R_SetViewSize (screenblocks); diff --git a/src/tables.cpp b/src/tables.cpp index 9e367d349..9679e8547 100644 --- a/src/tables.cpp +++ b/src/tables.cpp @@ -37,6 +37,4 @@ fixed_t finetangent[4096]; fixed_t finesine[10240]; -angle_t tantoangle[2049]; -cosine_inline finecosine; // in case this is actually needed diff --git a/src/tables.h b/src/tables.h index 085174892..e2cf93e63 100644 --- a/src/tables.h +++ b/src/tables.h @@ -24,11 +24,8 @@ // effectively, by shifting). // // int finesine[10240] - Sine lookup. -// Guess what, serves as cosine, too. // Remarkable thing is, how to use BAMs with this? // -// int tantoangle[2049] - ArcTan LUT, -// maps tan(angle) to angle fast. Gotta search. // //----------------------------------------------------------------------------- @@ -40,72 +37,25 @@ #include #include "basictypes.h" -#ifndef PI -#define PI 3.14159265358979323846 // matches value in gcc v2 math.h -#endif - - -#define FINEANGLEBITS 13 #define FINEANGLES 8192 #define FINEMASK (FINEANGLES-1) // 0x100000000 to 0x2000 #define ANGLETOFINESHIFT 19 -#define BOBTOFINESHIFT (FINEANGLEBITS - 6) - // Effective size is 10240. extern fixed_t finesine[5*FINEANGLES/4]; -// Re-use data, is just PI/2 phase shift. -// [RH] Instead of using a pointer, use some inline code -// (encapsulated in a struct so that we can still use array accesses). -struct cosine_inline -{ - fixed_t operator[] (unsigned int x) const - { - return finesine[x+FINEANGLES/4]; - } -}; -extern cosine_inline finecosine; - // Effective size is 4096. extern fixed_t finetangent[FINEANGLES/2]; // Binary Angle Measument, BAM. -#define ANG45 (0x20000000) -#define ANG90 (0x40000000) -#define ANG180 (0x80000000) -#define ANG270 (0xc0000000) - -#define ANGLE_45 (0x20000000) #define ANGLE_90 (0x40000000) #define ANGLE_180 (0x80000000) #define ANGLE_270 (0xc0000000) #define ANGLE_MAX (0xffffffff) -#define ANGLE_1 (ANGLE_45/45) -#define ANGLE_60 (ANGLE_180/3) -#define SLOPERANGE 2048 -#define SLOPEBITS 11 -#define DBITS (FRACBITS-SLOPEBITS) - typedef uint32 angle_t; -// Previously seen all over the place, code like this: abs(ang1 - ang2) -// Clang warns (and is absolutely correct) that technically, this -// could be optimized away and do nothing: -// warning: taking the absolute value of unsigned type 'unsigned int' has no effect -// note: remove the call to 'abs' since unsigned values cannot be negative -inline angle_t absangle(angle_t a) -{ - return (angle_t)abs((int32_t)a); -} - -// Effective size is 2049; -// The +1 size is to handle the case when x==y -// without additional checking. -extern angle_t tantoangle[SLOPERANGE+1]; - #endif // __TABLES_H__ From f301cf7c57fcd03802268f6c598703286cb87b82 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 28 Apr 2016 13:03:48 +0200 Subject: [PATCH 15/30] - don't use finetangent for generating xviewtoangle. --- src/r_main.cpp | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/r_main.cpp b/src/r_main.cpp index 072b03887..3996ee9c9 100644 --- a/src/r_main.cpp +++ b/src/r_main.cpp @@ -175,19 +175,21 @@ static int lastcenteryfrac; static inline int viewangletox(int i) { - if (finetangent[i] > FRACUNIT*2) + const double pimul = M_PI * 2 / FINEANGLES; + + // Don't waste time calculating the tangent of values outside the valid range. + // Checking the index where tan(i) becomes too large is a lot faster + if (i <= 604) // 604 is the highest index with finetangent < -2*FRACUNIT + { + return viewwidth + 1; + } + else if (i >= 4096 - 604) // same as above with reversed signs { return -1; } - else if (finetangent[i] < -FRACUNIT*2) - { - return viewwidth+1; - } - else - { - double t = FIXED2DBL(finetangent[i]) * FocalLengthX; - return clamp(xs_CeilToInt(CenterX - t), -1, viewwidth+1); - } + + double t = tan((i - FINEANGLES / 4)*pimul) * FocalLengthX; + return clamp(xs_CeilToInt(CenterX - t), -1, viewwidth+1); } //========================================================================== @@ -234,8 +236,6 @@ void R_InitTextureMapping () { double f = atan2((FocalLengthX / (x - centerx)), 1) / (2*M_PI); xtoviewangle[x] = ANGLE_270 + (angle_t)(0xffffffff * f); - - //xtoviewangle[x] = ANGLE_270 + tantoangle[i]; } for (x = 0; x < t1; ++x) { From 027b8d29b8cf5b976cfe5cdea07e021a94b80370 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 28 Apr 2016 13:59:06 +0200 Subject: [PATCH 16/30] - make FieldOfView a real angle and remove all uses of finetangent. --- src/r_main.cpp | 4 ++-- src/r_sky.cpp | 4 ++-- src/r_state.h | 2 +- src/r_swrenderer.cpp | 6 ++---- src/r_utility.cpp | 47 +++++++++++--------------------------------- src/r_utility.h | 3 +-- src/tables.cpp | 8 -------- src/tables.h | 7 ------- 8 files changed, 19 insertions(+), 62 deletions(-) diff --git a/src/r_main.cpp b/src/r_main.cpp index 3996ee9c9..5eb2e44f8 100644 --- a/src/r_main.cpp +++ b/src/r_main.cpp @@ -179,7 +179,7 @@ static inline int viewangletox(int i) // Don't waste time calculating the tangent of values outside the valid range. // Checking the index where tan(i) becomes too large is a lot faster - if (i <= 604) // 604 is the highest index with finetangent < -2*FRACUNIT + if (i <= 604) // 604 is the highest index with tan < -2 { return viewwidth + 1; } @@ -207,7 +207,7 @@ void R_InitTextureMapping () FocalLengthY = FocalLengthX * YaspectMul; // This is 1/FocalTangent before the widescreen extension of FOV. - viewingrangerecip = DivScale32(1, finetangent[FINEANGLES/4+(FieldOfView/2)]); + viewingrangerecip = FLOAT2FIXED(1. / tan(FieldOfView.Radians() / 2)); // [RH] Do not generate viewangletox, because texture mapping is no // longer done with trig, so it's not needed. diff --git a/src/r_sky.cpp b/src/r_sky.cpp index 0e0bc412a..9ea44db48 100644 --- a/src/r_sky.cpp +++ b/src/r_sky.cpp @@ -115,8 +115,8 @@ void R_InitSkyMap () skyiscale = float(r_Yaspect / freelookviewheight); skyscale = freelookviewheight / r_Yaspect; - skyiscale *= FieldOfView / 2048.f; - skyscale *= 2048.0 / FieldOfView; + skyiscale *= float(FieldOfView.Degrees / 90.); + skyscale *= float(90. / FieldOfView.Degrees); } if (skystretch) diff --git a/src/r_state.h b/src/r_state.h index 5a5501465..fe3a21060 100644 --- a/src/r_state.h +++ b/src/r_state.h @@ -82,7 +82,7 @@ extern AActor* camera; // [RH] camera instead of viewplayer extern sector_t* viewsector; // [RH] keep track of sector viewing from extern angle_t xtoviewangle[MAXWIDTH+1]; -extern int FieldOfView; +extern DAngle FieldOfView; int R_FindSkin (const char *name, int pclass); // [RH] Find a skin diff --git a/src/r_swrenderer.cpp b/src/r_swrenderer.cpp index 7eb1e13e9..d563986f7 100644 --- a/src/r_swrenderer.cpp +++ b/src/r_swrenderer.cpp @@ -50,8 +50,6 @@ void R_SetupColormap(player_t *); void R_SetupFreelook(); void R_InitRenderer(); -extern float LastFOV; - //========================================================================== // // DCanvas :: Init @@ -272,8 +270,8 @@ void FSoftwareRenderer::RenderTextureView (FCanvasTexture *tex, AActor *viewpoin unsigned char *savecolormap = fixedcolormap; FSpecialColormap *savecm = realfixedcolormap; - float savedfov = LastFOV; - R_SetFOV ((float)fov); + DAngle savedfov = FieldOfView; + R_SetFOV ((double)fov); R_RenderViewToCanvas (viewpoint, Canvas, 0, 0, tex->GetWidth(), tex->GetHeight(), tex->bFirstUpdate); R_SetFOV (savedfov); if (Pixels == Canvas->GetBuffer()) diff --git a/src/r_utility.cpp b/src/r_utility.cpp index 2374c9eea..c145998b7 100644 --- a/src/r_utility.cpp +++ b/src/r_utility.cpp @@ -138,7 +138,6 @@ angle_t LocalViewAngle; int LocalViewPitch; bool LocalKeyboardTurner; -float LastFOV; int WidescreenRatio; int setblocks; int extralight; @@ -147,7 +146,7 @@ double FocalTangent; unsigned int R_OldBlend = ~0; int validcount = 1; // increment every time a check is made -int FieldOfView = 2048; // Fineangles in the SCREENWIDTH wide window +DAngle FieldOfView = 90.; // Angles in the SCREENWIDTH wide window FCanvasTextureInfo *FCanvasTextureInfo::List; @@ -169,13 +168,6 @@ void R_InitTables (void) int i; const double pimul = M_PI*2/FINEANGLES; - // viewangle tangent table - finetangent[0] = (fixed_t)(FRACUNIT*g_tan ((0.5-FINEANGLES/4)*pimul)+0.5); - for (i = 1; i < FINEANGLES/2; i++) - { - finetangent[i] = (fixed_t)(FRACUNIT*g_tan ((i-FINEANGLES/4)*pimul)+0.5); - } - // finesine table for (i = 0; i < FINEANGLES/4; i++) { @@ -202,33 +194,18 @@ void R_InitTables (void) // //========================================================================== -void R_SetFOV (float fov) +void R_SetFOV (DAngle fov) { - if (fov < 5.f) - fov = 5.f; - else if (fov > 170.f) - fov = 170.f; - if (fov != LastFOV) + + if (fov < 5.) fov = 5.; + else if (fov > 170.) fov = 170.; + if (fov != FieldOfView) { - LastFOV = fov; - FieldOfView = (int)(fov * (float)FINEANGLES / 360.f); + FieldOfView = fov; setsizeneeded = true; } } -//========================================================================== -// -// R_GetFOV -// -// Returns the current field of view in degrees -// -//========================================================================== - -float R_GetFOV () -{ - return LastFOV; -} - //========================================================================== // // R_SetViewSize @@ -292,18 +269,16 @@ void R_SetWindow (int windowSize, int fullWidth, int fullHeight, int stHeight) } - int fov = FieldOfView; + DAngle fov = FieldOfView; // For widescreen displays, increase the FOV so that the middle part of the // screen that would be visible on a 4:3 display has the requested FOV. if (centerxwide != centerx) { // centerxwide is what centerx would be if the display was not widescreen - fov = int(atan(double(centerx)*tan(double(fov)*M_PI/(FINEANGLES))/double(centerxwide))*(FINEANGLES)/M_PI); - if (fov > 170*FINEANGLES/360) - fov = 170*FINEANGLES/360; + fov = DAngle::ToDegrees(2 * atan(centerx * tan(fov.Radians()/2) / double(centerxwide))); + if (fov > 170.) fov = 170.; } - - FocalTangent = FIXED2FLOAT(finetangent[FINEANGLES/4+fov/2]); + FocalTangent = tan(fov.Radians() / 2); Renderer->SetWindow(windowSize, fullWidth, fullHeight, stHeight, trueratio); } diff --git a/src/r_utility.h b/src/r_utility.h index f15d42052..8cabfa600 100644 --- a/src/r_utility.h +++ b/src/r_utility.h @@ -85,8 +85,7 @@ bool R_GetViewInterpolationStatus(); void R_ClearInterpolationPath(); void R_AddInterpolationPoint(const DVector3a &vec); void R_SetViewSize (int blocks); -void R_SetFOV (float fov); -float R_GetFOV (); +void R_SetFOV (DAngle fov); void R_SetupFrame (AActor * camera); void R_SetViewAngle (); diff --git a/src/tables.cpp b/src/tables.cpp index 9679e8547..9a88a9715 100644 --- a/src/tables.cpp +++ b/src/tables.cpp @@ -19,22 +19,14 @@ // Do not try to look them up :-). // In the order of appearance: // -// int finetangent[4096] - Tangens LUT. -// Should work with BAM fairly well (12 of 16bit, -// effectively, by shifting). -// // int finesine[10240] - Sine lookup. // Guess what, serves as cosine, too. // Remarkable thing is, how to use BAMs with this? -// -// int tantoangle[2049] - ArcTan LUT, -// maps tan(angle) to angle fast. Gotta search. // // //----------------------------------------------------------------------------- #include "tables.h" -fixed_t finetangent[4096]; fixed_t finesine[10240]; diff --git a/src/tables.h b/src/tables.h index e2cf93e63..1b2868a54 100644 --- a/src/tables.h +++ b/src/tables.h @@ -19,10 +19,6 @@ // Do not try to look them up :-). // In the order of appearance: // -// int finetangent[4096] - Tangens LUT. -// Should work with BAM fairly well (12 of 16bit, -// effectively, by shifting). -// // int finesine[10240] - Sine lookup. // Remarkable thing is, how to use BAMs with this? // @@ -46,9 +42,6 @@ // Effective size is 10240. extern fixed_t finesine[5*FINEANGLES/4]; -// Effective size is 4096. -extern fixed_t finetangent[FINEANGLES/2]; - // Binary Angle Measument, BAM. #define ANGLE_90 (0x40000000) #define ANGLE_180 (0x80000000) From 9f0c5d590977255a8a7485aa9a7f315c2e3a489a Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 28 Apr 2016 14:41:11 +0200 Subject: [PATCH 17/30] -let's better be cautious about precision and use the CRT sin and cos functions for rotated plane textures. --- src/r_plane.cpp | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/src/r_plane.cpp b/src/r_plane.cpp index 46b5098e1..d18ad19a5 100644 --- a/src/r_plane.cpp +++ b/src/r_plane.cpp @@ -1500,7 +1500,7 @@ void R_DrawNormalPlane (visplane_t *pl, double _xscale, double _yscale, fixed_t yscale = xs_ToFixed(32 - ds_ybits, _yscale); if (planeang != 0) { - double cosine = planeang.Cos(), sine = planeang.Sin(); + double cosine = cos(planeang.Radians()), sine = sin(planeang.Radians()); pviewx = FLOAT2FIXED(pl->xform.xOffs + ViewPos.X * cosine - ViewPos.Y * sine); pviewy = FLOAT2FIXED(pl->xform.yOffs - ViewPos.X * sine - ViewPos.Y * cosine); } @@ -1515,9 +1515,10 @@ void R_DrawNormalPlane (visplane_t *pl, double _xscale, double _yscale, fixed_t // left to right mapping planeang = ViewAngle - 90 + planeang; + // Scale will be unit scale at FocalLengthX (normally SCREENWIDTH/2) distance - xstepscale = xs_RoundToInt(xscale * planeang.Cos() / FocalLengthX); - ystepscale = xs_RoundToInt(yscale * -planeang.Sin() / FocalLengthX); + xstepscale = xs_RoundToInt(xscale * cos(planeang.Radians()) / FocalLengthX); + ystepscale = xs_RoundToInt(yscale * -sin(planeang.Radians()) / FocalLengthX); // [RH] flip for mirrors if (MirrorFlags & RF_XFLIP) @@ -1528,8 +1529,8 @@ void R_DrawNormalPlane (visplane_t *pl, double _xscale, double _yscale, fixed_t int x = pl->right - centerx; planeang += 90; - basexfrac = xs_RoundToInt(xscale * planeang.Cos()) + x*xstepscale; - baseyfrac = xs_RoundToInt(yscale * -planeang.Sin()) + x*ystepscale; + basexfrac = xs_RoundToInt(xscale * cos(planeang.Radians())) + x*xstepscale; + baseyfrac = xs_RoundToInt(yscale * -sin(planeang.Radians())) + x*ystepscale; planeheight = fabs(pl->height.Zat0() - ViewPos.Z); @@ -1638,15 +1639,15 @@ void R_DrawTiltedPlane (visplane_t *pl, double _xscale, double _yscale, fixed_t // m is the v direction vector in view space ang = DAngle(180.) - ViewAngle; - m[0] = yscale * ang.Cos(); - m[2] = yscale * ang.Sin(); + m[0] = yscale * cos(ang.Radians()); + m[2] = yscale * sin(ang.Radians()); // m[1] = pl->height.ZatPointF (0, iyscale) - pl->height.ZatPointF (0,0)); // VectorScale2 (m, 64.f/VectorLength(m)); // n is the u direction vector in view space ang += 90; - n[0] = -xscale * ang.Cos(); - n[2] = -xscale * ang.Sin(); + n[0] = -xscale * cos(ang.Radians()); + n[2] = -xscale * sin(ang.Radians()); // n[1] = pl->height.ZatPointF (ixscale, 0) - pl->height.ZatPointF (0,0)); // VectorScale2 (n, 64.f/VectorLength(n)); @@ -1654,9 +1655,10 @@ void R_DrawTiltedPlane (visplane_t *pl, double _xscale, double _yscale, fixed_t // how much you slope the surface. Use the commented-out code above instead to keep // the textures a constant size across the surface's plane instead. ang = pl->xform.Angle + pl->xform.baseAngle; - m[1] = pl->height.ZatPoint(ViewPos.X + yscale * ang.Sin(), ViewPos.Y + yscale * ang.Cos()) - zeroheight; + double cosine = cos(ang.Radians()), sine = sin(ang.Radians()); + m[1] = pl->height.ZatPoint(ViewPos.X + yscale * sine, ViewPos.Y + yscale * cosine) - zeroheight; ang += 90; - n[1] = pl->height.ZatPoint(ViewPos.X + xscale * ang.Sin(), ViewPos.Y + xscale * ang.Cos()) - zeroheight; + n[1] = pl->height.ZatPoint(ViewPos.X + xscale * sine, ViewPos.Y + xscale * cosine) - zeroheight; plane_su = p ^ m; plane_sv = p ^ n; From ef98757c7c8d95145e9be10e52d68d9aebd5fc9b Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 28 Apr 2016 15:59:37 +0200 Subject: [PATCH 18/30] - replaced finesine for texture warping with a smaller custom table, based on the old 2005 FP code, but fixes the generation of the sine table. - removed all remnants of finesine and deleted tables.c and tables.h. --- src/CMakeLists.txt | 1 - src/actor.h | 1 - src/b_bot.h | 1 - src/basictypes.h | 8 +++++ src/p_effect.h | 1 - src/p_enemy.h | 1 - src/p_floor.cpp | 1 - src/p_lnspec.cpp | 1 - src/p_local.h | 1 - src/p_pspr.h | 1 - src/p_things.cpp | 1 - src/p_udmf.h | 1 - src/po_man.cpp | 1 - src/r_local.h | 1 - src/r_main.cpp | 6 ++-- src/r_utility.cpp | 30 ------------------ src/tables.cpp | 32 ------------------- src/tables.h | 54 --------------------------------- src/textures/texturemanager.cpp | 4 +++ src/textures/textures.h | 8 ++++- src/textures/warptexture.cpp | 50 +++++++++++++++--------------- 21 files changed, 47 insertions(+), 158 deletions(-) delete mode 100644 src/tables.cpp delete mode 100644 src/tables.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 19f7c9c19..84d6f06b9 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1091,7 +1091,6 @@ set (PCH_SOURCES statistics.cpp stats.cpp stringtable.cpp - tables.cpp teaminfo.cpp tempfiles.cpp v_blend.cpp diff --git a/src/actor.h b/src/actor.h index 37815ba3c..0336c4185 100644 --- a/src/actor.h +++ b/src/actor.h @@ -24,7 +24,6 @@ #define __P_MOBJ_H__ // Basics. -#include "tables.h" #include "templates.h" // We need the thinker_t stuff. diff --git a/src/b_bot.h b/src/b_bot.h index 9f9fe55ba..f9085d6fb 100644 --- a/src/b_bot.h +++ b/src/b_bot.h @@ -8,7 +8,6 @@ #define __B_BOT_H__ #include "c_cvars.h" -#include "tables.h" #include "info.h" #include "doomdef.h" #include "d_ticcmd.h" diff --git a/src/basictypes.h b/src/basictypes.h index 7816fa557..ff2cd972e 100644 --- a/src/basictypes.h +++ b/src/basictypes.h @@ -72,6 +72,14 @@ typedef DWORD dsfixed_t; // fixedpt used by span drawer #define DWORD_MIN ((uint32)0) #define DWORD_MAX ((uint32)0xffffffff) +// the last remnants of tables.h +#define ANGLE_90 (0x40000000) +#define ANGLE_180 (0x80000000) +#define ANGLE_270 (0xc0000000) +#define ANGLE_MAX (0xffffffff) + +typedef uint32 angle_t; + #ifdef __GNUC__ #define GCCPRINTF(stri,firstargi) __attribute__((format(printf,stri,firstargi))) diff --git a/src/p_effect.h b/src/p_effect.h index 8ae272329..033bf042c 100644 --- a/src/p_effect.h +++ b/src/p_effect.h @@ -32,7 +32,6 @@ */ #include "vectors.h" -#include "tables.h" #define FX_ROCKET 0x00000001 #define FX_GRENADE 0x00000002 diff --git a/src/p_enemy.h b/src/p_enemy.h index 9e6b03b72..298c60725 100644 --- a/src/p_enemy.h +++ b/src/p_enemy.h @@ -2,7 +2,6 @@ #define __P_ENEMY_H__ #include "thingdef/thingdef.h" -#include "tables.h" struct sector_t; class AActor; diff --git a/src/p_floor.cpp b/src/p_floor.cpp index 94c294d2a..3f2b06f95 100644 --- a/src/p_floor.cpp +++ b/src/p_floor.cpp @@ -28,7 +28,6 @@ #include "s_sndseq.h" #include "doomstat.h" #include "r_state.h" -#include "tables.h" #include "farchive.h" #include "p_3dmidtex.h" #include "p_spec.h" diff --git a/src/p_lnspec.cpp b/src/p_lnspec.cpp index 2e6acd856..2f3052203 100644 --- a/src/p_lnspec.cpp +++ b/src/p_lnspec.cpp @@ -40,7 +40,6 @@ #include "p_enemy.h" #include "g_level.h" #include "v_palette.h" -#include "tables.h" #include "i_system.h" #include "a_sharedglobal.h" #include "a_lightning.h" diff --git a/src/p_local.h b/src/p_local.h index 1a8915495..ac92ad7b7 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -25,7 +25,6 @@ #include #include "doomtype.h" -#include "tables.h" #include "vectors.h" const double NO_VALUE = FLT_MAX; diff --git a/src/p_pspr.h b/src/p_pspr.h index 27f1778f3..397ac4fff 100644 --- a/src/p_pspr.h +++ b/src/p_pspr.h @@ -25,7 +25,6 @@ // Basic data types. // Needs fixed point, and BAM angles. -#include "tables.h" #include "thingdef/thingdef.h" #define WEAPONBOTTOM 128. diff --git a/src/p_things.cpp b/src/p_things.cpp index 4afc5deaf..ba1b29a1a 100644 --- a/src/p_things.cpp +++ b/src/p_things.cpp @@ -36,7 +36,6 @@ #include "p_local.h" #include "info.h" #include "s_sound.h" -#include "tables.h" #include "doomstat.h" #include "m_random.h" #include "c_console.h" diff --git a/src/p_udmf.h b/src/p_udmf.h index 9e7bce5e2..919f6e731 100644 --- a/src/p_udmf.h +++ b/src/p_udmf.h @@ -3,7 +3,6 @@ #include "sc_man.h" #include "m_fixed.h" -#include "tables.h" class UDMFParserBase { diff --git a/src/po_man.cpp b/src/po_man.cpp index d2faa6690..1f9c6dbfd 100644 --- a/src/po_man.cpp +++ b/src/po_man.cpp @@ -18,7 +18,6 @@ #include "w_wad.h" #include "m_swap.h" #include "m_bbox.h" -#include "tables.h" #include "s_sndseq.h" #include "a_sharedglobal.h" #include "p_3dmidtex.h" diff --git a/src/r_local.h b/src/r_local.h index 7977e6923..b0ba8841e 100644 --- a/src/r_local.h +++ b/src/r_local.h @@ -24,7 +24,6 @@ #define __R_LOCAL_H__ // Binary Angles, sine/cosine/atan lookups. -#include "tables.h" // Screen size related parameters. #include "doomdef.h" diff --git a/src/r_main.cpp b/src/r_main.cpp index 5eb2e44f8..518eaec7f 100644 --- a/src/r_main.cpp +++ b/src/r_main.cpp @@ -175,7 +175,7 @@ static int lastcenteryfrac; static inline int viewangletox(int i) { - const double pimul = M_PI * 2 / FINEANGLES; + const double pimul = M_PI / 4096; // Don't waste time calculating the tangent of values outside the valid range. // Checking the index where tan(i) becomes too large is a lot faster @@ -188,7 +188,7 @@ static inline int viewangletox(int i) return -1; } - double t = tan((i - FINEANGLES / 4)*pimul) * FocalLengthX; + double t = tan((i - 2048)*pimul) * FocalLengthX; return clamp(xs_CeilToInt(CenterX - t), -1, viewwidth+1); } @@ -230,7 +230,7 @@ void R_InitTextureMapping () { ++i; } - xtoviewangle[x] = (i << ANGLETOFINESHIFT) - ANGLE_90; + xtoviewangle[x] = (i << 19) - ANGLE_90; } for (x = t2 + 1; x <= viewwidth; ++x) { diff --git a/src/r_utility.cpp b/src/r_utility.cpp index c145998b7..701a3cffd 100644 --- a/src/r_utility.cpp +++ b/src/r_utility.cpp @@ -157,35 +157,6 @@ DAngle viewpitch; // CODE -------------------------------------------------------------------- static void R_Shutdown (); -//========================================================================== -// -// R_InitTables -// -//========================================================================== - -void R_InitTables (void) -{ - int i; - const double pimul = M_PI*2/FINEANGLES; - - // finesine table - for (i = 0; i < FINEANGLES/4; i++) - { - finesine[i] = (fixed_t)(FRACUNIT * g_sin (i*pimul)); - } - for (i = 0; i < FINEANGLES/4; i++) - { - finesine[i+FINEANGLES/4] = finesine[FINEANGLES/4-1-i]; - } - for (i = 0; i < FINEANGLES/2; i++) - { - finesine[i+FINEANGLES/2] = -finesine[i]; - } - finesine[FINEANGLES/4] = FRACUNIT; - finesine[FINEANGLES*3/4] = -FRACUNIT; - memcpy (&finesine[FINEANGLES], &finesine[0], sizeof(angle_t)*FINEANGLES/4); -} - //========================================================================== // // R_SetFOV @@ -364,7 +335,6 @@ void R_Init () //R_InitColormaps (); //StartScreen->Progress(); - R_InitTables (); R_InitTranslationTables (); R_SetViewSize (screenblocks); Renderer->Init(); diff --git a/src/tables.cpp b/src/tables.cpp deleted file mode 100644 index 9a88a9715..000000000 --- a/src/tables.cpp +++ /dev/null @@ -1,32 +0,0 @@ -// Emacs style mode select -*- C++ -*- -//----------------------------------------------------------------------------- -// -// $Id:$ -// -// Copyright (C) 1993-1996 by id Software, Inc. -// -// This source is available for distribution and/or modification -// only under the terms of the DOOM Source Code License as -// published by id Software. All rights reserved. -// -// The source is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License -// for more details. -// -// DESCRIPTION: -// Lookup tables. -// Do not try to look them up :-). -// In the order of appearance: -// -// int finesine[10240] - Sine lookup. -// Guess what, serves as cosine, too. -// Remarkable thing is, how to use BAMs with this? -// -// -//----------------------------------------------------------------------------- - -#include "tables.h" - -fixed_t finesine[10240]; - diff --git a/src/tables.h b/src/tables.h deleted file mode 100644 index 1b2868a54..000000000 --- a/src/tables.h +++ /dev/null @@ -1,54 +0,0 @@ -// Emacs style mode select -*- C++ -*- -//----------------------------------------------------------------------------- -// -// $Id:$ -// -// Copyright (C) 1993-1996 by id Software, Inc. -// -// This source is available for distribution and/or modification -// only under the terms of the DOOM Source Code License as -// published by id Software. All rights reserved. -// -// The source is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License -// for more details. -// -// DESCRIPTION: -// Lookup tables. -// Do not try to look them up :-). -// In the order of appearance: -// -// int finesine[10240] - Sine lookup. -// Remarkable thing is, how to use BAMs with this? -// -// -//----------------------------------------------------------------------------- - - -#ifndef __TABLES_H__ -#define __TABLES_H__ - -#include -#include -#include "basictypes.h" - -#define FINEANGLES 8192 -#define FINEMASK (FINEANGLES-1) - -// 0x100000000 to 0x2000 -#define ANGLETOFINESHIFT 19 - -// Effective size is 10240. -extern fixed_t finesine[5*FINEANGLES/4]; - -// Binary Angle Measument, BAM. -#define ANGLE_90 (0x40000000) -#define ANGLE_180 (0x80000000) -#define ANGLE_270 (0xc0000000) -#define ANGLE_MAX (0xffffffff) - - -typedef uint32 angle_t; - -#endif // __TABLES_H__ diff --git a/src/textures/texturemanager.cpp b/src/textures/texturemanager.cpp index b2c7164e2..1147f5168 100644 --- a/src/textures/texturemanager.cpp +++ b/src/textures/texturemanager.cpp @@ -72,6 +72,10 @@ FTextureManager::FTextureManager () { memset (HashFirst, -1, sizeof(HashFirst)); + for (int i = 0; i < 2048; ++i) + { + sintable[i] = short(sin(i*(M_PI / 1024)) * 16384); + } } //========================================================================== diff --git a/src/textures/textures.h b/src/textures/textures.h index 318e32644..23b66972d 100644 --- a/src/textures/textures.h +++ b/src/textures/textures.h @@ -446,6 +446,12 @@ private: TArray mSwitchDefs; TArray mAnimatedDoors; TArray BuildTileFiles; +public: + short sintable[2048]; // for texture warping + enum + { + SINMASK = 2047 + }; }; // A texture that doesn't really exist @@ -483,7 +489,7 @@ protected: BYTE *Pixels; Span **Spans; float Speed; - int WidthOffsetMultipiler, HeightOffsetMultipiler; // [mxd] + int WidthOffsetMultiplier, HeightOffsetMultiplier; // [mxd] virtual void MakeTexture (DWORD time); int NextPo2 (int v); // [mxd] diff --git a/src/textures/warptexture.cpp b/src/textures/warptexture.cpp index 4f166f24f..5ffd9138a 100644 --- a/src/textures/warptexture.cpp +++ b/src/textures/warptexture.cpp @@ -120,9 +120,9 @@ const BYTE *FWarpTexture::GetColumn (unsigned int column, const Span **spans_out return Pixels + column*Height; } -void FWarpTexture::MakeTexture (DWORD time) +void FWarpTexture::MakeTexture(DWORD time) { - const BYTE *otherpix = SourcePic->GetPixels (); + const BYTE *otherpix = SourcePic->GetPixels(); if (Pixels == NULL) { @@ -130,17 +130,17 @@ void FWarpTexture::MakeTexture (DWORD time) } if (Spans != NULL) { - FreeSpans (Spans); + FreeSpans(Spans); Spans = NULL; } GenTime = time; - BYTE *buffer = (BYTE *)alloca (MAX (Width, Height)); + BYTE *buffer = (BYTE *)alloca(MAX(Width, Height)); int xsize = Width; int ysize = Height; - int xmul = WidthOffsetMultipiler; // [mxd] - int ymul = HeightOffsetMultipiler; // [mxd] + int xmul = WidthOffsetMultiplier; // [mxd] + int ymul = HeightOffsetMultiplier; // [mxd] int xmask = WidthMask; int ymask = Height - 1; int ybits = HeightBits; @@ -153,39 +153,39 @@ void FWarpTexture::MakeTexture (DWORD time) DWORD timebase = DWORD(time * Speed * 32 / 28); // [mxd] Rewrote to fix animation for NPo2 textures - for (y = ysize-1; y >= 0; y--) + for (y = ysize - 1; y >= 0; y--) { - int xf = (finesine[(timebase+y*ymul)&FINEMASK]>>13) % xsize; - if(xf < 0) xf += xsize; + int xf = (TexMan.sintable[((timebase + y*ymul) >> 2)&TexMan.SINMASK] >> 11) % xsize; + if (xf < 0) xf += xsize; int xt = xf; const BYTE *source = otherpix + y; BYTE *dest = Pixels + y; - for (xt = xsize; xt; xt--, xf = (xf+1)%xsize, dest += ysize) + for (xt = xsize; xt; xt--, xf = (xf + 1) % xsize, dest += ysize) *dest = source[xf + ymask * xf]; } timebase = DWORD(time * Speed * 23 / 28); - for (x = xsize-1; x >= 0; x--) + for (x = xsize - 1; x >= 0; x--) { - int yf = (finesine[(time+(x+17)*xmul)&FINEMASK]>>13) % ysize; - if(yf < 0) yf += ysize; + int yf = (TexMan.sintable[((time + (x + 17)*xmul) >> 2)&TexMan.SINMASK] >> 11) % ysize; + if (yf < 0) yf += ysize; int yt = yf; const BYTE *source = Pixels + (x + ymask * x); BYTE *dest = buffer; - for (yt = ysize; yt; yt--, yf = (yf+1)%ysize) + for (yt = ysize; yt; yt--, yf = (yf + 1) % ysize) *dest++ = source[yf]; - memcpy (Pixels+(x+ymask*x), buffer, ysize); + memcpy(Pixels + (x + ymask*x), buffer, ysize); } } // [mxd] Non power of 2 textures need different offset multipliers, otherwise warp animation won't sync across texture void FWarpTexture::SetupMultipliers (int width, int height) { - WidthOffsetMultipiler = width; - HeightOffsetMultipiler = height; + WidthOffsetMultiplier = width; + HeightOffsetMultiplier = height; int widthpo2 = NextPo2(Width); int heightpo2 = NextPo2(Height); - if(widthpo2 != Width) WidthOffsetMultipiler = (int)(WidthOffsetMultipiler * ((float)widthpo2 / Width)); - if(heightpo2 != Height) HeightOffsetMultipiler = (int)(HeightOffsetMultipiler * ((float)heightpo2 / Height)); + if(widthpo2 != Width) WidthOffsetMultiplier = (int)(WidthOffsetMultiplier * ((float)widthpo2 / Width)); + if(heightpo2 != Height) HeightOffsetMultiplier = (int)(HeightOffsetMultiplier * ((float)heightpo2 / Height)); } int FWarpTexture::NextPo2 (int v) @@ -225,8 +225,8 @@ void FWarp2Texture::MakeTexture (DWORD time) int xsize = Width; int ysize = Height; - int xmul = WidthOffsetMultipiler; // [mxd] - int ymul = HeightOffsetMultipiler; // [mxd] + int xmul = WidthOffsetMultiplier; // [mxd] + int ymul = HeightOffsetMultiplier; // [mxd] int xmask = WidthMask; int ymask = Height - 1; int ybits = HeightBits; @@ -245,12 +245,12 @@ void FWarp2Texture::MakeTexture (DWORD time) for (y = 0; y < ysize; y++) { int xt = (x + 128 - + ((finesine[(y*ymul + timebase*5 + 900) & FINEMASK]*2)>>FRACBITS) - + ((finesine[(x*xmul + timebase*4 + 300) & FINEMASK]*2)>>FRACBITS)) % xsize; + + ((TexMan.sintable[((y*ymul + timebase*5 + 900) >> 2) & TexMan.SINMASK])>>13) + + ((TexMan.sintable[((x*xmul + timebase*4 + 300) >> 2) & TexMan.SINMASK])>>13)) % xsize; int yt = (y + 128 - + ((finesine[(y*ymul + timebase*3 + 700) & FINEMASK]*2)>>FRACBITS) - + ((finesine[(x*xmul + timebase*4 + 1200) & FINEMASK]*2)>>FRACBITS)) % ysize; + + ((TexMan.sintable[((y*ymul + timebase*3 + 700) >> 2) & TexMan.SINMASK])>>13) + + ((TexMan.sintable[((x*xmul + timebase*4 + 1200) >> 2) & TexMan.SINMASK])>>13)) % ysize; *dest++ = otherpix[(xt + ymask * xt) + yt]; } From af2a1769d81870da220e707d38e4bc28346392d9 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 28 Apr 2016 16:27:28 +0200 Subject: [PATCH 19/30] - use the FP2005 method to calculate xtoviewangle, because it is far more straightforward than the old version. --- src/r_main.cpp | 64 ++++++++------------------------------------------ 1 file changed, 10 insertions(+), 54 deletions(-) diff --git a/src/r_main.cpp b/src/r_main.cpp index 518eaec7f..fdeffb93b 100644 --- a/src/r_main.cpp +++ b/src/r_main.cpp @@ -165,33 +165,6 @@ static int lastcenteryfrac; // CODE -------------------------------------------------------------------- -//========================================================================== -// -// viewangletox -// -// Used solely for construction the xtoviewangle table. -// -//========================================================================== - -static inline int viewangletox(int i) -{ - const double pimul = M_PI / 4096; - - // Don't waste time calculating the tangent of values outside the valid range. - // Checking the index where tan(i) becomes too large is a lot faster - if (i <= 604) // 604 is the highest index with tan < -2 - { - return viewwidth + 1; - } - else if (i >= 4096 - 604) // same as above with reversed signs - { - return -1; - } - - double t = tan((i - 2048)*pimul) * FocalLengthX; - return clamp(xs_CeilToInt(CenterX - t), -1, viewwidth+1); -} - //========================================================================== // // R_InitTextureMapping @@ -200,46 +173,29 @@ static inline int viewangletox(int i) void R_InitTextureMapping () { - int i, x; + int i; - // Calc focallength so FieldOfView fineangles covers viewwidth. + // Calc focallength so FieldOfView angles cover viewwidth. FocalLengthX = CenterX / FocalTangent; FocalLengthY = FocalLengthX * YaspectMul; // This is 1/FocalTangent before the widescreen extension of FOV. viewingrangerecip = FLOAT2FIXED(1. / tan(FieldOfView.Radians() / 2)); - // [RH] Do not generate viewangletox, because texture mapping is no - // longer done with trig, so it's not needed. // Now generate xtoviewangle for sky texture mapping. - // We do this with a hybrid approach: The center 90 degree span is - // constructed as per the original code: - // Scan xtoviewangle to find the smallest view angle that maps to x. - // (viewangletox is sorted in non-increasing order.) - // This reduces the chances of "doubling-up" of texture columns in - // the drawn sky texture. - // The remaining arcs are done with tantoangle instead. + // [RH] Do not generate viewangletox, because texture mapping is no + // longer done with trig, so it's not needed. + const double slopestep = FocalTangent / centerx; + double slope; - const int t1 = MAX(int(CenterX - FocalLengthX), 0); - const int t2 = MIN(int(CenterX + FocalLengthX), viewwidth); - - for (i = 0, x = t2; x >= t1; --x) + for (i = centerx, slope = 0; i <= viewwidth; i++, slope += slopestep) { - while (viewangletox(i) > x) - { - ++i; - } - xtoviewangle[x] = (i << 19) - ANGLE_90; + xtoviewangle[i] = angle_t((2 * M_PI - atan(slope)) * (ANGLE_180 / M_PI)); } - for (x = t2 + 1; x <= viewwidth; ++x) + for (i = 0; i < centerx; i++) { - double f = atan2((FocalLengthX / (x - centerx)), 1) / (2*M_PI); - xtoviewangle[x] = ANGLE_270 + (angle_t)(0xffffffff * f); - } - for (x = 0; x < t1; ++x) - { - xtoviewangle[x] = (angle_t)(-(signed)xtoviewangle[viewwidth - x]); + xtoviewangle[i] = 0 - xtoviewangle[viewwidth - i - 1]; } } From 434e39e62fb0d9f912e3bd4f023fbb4c92727f38 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 28 Apr 2016 17:55:58 +0200 Subject: [PATCH 20/30] - made adjustments to ZDoom's last changes. --- src/gl/compatibility/gl_20.cpp | 8 +++++++- src/gl/data/gl_data.cpp | 4 ++-- src/gl/models/gl_models_md2.cpp | 4 ++-- src/gl/models/gl_models_md3.cpp | 4 ++-- src/gl/scene/gl_clipper.h | 1 - src/gl/scene/gl_drawinfo.h | 2 +- src/gl/scene/gl_scene.cpp | 6 +++--- 7 files changed, 17 insertions(+), 12 deletions(-) diff --git a/src/gl/compatibility/gl_20.cpp b/src/gl/compatibility/gl_20.cpp index 280affa1a..b06ce762b 100644 --- a/src/gl/compatibility/gl_20.cpp +++ b/src/gl/compatibility/gl_20.cpp @@ -143,12 +143,15 @@ BYTE *gl_WarpBuffer(BYTE *buffer, int Width, int Height, int warp, float Speed) int xmask = xsize - 1; int ymask = ysize - 1; int ds_xbits; - int i, x; + int i; if (warp == 1) { for (ds_xbits = -1, i = Width; i; i >>= 1, ds_xbits++); + // pending consolidation with the software renderer's code. + + /* for (x = xsize - 1; x >= 0; x--) { int yt, yf = (finesine[(timebase + (x + 17) * 128)&FINEMASK] >> 13) & ymask; @@ -172,12 +175,14 @@ BYTE *gl_WarpBuffer(BYTE *buffer, int Width, int Height, int warp, float Speed) } memcpy(out + y*xsize, linebuffer, xsize * sizeof(DWORD)); } + */ } else { int ybits; for (ybits = -1, i = ysize; i; i >>= 1, ybits++); + /* DWORD timebase = (r_FrameTime * Speed * 40 / 28); for (x = xsize - 1; x >= 0; x--) { @@ -194,6 +199,7 @@ BYTE *gl_WarpBuffer(BYTE *buffer, int Width, int Height, int warp, float Speed) *dest = *source; } } + */ } delete[] buffer; return (BYTE*)out; diff --git a/src/gl/data/gl_data.cpp b/src/gl/data/gl_data.cpp index ba6105d5a..2aea2b8a3 100644 --- a/src/gl/data/gl_data.cpp +++ b/src/gl/data/gl_data.cpp @@ -431,11 +431,11 @@ FTextureID gl_GetSpriteFrame(unsigned sprite, int frame, int rot, angle_t ang, b { if (sprframe->Texture[0] == sprframe->Texture[1]) { - rot = (ang + (angle_t)(ANGLE_45/2)*9) >> 28; + rot = (ang + (angle_t)(ANGLE_90/4)*9) >> 28; } else { - rot = (ang + (angle_t)(ANGLE_45/2)*9-(angle_t)(ANGLE_180/16)) >> 28; + rot = (ang + (angle_t)(ANGLE_90/4)*9-(angle_t)(ANGLE_180/16)) >> 28; } } if (mirror) *mirror = !!(sprframe->Flip&(1<> 9) / 127.0f - 0.5f) * PI; + float yaw = (packed & 511) / 512.0f * 2 * M_PI; + float pitch = ((packed >> 9) / 127.0f - 0.5f) * M_PI; float cosp = (float) cos(pitch); vec[VX] = (float) cos(yaw) * cosp; diff --git a/src/gl/models/gl_models_md3.cpp b/src/gl/models/gl_models_md3.cpp index 13f02bc0a..7e8a4845e 100644 --- a/src/gl/models/gl_models_md3.cpp +++ b/src/gl/models/gl_models_md3.cpp @@ -60,8 +60,8 @@ static void UnpackVector(unsigned short packed, float & nx, float & ny, float & { double lat = ( packed >> 8 ) & 0xff; double lng = ( packed & 0xff ); - lat *= PI/128; - lng *= PI/128; + lat *= M_PI/128; + lng *= M_PI/128; nx = cos(lat) * sin(lng); ny = sin(lat) * sin(lng); diff --git a/src/gl/scene/gl_clipper.h b/src/gl/scene/gl_clipper.h index 7d05cf701..977107e61 100644 --- a/src/gl/scene/gl_clipper.h +++ b/src/gl/scene/gl_clipper.h @@ -2,7 +2,6 @@ #define __GL_CLIPPER #include "doomtype.h" -#include "tables.h" #include "xs_Float.h" #include "r_utility.h" diff --git a/src/gl/scene/gl_drawinfo.h b/src/gl/scene/gl_drawinfo.h index 9745ade88..744ffeef4 100644 --- a/src/gl/scene/gl_drawinfo.h +++ b/src/gl/scene/gl_drawinfo.h @@ -229,7 +229,7 @@ struct FDrawInfo FDrawInfo * next; GLDrawList drawlists[GLDL_TYPES]; - GLDrawList *dldrawlists; // only gets allocated when needed. + GLDrawList *dldrawlists = NULL; // only gets allocated when needed. FDrawInfo(); ~FDrawInfo(); diff --git a/src/gl/scene/gl_scene.cpp b/src/gl/scene/gl_scene.cpp index a745f7307..f09343f44 100644 --- a/src/gl/scene/gl_scene.cpp +++ b/src/gl/scene/gl_scene.cpp @@ -793,7 +793,7 @@ sector_t * FGLRenderer::RenderViewpoint (AActor * camera, GL_IRECT * bounds, flo SetViewArea(); // We have to scale the pitch to account for the pixel stretching, because the playsim doesn't know about this and treats it as 1:1. - double radPitch = clamp(ViewPitch.Normalized180().Radians(), -PI / 2, PI / 2); + double radPitch = ViewPitch.Normalized180().Radians(); double angx = cos(radPitch); double angy = sin(radPitch) * glset.pixelstretch; double alen = sqrt(angx*angx + angy*angy); @@ -922,7 +922,7 @@ void FGLRenderer::RenderView (player_t* player) TThinkerIterator it(STAT_DLIGHT); GLRenderer->mLightCount = ((it.Next()) != NULL); - sector_t * viewsector = RenderViewpoint(player->camera, NULL, FieldOfView * 360.0f / FINEANGLES, ratio, fovratio, true, true); + sector_t * viewsector = RenderViewpoint(player->camera, NULL, FieldOfView.Degrees, ratio, fovratio, true, true); All.Unclock(); } @@ -952,7 +952,7 @@ void FGLRenderer::WriteSavePic (player_t *player, FILE *file, int width, int hei GLRenderer->mLightCount = ((it.Next()) != NULL); sector_t *viewsector = RenderViewpoint(players[consoleplayer].camera, &bounds, - FieldOfView * 360.0f / FINEANGLES, 1.6f, 1.6f, true, false); + FieldOfView.Degrees, 1.6f, 1.6f, true, false); glDisable(GL_STENCIL_TEST); gl_RenderState.SetFixedColormap(CM_DEFAULT); gl_RenderState.SetSoftLightLevel(-1); From 3bbb5c7237678bf18ef369e2de563d0e40bc8d36 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 28 Apr 2016 18:17:18 +0200 Subject: [PATCH 21/30] - moved the texture warping into templated subfunctions, so that the same code can be used for true color buffers as well. --- src/textures/warpbuffer.h | 61 ++++++++++++++++++++++++++++ src/textures/warptexture.cpp | 77 ++---------------------------------- 2 files changed, 65 insertions(+), 73 deletions(-) create mode 100644 src/textures/warpbuffer.h diff --git a/src/textures/warpbuffer.h b/src/textures/warpbuffer.h new file mode 100644 index 000000000..0110742f1 --- /dev/null +++ b/src/textures/warpbuffer.h @@ -0,0 +1,61 @@ + +template +void WarpBufferType1(TYPE *Pixels, const TYPE *source, int width, int height, int xmul, int ymul, unsigned time, float Speed) +{ + TYPE *buffer = (TYPE *)alloca(sizeof(TYPE) * MAX(width, height)); + int ymask = height - 1; + int x, y; + + // [mxd] Rewrote to fix animation for NPo2 textures + unsigned timebase = unsigned(time * Speed * 32 / 28); + for (y = height - 1; y >= 0; y--) + { + int xf = (TexMan.sintable[((timebase + y*ymul) >> 2)&TexMan.SINMASK] >> 11) % width; + if (xf < 0) xf += width; + int xt = xf; + const TYPE *sourcep = source + y; + TYPE *dest = Pixels + y; + for (xt = width; xt; xt--, xf = (xf + 1) % width, dest += height) + *dest = sourcep[xf + ymask * xf]; + } + timebase = unsigned(time * Speed * 23 / 28); + for (x = width - 1; x >= 0; x--) + { + int yf = (TexMan.sintable[((time + (x + 17)*xmul) >> 2)&TexMan.SINMASK] >> 11) % height; + if (yf < 0) yf += height; + int yt = yf; + const TYPE *sourcep = Pixels + (x + ymask * x); + TYPE *dest = buffer; + for (yt = height; yt; yt--, yf = (yf + 1) % height) + *dest++ = sourcep[yf]; + memcpy(Pixels + (x + ymask*x), buffer, height * sizeof(TYPE)); + } +} + + +template +void WarpBufferType2(TYPE *Pixels, const TYPE *source, int width, int height, int xmul, int ymul, unsigned time, float Speed) +{ + int ymask = height - 1; + int x, y; + + unsigned timebase = unsigned(time * Speed * 40 / 28); + // [mxd] Rewrote to fix animation for NPo2 textures + for (x = 0; x < width; x++) + { + TYPE *dest = Pixels + (x + ymask * x); + for (y = 0; y < height; y++) + { + int xt = (x + 128 + + ((TexMan.sintable[((y*ymul + timebase * 5 + 900) >> 2) & TexMan.SINMASK]) >> 13) + + ((TexMan.sintable[((x*xmul + timebase * 4 + 300) >> 2) & TexMan.SINMASK]) >> 13)) % width; + + int yt = (y + 128 + + ((TexMan.sintable[((y*ymul + timebase * 3 + 700) >> 2) & TexMan.SINMASK]) >> 13) + + ((TexMan.sintable[((x*xmul + timebase * 4 + 1200) >> 2) & TexMan.SINMASK]) >> 13)) % height; + + *dest++ = source[(xt + ymask * xt) + yt]; + } + } +} + diff --git a/src/textures/warptexture.cpp b/src/textures/warptexture.cpp index 5ffd9138a..54d697c22 100644 --- a/src/textures/warptexture.cpp +++ b/src/textures/warptexture.cpp @@ -38,6 +38,7 @@ #include "templates.h" #include "r_utility.h" #include "textures/textures.h" +#include "warpbuffer.h" FWarpTexture::FWarpTexture (FTexture *source) @@ -120,6 +121,7 @@ const BYTE *FWarpTexture::GetColumn (unsigned int column, const Span **spans_out return Pixels + column*Height; } + void FWarpTexture::MakeTexture(DWORD time) { const BYTE *otherpix = SourcePic->GetPixels(); @@ -135,46 +137,7 @@ void FWarpTexture::MakeTexture(DWORD time) } GenTime = time; - - BYTE *buffer = (BYTE *)alloca(MAX(Width, Height)); - int xsize = Width; - int ysize = Height; - int xmul = WidthOffsetMultiplier; // [mxd] - int ymul = HeightOffsetMultiplier; // [mxd] - int xmask = WidthMask; - int ymask = Height - 1; - int ybits = HeightBits; - int x, y; - - if ((1 << ybits) > Height) - { - ybits--; - } - - DWORD timebase = DWORD(time * Speed * 32 / 28); - // [mxd] Rewrote to fix animation for NPo2 textures - for (y = ysize - 1; y >= 0; y--) - { - int xf = (TexMan.sintable[((timebase + y*ymul) >> 2)&TexMan.SINMASK] >> 11) % xsize; - if (xf < 0) xf += xsize; - int xt = xf; - const BYTE *source = otherpix + y; - BYTE *dest = Pixels + y; - for (xt = xsize; xt; xt--, xf = (xf + 1) % xsize, dest += ysize) - *dest = source[xf + ymask * xf]; - } - timebase = DWORD(time * Speed * 23 / 28); - for (x = xsize - 1; x >= 0; x--) - { - int yf = (TexMan.sintable[((time + (x + 17)*xmul) >> 2)&TexMan.SINMASK] >> 11) % ysize; - if (yf < 0) yf += ysize; - int yt = yf; - const BYTE *source = Pixels + (x + ymask * x); - BYTE *dest = buffer; - for (yt = ysize; yt; yt--, yf = (yf + 1) % ysize) - *dest++ = source[yf]; - memcpy(Pixels + (x + ymask*x), buffer, ysize); - } + WarpBufferType1(Pixels, otherpix, Width, Height, WidthOffsetMultiplier, HeightOffsetMultiplier, time, Speed); } // [mxd] Non power of 2 textures need different offset multipliers, otherwise warp animation won't sync across texture @@ -222,39 +185,7 @@ void FWarp2Texture::MakeTexture (DWORD time) } GenTime = time; - - int xsize = Width; - int ysize = Height; - int xmul = WidthOffsetMultiplier; // [mxd] - int ymul = HeightOffsetMultiplier; // [mxd] - int xmask = WidthMask; - int ymask = Height - 1; - int ybits = HeightBits; - int x, y; - - if ((1 << ybits) > Height) - { - ybits--; - } - - DWORD timebase = DWORD(time * Speed * 40 / 28); - // [mxd] Rewrote to fix animation for NPo2 textures - for (x = 0; x < xsize; x++) - { - BYTE *dest = Pixels + (x + ymask * x); - for (y = 0; y < ysize; y++) - { - int xt = (x + 128 - + ((TexMan.sintable[((y*ymul + timebase*5 + 900) >> 2) & TexMan.SINMASK])>>13) - + ((TexMan.sintable[((x*xmul + timebase*4 + 300) >> 2) & TexMan.SINMASK])>>13)) % xsize; - - int yt = (y + 128 - + ((TexMan.sintable[((y*ymul + timebase*3 + 700) >> 2) & TexMan.SINMASK])>>13) - + ((TexMan.sintable[((x*xmul + timebase*4 + 1200) >> 2) & TexMan.SINMASK])>>13)) % ysize; - - *dest++ = otherpix[(xt + ymask * xt) + yt]; - } - } + WarpBufferType2(Pixels, otherpix, Width, Height, WidthOffsetMultiplier, HeightOffsetMultiplier, time, Speed); } //========================================================================== From e3fad118d2722072b323db92533bd2faef3ae8b6 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 28 Apr 2016 19:04:01 +0200 Subject: [PATCH 22/30] - use the templated warp functions instead of the limited GZDoom 1.x version. gl_WarpBuffer has been removed. --- src/gl/compatibility/gl_20.cpp | 82 --------------------------------- src/gl/textures/gl_material.cpp | 17 +++++-- src/textures/textures.h | 4 +- 3 files changed, 14 insertions(+), 89 deletions(-) diff --git a/src/gl/compatibility/gl_20.cpp b/src/gl/compatibility/gl_20.cpp index b06ce762b..d0de0589c 100644 --- a/src/gl/compatibility/gl_20.cpp +++ b/src/gl/compatibility/gl_20.cpp @@ -123,88 +123,6 @@ void gl_SetTextureMode(int type) } } -//=========================================================================== -// -// FGLTex::WarpBuffer -// -//=========================================================================== - -BYTE *gl_WarpBuffer(BYTE *buffer, int Width, int Height, int warp, float Speed) -{ - if (Width > 256 || Height > 256) return buffer; - - DWORD *in = (DWORD*)buffer; - DWORD *out = (DWORD*)new BYTE[4 * Width*Height]; - - static DWORD linebuffer[256]; // anything larger will bring down performance so it is excluded above. - DWORD timebase = DWORD(r_FrameTime*Speed * 23 / 28); - int xsize = Width; - int ysize = Height; - int xmask = xsize - 1; - int ymask = ysize - 1; - int ds_xbits; - int i; - - if (warp == 1) - { - for (ds_xbits = -1, i = Width; i; i >>= 1, ds_xbits++); - - // pending consolidation with the software renderer's code. - - /* - for (x = xsize - 1; x >= 0; x--) - { - int yt, yf = (finesine[(timebase + (x + 17) * 128)&FINEMASK] >> 13) & ymask; - const DWORD *source = in + x; - DWORD *dest = out + x; - for (yt = ysize; yt; yt--, yf = (yf + 1)&ymask, dest += xsize) - { - *dest = *(source + (yf << ds_xbits)); - } - } - timebase = DWORD(r_FrameTime*Speed * 32 / 28); - int y; - for (y = ysize - 1; y >= 0; y--) - { - int xt, xf = (finesine[(timebase + y * 128)&FINEMASK] >> 13) & xmask; - DWORD *source = out + (y << ds_xbits); - DWORD *dest = linebuffer; - for (xt = xsize; xt; xt--, xf = (xf + 1)&xmask) - { - *dest++ = *(source + xf); - } - memcpy(out + y*xsize, linebuffer, xsize * sizeof(DWORD)); - } - */ - } - else - { - int ybits; - for (ybits = -1, i = ysize; i; i >>= 1, ybits++); - - /* - DWORD timebase = (r_FrameTime * Speed * 40 / 28); - for (x = xsize - 1; x >= 0; x--) - { - for (int y = ysize - 1; y >= 0; y--) - { - int xt = (x + 128 - + ((finesine[(y * 128 + timebase * 5 + 900) & 8191] * 2) >> FRACBITS) - + ((finesine[(x * 256 + timebase * 4 + 300) & 8191] * 2) >> FRACBITS)) & xmask; - int yt = (y + 128 - + ((finesine[(y * 128 + timebase * 3 + 700) & 8191] * 2) >> FRACBITS) - + ((finesine[(x * 256 + timebase * 4 + 1200) & 8191] * 2) >> FRACBITS)) & ymask; - const DWORD *source = in + (xt << ybits) + yt; - DWORD *dest = out + (x << ybits) + y; - *dest = *source; - } - } - */ - } - delete[] buffer; - return (BYTE*)out; -} - //========================================================================== // // diff --git a/src/gl/textures/gl_material.cpp b/src/gl/textures/gl_material.cpp index f3743bd3a..a900a1e45 100644 --- a/src/gl/textures/gl_material.cpp +++ b/src/gl/textures/gl_material.cpp @@ -47,6 +47,7 @@ #include "templates.h" #include "sc_man.h" #include "colormatcher.h" +#include "textures/warpbuffer.h" //#include "gl/gl_intern.h" @@ -72,7 +73,6 @@ EXTERN_CVAR(Bool, gl_texture_usehires) // The GL texture maintenance class // //=========================================================================== -BYTE *gl_WarpBuffer(BYTE *buffer, int Width, int Height, int warp, float Speed); //=========================================================================== // @@ -310,11 +310,18 @@ const FHardwareTexture *FGLTexture::Bind(int texunit, int clampmode, int transla if (!tex->bHasCanvas) { buffer = CreateTexBuffer(translation, w, h, hirescheck, true, alphatrans); - if (tex->bWarped && gl.glslversion == 0) + if (tex->bWarped && gl.glslversion == 0 && w*h <= 256*256) // do not software-warp larger textures, especially on the old systems that still need this fallback. { - // need to warp - buffer = gl_WarpBuffer(buffer, w, h, tex->bWarped, static_cast(tex)->GetSpeed()); - static_cast(tex)->GenTime = r_FrameTime; + // need to do software warping + FWarpTexture *wt = static_cast(tex); + unsigned char *warpbuffer = new unsigned char[w*h*4]; + if (tex->bWarped != 2) + WarpBufferType1((DWORD*)warpbuffer, (const DWORD*)buffer, w, h, wt->WidthOffsetMultiplier, wt->HeightOffsetMultiplier, r_FrameTime, wt->Speed); + else + WarpBufferType2((DWORD*)warpbuffer, (const DWORD*)buffer, w, h, wt->WidthOffsetMultiplier, wt->HeightOffsetMultiplier, r_FrameTime, wt->Speed); + delete[] buffer; + buffer = warpbuffer; + wt->GenTime = r_FrameTime; } tex->ProcessData(buffer, w, h, false); } diff --git a/src/textures/textures.h b/src/textures/textures.h index 778b955d4..4aa30605f 100644 --- a/src/textures/textures.h +++ b/src/textures/textures.h @@ -555,12 +555,12 @@ public: FTexture *GetRedirect(bool wantwarped); DWORD GenTime; + float Speed; + int WidthOffsetMultiplier, HeightOffsetMultiplier; // [mxd] protected: FTexture *SourcePic; BYTE *Pixels; Span **Spans; - float Speed; - int WidthOffsetMultiplier, HeightOffsetMultiplier; // [mxd] virtual void MakeTexture (DWORD time); int NextPo2 (int v); // [mxd] From 21283b18f447dc3ee5ff85a1a14db1302a7af2b7 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 29 Apr 2016 01:48:06 +0200 Subject: [PATCH 23/30] - preparations for using clip planes on line portals. --- src/gl/renderer/gl_renderer.cpp | 1 + src/gl/renderer/gl_renderer.h | 1 + src/gl/renderer/gl_renderstate.cpp | 16 +++- src/gl/renderer/gl_renderstate.h | 33 ++++++++ src/gl/scene/gl_bsp.cpp | 14 ++-- src/gl/scene/gl_portal.cpp | 102 +++++++++++++----------- src/gl/scene/gl_portal.h | 7 +- src/gl/scene/gl_scene.cpp | 2 +- src/gl/scene/gl_sprite.cpp | 8 +- src/gl/shaders/gl_shader.cpp | 1 + src/gl/shaders/gl_shader.h | 17 ++-- wadsrc/static/shaders/glsl/shaderdefs.i | 1 + 12 files changed, 133 insertions(+), 70 deletions(-) diff --git a/src/gl/renderer/gl_renderer.cpp b/src/gl/renderer/gl_renderer.cpp index cca2e9b2b..e3b9b0a8b 100644 --- a/src/gl/renderer/gl_renderer.cpp +++ b/src/gl/renderer/gl_renderer.cpp @@ -84,6 +84,7 @@ FGLRenderer::FGLRenderer(OpenGLFrameBuffer *fb) { framebuffer = fb; + mClipPortal = NULL; mCurrentPortal = NULL; mMirrorCount = 0; mPlaneMirrorCount = 0; diff --git a/src/gl/renderer/gl_renderer.h b/src/gl/renderer/gl_renderer.h index d09ac1948..52ce5b2fa 100644 --- a/src/gl/renderer/gl_renderer.h +++ b/src/gl/renderer/gl_renderer.h @@ -59,6 +59,7 @@ class FGLRenderer public: OpenGLFrameBuffer *framebuffer; + GLPortal *mClipPortal; GLPortal *mCurrentPortal; int mMirrorCount; int mPlaneMirrorCount; diff --git a/src/gl/renderer/gl_renderstate.cpp b/src/gl/renderer/gl_renderstate.cpp index fdb0e3cc5..15a575e79 100644 --- a/src/gl/renderer/gl_renderstate.cpp +++ b/src/gl/renderer/gl_renderstate.cpp @@ -69,7 +69,7 @@ TArray gl_MatrixStack; void FRenderState::Reset() { mTextureEnabled = true; - mSplitEnabled = mBrightmapEnabled = mFogEnabled = mGlowEnabled = false; + mClipLineEnabled = mSplitEnabled = mBrightmapEnabled = mFogEnabled = mGlowEnabled = false; mColorMask[0] = mColorMask[1] = mColorMask[2] = mColorMask[3] = true; currentColorMask[0] = currentColorMask[1] = currentColorMask[2] = currentColorMask[3] = true; mFogColor.d = -1; @@ -171,10 +171,22 @@ bool FRenderState::ApplyShader() activeShader->muSplitBottomPlane.Set(mSplitBottomPlane.vec); activeShader->currentsplitstate = 1; } - else + else if (activeShader->currentsplitstate) { activeShader->muSplitTopPlane.Set(nulvec); activeShader->muSplitBottomPlane.Set(nulvec); + activeShader->currentsplitstate = 0; + } + + if (mClipLineEnabled) + { + activeShader->muClipLine.Set(mClipLine.vec); + activeShader->currentcliplinestate = 1; + } + else if (activeShader->currentcliplinestate) + { + activeShader->muClipLine.Set(-10000000.0, 0, 0, 0); + activeShader->currentcliplinestate = 0; } if (mColormapState != activeShader->currentfixedcolormap) diff --git a/src/gl/renderer/gl_renderstate.h b/src/gl/renderer/gl_renderstate.h index ca240c398..829edeec0 100644 --- a/src/gl/renderer/gl_renderstate.h +++ b/src/gl/renderer/gl_renderstate.h @@ -47,6 +47,7 @@ class FRenderState bool mFogEnabled; bool mGlowEnabled; bool mSplitEnabled; + bool mClipLineEnabled; bool mBrightmapEnabled; bool mColorMask[4]; bool currentColorMask[4]; @@ -73,6 +74,7 @@ class FRenderState FStateVec4 mGlowTop, mGlowBottom; FStateVec4 mGlowTopPlane, mGlowBottomPlane; FStateVec4 mSplitTopPlane, mSplitBottomPlane; + FStateVec4 mClipLine; PalEntry mFogColor; PalEntry mObjectColor; FStateVec4 mDynColor; @@ -145,6 +147,16 @@ public: return mClipHeightDirection; } + FStateVec4 &GetClipLine() + { + return mClipLine; + } + + bool GetClipLineState() + { + return mClipLineEnabled; + } + void SetClipHeight(float height, float direction); void SetColor(float r, float g, float b, float a = 1.f, int desat = 0) @@ -241,6 +253,27 @@ public: } } + void SetClipLine(line_t *line) + { + mClipLine.Set(line->v1->fX(), line->v1->fY(), line->Delta().X, line->Delta().Y); + } + + void EnableClipLine(bool on) + { + if (gl.glslversion >= 1.3f) + { + mClipLineEnabled = on; + if (on) + { + glEnable(GL_CLIP_DISTANCE0); + } + else + { + glDisable(GL_CLIP_DISTANCE0); + } + } + } + void SetLightIndex(int n) { mLightIndex = n; diff --git a/src/gl/scene/gl_bsp.cpp b/src/gl/scene/gl_bsp.cpp index 98053784c..b9915dd72 100644 --- a/src/gl/scene/gl_bsp.cpp +++ b/src/gl/scene/gl_bsp.cpp @@ -111,7 +111,7 @@ static void AddLine (seg_t *seg, bool portalclip) if (portalclip) { - int clipres = GLRenderer->mCurrentPortal->ClipSeg(seg); + int clipres = GLRenderer->mClipPortal->ClipSeg(seg); if (clipres == GLPortal::PClip_InFront) return; } @@ -218,7 +218,7 @@ static void PolySubsector(subsector_t * sub) { if (line->linedef) { - AddLine (line, GLRenderer->mCurrentPortal != NULL); + AddLine (line, GLRenderer->mClipPortal != NULL); } line++; } @@ -313,11 +313,11 @@ static inline void AddLines(subsector_t * sub, sector_t * sector) { if (seg->linedef == NULL) { - if (!(sub->flags & SSECF_DRAWN)) AddLine (seg, GLRenderer->mCurrentPortal != NULL); + if (!(sub->flags & SSECF_DRAWN)) AddLine (seg, GLRenderer->mClipPortal != NULL); } else if (!(seg->sidedef->Flags & WALLF_POLYOBJ)) { - AddLine (seg, GLRenderer->mCurrentPortal != NULL); + AddLine (seg, GLRenderer->mClipPortal != NULL); } seg++; } @@ -447,12 +447,12 @@ static void DoSubsector(subsector_t * sub) fakesector=gl_FakeFlat(sector, &fake, false); - if (GLRenderer->mCurrentPortal) + if (GLRenderer->mClipPortal) { - int clipres = GLRenderer->mCurrentPortal->ClipSubsector(sub); + int clipres = GLRenderer->mClipPortal->ClipSubsector(sub); if (clipres == GLPortal::PClip_InFront) { - line_t *line = GLRenderer->mCurrentPortal->ClipLine(); + line_t *line = GLRenderer->mClipPortal->ClipLine(); // The subsector is out of range, but we still have to check lines that lie directly on the boundary and may expose their upper or lower parts. if (line) AddSpecialPortalLines(sub, fakesector, line); return; diff --git a/src/gl/scene/gl_portal.cpp b/src/gl/scene/gl_portal.cpp index 93f25f28e..f165de630 100644 --- a/src/gl/scene/gl_portal.cpp +++ b/src/gl/scene/gl_portal.cpp @@ -300,9 +300,6 @@ bool GLPortal::Start(bool usestencil, bool doquery) glDisable(GL_DEPTH_TEST); } } - planestack.Push(gl_RenderState.GetClipHeight()); - planestack.Push(gl_RenderState.GetClipHeightDirection()); - gl_RenderState.SetClipHeight(0., 0.); // save viewpoint savedViewPos = ViewPos; @@ -313,8 +310,12 @@ bool GLPortal::Start(bool usestencil, bool doquery) savedviewpath[0] = ViewPath[0]; savedviewpath[1] = ViewPath[1]; - NextPortal = GLRenderer->mCurrentPortal; - GLRenderer->mCurrentPortal = NULL; // Portals which need this have to set it themselves + PrevPortal = GLRenderer->mCurrentPortal; + PrevClipPortal = GLRenderer->mClipPortal; + GLRenderer->mClipPortal = NULL; // Portals which need this have to set it themselves + GLRenderer->mCurrentPortal = this; + + if (PrevPortal != NULL) PrevPortal->PushState(); PortalAll.Unclock(); return true; } @@ -359,12 +360,9 @@ void GLPortal::End(bool usestencil) bool needdepth = NeedDepthBuffer(); PortalAll.Clock(); - GLRenderer->mCurrentPortal = NextPortal; - - float f, d; - planestack.Pop(d); - planestack.Pop(f); - gl_RenderState.SetClipHeight(f, d); + if (PrevPortal != NULL) PrevPortal->PopState(); + GLRenderer->mCurrentPortal = PrevPortal; + GLRenderer->mClipPortal = PrevClipPortal; if (usestencil) { @@ -806,14 +804,59 @@ void GLPlaneMirrorPortal::DrawContents() PlaneMirrorMode=old_pm; } +void GLPlaneMirrorPortal::PushState() +{ + planestack.Push(gl_RenderState.GetClipHeight()); + planestack.Push(gl_RenderState.GetClipHeightDirection()); + gl_RenderState.SetClipHeight(0.f, 0.f); +} + +void GLPlaneMirrorPortal::PopState() +{ + float d, f; + planestack.Pop(d); + planestack.Pop(f); + gl_RenderState.SetClipHeight(f, d); +} + //----------------------------------------------------------------------------- // -// GLPlaneMirrorPortal::DrawContents +// Common code for line to line and mirror portals // //----------------------------------------------------------------------------- +int GLLinePortal::ClipSeg(seg_t *seg) +{ + line_t *linedef = seg->linedef; + if (!linedef) + { + return PClip_Inside; // should be handled properly. + } + return P_ClipLineToPortal(linedef, line(), ViewPos) ? PClip_InFront : PClip_Inside; +} + +int GLLinePortal::ClipSubsector(subsector_t *sub) +{ + // this seg is completely behind the mirror! + for(unsigned int i=0;inumlines;i++) + { + if (P_PointOnLineSidePrecise(sub->firstline[i].v1->fPos(), line()) == 0) return PClip_Inside; + } + return PClip_InFront; +} + +int GLLinePortal::ClipPoint(const DVector2 &pos) +{ + if (P_PointOnLineSidePrecise(pos, line())) + { + return PClip_InFront; + } + return PClip_Inside; +} + + //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // @@ -837,7 +880,7 @@ void GLMirrorPortal::DrawContents() return; } - GLRenderer->mCurrentPortal = this; + GLRenderer->mClipPortal = this; DAngle StartAngle = ViewAngle; DVector3 StartPos = ViewPos; @@ -910,37 +953,6 @@ void GLMirrorPortal::DrawContents() MirrorFlag--; } - -int GLLinePortal::ClipSeg(seg_t *seg) -{ - line_t *linedef = seg->linedef; - if (!linedef) - { - return PClip_Inside; // should be handled properly. - } - return P_ClipLineToPortal(linedef, line(), ViewPos) ? PClip_InFront : PClip_Inside; -} - -int GLLinePortal::ClipSubsector(subsector_t *sub) -{ - // this seg is completely behind the mirror! - for(unsigned int i=0;inumlines;i++) - { - if (P_PointOnLineSidePrecise(sub->firstline[i].v1->fPos(), line()) == 0) return PClip_Inside; - } - return PClip_InFront; -} - -int GLLinePortal::ClipPoint(const DVector2 &pos) -{ - if (P_PointOnLineSidePrecise(pos, line())) - { - return PClip_InFront; - } - return PClip_Inside; -} - - //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // @@ -965,7 +977,7 @@ void GLLineToLinePortal::DrawContents() return; } - GLRenderer->mCurrentPortal = this; + GLRenderer->mClipPortal = this; line_t *origin = glport->reference->mOrigin; P_TranslatePortalXY(origin, ViewPos.X, ViewPos.Y); diff --git a/src/gl/scene/gl_portal.h b/src/gl/scene/gl_portal.h index 8fe54c5b1..870009845 100644 --- a/src/gl/scene/gl_portal.h +++ b/src/gl/scene/gl_portal.h @@ -107,7 +107,8 @@ private: area_t savedviewarea; bool savedshowviewer; DVector3 savedviewpath[2]; - GLPortal *NextPortal; + GLPortal *PrevPortal; + GLPortal *PrevClipPortal; TArray savedmapsection; TArray mPrimIndices; @@ -130,6 +131,8 @@ protected: virtual const char *GetName() = 0; void SaveMapSection(); void RestoreMapSection(); + virtual void PushState() {} + virtual void PopState() {} public: @@ -341,6 +344,8 @@ protected: virtual void DrawContents(); virtual void * GetSource() const { return origin; } virtual const char *GetName(); + virtual void PushState(); + virtual void PopState(); secplane_t * origin; public: diff --git a/src/gl/scene/gl_scene.cpp b/src/gl/scene/gl_scene.cpp index f09343f44..1b6b8e87f 100644 --- a/src/gl/scene/gl_scene.cpp +++ b/src/gl/scene/gl_scene.cpp @@ -503,7 +503,7 @@ void FGLRenderer::DrawScene(bool toscreen) static int recursion=0; CreateScene(); - GLRenderer->mCurrentPortal = NULL; // this must be reset before any portal recursion takes place. + GLRenderer->mClipPortal = NULL; // this must be reset before any portal recursion takes place. // Up to this point in the main draw call no rendering is performed so we can wait // with swapping the render buffer until now. diff --git a/src/gl/scene/gl_sprite.cpp b/src/gl/scene/gl_sprite.cpp index 942a2e555..63a4f9c8c 100644 --- a/src/gl/scene/gl_sprite.cpp +++ b/src/gl/scene/gl_sprite.cpp @@ -581,9 +581,9 @@ void GLSprite::Process(AActor* thing, sector_t * sector, bool thruportal) thing->flags7 |= MF7_FLYCHEAT; // do this only once for the very first frame, but not if it gets into range again. } - if (GLRenderer->mCurrentPortal) + if (GLRenderer->mClipPortal) { - int clipres = GLRenderer->mCurrentPortal->ClipPoint(thingpos); + int clipres = GLRenderer->mClipPortal->ClipPoint(thingpos); if (clipres == GLPortal::PClip_InFront) return; } @@ -894,9 +894,9 @@ void GLSprite::Process(AActor* thing, sector_t * sector, bool thruportal) void GLSprite::ProcessParticle (particle_t *particle, sector_t *sector)//, int shade, int fakeside) { - if (GLRenderer->mCurrentPortal) + if (GLRenderer->mClipPortal) { - int clipres = GLRenderer->mCurrentPortal->ClipPoint(particle->Pos); + int clipres = GLRenderer->mClipPortal->ClipPoint(particle->Pos); if (clipres == GLPortal::PClip_InFront) return; } diff --git a/src/gl/shaders/gl_shader.cpp b/src/gl/shaders/gl_shader.cpp index a86c57101..ea8f5aa92 100644 --- a/src/gl/shaders/gl_shader.cpp +++ b/src/gl/shaders/gl_shader.cpp @@ -278,6 +278,7 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char * muGlowTopPlane.Init(hShader, "uGlowTopPlane"); muSplitBottomPlane.Init(hShader, "uSplitBottomPlane"); muSplitTopPlane.Init(hShader, "uSplitTopPlane"); + muClipLine.Init(hShader, "uClipLine"); muFixedColormap.Init(hShader, "uFixedColormap"); muInterpolationFactor.Init(hShader, "uInterpolationFactor"); muClipHeight.Init(hShader, "uClipHeight"); diff --git a/src/gl/shaders/gl_shader.h b/src/gl/shaders/gl_shader.h index a7f7e4277..ca534c31d 100644 --- a/src/gl/shaders/gl_shader.h +++ b/src/gl/shaders/gl_shader.h @@ -220,6 +220,7 @@ class FShader FUniform4f muGlowTopPlane; FUniform4f muSplitBottomPlane; FUniform4f muSplitTopPlane; + FUniform4f muClipLine; FBufferedUniform1f muInterpolationFactor; FBufferedUniform1f muClipHeight; FBufferedUniform1f muClipHeightDirection; @@ -234,22 +235,18 @@ class FShader public: int fakevb_index; private: - int currentglowstate; - int currentsplitstate; - int currentfixedcolormap; - bool currentTextureMatrixState; - bool currentModelMatrixState; + int currentglowstate = 0; + int currentsplitstate = 0; + int currentcliplinestate = 0; + int currentfixedcolormap = 0; + bool currentTextureMatrixState = true;// by setting the matrix state to 'true' it is guaranteed to be set the first time the render state gets applied. + bool currentModelMatrixState = true; public: FShader(const char *name) : mName(name) { hShader = hVertProg = hFragProg = 0; - currentglowstate = 0; - currentsplitstate = 0; - currentfixedcolormap = 0; - currentTextureMatrixState = true; // by setting the matrix state to 'true' it is guaranteed to be set the first time the render state gets applied. - currentModelMatrixState = true; } ~FShader(); diff --git a/wadsrc/static/shaders/glsl/shaderdefs.i b/wadsrc/static/shaders/glsl/shaderdefs.i index 5259bb5fd..7500a0cfc 100644 --- a/wadsrc/static/shaders/glsl/shaderdefs.i +++ b/wadsrc/static/shaders/glsl/shaderdefs.i @@ -8,6 +8,7 @@ uniform vec4 uCameraPos; uniform int uTextureMode; uniform float uClipHeight, uClipHeightDirection; uniform vec2 uClipSplit; +uniform vec4 uClipLine; uniform float uAlphaThreshold; From 96228ca15f642b20070e4938e97b83b4fd3b67b7 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 28 Apr 2016 21:07:17 -0500 Subject: [PATCH 24/30] Trying to fix some rounding, not sure it's actually correct yet --- src/r_segs.cpp | 55 ++++++++++---------------------------------------- 1 file changed, 11 insertions(+), 44 deletions(-) diff --git a/src/r_segs.cpp b/src/r_segs.cpp index 546544f81..6625d2524 100644 --- a/src/r_segs.cpp +++ b/src/r_segs.cpp @@ -1134,7 +1134,7 @@ void wallscan (int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t *l dc_count = y2ve[0] - y1ve[0]; iscale = swal[x] * yrepeat; dc_iscale = xs_ToFixed(fracbits, iscale); - dc_texturefrac = xs_ToFixed(fracbits, dc_texturemid + iscale * (y1ve[0] - CenterY + 1)); + dc_texturefrac = xs_ToFixed(fracbits, dc_texturemid + iscale * (y1ve[0] - CenterY + 0.5)); dovline1(); } @@ -1153,7 +1153,7 @@ void wallscan (int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t *l bufplce[z] = getcol (rw_pic, (lwal[x+z] + xoffset) >> FRACBITS); iscale = swal[x + z] * yrepeat; vince[z] = xs_ToFixed(fracbits, iscale); - vplce[z] = xs_ToFixed(fracbits, dc_texturemid + iscale * (y1ve[z] - CenterY + 1)); + vplce[z] = xs_ToFixed(fracbits, dc_texturemid + iscale * (y1ve[z] - CenterY + 0.5)); } if (bad == 15) { @@ -1229,7 +1229,7 @@ void wallscan (int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t *l dc_count = y2ve[0] - y1ve[0]; iscale = swal[x] * yrepeat; dc_iscale = xs_ToFixed(fracbits, iscale); - dc_texturefrac = xs_ToFixed(fracbits, dc_texturemid + iscale * (y1ve[0] - CenterY + 1)); + dc_texturefrac = xs_ToFixed(fracbits, dc_texturemid + iscale * (y1ve[0] - CenterY + 0.5)); dovline1(); } @@ -1484,7 +1484,7 @@ void maskwallscan (int x1, int x2, short *uwal, short *dwal, float *swal, fixed_ dc_count = y2ve[0] - y1ve[0]; iscale = swal[x] * yrepeat; dc_iscale = xs_ToFixed(fracbits, iscale); - dc_texturefrac = xs_ToFixed(fracbits, dc_texturemid + iscale * (y1ve[0] - CenterY + 1)); + dc_texturefrac = xs_ToFixed(fracbits, dc_texturemid + iscale * (y1ve[0] - CenterY + 0.5)); domvline1(); } @@ -1501,7 +1501,7 @@ void maskwallscan (int x1, int x2, short *uwal, short *dwal, float *swal, fixed_ bufplce[z] = getcol (rw_pic, (lwal[dax] + xoffset) >> FRACBITS); iscale = swal[dax] * yrepeat; vince[z] = xs_ToFixed(fracbits, iscale); - vplce[z] = xs_ToFixed(fracbits, dc_texturemid + iscale * (y1ve[z] - CenterY + 1)); + vplce[z] = xs_ToFixed(fracbits, dc_texturemid + iscale * (y1ve[z] - CenterY + 0.5)); } if (bad == 15) { @@ -1575,7 +1575,7 @@ void maskwallscan (int x1, int x2, short *uwal, short *dwal, float *swal, fixed_ dc_count = y2ve[0] - y1ve[0]; iscale = swal[x] * yrepeat; dc_iscale = xs_ToFixed(fracbits, iscale); - dc_texturefrac = xs_ToFixed(fracbits, dc_texturemid + iscale * (y1ve[0] - CenterY + 1)); + dc_texturefrac = xs_ToFixed(fracbits, dc_texturemid + iscale * (y1ve[0] - CenterY + 0.5)); domvline1(); } @@ -1660,7 +1660,7 @@ void transmaskwallscan (int x1, int x2, short *uwal, short *dwal, float *swal, f dc_count = y2ve[0] - y1ve[0]; iscale = swal[x] * yrepeat; dc_iscale = xs_ToFixed(fracbits, iscale); - dc_texturefrac = xs_ToFixed(fracbits, dc_texturemid + iscale * (y1ve[0] - CenterY + 1)); + dc_texturefrac = xs_ToFixed(fracbits, dc_texturemid + iscale * (y1ve[0] - CenterY + 0.5)); tmvline1(); } @@ -1677,7 +1677,7 @@ void transmaskwallscan (int x1, int x2, short *uwal, short *dwal, float *swal, f bufplce[z] = getcol (rw_pic, (lwal[dax] + xoffset) >> FRACBITS); iscale = swal[dax] * yrepeat; vince[z] = xs_ToFixed(fracbits, iscale); - vplce[z] = xs_ToFixed(fracbits, dc_texturemid + vince[z] * (y1ve[z] - CenterY + 1)); + vplce[z] = xs_ToFixed(fracbits, dc_texturemid + vince[z] * (y1ve[z] - CenterY + 0.5)); } if (bad == 15) { @@ -1754,7 +1754,7 @@ void transmaskwallscan (int x1, int x2, short *uwal, short *dwal, float *swal, f dc_count = y2ve[0] - y1ve[0]; iscale = swal[x] * yrepeat; dc_iscale = xs_ToFixed(fracbits, iscale); - dc_texturefrac = xs_ToFixed(fracbits, dc_texturemid + iscale * (y1ve[0] - CenterY + 1)); + dc_texturefrac = xs_ToFixed(fracbits, dc_texturemid + iscale * (y1ve[0] - CenterY + 0.5)); tmvline1(); } @@ -2683,7 +2683,6 @@ int OWallMost (short *mostbuf, double z, const FWallCoords *wallc) } ix1 = wallc->sx1; iy1 = wallc->sz1; ix2 = wallc->sx2; iy2 = wallc->sz2; -#if 1 if (bad & 3) { // the line intersects the top of the screen double t = (z-s1) / (s2-s1); @@ -2728,40 +2727,8 @@ int OWallMost (short *mostbuf, double z, const FWallCoords *wallc) else { fixed_t yinc = FLOAT2FIXED(((z * InvZtoScale / iy2) - y) / (ix2 - ix1)); - qinterpolatedown16short (&mostbuf[ix1], ix2-ix1, FLOAT2FIXED(y + CenterY), yinc); + qinterpolatedown16short (&mostbuf[ix1], ix2-ix1, FLOAT2FIXED(y + CenterY) + FRACUNIT/2, yinc); } -#else - double max = viewheight; - double zz = z / 65536.0; -#if 0 - double z1 = zz * InvZtoScale / wallc->sz1; - double z2 = zz * InvZtoScale / wallc->sz2 - z1; - z2 /= (wallc->sx2 - wallc->sx1); - z1 += centeryfrac / 65536.0; - - for (int x = wallc->sx1; x < wallc->sx2; ++x) - { - mostbuf[x] = xs_RoundToInt(clamp(z1, 0.0, max)); - z1 += z2; - } -#else - double top, bot, i; - - i = wallc->sx1 - centerx; - top = WallT.UoverZorg + WallT.UoverZstep * i; - bot = WallT.InvZorg + WallT.InvZstep * i; - double cy = centeryfrac / 65536.0; - - for (int x = wallc->sx1; x < wallc->sx2; x++) - { - double frac = top / bot; - double scale = frac * WallT.DepthScale + WallT.DepthOrg; - mostbuf[x] = xs_RoundToInt(clamp(zz / scale + cy, 0.0, max)); - top += WallT.UoverZstep; - bot += WallT.InvZstep; - } -#endif -#endif return bad; } @@ -2914,7 +2881,7 @@ int WallMost (short *mostbuf, const secplane_t &plane, const FWallCoords *wallc) else { fixed_t yinc = FLOAT2FIXED(((z2 * InvZtoScale / iy2) - y) / (ix2-ix1)); - qinterpolatedown16short (&mostbuf[ix1], ix2-ix1, FLOAT2FIXED(y + CenterY), yinc); + qinterpolatedown16short (&mostbuf[ix1], ix2-ix1, FLOAT2FIXED(y + CenterY) + FRACUNIT/2, yinc); } return bad; From 8f3921190feb9fdbe88433ef1297af77cfe2061c Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 28 Apr 2016 21:07:58 -0500 Subject: [PATCH 25/30] Keep values in floats longer for visplane drawing --- src/r_main.cpp | 90 ++++++++++++++++++++++++------------------------- src/r_plane.cpp | 52 +++++++++++++++++----------- src/r_plane.h | 2 +- 3 files changed, 77 insertions(+), 67 deletions(-) diff --git a/src/r_main.cpp b/src/r_main.cpp index fdeffb93b..58e94e544 100644 --- a/src/r_main.cpp +++ b/src/r_main.cpp @@ -501,63 +501,61 @@ void R_SetupColormap(player_t *player) void R_SetupFreelook() { - { - double dy; + double dy; - if (camera != NULL) + if (camera != NULL) + { + dy = FocalLengthY * (-ViewPitch).Tan(); + } + else + { + dy = 0; + } + + CenterY = (viewheight / 2.0) + dy; + centery = xs_ToInt(CenterY); + globaluclip = -CenterY / InvZtoScale; + globaldclip = (viewheight - CenterY) / InvZtoScale; + + //centeryfrac &= 0xffff0000; + int e, i; + + i = 0; + e = viewheight; + float focus = float(FocalLengthY); + float den; + float cy = float(CenterY); + if (i < centery) + { + den = cy - i - 0.5f; + if (e <= centery) { - dy = FocalLengthY * (-ViewPitch).Tan(); - } - else - { - dy = 0; - } - - CenterY = (viewheight / 2.0) + dy; - centery = xs_ToInt(CenterY); - globaluclip = -CenterY / InvZtoScale; - globaldclip = (viewheight - CenterY) / InvZtoScale; - - //centeryfrac &= 0xffff0000; - int e, i; - - i = 0; - e = viewheight; - float focus = float(FocalLengthY); - float den; - float cy = float(CenterY); - if (i < centery) - { - den = cy - i - 0.5f; - if (e <= centery) - { - do { - yslope[i] = FLOAT2FIXED(focus / den); - den -= 1; - } while (++i < e); - } - else - { - do { - yslope[i] = FLOAT2FIXED(focus / den); - den -= 1; - } while (++i < centery); - den = i - cy + 0.5f; - do { - yslope[i] = FLOAT2FIXED(focus / den); - den += 1; - } while (++i < e); - } + do { + yslope[i] = focus / den; + den -= 1; + } while (++i < e); } else { + do { + yslope[i] = focus / den; + den -= 1; + } while (++i < centery); den = i - cy + 0.5f; do { - yslope[i] = FLOAT2FIXED(focus / den); + yslope[i] = focus / den; den += 1; } while (++i < e); } } + else + { + den = i - cy + 0.5f; + do { + yslope[i] = focus / den; + den += 1; + } while (++i < e); + } } //========================================================================== diff --git a/src/r_plane.cpp b/src/r_plane.cpp index d18ad19a5..2fb90fa6f 100644 --- a/src/r_plane.cpp +++ b/src/r_plane.cpp @@ -141,10 +141,10 @@ fixed_t pviewx, pviewy; void R_DrawTiltedPlane_ASM (int y, int x1); } -fixed_t yslope[MAXHEIGHT]; +float yslope[MAXHEIGHT]; static fixed_t xscale, yscale; -static DWORD xstepscale, ystepscale; -static DWORD basexfrac, baseyfrac; +static double xstepscale, ystepscale; +static double basexfrac, baseyfrac; #ifdef X86_ASM extern "C" void R_SetSpanSource_ASM (const BYTE *flat); @@ -205,7 +205,7 @@ void R_DeinitPlanes () void R_MapPlane (int y, int x1) { int x2 = spanend[y]; - fixed_t distance; + double distance; #ifdef RANGECHECK if (x2 < x1 || x1<0 || x2>=viewwidth || (unsigned)y>=(unsigned)viewheight) @@ -217,12 +217,12 @@ void R_MapPlane (int y, int x1) // [RH] Notice that I dumped the caching scheme used by Doom. // It did not offer any appreciable speedup. - distance = xs_ToInt(planeheight * yslope[y]); + distance = planeheight * yslope[y]; - ds_xstep = FixedMul (distance, xstepscale); - ds_ystep = FixedMul (distance, ystepscale); - ds_xfrac = FixedMul (distance, basexfrac) + pviewx; - ds_yfrac = FixedMul (distance, baseyfrac) + pviewy; + ds_xstep = xs_ToFixed(32-ds_xbits, distance * xstepscale); + ds_ystep = xs_ToFixed(32-ds_ybits, distance * ystepscale); + ds_xfrac = xs_ToFixed(32-ds_xbits, distance * basexfrac) + pviewx; + ds_yfrac = xs_ToFixed(32-ds_ybits, distance * baseyfrac) + pviewy; if (plane_shade) { @@ -1495,12 +1495,15 @@ void R_DrawNormalPlane (visplane_t *pl, double _xscale, double _yscale, fixed_t return; } - DAngle planeang = pl->xform.Angle + pl->xform.baseAngle; + double planeang = (pl->xform.Angle + pl->xform.baseAngle).Radians(); + double xstep, ystep, leftxfrac, leftyfrac, rightxfrac, rightyfrac; + double x; + xscale = xs_ToFixed(32 - ds_xbits, _xscale); yscale = xs_ToFixed(32 - ds_ybits, _yscale); if (planeang != 0) { - double cosine = cos(planeang.Radians()), sine = sin(planeang.Radians()); + double cosine = cos(planeang), sine = sin(planeang); pviewx = FLOAT2FIXED(pl->xform.xOffs + ViewPos.X * cosine - ViewPos.Y * sine); pviewy = FLOAT2FIXED(pl->xform.yOffs - ViewPos.X * sine - ViewPos.Y * cosine); } @@ -1514,23 +1517,32 @@ void R_DrawNormalPlane (visplane_t *pl, double _xscale, double _yscale, fixed_t pviewy = FixedMul (yscale, pviewy); // left to right mapping - planeang = ViewAngle - 90 + planeang; + planeang += (ViewAngle - 90).Radians(); // Scale will be unit scale at FocalLengthX (normally SCREENWIDTH/2) distance - xstepscale = xs_RoundToInt(xscale * cos(planeang.Radians()) / FocalLengthX); - ystepscale = xs_RoundToInt(yscale * -sin(planeang.Radians()) / FocalLengthX); + xstep = cos(planeang) / FocalLengthX; + ystep = -sin(planeang) / FocalLengthX; // [RH] flip for mirrors if (MirrorFlags & RF_XFLIP) { - xstepscale = (DWORD)(-(SDWORD)xstepscale); - ystepscale = (DWORD)(-(SDWORD)ystepscale); + xstep = -xstep; + ystep = -ystep; } - int x = pl->right - centerx; - planeang += 90; - basexfrac = xs_RoundToInt(xscale * cos(planeang.Radians())) + x*xstepscale; - baseyfrac = xs_RoundToInt(yscale * -sin(planeang.Radians())) + x*ystepscale; + planeang += M_PI/2; + double cosine = cos(planeang), sine = -sin(planeang); + x = pl->right - centerx - 0.5; + rightxfrac = _xscale * (cosine + x * xstep); + rightyfrac = _yscale * (sine + x * ystep); + x = pl->left - centerx - 0.5; + leftxfrac = _xscale * (cosine + x * xstep); + leftyfrac = _yscale * (sine + x * ystep); + + basexfrac = rightxfrac; + baseyfrac = rightyfrac; + xstepscale = (rightxfrac - leftxfrac) / (pl->right - pl->left); + ystepscale = (rightyfrac - leftyfrac) / (pl->right - pl->left); planeheight = fabs(pl->height.Zat0() - ViewPos.Z); diff --git a/src/r_plane.h b/src/r_plane.h index fcd02ed68..d4db3dc09 100644 --- a/src/r_plane.h +++ b/src/r_plane.h @@ -80,7 +80,7 @@ extern planefunction_t ceilingfunc_t; extern short floorclip[MAXWIDTH]; extern short ceilingclip[MAXWIDTH]; -extern fixed_t yslope[MAXHEIGHT]; +extern float yslope[MAXHEIGHT]; void R_InitPlanes (); void R_DeinitPlanes (); From f3d273c94f791a0813ff7d8ffce0414c2192d6c4 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 28 Apr 2016 22:06:57 -0500 Subject: [PATCH 26/30] Fixed: Tiled midtextures could go up past the ceiling when a 3D floor is in view --- src/r_segs.cpp | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/r_segs.cpp b/src/r_segs.cpp index 6625d2524..4c91a1314 100644 --- a/src/r_segs.cpp +++ b/src/r_segs.cpp @@ -231,6 +231,7 @@ void R_RenderMaskedSegRange (drawseg_t *ds, int x1, int x2) double texheight, texheightscale; bool notrelevant = false; double rowoffset; + bool wrap = false; const sector_t *sec; @@ -334,8 +335,8 @@ void R_RenderMaskedSegRange (drawseg_t *ds, int x1, int x2) rowoffset = curline->sidedef->GetTextureYOffset(side_t::mid); - if (!(curline->linedef->flags & ML_WRAP_MIDTEX) && - !(curline->sidedef->Flags & WALLF_WRAP_MIDTEX)) + wrap = (curline->linedef->flags & ML_WRAP_MIDTEX) || (curline->sidedef->Flags & WALLF_WRAP_MIDTEX); + if (!wrap) { // Texture does not wrap vertically. double textop; @@ -482,7 +483,7 @@ void R_RenderMaskedSegRange (drawseg_t *ds, int x1, int x2) { // rowoffset is added before the multiply so that the masked texture will // still be positioned in world units rather than texels. - dc_texturemid = (dc_texturemid + rowoffset - ViewPos.Z) * MaskedScaleY; + dc_texturemid = (dc_texturemid - ViewPos.Z + rowoffset) * MaskedScaleY; } else { @@ -543,8 +544,11 @@ clearfog: { if (fake3D & FAKE3D_REFRESHCLIP) { - assert(ds->bkup >= 0); - memcpy(openings + ds->sprtopclip, openings + ds->bkup, (ds->x2 - ds->x1) * 2); + if (!wrap) + { + assert(ds->bkup >= 0); + memcpy(openings + ds->sprtopclip, openings + ds->bkup, (ds->x2 - ds->x1) * 2); + } } else { From 4a72c7d2f1ec6bb6d4e9bc0ecf86e1f8e673a9bb Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 29 Apr 2016 11:44:17 +0200 Subject: [PATCH 27/30] - fixed: Decals may not be serialized before thinkers. Since decals may have thinkers attached this will crash when such a savegame gets loaded, because the thinker lists get reset in P_SerializeThinkers, deleting any thinker that already was processed. I also added an error message that immediately aborts the save process if such an out-of-sequence thinker is attempted to be written out. This obviously breaks savegame compatibility again... --- src/farchive.cpp | 6 ++++++ src/farchive.h | 11 +++++++++++ src/g_shared/a_quake.cpp | 5 +---- src/p_saveg.cpp | 13 ++++++++++++- src/version.h | 4 ++-- wadsrc/static/xlat/eternity.txt | 3 +++ 6 files changed, 35 insertions(+), 7 deletions(-) diff --git a/src/farchive.cpp b/src/farchive.cpp index 477d22718..fc3d75bbb 100644 --- a/src/farchive.cpp +++ b/src/farchive.cpp @@ -1054,6 +1054,12 @@ FArchive &FArchive::SerializePointer (void *ptrbase, BYTE **ptr, DWORD elemSize) FArchive &FArchive::SerializeObject (DObject *&object, PClass *type) { + if (!m_ThinkersAllowed && type->IsDescendantOf(RUNTIME_CLASS(DThinker))) + { + assert(true); + I_Error("Tried to serialize a thinker before P_SerializeThinkers"); + } + if (!type->IsDescendantOf(RUNTIME_CLASS(PClass))) { // a regular object if (IsStoring()) diff --git a/src/farchive.h b/src/farchive.h index b6722986a..44ae8c001 100644 --- a/src/farchive.h +++ b/src/farchive.h @@ -216,6 +216,16 @@ inline FArchive& operator<< (signed char *&str) { return operator<< ((char *&)st inline FArchive& operator<< (bool &b) { return operator<< ((BYTE &)b); } inline FArchive& operator<< (DObject* &object) { return ReadObject (object, RUNTIME_CLASS(DObject)); } + void EnableThinkers() + { + m_ThinkersAllowed = true; + } + + bool ThinkersAllowed() + { + return m_ThinkersAllowed; + } + protected: enum { EObjectHashSize = 137 }; @@ -253,6 +263,7 @@ protected: int *m_SpriteMap; size_t m_NumSprites; + bool m_ThinkersAllowed = false; FArchive (); void AttachToFile (FFile &file); diff --git a/src/g_shared/a_quake.cpp b/src/g_shared/a_quake.cpp index 1d1117125..7908c907c 100644 --- a/src/g_shared/a_quake.cpp +++ b/src/g_shared/a_quake.cpp @@ -72,10 +72,7 @@ void DEarthquake::Serialize (FArchive &arc) << m_QuakeSFX << m_Flags << m_CountdownStart << m_WaveSpeed << m_Falloff << m_Highpoint << m_MiniCount; - if (SaveVersion >= 4544) - { - arc << m_RollIntensity << m_RollWave; - } + << m_RollIntensity << m_RollWave; } //========================================================================== diff --git a/src/p_saveg.cpp b/src/p_saveg.cpp index 9af2cd573..af5992488 100644 --- a/src/p_saveg.cpp +++ b/src/p_saveg.cpp @@ -423,7 +423,6 @@ void P_SerializeWorld (FArchive &arc) << si->LeftSide << si->RightSide << si->Index; - DBaseDecal::SerializeChain (arc, &si->AttachedDecals); } } @@ -452,6 +451,7 @@ void P_SerializeWorldActors(FArchive &arc) { int i; sector_t *sec; + line_t *line; for (i = 0, sec = sectors; i < numsectors; i++, sec++) { @@ -465,6 +465,16 @@ void P_SerializeWorldActors(FArchive &arc) { arc << s.mSkybox; } + for (i = 0, line = lines; i < numlines; i++, line++) + { + for (int s = 0; s < 2; s++) + { + if (line->sidedef[s] != NULL) + { + DBaseDecal::SerializeChain(arc, &line->sidedef[s]->AttachedDecals); + } + } + } } void extsector_t::Serialize(FArchive &arc) @@ -504,6 +514,7 @@ FArchive &operator<< (FArchive &arc, sector_t::splane &p) void P_SerializeThinkers (FArchive &arc, bool hubLoad) { + arc.EnableThinkers(); DImpactDecal::SerializeTime (arc); DThinker::SerializeAll (arc, hubLoad); } diff --git a/src/version.h b/src/version.h index 096efa48c..21d05b3ed 100644 --- a/src/version.h +++ b/src/version.h @@ -72,11 +72,11 @@ const char *GetVersionString(); // SAVESIG should match SAVEVER. // MINSAVEVER is the minimum level snapshot version that can be loaded. -#define MINSAVEVER 4543 +#define MINSAVEVER 4545 // Use 4500 as the base git save version, since it's higher than the // SVN revision ever got. -#define SAVEVER 4544 +#define SAVEVER 4545 #define SAVEVERSTRINGIFY2(x) #x #define SAVEVERSTRINGIFY(x) SAVEVERSTRINGIFY2(x) diff --git a/wadsrc/static/xlat/eternity.txt b/wadsrc/static/xlat/eternity.txt index bfdac2cec..bc5159d11 100644 --- a/wadsrc/static/xlat/eternity.txt +++ b/wadsrc/static/xlat/eternity.txt @@ -231,3 +231,6 @@ enum 444 = 0, Teleport(0) 445 = 0, Teleport_NoFog(0) 446 = 0, Teleport_Line(0) +447 = 0, Exit_Normal(0) +448 = 0, Exit_Secret(0) +449 = 0, Teleport_NewMap(0) From 70bf6493645b622c7994c83c743769ff4e09a0bf Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 29 Apr 2016 12:26:57 +0200 Subject: [PATCH 28/30] - added clip planes for line portals and mirrors. This should eliminate the remaining problems with some visible geometry in front of the portal, it is also necessary to handle sprite splitting across line portals properly. --- src/gl/scene/gl_portal.cpp | 27 +++++++++++++++++++++++++++ src/gl/scene/gl_portal.h | 2 ++ wadsrc/static/shaders/glsl/main.vp | 8 ++++++-- 3 files changed, 35 insertions(+), 2 deletions(-) diff --git a/src/gl/scene/gl_portal.cpp b/src/gl/scene/gl_portal.cpp index f165de630..be25409e2 100644 --- a/src/gl/scene/gl_portal.cpp +++ b/src/gl/scene/gl_portal.cpp @@ -825,7 +825,28 @@ void GLPlaneMirrorPortal::PopState() // //----------------------------------------------------------------------------- +void GLLinePortal::PushState() +{ + FStateVec4 &v = gl_RenderState.GetClipLine(); + planestack.Push(v.vec[0]); + planestack.Push(v.vec[1]); + planestack.Push(v.vec[2]); + planestack.Push(v.vec[3]); + planestack.Push(gl_RenderState.GetClipLineState()); + gl_RenderState.EnableClipLine(false); +} +void GLLinePortal::PopState() +{ + FStateVec4 &v = gl_RenderState.GetClipLine(); + float e; + planestack.Pop(e); + planestack.Pop(v.vec[3]); + planestack.Pop(v.vec[2]); + planestack.Pop(v.vec[1]); + planestack.Pop(v.vec[0]); + gl_RenderState.EnableClipLine(e != 0); +} int GLLinePortal::ClipSeg(seg_t *seg) { @@ -948,7 +969,10 @@ void GLMirrorPortal::DrawContents() angle_t a1 = linedef->v2->GetClipAngle(); clipper.SafeAddClipRange(a1,a2); + gl_RenderState.SetClipLine(linedef); + gl_RenderState.EnableClipLine(true); GLRenderer->DrawScene(); + gl_RenderState.EnableClipLine(false); MirrorFlag--; } @@ -1018,7 +1042,10 @@ void GLLineToLinePortal::DrawContents() GLRenderer->SetupView(ViewPos.X, ViewPos.Y, ViewPos.Z, ViewAngle, !!(MirrorFlag&1), !!(PlaneMirrorFlag&1)); ClearClipper(); + gl_RenderState.SetClipLine(glport->reference->mDestination); + gl_RenderState.EnableClipLine(true); GLRenderer->DrawScene(); + gl_RenderState.EnableClipLine(false); RestoreMapSection(); } diff --git a/src/gl/scene/gl_portal.h b/src/gl/scene/gl_portal.h index 870009845..2962a4be1 100644 --- a/src/gl/scene/gl_portal.h +++ b/src/gl/scene/gl_portal.h @@ -225,6 +225,8 @@ struct GLLinePortal : public GLPortal virtual int ClipSubsector(subsector_t *sub); virtual int ClipPoint(const DVector2 &pos); virtual bool NeedCap() { return false; } + virtual void PushState(); + virtual void PopState(); }; diff --git a/wadsrc/static/shaders/glsl/main.vp b/wadsrc/static/shaders/glsl/main.vp index 44aec6199..7cc4d4d83 100644 --- a/wadsrc/static/shaders/glsl/main.vp +++ b/wadsrc/static/shaders/glsl/main.vp @@ -55,11 +55,15 @@ void main() #endif - // clip planes used for reflective flats - if (uClipHeightDirection != 0.0) + + if (uClipHeightDirection != 0.0) // clip planes used for reflective flats { gl_ClipDistance[0] = (worldcoord.y - uClipHeight) * uClipHeightDirection; } + else if (uClipLine.x > -1000000.0) // and for line portals - this will never be active at the same time as the reflective planes clipping so it can use the same hardware clip plane. + { + gl_ClipDistance[0] = -( (worldcoord.z - uClipLine.y) * uClipLine.z + (uClipLine.x - worldcoord.x) * uClipLine.w ) + 1.0/32768.0; // allow a tiny bit of imprecisions for colinear linedefs. + } // clip planes used for translucency splitting gl_ClipDistance[1] = worldcoord.y - uClipSplit.x; From b9687b4a57814e1a9fd5cfb58ce9c8cd4f78b72b Mon Sep 17 00:00:00 2001 From: MajorCooke Date: Fri, 29 Apr 2016 06:33:38 -0500 Subject: [PATCH 29/30] Compiler fix --- src/g_shared/a_quake.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/g_shared/a_quake.cpp b/src/g_shared/a_quake.cpp index 7908c907c..74c416468 100644 --- a/src/g_shared/a_quake.cpp +++ b/src/g_shared/a_quake.cpp @@ -71,7 +71,7 @@ void DEarthquake::Serialize (FArchive &arc) << m_TremorRadius << m_DamageRadius << m_QuakeSFX << m_Flags << m_CountdownStart << m_WaveSpeed - << m_Falloff << m_Highpoint << m_MiniCount; + << m_Falloff << m_Highpoint << m_MiniCount << m_RollIntensity << m_RollWave; } From 8309d8f634eda3bf6f00beedb6a59b68ae291bfa Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 29 Apr 2016 23:14:04 +0200 Subject: [PATCH 30/30] - fixed coordinate typo. --- src/p_map.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_map.cpp b/src/p_map.cpp index 959412a13..5623af25a 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -6446,7 +6446,7 @@ void AActor::UpdateRenderSectorList() if (PortalBlockmap.containsLines && Pos().XY() != OldRenderPos.XY()) { int bx = GetBlockX(X()); - int by = GetBlockX(Y()); + int by = GetBlockY(Y()); FBoundingBox bb(X(), Y(), MIN(radius*1.5, 128.)); // Don't go further than 128 map units, even for large actors // Are there any portals near the actor's position? if (bx >= 0 && by >= 0 && bx < bmapwidth && by < bmapheight && PortalBlockmap(bx, by).neighborContainsLines)