mirror of
https://github.com/ZDoom/qzdoom-gpl.git
synced 2024-11-26 05:41:39 +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/renderer/gl_renderer.h"
|
||||
#include "gl/renderer/gl_postprocessstate.h"
|
||||
#include "gl/renderer/gl_renderbuffers.h"
|
||||
#include "gl/shaders/gl_shadowmapshader.h"
|
||||
#include "r_state.h"
|
||||
|
||||
void FShadowMap::Clear()
|
||||
{
|
||||
if (mLightList != 0)
|
||||
{
|
||||
glDeleteBuffers(1, (GLuint*)&mLightList);
|
||||
mLightList = 0;
|
||||
}
|
||||
|
||||
mLightBSP.Clear();
|
||||
}
|
||||
|
||||
void FShadowMap::Update()
|
||||
{
|
||||
TThinkerIterator<ADynamicLight> it(STAT_DLIGHT);
|
||||
while (true)
|
||||
{
|
||||
ADynamicLight *light = it.Next();
|
||||
if (!light) break;
|
||||
}
|
||||
UploadLights();
|
||||
|
||||
FGLDebug::PushGroup("ShadowMap");
|
||||
FGLPostProcessState savedState;
|
||||
|
||||
GLRenderer->mBuffers->BindShadowMapFB();
|
||||
|
||||
GLRenderer->mShadowMapShader->Bind();
|
||||
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, mLightList);
|
||||
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, mLightBSP.GetNodesBuffer());
|
||||
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, mLightBSP.GetSegsBuffer());
|
||||
|
||||
|
@ -58,8 +63,41 @@ void FShadowMap::Update()
|
|||
const auto &viewport = GLRenderer->mScreenViewport;
|
||||
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, 3, 0);
|
||||
|
||||
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();
|
||||
|
||||
private:
|
||||
void UploadLights();
|
||||
|
||||
FLightBSP mLightBSP;
|
||||
int mLightList = 0;
|
||||
TArray<float> lights;
|
||||
|
||||
FShadowMap(const 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]);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// 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.)
|
||||
|
|
|
@ -49,6 +49,9 @@ public:
|
|||
void BindEyeTexture(int eye, int texunit);
|
||||
void BindEyeFB(int eye, bool readBuffer = false);
|
||||
|
||||
void BindShadowMapFB();
|
||||
void BindShadowMapTexture(int index);
|
||||
|
||||
enum { NumBloomLevels = 4 };
|
||||
FGLBloomTextureLevel BloomLevels[NumBloomLevels];
|
||||
|
||||
|
@ -89,6 +92,7 @@ private:
|
|||
void CreateBloom(int width, int height);
|
||||
void CreateExposureLevels(int width, int height);
|
||||
void CreateEyeBuffers(int eye);
|
||||
void CreateShadowMap();
|
||||
void CreateAmbientOcclusion(int width, int height);
|
||||
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);
|
||||
|
@ -133,6 +137,10 @@ private:
|
|||
TArray<GLuint> mEyeTextures;
|
||||
TArray<GLuint> mEyeFBs;
|
||||
|
||||
// Shadow map texture
|
||||
GLuint mShadowMapTexture = 0;
|
||||
GLuint mShadowMapFB = 0;
|
||||
|
||||
static bool FailedCreate;
|
||||
static bool BuffersActive;
|
||||
};
|
||||
|
|
|
@ -16,6 +16,11 @@ struct GPUSeg
|
|||
vec4 bSolid;
|
||||
};
|
||||
|
||||
layout(std430, binding = 1) buffer LightList
|
||||
{
|
||||
vec4 lights[];
|
||||
};
|
||||
|
||||
layout(std430, binding = 2) buffer LightNodes
|
||||
{
|
||||
GPUNode bspNodes[];
|
||||
|
@ -112,5 +117,16 @@ float rayTest(vec2 from, vec2 to)
|
|||
|
||||
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