mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-12-03 09:23:19 +00:00
- hook up dynamic lights
This commit is contained in:
parent
a55412fcf6
commit
97a4f25771
7 changed files with 101 additions and 12 deletions
|
@ -44,7 +44,7 @@ FLightBuffer::FLightBuffer()
|
|||
// Hack alert: On Intel's GL driver SSBO's perform quite worse than UBOs.
|
||||
// We only want to disable using SSBOs for lights but not disable the feature entirely.
|
||||
// Note that using an uniform buffer here will limit the number of lights per surface so it isn't done for NVidia and AMD.
|
||||
if (screen->IsVulkan() || ((screen->hwcaps & RFL_SHADER_STORAGE_BUFFER) && !strstr(screen->vendorstring, "Intel")))
|
||||
if (screen->IsVulkan() || screen->IsPoly() || ((screen->hwcaps & RFL_SHADER_STORAGE_BUFFER) && !strstr(screen->vendorstring, "Intel")))
|
||||
{
|
||||
mBufferType = true;
|
||||
mBlockAlign = 0;
|
||||
|
|
|
@ -89,19 +89,13 @@ void PolyVertexInputAssembly::Load(PolyTriangleThreadData *thread, const void *v
|
|||
const float *attrVertex = reinterpret_cast<const float*>(vertex + mOffsets[VATTR_VERTEX]);
|
||||
const float *attrTexcoord = reinterpret_cast<const float*>(vertex + mOffsets[VATTR_TEXCOORD]);
|
||||
const uint8_t *attrColor = reinterpret_cast<const uint8_t*>(vertex + mOffsets[VATTR_COLOR]);
|
||||
const uint32_t* attrNormal = reinterpret_cast<const uint32_t*>(vertex + mOffsets[VATTR_NORMAL]);
|
||||
const uint32_t* attrNormal2 = reinterpret_cast<const uint32_t*>(vertex + mOffsets[VATTR_NORMAL2]);
|
||||
|
||||
thread->mainVertexShader.aPosition = { attrVertex[0], attrVertex[1], attrVertex[2], 1.0f };
|
||||
thread->mainVertexShader.aTexCoord = { attrTexcoord[0], attrTexcoord[1] };
|
||||
|
||||
if (UseVertexData)
|
||||
{
|
||||
uint32_t r = attrColor[0];
|
||||
uint32_t g = attrColor[1];
|
||||
uint32_t b = attrColor[2];
|
||||
uint32_t a = attrColor[3];
|
||||
thread->mainVertexShader.aColor = MAKEARGB(a, r, g, b);
|
||||
}
|
||||
else
|
||||
if ((UseVertexData & 1) == 0)
|
||||
{
|
||||
const auto &c = thread->mainVertexShader.Data.uVertexColor;
|
||||
thread->mainVertexShader.aColor = MAKEARGB(
|
||||
|
@ -111,6 +105,34 @@ void PolyVertexInputAssembly::Load(PolyTriangleThreadData *thread, const void *v
|
|||
static_cast<uint32_t>(c.Z * 255.0f + 0.5f)
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t r = attrColor[0];
|
||||
uint32_t g = attrColor[1];
|
||||
uint32_t b = attrColor[2];
|
||||
uint32_t a = attrColor[3];
|
||||
thread->mainVertexShader.aColor = MAKEARGB(a, r, g, b);
|
||||
}
|
||||
|
||||
if ((UseVertexData & 2) == 0)
|
||||
{
|
||||
const auto &n = thread->mainVertexShader.Data.uVertexNormal;
|
||||
thread->mainVertexShader.aNormal = Vec4f(n.X, n.Y, n.Z, 1.0);
|
||||
thread->mainVertexShader.aNormal2 = thread->mainVertexShader.aNormal;
|
||||
}
|
||||
else
|
||||
{
|
||||
int n = *attrNormal;
|
||||
int n2 = *attrNormal2;
|
||||
float x = ((n << 22) >> 22) / 512.0f;
|
||||
float y = ((n << 12) >> 22) / 512.0f;
|
||||
float z = ((n << 2) >> 22) / 512.0f;
|
||||
float x2 = ((n2 << 22) >> 22) / 512.0f;
|
||||
float y2 = ((n2 << 12) >> 22) / 512.0f;
|
||||
float z2 = ((n2 << 2) >> 22) / 512.0f;
|
||||
thread->mainVertexShader.aNormal = Vec4f(x, y, z, 0.0f);
|
||||
thread->mainVertexShader.aNormal2 = Vec4f(x2, y2, z2, 0.0f);
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -100,6 +100,8 @@ void PolyFrameBuffer::InitializeState()
|
|||
mViewpoints = new HWViewpointBuffer;
|
||||
mLights = new FLightBuffer();
|
||||
|
||||
PolyTriangleDrawer::SetLightBuffer(GetDrawCommands(), mLightBuffer->Memory());
|
||||
|
||||
CheckCanvas();
|
||||
}
|
||||
|
||||
|
@ -485,7 +487,10 @@ IIndexBuffer *PolyFrameBuffer::CreateIndexBuffer()
|
|||
|
||||
IDataBuffer *PolyFrameBuffer::CreateDataBuffer(int bindingpoint, bool ssbo, bool needsresize)
|
||||
{
|
||||
return new PolyDataBuffer(bindingpoint, ssbo, needsresize);
|
||||
IDataBuffer *buffer = new PolyDataBuffer(bindingpoint, ssbo, needsresize);
|
||||
if (bindingpoint == LIGHTBUF_BINDINGPOINT)
|
||||
mLightBuffer = buffer;
|
||||
return buffer;
|
||||
}
|
||||
|
||||
void PolyFrameBuffer::SetTextureFilterMode()
|
||||
|
|
|
@ -76,6 +76,8 @@ private:
|
|||
|
||||
void CheckCanvas();
|
||||
|
||||
IDataBuffer *mLightBuffer = nullptr;
|
||||
|
||||
std::unique_ptr<PolyRenderState> mRenderState;
|
||||
std::unique_ptr<DCanvas> mCanvas;
|
||||
std::unique_ptr<PolyDepthStencil> mDepthStencil;
|
||||
|
|
|
@ -108,6 +108,11 @@ void PolyTriangleDrawer::SetIndexBuffer(const DrawerCommandQueuePtr &queue, cons
|
|||
queue->Push<PolySetIndexBufferCommand>(elements);
|
||||
}
|
||||
|
||||
void PolyTriangleDrawer::SetLightBuffer(const DrawerCommandQueuePtr& queue, const void *lights)
|
||||
{
|
||||
queue->Push<PolySetLightBufferCommand>(lights);
|
||||
}
|
||||
|
||||
void PolyTriangleDrawer::PushDrawArgs(const DrawerCommandQueuePtr &queue, const PolyDrawArgs &args)
|
||||
{
|
||||
queue->Push<PolyPushDrawArgsCommand>(args);
|
||||
|
@ -309,6 +314,42 @@ void PolyTriangleThreadData::PushStreamData(const StreamData &data, const PolyPu
|
|||
drawargs.SetLight(GetColorTable(cm), 255, mainVertexShader.Viewpoint->mGlobVis * 32.0f, true);
|
||||
}
|
||||
|
||||
int numLights = 0;
|
||||
if (constants.uLightIndex >= 0)
|
||||
{
|
||||
const FVector4 &lightRange = lights[constants.uLightIndex];
|
||||
static_assert(sizeof(FVector4) == 16, "sizeof(FVector4) is not 16 bytes");
|
||||
if (lightRange.Y > lightRange.X)
|
||||
{
|
||||
int start = constants.uLightIndex + 1;
|
||||
int modulatedStart = static_cast<int>(lightRange.X) + start;
|
||||
int modulatedEnd = static_cast<int>(lightRange.Y) + start;
|
||||
for (int i = modulatedStart; i < modulatedEnd; i += 4)
|
||||
{
|
||||
if (numLights == maxPolyLights)
|
||||
break;
|
||||
|
||||
auto &lightpos = lights[i];
|
||||
auto &lightcolor = lights[i + 1];
|
||||
//auto &lightspot1 = lights[i + 2];
|
||||
//auto &lightspot2 = lights[i + 3];
|
||||
uint32_t r = (int)clamp(lightcolor.X * 255.0f, 0.0f, 255.0f);
|
||||
uint32_t g = (int)clamp(lightcolor.Y * 255.0f, 0.0f, 255.0f);
|
||||
uint32_t b = (int)clamp(lightcolor.Z * 255.0f, 0.0f, 255.0f);
|
||||
|
||||
auto& polylight = polyLights[numLights++];
|
||||
polylight.x = lightpos.X;
|
||||
polylight.y = lightpos.Y;
|
||||
polylight.z = lightpos.Z;
|
||||
polylight.radius = 256.0f / lightpos.W;
|
||||
polylight.color = (r << 16) | (g << 8) | b;
|
||||
if (lightcolor.W < 0.0f)
|
||||
polylight.radius = -polylight.radius;
|
||||
}
|
||||
}
|
||||
}
|
||||
drawargs.SetLights(polyLights, numLights);
|
||||
|
||||
if (SpecialEffect != EFF_NONE)
|
||||
{
|
||||
// To do: need new drawers for these
|
||||
|
@ -794,6 +835,7 @@ void PolyTriangleThreadData::DrawShadedTriangle(const ShadedTriVertex *const* ve
|
|||
return;
|
||||
|
||||
drawargs.SetColor(vert[0]->vColor, 0);
|
||||
drawargs.SetNormal(FVector3(vert[0]->vWorldNormal.X, vert[0]->vWorldNormal.Y, vert[0]->vWorldNormal.Z));
|
||||
|
||||
// Cull, clip and generate additional vertices as needed
|
||||
ScreenTriVertex clippedvert[max_additional_vertices];
|
||||
|
|
|
@ -42,6 +42,7 @@ public:
|
|||
static void SetInputAssembly(const DrawerCommandQueuePtr &queue, PolyInputAssembly *input);
|
||||
static void SetVertexBuffer(const DrawerCommandQueuePtr &queue, const void *vertices);
|
||||
static void SetIndexBuffer(const DrawerCommandQueuePtr &queue, const void *elements);
|
||||
static void SetLightBuffer(const DrawerCommandQueuePtr& queue, const void *lights);
|
||||
static void SetViewpointUniforms(const DrawerCommandQueuePtr &queue, const HWViewpointUniforms *uniforms);
|
||||
static void SetDepthClamp(const DrawerCommandQueuePtr &queue, bool on);
|
||||
static void SetDepthMask(const DrawerCommandQueuePtr &queue, bool on);
|
||||
|
@ -143,6 +144,7 @@ public:
|
|||
void SetInputAssembly(PolyInputAssembly *input) { inputAssembly = input; }
|
||||
void SetVertexBuffer(const void *data) { vertices = data; }
|
||||
void SetIndexBuffer(const void *data) { elements = (const unsigned int *)data; }
|
||||
void SetLightBuffer(const void *data) { lights = (const FVector4 *)data; }
|
||||
void SetViewpointUniforms(const HWViewpointUniforms *uniforms);
|
||||
void SetDepthClamp(bool on);
|
||||
void SetDepthMask(bool on);
|
||||
|
@ -237,6 +239,10 @@ public:
|
|||
|
||||
const void *vertices = nullptr;
|
||||
const unsigned int *elements = nullptr;
|
||||
const FVector4 *lights = nullptr;
|
||||
|
||||
enum { maxPolyLights = 16 };
|
||||
PolyLight polyLights[maxPolyLights];
|
||||
|
||||
PolyMainVertexShader mainVertexShader;
|
||||
|
||||
|
@ -455,6 +461,16 @@ private:
|
|||
const void *indices;
|
||||
};
|
||||
|
||||
class PolySetLightBufferCommand : public PolyDrawerCommand
|
||||
{
|
||||
public:
|
||||
PolySetLightBufferCommand(const void *lights) : lights(lights) { }
|
||||
void Execute(DrawerThread *thread) override { PolyTriangleThreadData::Get(thread)->SetLightBuffer(lights); }
|
||||
|
||||
private:
|
||||
const void *lights;
|
||||
};
|
||||
|
||||
class PolySetInputAssemblyCommand : public PolyDrawerCommand
|
||||
{
|
||||
public:
|
||||
|
|
|
@ -17,6 +17,7 @@ public:
|
|||
Vec4f vTexCoord;
|
||||
uint32_t vColor;
|
||||
Vec4f pixelpos;
|
||||
Vec4f vWorldNormal;
|
||||
};
|
||||
|
||||
class PolyMainVertexShader : public ShadedTriVertex
|
||||
|
@ -33,7 +34,6 @@ public:
|
|||
// Output
|
||||
Vec3f glowdist;
|
||||
Vec3f gradientdist;
|
||||
Vec4f vWorldNormal;
|
||||
Vec4f vEyeNormal;
|
||||
|
||||
// Defines
|
||||
|
@ -245,6 +245,8 @@ public:
|
|||
|
||||
vColor = drawargs->Color();
|
||||
|
||||
vWorldNormal = { drawargs->Normal().X, drawargs->Normal().Y, drawargs->Normal().Z };
|
||||
|
||||
// Calculate gl_ClipDistance[i]
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue