From 9a9fe7c133f92263e57925275bbd6c6da39e47ae Mon Sep 17 00:00:00 2001
From: Rachael Alexanderson <eruanna@drdteam.org>
Date: Sat, 29 Jul 2017 11:03:40 -0400
Subject: [PATCH] - implemented GetCaps() for OpenGL - renamed
 RFF_FRAGMENTSHADER to RFF_MATSHADER - D_Display now calls Renderer->GetCaps()
 and stores it in a global variable for later use.

---
 src/actor.h                         |  2 +-
 src/d_main.cpp                      |  4 ++++
 src/d_main.h                        |  3 +++
 src/gl/scene/gl_scene.cpp           | 25 +++++++++++++++++++++++++
 src/r_renderer.h                    |  1 +
 wadsrc/static/zscript/constants.txt |  2 +-
 6 files changed, 35 insertions(+), 2 deletions(-)

diff --git a/src/actor.h b/src/actor.h
index 83c0fa37b..3343419f3 100644
--- a/src/actor.h
+++ b/src/actor.h
@@ -527,7 +527,7 @@ enum ActorRenderFeatureFlag
 	RFF_TILTPITCH		= 1<<3, // full free-look
 	RFF_ROLLSPRITES		= 1<<4, // roll sprites
 	RFF_UNCLIPPEDTEX	= 1<<5, // midtex and sprite can render "into" flats and walls
-	RFF_FRAGMENTSHADER	= 1<<6, // fragment (material) shaders
+	RFF_MATSHADER		= 1<<6, // material shaders
 	RFF_POSTSHADER		= 1<<7, // post-process shaders (renderbuffers)
 	RFF_BRIGHTMAP		= 1<<8, // brightmaps
 	RFF_COLORMAP		= 1<<9, // custom colormaps (incl. ability to fullbright certain ranges, ala Strife)
diff --git a/src/d_main.cpp b/src/d_main.cpp
index 6bffbce1b..57c5d8478 100644
--- a/src/d_main.cpp
+++ b/src/d_main.cpp
@@ -247,6 +247,9 @@ bool batchrun;	// just run the startup and collect all error messages in a logfi
 
 cycle_t FrameCycles;
 
+// [SP] Store the capabilities of the renderer in a global variable, to prevent excessive per-frame processing
+uint32_t r_renderercaps = 0;
+
 
 // PRIVATE DATA DEFINITIONS ------------------------------------------------
 
@@ -671,6 +674,7 @@ void D_Display ()
 	cycles.Clock();
 
 	r_UseVanillaTransparency = UseVanillaTransparency(); // [SP] Cache UseVanillaTransparency() call
+	r_renderercaps = Renderer->GetCaps(); // [SP] Get the current capabilities of the renderer
 
 	if (players[consoleplayer].camera == NULL)
 	{
diff --git a/src/d_main.h b/src/d_main.h
index ca8d40322..b7b9fabcd 100644
--- a/src/d_main.h
+++ b/src/d_main.h
@@ -64,6 +64,9 @@ bool D_AddFile (TArray<FString> &wadfiles, const char *file, bool check = true,
 // [RH] Set this to something to draw an icon during the next screen refresh.
 extern const char *D_DrawIcon;
 
+// [SP] Store the capabilities of the renderer in a global variable, to prevent excessive per-frame processing
+extern uint32_t r_renderercaps;
+
 
 struct WadStuff
 {
diff --git a/src/gl/scene/gl_scene.cpp b/src/gl/scene/gl_scene.cpp
index 2dc4953cf..ad3af273b 100644
--- a/src/gl/scene/gl_scene.cpp
+++ b/src/gl/scene/gl_scene.cpp
@@ -84,6 +84,7 @@ EXTERN_CVAR (Bool, cl_capfps)
 EXTERN_CVAR (Bool, r_deathcamera)
 EXTERN_CVAR (Float, underwater_fade_scalar)
 EXTERN_CVAR (Float, r_visibility)
+EXTERN_CVAR (Bool, gl_legacy_mode)
 
 extern bool NoInterpolateView;
 
@@ -993,6 +994,7 @@ struct FGLInterface : public FRenderer
 	int GetMaxViewPitch(bool down) override;
 	void SetClearColor(int color) override;
 	void Init() override;
+	uint32_t GetCaps() override;
 };
 
 //==========================================================================
@@ -1160,6 +1162,29 @@ bool FGLInterface::RequireGLNodes()
 	return true; 
 }
 
+uint32_t FGLInterface::GetCaps()
+{
+	// describe our basic feature set
+	ActorRenderFeatureFlags FlagSet = RFF_FLATSPRITES | RFF_MODELS | RFF_SLOPE3DFLOORS |
+		RFF_TILTPITCH | RFF_ROLLSPRITES | RFF_POLYGONAL | RFF_VOXELS;
+	if (gl_legacy_mode)
+	{
+		// legacy mode always has truecolor because palette tonemap is not available
+		FlagSet |= RFF_TRUECOLOR;
+	}
+	else if (!(FGLRenderBuffers::IsEnabled()))
+	{
+		// truecolor is always available when renderbuffers are unavailable because palette tonemap is not possible
+		FlagSet |= RFF_TRUECOLOR | RFF_MATSHADER;
+	}
+	else
+	{
+		if (gl_tonemap != 5) // not running palette tonemap shader
+			FlagSet |= RFF_TRUECOLOR;
+		FlagSet |= RFF_MATSHADER | RFF_POSTSHADER;
+	}
+	return (uint32_t)FlagSet;
+}
 //===========================================================================
 //
 // 
diff --git a/src/r_renderer.h b/src/r_renderer.h
index 01d241bb9..5d6ee856c 100644
--- a/src/r_renderer.h
+++ b/src/r_renderer.h
@@ -54,6 +54,7 @@ struct FRenderer
 	virtual void CleanLevelData() {}
 	virtual bool RequireGLNodes() { return false; }
 
+	virtual uint32_t GetCaps() { return 0; }
 };
 
 
diff --git a/wadsrc/static/zscript/constants.txt b/wadsrc/static/zscript/constants.txt
index d6bc27248..44f2e8c91 100644
--- a/wadsrc/static/zscript/constants.txt
+++ b/wadsrc/static/zscript/constants.txt
@@ -1183,7 +1183,7 @@ enum ActorRenderFeatureFlag
 	RFF_TILTPITCH		= 1<<3, // full free-look
 	RFF_ROLLSPRITES		= 1<<4, // roll sprites
 	RFF_UNCLIPPEDTEX	= 1<<5, // midtex and sprite can render "into" flats and walls
-	RFF_FRAGMENTSHADER	= 1<<6, // fragment (material) shaders
+	RFF_MATSHADER		= 1<<6, // material shaders
 	RFF_POSTSHADER		= 1<<7, // post-process shaders (renderbuffers)
 	RFF_BRIGHTMAP		= 1<<8, // brightmaps
 	RFF_COLORMAP		= 1<<9, // custom colormaps (incl. ability to fullbright certain ranges, ala Strife)