mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-11 15:22:16 +00:00
Move all GPU handling to gl_shadowmap and rename gl_lightbsp to gl_aabbtree
This commit is contained in:
parent
8687a9868a
commit
d09c3ad305
5 changed files with 74 additions and 147 deletions
|
@ -939,7 +939,7 @@ set( FASTMATH_SOURCES
|
|||
gl/dynlights/gl_glow.cpp
|
||||
gl/dynlights/gl_dynlight1.cpp
|
||||
gl/dynlights/gl_lightbuffer.cpp
|
||||
gl/dynlights/gl_lightbsp.cpp
|
||||
gl/dynlights/gl_aabbtree.cpp
|
||||
gl/dynlights/gl_shadowmap.cpp
|
||||
gl/shaders/gl_shader.cpp
|
||||
gl/shaders/gl_texshader.cpp
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
//
|
||||
//---------------------------------------------------------------------------
|
||||
// 2D collision tree for 1D shadowmap lights
|
||||
// AABB-tree used for ray testing
|
||||
// Copyright(C) 2017 Magnus Norddahl
|
||||
// All rights reserved.
|
||||
//
|
||||
|
@ -22,106 +22,11 @@
|
|||
|
||||
#include "gl/system/gl_system.h"
|
||||
#include "gl/shaders/gl_shader.h"
|
||||
#include "gl/dynlights/gl_lightbsp.h"
|
||||
#include "gl/dynlights/gl_aabbtree.h"
|
||||
#include "gl/system/gl_interface.h"
|
||||
#include "r_state.h"
|
||||
#include "g_levellocals.h"
|
||||
|
||||
int FLightBSP::GetNodesBuffer()
|
||||
{
|
||||
UpdateBuffers();
|
||||
return NodesBuffer;
|
||||
}
|
||||
|
||||
int FLightBSP::GetLinesBuffer()
|
||||
{
|
||||
UpdateBuffers();
|
||||
return LinesBuffer;
|
||||
}
|
||||
|
||||
void FLightBSP::UpdateBuffers()
|
||||
{
|
||||
if (numnodes != NumNodes || numsegs != NumSegs) // To do: there is probably a better way to detect a map change than this..
|
||||
Clear();
|
||||
|
||||
if (NodesBuffer == 0)
|
||||
GenerateBuffers();
|
||||
}
|
||||
|
||||
void FLightBSP::GenerateBuffers()
|
||||
{
|
||||
if (!Shape)
|
||||
Shape.reset(new LevelAABBTree());
|
||||
UploadNodes();
|
||||
UploadSegs();
|
||||
}
|
||||
|
||||
void FLightBSP::UploadNodes()
|
||||
{
|
||||
#if 0
|
||||
if (Shape->nodes.Size() > 0)
|
||||
{
|
||||
FILE *file = fopen("nodes.txt", "wb");
|
||||
fwrite(&Shape->nodes[0], sizeof(AABBTreeNode) * Shape->nodes.Size(), 1, file);
|
||||
fclose(file);
|
||||
}
|
||||
#endif
|
||||
|
||||
int oldBinding = 0;
|
||||
glGetIntegerv(GL_SHADER_STORAGE_BUFFER_BINDING, &oldBinding);
|
||||
|
||||
glGenBuffers(1, (GLuint*)&NodesBuffer);
|
||||
glBindBuffer(GL_SHADER_STORAGE_BUFFER, NodesBuffer);
|
||||
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(AABBTreeNode) * Shape->nodes.Size(), &Shape->nodes[0], GL_STATIC_DRAW);
|
||||
glBindBuffer(GL_SHADER_STORAGE_BUFFER, oldBinding);
|
||||
|
||||
NumNodes = numnodes;
|
||||
}
|
||||
|
||||
void FLightBSP::UploadSegs()
|
||||
{
|
||||
#if 0
|
||||
if (Shape->lines.Size() > 0)
|
||||
{
|
||||
FILE *file = fopen("lines.txt", "wb");
|
||||
fwrite(&Shape->lines[0], sizeof(AABBTreeLine) * Shape->lines.Size(), 1, file);
|
||||
fclose(file);
|
||||
}
|
||||
#endif
|
||||
|
||||
int oldBinding = 0;
|
||||
glGetIntegerv(GL_SHADER_STORAGE_BUFFER_BINDING, &oldBinding);
|
||||
|
||||
glGenBuffers(1, (GLuint*)&LinesBuffer);
|
||||
glBindBuffer(GL_SHADER_STORAGE_BUFFER, LinesBuffer);
|
||||
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(AABBTreeLine) * Shape->lines.Size(), &Shape->lines[0], GL_STATIC_DRAW);
|
||||
glBindBuffer(GL_SHADER_STORAGE_BUFFER, oldBinding);
|
||||
|
||||
NumSegs = numsegs;
|
||||
}
|
||||
|
||||
void FLightBSP::Clear()
|
||||
{
|
||||
if (NodesBuffer != 0)
|
||||
{
|
||||
glDeleteBuffers(1, (GLuint*)&NodesBuffer);
|
||||
NodesBuffer = 0;
|
||||
}
|
||||
if (LinesBuffer != 0)
|
||||
{
|
||||
glDeleteBuffers(1, (GLuint*)&LinesBuffer);
|
||||
LinesBuffer = 0;
|
||||
}
|
||||
Shape.reset();
|
||||
}
|
||||
|
||||
bool FLightBSP::ShadowTest(const DVector3 &light, const DVector3 &pos)
|
||||
{
|
||||
return Shape->RayTest(light, pos) >= 1.0f;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
LevelAABBTree::LevelAABBTree()
|
||||
{
|
||||
// Calculate the center of all lines
|
|
@ -2,7 +2,6 @@
|
|||
#pragma once
|
||||
|
||||
#include "vectors.h"
|
||||
#include <memory>
|
||||
|
||||
// Node in a binary AABB tree
|
||||
struct AABBTreeNode
|
||||
|
@ -14,7 +13,7 @@ struct AABBTreeNode
|
|||
float aabb_left, aabb_top;
|
||||
float aabb_right, aabb_bottom;
|
||||
|
||||
// Children node indices
|
||||
// Child node indices
|
||||
int left_node;
|
||||
int right_node;
|
||||
|
||||
|
@ -45,7 +44,7 @@ public:
|
|||
// Line segments for the leaf nodes in the tree.
|
||||
TArray<AABBTreeLine> lines;
|
||||
|
||||
// Shoot a ray from ray_start to ray_end and return the first hit as a fractional value between 0 and 1. Returns 1 if no line was hit.
|
||||
// Shoot a ray from ray_start to ray_end and return the closest hit as a fractional value between 0 and 1. Returns 1 if no line was hit.
|
||||
double RayTest(const DVector3 &ray_start, const DVector3 &ray_end);
|
||||
|
||||
private:
|
||||
|
@ -58,32 +57,3 @@ private:
|
|||
// Generate a tree node and its children recursively
|
||||
int GenerateTreeNode(int *lines, int num_lines, const FVector2 *centroids, int *work_buffer);
|
||||
};
|
||||
|
||||
class FLightBSP
|
||||
{
|
||||
public:
|
||||
FLightBSP() { }
|
||||
~FLightBSP() { Clear(); }
|
||||
|
||||
int GetNodesBuffer();
|
||||
int GetLinesBuffer();
|
||||
void Clear();
|
||||
|
||||
bool ShadowTest(const DVector3 &light, const DVector3 &pos);
|
||||
|
||||
private:
|
||||
void UpdateBuffers();
|
||||
void GenerateBuffers();
|
||||
void UploadNodes();
|
||||
void UploadSegs();
|
||||
|
||||
FLightBSP(const FLightBSP &) = delete;
|
||||
FLightBSP &operator=(FLightBSP &) = delete;
|
||||
|
||||
int NodesBuffer = 0;
|
||||
int LinesBuffer = 0;
|
||||
int NumNodes = 0;
|
||||
int NumSegs = 0;
|
||||
|
||||
std::unique_ptr<LevelAABBTree> Shape;
|
||||
};
|
|
@ -32,19 +32,9 @@
|
|||
#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()
|
||||
{
|
||||
UploadAABBTree();
|
||||
UploadLights();
|
||||
|
||||
FGLDebug::PushGroup("ShadowMap");
|
||||
|
@ -54,8 +44,8 @@ void FShadowMap::Update()
|
|||
|
||||
GLRenderer->mShadowMapShader->Bind();
|
||||
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, mLightList);
|
||||
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, mLightBSP.GetNodesBuffer());
|
||||
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, mLightBSP.GetLinesBuffer());
|
||||
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, mNodesBuffer);
|
||||
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, mLinesBuffer);
|
||||
|
||||
glViewport(0, 0, 1024, 1024);
|
||||
GLRenderer->RenderScreenQuad();
|
||||
|
@ -72,6 +62,14 @@ void FShadowMap::Update()
|
|||
FGLDebug::PopGroup();
|
||||
}
|
||||
|
||||
bool FShadowMap::ShadowTest(ADynamicLight *light, const DVector3 &pos)
|
||||
{
|
||||
if (mAABBTree)
|
||||
return mAABBTree->RayTest(light->Pos(), pos) >= 1.0f;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
void FShadowMap::UploadLights()
|
||||
{
|
||||
mLights.Clear();
|
||||
|
@ -107,7 +105,52 @@ void FShadowMap::UploadLights()
|
|||
glBindBuffer(GL_SHADER_STORAGE_BUFFER, oldBinding);
|
||||
}
|
||||
|
||||
bool FShadowMap::ShadowTest(ADynamicLight *light, const DVector3 &pos)
|
||||
void FShadowMap::UploadAABBTree()
|
||||
{
|
||||
return mLightBSP.ShadowTest(light->Pos(), pos);
|
||||
if (numnodes != mLastNumNodes || numsegs != mLastNumSegs) // To do: there is probably a better way to detect a map change than this..
|
||||
Clear();
|
||||
|
||||
if (mAABBTree)
|
||||
return;
|
||||
|
||||
mAABBTree.reset(new LevelAABBTree());
|
||||
|
||||
int oldBinding = 0;
|
||||
glGetIntegerv(GL_SHADER_STORAGE_BUFFER_BINDING, &oldBinding);
|
||||
|
||||
glGenBuffers(1, (GLuint*)&mNodesBuffer);
|
||||
glBindBuffer(GL_SHADER_STORAGE_BUFFER, mNodesBuffer);
|
||||
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(AABBTreeNode) * mAABBTree->nodes.Size(), &mAABBTree->nodes[0], GL_STATIC_DRAW);
|
||||
|
||||
glGenBuffers(1, (GLuint*)&mLinesBuffer);
|
||||
glBindBuffer(GL_SHADER_STORAGE_BUFFER, mLinesBuffer);
|
||||
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(AABBTreeLine) * mAABBTree->lines.Size(), &mAABBTree->lines[0], GL_STATIC_DRAW);
|
||||
|
||||
glBindBuffer(GL_SHADER_STORAGE_BUFFER, oldBinding);
|
||||
}
|
||||
|
||||
void FShadowMap::Clear()
|
||||
{
|
||||
if (mLightList != 0)
|
||||
{
|
||||
glDeleteBuffers(1, (GLuint*)&mLightList);
|
||||
mLightList = 0;
|
||||
}
|
||||
|
||||
if (mNodesBuffer != 0)
|
||||
{
|
||||
glDeleteBuffers(1, (GLuint*)&mNodesBuffer);
|
||||
mNodesBuffer = 0;
|
||||
}
|
||||
|
||||
if (mLinesBuffer != 0)
|
||||
{
|
||||
glDeleteBuffers(1, (GLuint*)&mLinesBuffer);
|
||||
mLinesBuffer = 0;
|
||||
}
|
||||
|
||||
mAABBTree.reset();
|
||||
|
||||
mLastNumNodes = numnodes;
|
||||
mLastNumSegs = numsegs;
|
||||
}
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "gl/dynlights/gl_lightbsp.h"
|
||||
#include "gl/dynlights/gl_aabbtree.h"
|
||||
#include "tarray.h"
|
||||
#include <memory>
|
||||
|
||||
class ADynamicLight;
|
||||
|
||||
|
@ -20,13 +21,21 @@ public:
|
|||
bool ShadowTest(ADynamicLight *light, const DVector3 &pos);
|
||||
|
||||
private:
|
||||
void UploadAABBTree();
|
||||
void UploadLights();
|
||||
|
||||
FLightBSP mLightBSP;
|
||||
int mLightList = 0;
|
||||
TArray<float> mLights;
|
||||
TMap<ADynamicLight*, int> mLightToShadowmap;
|
||||
|
||||
int mNodesBuffer = 0;
|
||||
int mLinesBuffer = 0;
|
||||
|
||||
int mLastNumNodes = 0;
|
||||
int mLastNumSegs = 0;
|
||||
|
||||
std::unique_ptr<LevelAABBTree> mAABBTree;
|
||||
|
||||
FShadowMap(const FShadowMap &) = delete;
|
||||
FShadowMap &operator=(FShadowMap &) = delete;
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue