mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-14 08:31:23 +00:00
Create a shadowmap texture and upload light list
This commit is contained in:
parent
7a4b01471d
commit
62c285f7b3
5 changed files with 111 additions and 7 deletions
|
@ -28,27 +28,32 @@
|
||||||
#include "gl/system/gl_debug.h"
|
#include "gl/system/gl_debug.h"
|
||||||
#include "gl/renderer/gl_renderer.h"
|
#include "gl/renderer/gl_renderer.h"
|
||||||
#include "gl/renderer/gl_postprocessstate.h"
|
#include "gl/renderer/gl_postprocessstate.h"
|
||||||
|
#include "gl/renderer/gl_renderbuffers.h"
|
||||||
#include "gl/shaders/gl_shadowmapshader.h"
|
#include "gl/shaders/gl_shadowmapshader.h"
|
||||||
#include "r_state.h"
|
#include "r_state.h"
|
||||||
|
|
||||||
void FShadowMap::Clear()
|
void FShadowMap::Clear()
|
||||||
{
|
{
|
||||||
|
if (mLightList != 0)
|
||||||
|
{
|
||||||
|
glDeleteBuffers(1, (GLuint*)&mLightList);
|
||||||
|
mLightList = 0;
|
||||||
|
}
|
||||||
|
|
||||||
mLightBSP.Clear();
|
mLightBSP.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void FShadowMap::Update()
|
void FShadowMap::Update()
|
||||||
{
|
{
|
||||||
TThinkerIterator<ADynamicLight> it(STAT_DLIGHT);
|
UploadLights();
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
ADynamicLight *light = it.Next();
|
|
||||||
if (!light) break;
|
|
||||||
}
|
|
||||||
|
|
||||||
FGLDebug::PushGroup("ShadowMap");
|
FGLDebug::PushGroup("ShadowMap");
|
||||||
FGLPostProcessState savedState;
|
FGLPostProcessState savedState;
|
||||||
|
|
||||||
|
GLRenderer->mBuffers->BindShadowMapFB();
|
||||||
|
|
||||||
GLRenderer->mShadowMapShader->Bind();
|
GLRenderer->mShadowMapShader->Bind();
|
||||||
|
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, mLightList);
|
||||||
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, mLightBSP.GetNodesBuffer());
|
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, mLightBSP.GetNodesBuffer());
|
||||||
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, mLightBSP.GetSegsBuffer());
|
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, mLightBSP.GetSegsBuffer());
|
||||||
|
|
||||||
|
@ -58,8 +63,41 @@ void FShadowMap::Update()
|
||||||
const auto &viewport = GLRenderer->mScreenViewport;
|
const auto &viewport = GLRenderer->mScreenViewport;
|
||||||
glViewport(viewport.left, viewport.top, viewport.width, viewport.height);
|
glViewport(viewport.left, viewport.top, viewport.width, viewport.height);
|
||||||
|
|
||||||
|
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, 0);
|
||||||
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, 0);
|
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, 0);
|
||||||
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, 0);
|
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, 0);
|
||||||
|
|
||||||
FGLDebug::PopGroup();
|
FGLDebug::PopGroup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FShadowMap::UploadLights()
|
||||||
|
{
|
||||||
|
lights.Clear();
|
||||||
|
|
||||||
|
TThinkerIterator<ADynamicLight> it(STAT_DLIGHT);
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
ADynamicLight *light = it.Next();
|
||||||
|
if (!light) break;
|
||||||
|
|
||||||
|
lights.Push(light->X());
|
||||||
|
lights.Push(light->Y());
|
||||||
|
lights.Push(light->Z());
|
||||||
|
lights.Push(light->GetRadius());
|
||||||
|
|
||||||
|
if (lights.Size() == 1024) // Only 1024 lights for now
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (lights.Size() < 1024 * 4)
|
||||||
|
lights.Push(0.0f);
|
||||||
|
|
||||||
|
if (mLightList == 0)
|
||||||
|
glGenBuffers(1, (GLuint*)&mLightList);
|
||||||
|
|
||||||
|
int oldBinding = 0;
|
||||||
|
glGetIntegerv(GL_SHADER_STORAGE_BUFFER_BINDING, &oldBinding);
|
||||||
|
glBindBuffer(GL_SHADER_STORAGE_BUFFER, mLightList);
|
||||||
|
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(float) * lights.Size(), &lights[0], GL_STATIC_DRAW);
|
||||||
|
glBindBuffer(GL_SHADER_STORAGE_BUFFER, oldBinding);
|
||||||
|
}
|
|
@ -13,7 +13,11 @@ public:
|
||||||
void Update();
|
void Update();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void UploadLights();
|
||||||
|
|
||||||
FLightBSP mLightBSP;
|
FLightBSP mLightBSP;
|
||||||
|
int mLightList = 0;
|
||||||
|
TArray<float> lights;
|
||||||
|
|
||||||
FShadowMap(const FShadowMap &) = delete;
|
FShadowMap(const FShadowMap &) = delete;
|
||||||
FShadowMap &operator=(FShadowMap &) = delete;
|
FShadowMap &operator=(FShadowMap &) = delete;
|
||||||
|
|
|
@ -741,6 +741,44 @@ void FGLRenderBuffers::BindEyeFB(int eye, bool readBuffer)
|
||||||
glBindFramebuffer(readBuffer ? GL_READ_FRAMEBUFFER : GL_FRAMEBUFFER, mEyeFBs[eye]);
|
glBindFramebuffer(readBuffer ? GL_READ_FRAMEBUFFER : GL_FRAMEBUFFER, mEyeFBs[eye]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// Shadow map texture and frame buffers
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
void FGLRenderBuffers::BindShadowMapFB()
|
||||||
|
{
|
||||||
|
CreateShadowMap();
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, mShadowMapFB);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FGLRenderBuffers::BindShadowMapTexture(int texunit)
|
||||||
|
{
|
||||||
|
CreateShadowMap();
|
||||||
|
glActiveTexture(GL_TEXTURE0 + texunit);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, mShadowMapTexture);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FGLRenderBuffers::CreateShadowMap()
|
||||||
|
{
|
||||||
|
if (mShadowMapTexture != 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
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);
|
||||||
|
mShadowMapFB = CreateFrameBuffer("ShadowMapFB", mShadowMapTexture);
|
||||||
|
|
||||||
|
glBindTexture(GL_TEXTURE_2D, textureBinding);
|
||||||
|
glActiveTexture(activeTex);
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, frameBufferBinding);
|
||||||
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// Makes the scene frame buffer active (multisample, depth, stecil, etc.)
|
// Makes the scene frame buffer active (multisample, depth, stecil, etc.)
|
||||||
|
|
|
@ -49,6 +49,9 @@ public:
|
||||||
void BindEyeTexture(int eye, int texunit);
|
void BindEyeTexture(int eye, int texunit);
|
||||||
void BindEyeFB(int eye, bool readBuffer = false);
|
void BindEyeFB(int eye, bool readBuffer = false);
|
||||||
|
|
||||||
|
void BindShadowMapFB();
|
||||||
|
void BindShadowMapTexture(int index);
|
||||||
|
|
||||||
enum { NumBloomLevels = 4 };
|
enum { NumBloomLevels = 4 };
|
||||||
FGLBloomTextureLevel BloomLevels[NumBloomLevels];
|
FGLBloomTextureLevel BloomLevels[NumBloomLevels];
|
||||||
|
|
||||||
|
@ -89,6 +92,7 @@ private:
|
||||||
void CreateBloom(int width, int height);
|
void CreateBloom(int width, int height);
|
||||||
void CreateExposureLevels(int width, int height);
|
void CreateExposureLevels(int width, int height);
|
||||||
void CreateEyeBuffers(int eye);
|
void CreateEyeBuffers(int eye);
|
||||||
|
void CreateShadowMap();
|
||||||
void CreateAmbientOcclusion(int width, int height);
|
void CreateAmbientOcclusion(int width, int height);
|
||||||
GLuint Create2DTexture(const FString &name, GLuint format, int width, int height, const void *data = nullptr);
|
GLuint Create2DTexture(const FString &name, GLuint format, int width, int height, const void *data = nullptr);
|
||||||
GLuint Create2DMultisampleTexture(const FString &name, GLuint format, int width, int height, int samples, bool fixedSampleLocations);
|
GLuint Create2DMultisampleTexture(const FString &name, GLuint format, int width, int height, int samples, bool fixedSampleLocations);
|
||||||
|
@ -133,6 +137,10 @@ private:
|
||||||
TArray<GLuint> mEyeTextures;
|
TArray<GLuint> mEyeTextures;
|
||||||
TArray<GLuint> mEyeFBs;
|
TArray<GLuint> mEyeFBs;
|
||||||
|
|
||||||
|
// Shadow map texture
|
||||||
|
GLuint mShadowMapTexture = 0;
|
||||||
|
GLuint mShadowMapFB = 0;
|
||||||
|
|
||||||
static bool FailedCreate;
|
static bool FailedCreate;
|
||||||
static bool BuffersActive;
|
static bool BuffersActive;
|
||||||
};
|
};
|
||||||
|
|
|
@ -16,6 +16,11 @@ struct GPUSeg
|
||||||
vec4 bSolid;
|
vec4 bSolid;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
layout(std430, binding = 1) buffer LightList
|
||||||
|
{
|
||||||
|
vec4 lights[];
|
||||||
|
};
|
||||||
|
|
||||||
layout(std430, binding = 2) buffer LightNodes
|
layout(std430, binding = 2) buffer LightNodes
|
||||||
{
|
{
|
||||||
GPUNode bspNodes[];
|
GPUNode bspNodes[];
|
||||||
|
@ -112,5 +117,16 @@ float rayTest(vec2 from, vec2 to)
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
FragColor = vec4(rayTest(vec2(0.0, 0.0), vec2(1.0, 1.0)));
|
int lightIndex = int(gl_FragCoord.y);
|
||||||
|
int x = int(gl_FragCoord.x);
|
||||||
|
|
||||||
|
vec4 light = lights[lightIndex];
|
||||||
|
float radius = light.w;
|
||||||
|
vec2 lightpos = light.xy;
|
||||||
|
vec2 pixelpos = lightpos + vec2(10.0);
|
||||||
|
|
||||||
|
if (radius > 0.0)
|
||||||
|
FragColor = vec4(rayTest(lightpos, pixelpos), 0.0, 0.0, 1.0);
|
||||||
|
else
|
||||||
|
FragColor = vec4(1.0, 0.0, 0.0, 1.0);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue