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 FloatBobPhase;
double FloatBobStrength;
uint8_t FriendPlayer; // [RH] Player # + 1 this friendly monster works for (so 0 is no player, 1 is player 0, etc)
PalEntry BloodColor;
uint32_t BloodTranslation;

View file

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

View file

@ -33,6 +33,7 @@
#include "gl/shaders/gl_shadowmapshader.h"
#include "r_state.h"
#include "g_levellocals.h"
#include "stats.h"
/*
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.
*/
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()
{
UpdateCycles.Reset();
LightsProcessed = 0;
LightsShadowmapped = 0;
if (!IsEnabled())
return;
UpdateCycles.Clock();
UploadAABBTree();
UploadLights();
@ -81,11 +119,12 @@ void FShadowMap::Update()
GLRenderer->mBuffers->BindShadowMapFB();
GLRenderer->mShadowMapShader->Bind();
GLRenderer->mShadowMapShader->ShadowmapQuality.Set(gl_shadowmap_quality);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, mLightList);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, mNodesBuffer);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, mLinesBuffer);
glViewport(0, 0, 1024, 1024);
glViewport(0, 0, gl_shadowmap_quality, 1024);
GLRenderer->RenderScreenQuad();
const auto &viewport = GLRenderer->mScreenViewport;
@ -98,6 +137,8 @@ void FShadowMap::Update()
GLRenderer->mBuffers->BindShadowMapTexture(16);
FGLDebug::PopGroup();
UpdateCycles.Unclock();
}
bool FShadowMap::ShadowTest(ADynamicLight *light, const DVector3 &pos)
@ -133,8 +174,11 @@ void FShadowMap::UploadLights()
TThinkerIterator<ADynamicLight> it(STAT_DLIGHT);
while (auto light = it.Next())
{
LightsProcessed++;
if (light->shadowmapped)
{
LightsShadowmapped++;
mLightToShadowmap[light] = lightindex >> 2;
mLights[lightindex] = light->X();

View file

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

View file

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

View file

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

View file

@ -8,6 +8,8 @@ class FShadowMapShader
public:
void Bind();
FBufferedUniform1f ShadowmapQuality;
private:
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_particles);
EXTERN_CVAR (Bool, gl_light_shadowmap);
EXTERN_CVAR (Int, gl_shadowmap_quality);
EXTERN_CVAR(Int, gl_fogmode)
EXTERN_CVAR(Int, gl_lightmode)

View file

@ -29,8 +29,10 @@
#include "gl/system/gl_system.h"
#include "gl/system/gl_interface.h"
#include "gl/system/gl_debug.h"
#include "stats.h"
#include <set>
#include <string>
#include <vector>
#ifndef _MSC_VER
#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);
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
@ -54,6 +70,22 @@ CVAR(Bool, gl_debug_breakpoint, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG);
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())
return;
@ -98,6 +130,14 @@ void FGLDebug::PushGroup(const FString &name)
{
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()
@ -106,6 +146,11 @@ void FGLDebug::PopGroup()
{
glPopDebugGroup();
}
if (gpuStatActive)
{
glEndQuery(GL_TIME_ELAPSED);
}
}
//-----------------------------------------------------------------------------

View file

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

View file

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

View file

@ -653,6 +653,15 @@ DEFINE_PROPERTY(floatbobphase, I, Actor)
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 ()
{
int textScale = active_con_scale();
int fontheight = ConFont->GetHeight() + 1;
int y = SCREENHEIGHT;
int y = SCREENHEIGHT / textScale;
int count = 0;
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.
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++;
}
}

View file

@ -2,6 +2,11 @@
in vec2 TexCoord;
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
{
vec2 aabb_min;
@ -140,12 +145,12 @@ void main()
if (radius > 0.0)
{
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 1: pixelpos = vec2(1.0, (gl_FragCoord.x - 384.0) / 128.0); break;
case 2: pixelpos = vec2(-(gl_FragCoord.x - 640.0) / 128.0, -1.0); break;
case 3: pixelpos = vec2(-1.0, -(gl_FragCoord.x - 896.0) / 128.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 - float(ShadowmapQuality/4.0 + ShadowmapQuality/8.0)) / float(ShadowmapQuality/8.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 - float(ShadowmapQuality*3.0/4.0 + ShadowmapQuality/8.0)) / float(ShadowmapQuality/8.0)); break;
}
pixelpos = lightpos + pixelpos * radius;

View file

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