mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-10 14:51:51 +00:00
This commit is contained in:
commit
64b22f6cb3
15 changed files with 144 additions and 12 deletions
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -8,6 +8,8 @@ class FShadowMapShader
|
|||
public:
|
||||
void Bind();
|
||||
|
||||
FBufferedUniform1f ShadowmapQuality;
|
||||
|
||||
private:
|
||||
FShaderProgram mShader;
|
||||
};
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
|
@ -503,6 +503,7 @@ xx(Scale)
|
|||
xx(ScaleX)
|
||||
xx(ScaleY)
|
||||
xx(Floatbobphase)
|
||||
xx(Floatbobstrength)
|
||||
xx(Target)
|
||||
xx(Master)
|
||||
xx(Tracer)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//==========================================================================
|
||||
|
|
|
@ -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++;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Reference in a new issue