This commit is contained in:
Rachael Alexanderson 2017-06-03 22:34:13 -04:00
commit 64b22f6cb3
15 changed files with 144 additions and 12 deletions

View file

@ -1171,6 +1171,7 @@ public:
uint8_t smokecounter; uint8_t smokecounter;
uint8_t FloatBobPhase; uint8_t FloatBobPhase;
double FloatBobStrength;
uint8_t FriendPlayer; // [RH] Player # + 1 this friendly monster works for (so 0 is no player, 1 is player 0, etc) uint8_t FriendPlayer; // [RH] Player # + 1 this friendly monster works for (so 0 is no player, 1 is player 0, etc)
PalEntry BloodColor; PalEntry BloodColor;
uint32_t BloodTranslation; uint32_t BloodTranslation;

View file

@ -1079,7 +1079,7 @@ bool DBaseStatusBar::MustDrawLog(EHudState state)
{ {
IFVIRTUAL(DBaseStatusBar, MustDrawLog) IFVIRTUAL(DBaseStatusBar, MustDrawLog)
{ {
VMValue params[] = { (DObject*)this }; VMValue params[] = { (DObject*)this, int(state) };
int rv; int rv;
VMReturn ret(&rv); VMReturn ret(&rv);
VMCall(func, params, countof(params), &ret, 1); VMCall(func, params, countof(params), &ret, 1);

View file

@ -33,6 +33,7 @@
#include "gl/shaders/gl_shadowmapshader.h" #include "gl/shaders/gl_shadowmapshader.h"
#include "r_state.h" #include "r_state.h"
#include "g_levellocals.h" #include "g_levellocals.h"
#include "stats.h"
/* /*
The 1D shadow maps are stored in a 1024x1024 texture as float depth values (R32F). The 1D shadow maps are stored in a 1024x1024 texture as float depth values (R32F).
@ -67,11 +68,48 @@
as on the CPU, except everything uses indexes as pointers are not allowed in GLSL. as on the CPU, except everything uses indexes as pointers are not allowed in GLSL.
*/ */
namespace
{
cycle_t UpdateCycles;
int LightsProcessed;
int LightsShadowmapped;
}
ADD_STAT(shadowmap)
{
FString out;
out.Format("upload=%04.2f ms lights=%d shadowmapped=%d", UpdateCycles.TimeMS(), LightsProcessed, LightsShadowmapped);
return out;
}
CUSTOM_CVAR(Int, gl_shadowmap_quality, 128, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
{
switch (self)
{
case 32:
case 64:
case 128:
case 256:
case 512:
case 1024:
break;
default:
self = 128;
break;
}
}
void FShadowMap::Update() void FShadowMap::Update()
{ {
UpdateCycles.Reset();
LightsProcessed = 0;
LightsShadowmapped = 0;
if (!IsEnabled()) if (!IsEnabled())
return; return;
UpdateCycles.Clock();
UploadAABBTree(); UploadAABBTree();
UploadLights(); UploadLights();
@ -81,11 +119,12 @@ void FShadowMap::Update()
GLRenderer->mBuffers->BindShadowMapFB(); GLRenderer->mBuffers->BindShadowMapFB();
GLRenderer->mShadowMapShader->Bind(); GLRenderer->mShadowMapShader->Bind();
GLRenderer->mShadowMapShader->ShadowmapQuality.Set(gl_shadowmap_quality);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, mLightList); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, mLightList);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, mNodesBuffer); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, mNodesBuffer);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, mLinesBuffer); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, mLinesBuffer);
glViewport(0, 0, 1024, 1024); glViewport(0, 0, gl_shadowmap_quality, 1024);
GLRenderer->RenderScreenQuad(); GLRenderer->RenderScreenQuad();
const auto &viewport = GLRenderer->mScreenViewport; const auto &viewport = GLRenderer->mScreenViewport;
@ -98,6 +137,8 @@ void FShadowMap::Update()
GLRenderer->mBuffers->BindShadowMapTexture(16); GLRenderer->mBuffers->BindShadowMapTexture(16);
FGLDebug::PopGroup(); FGLDebug::PopGroup();
UpdateCycles.Unclock();
} }
bool FShadowMap::ShadowTest(ADynamicLight *light, const DVector3 &pos) bool FShadowMap::ShadowTest(ADynamicLight *light, const DVector3 &pos)
@ -133,8 +174,11 @@ void FShadowMap::UploadLights()
TThinkerIterator<ADynamicLight> it(STAT_DLIGHT); TThinkerIterator<ADynamicLight> it(STAT_DLIGHT);
while (auto light = it.Next()) while (auto light = it.Next())
{ {
LightsProcessed++;
if (light->shadowmapped) if (light->shadowmapped)
{ {
LightsShadowmapped++;
mLightToShadowmap[light] = lightindex >> 2; mLightToShadowmap[light] = lightindex >> 2;
mLights[lightindex] = light->X(); mLights[lightindex] = light->X();

View file

@ -81,6 +81,7 @@ FGLRenderBuffers::~FGLRenderBuffers()
ClearBloom(); ClearBloom();
ClearExposureLevels(); ClearExposureLevels();
ClearAmbientOcclusion(); ClearAmbientOcclusion();
ClearShadowMap();
} }
void FGLRenderBuffers::ClearScene() void FGLRenderBuffers::ClearScene()
@ -759,18 +760,27 @@ void FGLRenderBuffers::BindShadowMapTexture(int texunit)
glBindTexture(GL_TEXTURE_2D, mShadowMapTexture); glBindTexture(GL_TEXTURE_2D, mShadowMapTexture);
} }
void FGLRenderBuffers::ClearShadowMap()
{
DeleteFrameBuffer(mShadowMapFB);
DeleteTexture(mShadowMapTexture);
mCurrentShadowMapSize = 0;
}
void FGLRenderBuffers::CreateShadowMap() void FGLRenderBuffers::CreateShadowMap()
{ {
if (mShadowMapTexture != 0) if (mShadowMapTexture != 0 && gl_shadowmap_quality == mCurrentShadowMapSize)
return; return;
ClearShadowMap();
GLint activeTex, textureBinding, frameBufferBinding; GLint activeTex, textureBinding, frameBufferBinding;
glGetIntegerv(GL_ACTIVE_TEXTURE, &activeTex); glGetIntegerv(GL_ACTIVE_TEXTURE, &activeTex);
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
glGetIntegerv(GL_TEXTURE_BINDING_2D, &textureBinding); glGetIntegerv(GL_TEXTURE_BINDING_2D, &textureBinding);
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &frameBufferBinding); glGetIntegerv(GL_FRAMEBUFFER_BINDING, &frameBufferBinding);
mShadowMapTexture = Create2DTexture("ShadowMap", GL_R32F, 1024, 1024); mShadowMapTexture = Create2DTexture("ShadowMap", GL_R32F, gl_shadowmap_quality, 1024);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
@ -781,6 +791,8 @@ void FGLRenderBuffers::CreateShadowMap()
glBindTexture(GL_TEXTURE_2D, textureBinding); glBindTexture(GL_TEXTURE_2D, textureBinding);
glActiveTexture(activeTex); glActiveTexture(activeTex);
glBindFramebuffer(GL_FRAMEBUFFER, frameBufferBinding); glBindFramebuffer(GL_FRAMEBUFFER, frameBufferBinding);
mCurrentShadowMapSize = gl_shadowmap_quality;
} }
//========================================================================== //==========================================================================

View file

@ -89,6 +89,7 @@ private:
void ClearBloom(); void ClearBloom();
void ClearExposureLevels(); void ClearExposureLevels();
void ClearAmbientOcclusion(); void ClearAmbientOcclusion();
void ClearShadowMap();
void CreateScene(int width, int height, int samples, bool needsSceneTextures); void CreateScene(int width, int height, int samples, bool needsSceneTextures);
void CreatePipeline(int width, int height); void CreatePipeline(int width, int height);
void CreateBloom(int width, int height); void CreateBloom(int width, int height);
@ -142,6 +143,7 @@ private:
// Shadow map texture // Shadow map texture
GLuint mShadowMapTexture = 0; GLuint mShadowMapTexture = 0;
GLuint mShadowMapFB = 0; GLuint mShadowMapFB = 0;
int mCurrentShadowMapSize = 0;
static bool FailedCreate; static bool FailedCreate;
static bool BuffersActive; static bool BuffersActive;

View file

@ -40,6 +40,7 @@ void FShadowMapShader::Bind()
mShader.SetFragDataLocation(0, "FragColor"); mShader.SetFragDataLocation(0, "FragColor");
mShader.Link("shaders/glsl/shadowmap"); mShader.Link("shaders/glsl/shadowmap");
mShader.SetAttribLocation(0, "PositionInProjection"); mShader.SetAttribLocation(0, "PositionInProjection");
ShadowmapQuality.Init(mShader, "ShadowmapQuality");
} }
mShader.Bind(); mShader.Bind();
} }

View file

@ -8,6 +8,8 @@ class FShadowMapShader
public: public:
void Bind(); void Bind();
FBufferedUniform1f ShadowmapQuality;
private: private:
FShaderProgram mShader; FShaderProgram mShader;
}; };

View file

@ -27,6 +27,7 @@ EXTERN_CVAR (Bool, gl_lights_checkside);
EXTERN_CVAR (Bool, gl_light_sprites); EXTERN_CVAR (Bool, gl_light_sprites);
EXTERN_CVAR (Bool, gl_light_particles); EXTERN_CVAR (Bool, gl_light_particles);
EXTERN_CVAR (Bool, gl_light_shadowmap); EXTERN_CVAR (Bool, gl_light_shadowmap);
EXTERN_CVAR (Int, gl_shadowmap_quality);
EXTERN_CVAR(Int, gl_fogmode) EXTERN_CVAR(Int, gl_fogmode)
EXTERN_CVAR(Int, gl_lightmode) EXTERN_CVAR(Int, gl_lightmode)

View file

@ -29,8 +29,10 @@
#include "gl/system/gl_system.h" #include "gl/system/gl_system.h"
#include "gl/system/gl_interface.h" #include "gl/system/gl_interface.h"
#include "gl/system/gl_debug.h" #include "gl/system/gl_debug.h"
#include "stats.h"
#include <set> #include <set>
#include <string> #include <string>
#include <vector>
#ifndef _MSC_VER #ifndef _MSC_VER
#include <signal.h> #include <signal.h>
@ -46,6 +48,20 @@ CUSTOM_CVAR(Int, gl_debug_level, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOIN
CVAR(Bool, gl_debug_breakpoint, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG); CVAR(Bool, gl_debug_breakpoint, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG);
namespace
{
bool gpuStatActive = false;
bool keepGpuStatActive = false;
std::vector<std::pair<FString, GLuint>> timeElapsedQueries;
FString gpuStatOutput;
}
ADD_STAT(gpu)
{
keepGpuStatActive = true;
return gpuStatOutput;
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// //
// Updates OpenGL debugging state // Updates OpenGL debugging state
@ -54,6 +70,22 @@ CVAR(Bool, gl_debug_breakpoint, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG);
void FGLDebug::Update() void FGLDebug::Update()
{ {
gpuStatOutput = "";
for (auto &query : timeElapsedQueries)
{
GLuint timeElapsed = 0;
glGetQueryObjectuiv(query.second, GL_QUERY_RESULT, &timeElapsed);
glDeleteQueries(1, &query.second);
FString out;
out.Format("%s=%04.2f ms\n", query.first.GetChars(), timeElapsed / 1000000.0f);
gpuStatOutput += out;
}
timeElapsedQueries.clear();
gpuStatActive = keepGpuStatActive;
keepGpuStatActive = false;
if (!HasDebugApi()) if (!HasDebugApi())
return; return;
@ -98,6 +130,14 @@ void FGLDebug::PushGroup(const FString &name)
{ {
glPushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, 0, (GLsizei)name.Len(), name.GetChars()); glPushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, 0, (GLsizei)name.Len(), name.GetChars());
} }
if (gpuStatActive)
{
GLuint queryHandle = 0;
glGenQueries(1, &queryHandle);
glBeginQuery(GL_TIME_ELAPSED, queryHandle);
timeElapsedQueries.push_back({ name, queryHandle });
}
} }
void FGLDebug::PopGroup() void FGLDebug::PopGroup()
@ -106,6 +146,11 @@ void FGLDebug::PopGroup()
{ {
glPopDebugGroup(); glPopDebugGroup();
} }
if (gpuStatActive)
{
glEndQuery(GL_TIME_ELAPSED);
}
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------

View file

@ -503,6 +503,7 @@ xx(Scale)
xx(ScaleX) xx(ScaleX)
xx(ScaleY) xx(ScaleY)
xx(Floatbobphase) xx(Floatbobphase)
xx(Floatbobstrength)
xx(Target) xx(Target)
xx(Master) xx(Master)
xx(Tracer) xx(Tracer)

View file

@ -282,6 +282,7 @@ DEFINE_FIELD(AActor, Floorclip)
DEFINE_FIELD(AActor, DamageType) DEFINE_FIELD(AActor, DamageType)
DEFINE_FIELD(AActor, DamageTypeReceived) DEFINE_FIELD(AActor, DamageTypeReceived)
DEFINE_FIELD(AActor, FloatBobPhase) DEFINE_FIELD(AActor, FloatBobPhase)
DEFINE_FIELD(AActor, FloatBobStrength)
DEFINE_FIELD(AActor, RipperLevel) DEFINE_FIELD(AActor, RipperLevel)
DEFINE_FIELD(AActor, RipLevelMin) DEFINE_FIELD(AActor, RipLevelMin)
DEFINE_FIELD(AActor, RipLevelMax) DEFINE_FIELD(AActor, RipLevelMax)
@ -443,6 +444,7 @@ void AActor::Serialize(FSerializer &arc)
("inventory", Inventory) ("inventory", Inventory)
A("inventoryid", InventoryID) A("inventoryid", InventoryID)
A("floatbobphase", FloatBobPhase) A("floatbobphase", FloatBobPhase)
A("floatbobstrength", FloatBobStrength)
A("translation", Translation) A("translation", Translation)
A("bloodcolor", BloodColor) A("bloodcolor", BloodColor)
A("bloodtranslation", BloodTranslation) A("bloodtranslation", BloodTranslation)
@ -7991,7 +7993,7 @@ double AActor::GetBobOffset(double ticfrac) const
{ {
return 0; return 0;
} }
return BobSin(FloatBobPhase + level.maptime + ticfrac); return BobSin(FloatBobPhase + level.maptime + ticfrac) * FloatBobStrength;
} }
DEFINE_ACTION_FUNCTION(AActor, GetBobOffset) DEFINE_ACTION_FUNCTION(AActor, GetBobOffset)

View file

@ -653,6 +653,15 @@ DEFINE_PROPERTY(floatbobphase, I, Actor)
defaults->FloatBobPhase = id; defaults->FloatBobPhase = id;
} }
//==========================================================================
//
//==========================================================================
DEFINE_PROPERTY(floatbobstrength, F, Actor)
{
PROP_DOUBLE_PARM(id, 0);
defaults->FloatBobStrength = id;
}
//========================================================================== //==========================================================================
// //
//========================================================================== //==========================================================================

View file

@ -89,8 +89,10 @@ void FStat::ToggleStat ()
void FStat::PrintStat () void FStat::PrintStat ()
{ {
int textScale = active_con_scale();
int fontheight = ConFont->GetHeight() + 1; int fontheight = ConFont->GetHeight() + 1;
int y = SCREENHEIGHT; int y = SCREENHEIGHT / textScale;
int count = 0; int count = 0;
for (FStat *stat = FirstStat; stat != NULL; stat = stat->m_Next) for (FStat *stat = FirstStat; stat != NULL; stat = stat->m_Next)
@ -107,7 +109,10 @@ void FStat::PrintStat ()
// Count number of linefeeds but ignore terminating ones. // Count number of linefeeds but ignore terminating ones.
if (stattext[i] == '\n') y -= fontheight; if (stattext[i] == '\n') y -= fontheight;
} }
screen->DrawText(ConFont, CR_GREEN, 5, y, stattext, TAG_DONE); screen->DrawText(ConFont, CR_GREEN, 5 / textScale, y, stattext,
DTA_VirtualWidth, screen->GetWidth() / textScale,
DTA_VirtualHeight, screen->GetHeight() / textScale,
DTA_KeepRatio, true, TAG_DONE);
count++; count++;
} }
} }

View file

@ -2,6 +2,11 @@
in vec2 TexCoord; in vec2 TexCoord;
out vec4 FragColor; out vec4 FragColor;
// This constant must match the same constant in gl_shadowmap.h
// #define ShadowmapQuality 1024
//#define ShadowmapQuality 128
uniform float ShadowmapQuality;
struct GPUNode struct GPUNode
{ {
vec2 aabb_min; vec2 aabb_min;
@ -140,12 +145,12 @@ void main()
if (radius > 0.0) if (radius > 0.0)
{ {
vec2 pixelpos; vec2 pixelpos;
switch (int(gl_FragCoord.x) / 256) switch (int(gl_FragCoord.x) / int(ShadowmapQuality/4.0))
{ {
case 0: pixelpos = vec2((gl_FragCoord.x - 128.0) / 128.0, 1.0); break; case 0: pixelpos = vec2((gl_FragCoord.x - float(ShadowmapQuality/8.0)) / float(ShadowmapQuality/8.0), 1.0); break;
case 1: pixelpos = vec2(1.0, (gl_FragCoord.x - 384.0) / 128.0); break; case 1: pixelpos = vec2(1.0, (gl_FragCoord.x - float(ShadowmapQuality/4.0 + ShadowmapQuality/8.0)) / float(ShadowmapQuality/8.0)); break;
case 2: pixelpos = vec2(-(gl_FragCoord.x - 640.0) / 128.0, -1.0); break; case 2: pixelpos = vec2(-(gl_FragCoord.x - float(ShadowmapQuality/2.0 + ShadowmapQuality/8.0)) / float(ShadowmapQuality/8.0), -1.0); break;
case 3: pixelpos = vec2(-1.0, -(gl_FragCoord.x - 896.0) / 128.0); break; case 3: pixelpos = vec2(-1.0, -(gl_FragCoord.x - float(ShadowmapQuality*3.0/4.0 + ShadowmapQuality/8.0)) / float(ShadowmapQuality/8.0)); break;
} }
pixelpos = lightpos + pixelpos * radius; pixelpos = lightpos + pixelpos * radius;

View file

@ -131,6 +131,7 @@ class Actor : Thinker native
native name DamageType; native name DamageType;
native name DamageTypeReceived; native name DamageTypeReceived;
native uint8 FloatBobPhase; native uint8 FloatBobPhase;
native double FloatBobStrength;
native int RipperLevel; native int RipperLevel;
native int RipLevelMin; native int RipLevelMin;
native int RipLevelMax; native int RipLevelMax;
@ -325,6 +326,7 @@ class Actor : Thinker native
BounceCount -1; BounceCount -1;
FloatSpeed 4; FloatSpeed 4;
FloatBobPhase -1; // randomly initialize by default FloatBobPhase -1; // randomly initialize by default
FloatBobStrength 1.0;
Gravity 1; Gravity 1;
Friction 1; Friction 1;
DamageFactor 1.0; // damage multiplier as target of damage. DamageFactor 1.0; // damage multiplier as target of damage.