mirror of
https://gitea.wildfiregames.com/0ad/0ad
synced 2026-06-16 05:13:58 -07:00
Removes ARB (legacy OpenGL) backend
ARB is a legacy backend which uses old assembly shaders. It makes writing shaders more complex. According to the stats https://feedback.wildfiregames.com we small amount of players with ARB. Fixes #8533
This commit is contained in:
parent
963fed0036
commit
0432b86de7
17 changed files with 742 additions and 1500 deletions
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (C) 2025 Wildfire Games.
|
||||
/* Copyright (C) 2026 Wildfire Games.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (C) 2025 Wildfire Games.
|
||||
/* Copyright (C) 2026 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
|
|
@ -222,8 +222,6 @@ bool CShaderManager::LoadTechnique(CShaderTechniquePtr& tech)
|
|||
XMBElement root = XeroFile.GetRoot();
|
||||
|
||||
PS::StaticVector<std::string_view, 3> supportedShaders;
|
||||
if (m_Device->GetBackend() == Renderer::Backend::Backend::GL_ARB)
|
||||
supportedShaders.emplace_back("arb");
|
||||
if (m_Device->GetBackend() == Renderer::Backend::Backend::GL)
|
||||
supportedShaders.emplace_back("glsl");
|
||||
if (m_Device->GetBackend() == Renderer::Backend::Backend::VULKAN)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (C) 2025 Wildfire Games.
|
||||
/* Copyright (C) 2026 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
|
|
@ -65,7 +65,6 @@ X(RENDER_DEBUG_MODE_NONE)
|
|||
X(SHADOWS_CASCADE_COUNT)
|
||||
X(USE_DESCRIPTOR_INDEXING)
|
||||
X(USE_FANCY_EFFECTS)
|
||||
X(USE_FP_SHADOW)
|
||||
X(USE_GPU_INSTANCING)
|
||||
X(USE_INSTANCING)
|
||||
X(USE_NORMALS)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (C) 2025 Wildfire Games.
|
||||
/* Copyright (C) 2026 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
|
|
@ -89,9 +89,6 @@ Renderer::Backend::Backend GetFallbackBackend(const Renderer::Backend::Backend b
|
|||
switch (backend)
|
||||
{
|
||||
case Renderer::Backend::Backend::GL:
|
||||
fallback = Renderer::Backend::Backend::GL_ARB;
|
||||
break;
|
||||
case Renderer::Backend::Backend::GL_ARB:
|
||||
fallback = Renderer::Backend::Backend::DUMMY;
|
||||
break;
|
||||
case Renderer::Backend::Backend::DUMMY:
|
||||
|
|
@ -111,9 +108,6 @@ std::string_view GetBackendName(const Renderer::Backend::Backend backend)
|
|||
case Renderer::Backend::Backend::GL:
|
||||
name = "GL";
|
||||
break;
|
||||
case Renderer::Backend::Backend::GL_ARB:
|
||||
name = "GL ARB";
|
||||
break;
|
||||
case Renderer::Backend::Backend::DUMMY:
|
||||
name = "Dummy";
|
||||
break;
|
||||
|
|
@ -306,9 +300,7 @@ void CVideoMode::ReadConfig()
|
|||
m_ConfigVSync = g_ConfigDB.Get("vsync", m_ConfigVSync);
|
||||
|
||||
const std::string rendererBackend{g_ConfigDB.Get("rendererbackend", std::string{})};
|
||||
if (rendererBackend == "glarb")
|
||||
m_Backend = Renderer::Backend::Backend::GL_ARB;
|
||||
else if (rendererBackend == "dummy")
|
||||
if (rendererBackend == "dummy")
|
||||
m_Backend = Renderer::Backend::Backend::DUMMY;
|
||||
else if (rendererBackend == "vulkan")
|
||||
m_Backend = Renderer::Backend::Backend::VULKAN;
|
||||
|
|
@ -334,9 +326,7 @@ bool CVideoMode::SetVideoMode(int w, int h, int bpp, bool fullscreen)
|
|||
|
||||
if (!m_Window)
|
||||
{
|
||||
const bool isGLBackend =
|
||||
m_Backend == Renderer::Backend::Backend::GL ||
|
||||
m_Backend == Renderer::Backend::Backend::GL_ARB;
|
||||
const bool isGLBackend{m_Backend == Renderer::Backend::Backend::GL};
|
||||
if (isGLBackend)
|
||||
{
|
||||
SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, 1);
|
||||
|
|
@ -595,7 +585,7 @@ bool CVideoMode::InitSDL()
|
|||
// Calling SDL_Quit twice appears to be harmless, though, and avoids the problem
|
||||
// by destroying the context *before* the driver's atexit hook is called.
|
||||
// (Note that atexit hooks are guaranteed to be called in reverse order of their registration.)
|
||||
if (m_Backend == Renderer::Backend::Backend::GL || m_Backend == Renderer::Backend::Backend::GL_ARB)
|
||||
if (m_Backend == Renderer::Backend::Backend::GL)
|
||||
atexit(SDL_Quit);
|
||||
// End work around.
|
||||
|
||||
|
|
@ -660,10 +650,7 @@ bool CVideoMode::TryCreateBackendDevice(SDL_Window* window)
|
|||
switch (m_Backend)
|
||||
{
|
||||
case Renderer::Backend::Backend::GL:
|
||||
m_BackendDevice = Renderer::Backend::GL::CreateDevice(window, false);
|
||||
break;
|
||||
case Renderer::Backend::Backend::GL_ARB:
|
||||
m_BackendDevice = Renderer::Backend::GL::CreateDevice(window, true);
|
||||
m_BackendDevice = Renderer::Backend::GL::CreateDevice(window);
|
||||
break;
|
||||
case Renderer::Backend::Backend::DUMMY:
|
||||
m_BackendDevice = Renderer::Backend::Dummy::CreateDevice(window);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (C) 2025 Wildfire Games.
|
||||
/* Copyright (C) 2026 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
|
|
@ -59,11 +59,11 @@ struct IModelDef : public CModelDefRPrivate
|
|||
/// Indices are the same for all models, so share them
|
||||
VertexIndexArray m_IndexArray;
|
||||
|
||||
IModelDef(const CModelDefPtr& mdef, bool calculateTangents);
|
||||
IModelDef(const CModelDefPtr& mdef);
|
||||
};
|
||||
|
||||
|
||||
IModelDef::IModelDef(const CModelDefPtr& mdef, bool calculateTangents)
|
||||
IModelDef::IModelDef(const CModelDefPtr& mdef)
|
||||
: m_IndexArray(Renderer::Backend::IBuffer::Usage::TRANSFER_DST),
|
||||
m_Array(Renderer::Backend::IBuffer::Type::VERTEX, Renderer::Backend::IBuffer::Usage::TRANSFER_DST)
|
||||
{
|
||||
|
|
@ -82,116 +82,86 @@ IModelDef::IModelDef(const CModelDefPtr& mdef, bool calculateTangents)
|
|||
m_Array.AddAttribute(&m_UVs[i]);
|
||||
}
|
||||
|
||||
if (calculateTangents)
|
||||
// Generate tangents for the geometry:-
|
||||
|
||||
m_Tangent.format = Renderer::Backend::Format::R32G32B32A32_SFLOAT;
|
||||
m_Array.AddAttribute(&m_Tangent);
|
||||
|
||||
// floats per vertex; position + normal + tangent + UV*sets
|
||||
int numVertexAttrs = 3 + 3 + 4 + 2 * mdef->GetNumUVsPerVertex();
|
||||
|
||||
// the tangent generation can increase the number of vertices temporarily
|
||||
// so reserve a bit more memory to avoid reallocations in GenTangents (in most cases)
|
||||
std::vector<float> newVertices;
|
||||
newVertices.reserve(numVertexAttrs * numVertices * 2);
|
||||
|
||||
// Generate the tangents
|
||||
ModelRenderer::GenTangents(mdef, newVertices, false);
|
||||
|
||||
// how many vertices do we have after generating tangents?
|
||||
int newNumVert = newVertices.size() / numVertexAttrs;
|
||||
|
||||
std::vector<int> remapTable(newNumVert);
|
||||
std::vector<float> vertexDataOut(newNumVert * numVertexAttrs);
|
||||
|
||||
// re-weld the mesh to remove duplicated vertices
|
||||
int numVertices2 = WeldMesh(&remapTable[0], &vertexDataOut[0],
|
||||
&newVertices[0], newNumVert, numVertexAttrs);
|
||||
|
||||
// Copy the model data to graphics memory:-
|
||||
|
||||
m_Array.SetNumberOfVertices(numVertices2);
|
||||
m_Array.Layout();
|
||||
|
||||
VertexArrayIterator<CVector3D> Position = m_Position.GetIterator<CVector3D>();
|
||||
VertexArrayIterator<CVector3D> Normal = m_Normal.GetIterator<CVector3D>();
|
||||
VertexArrayIterator<CVector4D> Tangent = m_Tangent.GetIterator<CVector4D>();
|
||||
|
||||
// copy everything into the vertex array
|
||||
for (int i = 0; i < numVertices2; i++)
|
||||
{
|
||||
// Generate tangents for the geometry:-
|
||||
int q = numVertexAttrs * i;
|
||||
|
||||
m_Tangent.format = Renderer::Backend::Format::R32G32B32A32_SFLOAT;
|
||||
m_Array.AddAttribute(&m_Tangent);
|
||||
Position[i] = CVector3D(vertexDataOut[q + 0], vertexDataOut[q + 1], vertexDataOut[q + 2]);
|
||||
q += 3;
|
||||
|
||||
// floats per vertex; position + normal + tangent + UV*sets
|
||||
int numVertexAttrs = 3 + 3 + 4 + 2 * mdef->GetNumUVsPerVertex();
|
||||
Normal[i] = CVector3D(vertexDataOut[q + 0], vertexDataOut[q + 1], vertexDataOut[q + 2]);
|
||||
q += 3;
|
||||
|
||||
// the tangent generation can increase the number of vertices temporarily
|
||||
// so reserve a bit more memory to avoid reallocations in GenTangents (in most cases)
|
||||
std::vector<float> newVertices;
|
||||
newVertices.reserve(numVertexAttrs * numVertices * 2);
|
||||
Tangent[i] = CVector4D(vertexDataOut[q + 0], vertexDataOut[q + 1], vertexDataOut[q + 2],
|
||||
vertexDataOut[q + 3]);
|
||||
q += 4;
|
||||
|
||||
// Generate the tangents
|
||||
ModelRenderer::GenTangents(mdef, newVertices, false);
|
||||
|
||||
// how many vertices do we have after generating tangents?
|
||||
int newNumVert = newVertices.size() / numVertexAttrs;
|
||||
|
||||
std::vector<int> remapTable(newNumVert);
|
||||
std::vector<float> vertexDataOut(newNumVert * numVertexAttrs);
|
||||
|
||||
// re-weld the mesh to remove duplicated vertices
|
||||
int numVertices2 = WeldMesh(&remapTable[0], &vertexDataOut[0],
|
||||
&newVertices[0], newNumVert, numVertexAttrs);
|
||||
|
||||
// Copy the model data to graphics memory:-
|
||||
|
||||
m_Array.SetNumberOfVertices(numVertices2);
|
||||
m_Array.Layout();
|
||||
|
||||
VertexArrayIterator<CVector3D> Position = m_Position.GetIterator<CVector3D>();
|
||||
VertexArrayIterator<CVector3D> Normal = m_Normal.GetIterator<CVector3D>();
|
||||
VertexArrayIterator<CVector4D> Tangent = m_Tangent.GetIterator<CVector4D>();
|
||||
|
||||
// copy everything into the vertex array
|
||||
for (int i = 0; i < numVertices2; i++)
|
||||
for (size_t j = 0; j < mdef->GetNumUVsPerVertex(); j++)
|
||||
{
|
||||
int q = numVertexAttrs * i;
|
||||
|
||||
Position[i] = CVector3D(vertexDataOut[q + 0], vertexDataOut[q + 1], vertexDataOut[q + 2]);
|
||||
q += 3;
|
||||
|
||||
Normal[i] = CVector3D(vertexDataOut[q + 0], vertexDataOut[q + 1], vertexDataOut[q + 2]);
|
||||
q += 3;
|
||||
|
||||
Tangent[i] = CVector4D(vertexDataOut[q + 0], vertexDataOut[q + 1], vertexDataOut[q + 2],
|
||||
vertexDataOut[q + 3]);
|
||||
q += 4;
|
||||
|
||||
for (size_t j = 0; j < mdef->GetNumUVsPerVertex(); j++)
|
||||
{
|
||||
VertexArrayIterator<float[2]> UVit = m_UVs[j].GetIterator<float[2]>();
|
||||
UVit[i][0] = vertexDataOut[q + 0 + 2 * j];
|
||||
UVit[i][1] = vertexDataOut[q + 1 + 2 * j];
|
||||
}
|
||||
VertexArrayIterator<float[2]> UVit = m_UVs[j].GetIterator<float[2]>();
|
||||
UVit[i][0] = vertexDataOut[q + 0 + 2 * j];
|
||||
UVit[i][1] = vertexDataOut[q + 1 + 2 * j];
|
||||
}
|
||||
|
||||
// upload vertex data
|
||||
m_Array.Upload();
|
||||
m_Array.FreeBackingStore();
|
||||
|
||||
m_IndexArray.SetNumberOfVertices(mdef->GetNumFaces() * 3);
|
||||
m_IndexArray.Layout();
|
||||
|
||||
VertexArrayIterator<u16> Indices = m_IndexArray.GetIterator();
|
||||
|
||||
size_t idxidx = 0;
|
||||
|
||||
// reindex geometry and upload index
|
||||
for (size_t j = 0; j < mdef->GetNumFaces(); ++j)
|
||||
{
|
||||
Indices[idxidx++] = remapTable[j * 3 + 0];
|
||||
Indices[idxidx++] = remapTable[j * 3 + 1];
|
||||
Indices[idxidx++] = remapTable[j * 3 + 2];
|
||||
}
|
||||
|
||||
m_IndexArray.Upload();
|
||||
m_IndexArray.FreeBackingStore();
|
||||
}
|
||||
else
|
||||
|
||||
// upload vertex data
|
||||
m_Array.Upload();
|
||||
m_Array.FreeBackingStore();
|
||||
|
||||
m_IndexArray.SetNumberOfVertices(mdef->GetNumFaces() * 3);
|
||||
m_IndexArray.Layout();
|
||||
|
||||
VertexArrayIterator<u16> Indices = m_IndexArray.GetIterator();
|
||||
|
||||
size_t idxidx = 0;
|
||||
|
||||
// reindex geometry and upload index
|
||||
for (size_t j = 0; j < mdef->GetNumFaces(); ++j)
|
||||
{
|
||||
// Upload model without calculating tangents:-
|
||||
|
||||
m_Array.SetNumberOfVertices(numVertices);
|
||||
m_Array.Layout();
|
||||
|
||||
VertexArrayIterator<CVector3D> Position = m_Position.GetIterator<CVector3D>();
|
||||
VertexArrayIterator<CVector3D> Normal = m_Normal.GetIterator<CVector3D>();
|
||||
|
||||
ModelRenderer::CopyPositionAndNormals(mdef, Position, Normal);
|
||||
|
||||
for (size_t i = 0; i < mdef->GetNumUVsPerVertex(); i++)
|
||||
{
|
||||
VertexArrayIterator<float[2]> UVit = m_UVs[i].GetIterator<float[2]>();
|
||||
ModelRenderer::BuildUV(mdef, UVit, i);
|
||||
}
|
||||
|
||||
m_Array.Upload();
|
||||
m_Array.FreeBackingStore();
|
||||
|
||||
m_IndexArray.SetNumberOfVertices(mdef->GetNumFaces()*3);
|
||||
m_IndexArray.Layout();
|
||||
ModelRenderer::BuildIndices(mdef, m_IndexArray.GetIterator());
|
||||
m_IndexArray.Upload();
|
||||
m_IndexArray.FreeBackingStore();
|
||||
Indices[idxidx++] = remapTable[j * 3 + 0];
|
||||
Indices[idxidx++] = remapTable[j * 3 + 1];
|
||||
Indices[idxidx++] = remapTable[j * 3 + 2];
|
||||
}
|
||||
|
||||
m_IndexArray.Upload();
|
||||
m_IndexArray.FreeBackingStore();
|
||||
|
||||
const uint32_t stride = m_Array.GetStride();
|
||||
constexpr size_t MAX_UV = 2;
|
||||
|
||||
|
|
@ -214,31 +184,25 @@ IModelDef::IModelDef(const CModelDefPtr& mdef, bool calculateTangents)
|
|||
Renderer::Backend::VertexAttributeRate::PER_VERTEX, 0});
|
||||
}
|
||||
|
||||
if (calculateTangents)
|
||||
{
|
||||
attributes.push_back({
|
||||
Renderer::Backend::VertexAttributeStream::UV2,
|
||||
m_Tangent.format, m_Tangent.offset, stride,
|
||||
Renderer::Backend::VertexAttributeRate::PER_VERTEX, 0});
|
||||
}
|
||||
attributes.push_back({
|
||||
Renderer::Backend::VertexAttributeStream::UV2,
|
||||
m_Tangent.format, m_Tangent.offset, stride,
|
||||
Renderer::Backend::VertexAttributeRate::PER_VERTEX, 0});
|
||||
|
||||
m_VertexInputLayout = g_Renderer.GetVertexInputLayout({attributes.begin(), attributes.end()});
|
||||
}
|
||||
|
||||
struct InstancingModelRendererInternals
|
||||
{
|
||||
bool calculateTangents;
|
||||
|
||||
/// Previously prepared modeldef
|
||||
IModelDef* imodeldef;
|
||||
};
|
||||
|
||||
|
||||
// Construction and Destruction
|
||||
InstancingModelRenderer::InstancingModelRenderer(bool calculateTangents)
|
||||
InstancingModelRenderer::InstancingModelRenderer()
|
||||
{
|
||||
m = new InstancingModelRendererInternals;
|
||||
m->calculateTangents = calculateTangents;
|
||||
m->imodeldef = 0;
|
||||
}
|
||||
|
||||
|
|
@ -258,7 +222,7 @@ CModelRData* InstancingModelRenderer::CreateModelData(const void* key, CModel* m
|
|||
|
||||
if (!imodeldef)
|
||||
{
|
||||
imodeldef = new IModelDef(mdef, m->calculateTangents);
|
||||
imodeldef = new IModelDef(mdef);
|
||||
mdef->SetRenderData(m, imodeldef);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (C) 2025 Wildfire Games.
|
||||
/* Copyright (C) 2026 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
|
|
@ -37,7 +37,7 @@ struct InstancingModelRendererInternals;
|
|||
class InstancingModelRenderer : public ModelVertexRenderer
|
||||
{
|
||||
public:
|
||||
InstancingModelRenderer(bool calculateTangents);
|
||||
InstancingModelRenderer();
|
||||
~InstancingModelRenderer();
|
||||
|
||||
// Implementations
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (C) 2025 Wildfire Games.
|
||||
/* Copyright (C) 2026 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
|
|
@ -115,9 +115,7 @@ bool CPostprocManager::IsEnabled() const
|
|||
Renderer::Backend::ITexture::Usage::DEPTH_STENCIL_ATTACHMENT, true, true)
|
||||
!= Renderer::Backend::Format::UNDEFINED;
|
||||
return
|
||||
g_RenderingOptions.GetPostProc() &&
|
||||
m_Device->GetBackend() != Renderer::Backend::Backend::GL_ARB &&
|
||||
isDepthStencilFormatPresent;
|
||||
g_RenderingOptions.GetPostProc() && isDepthStencilFormatPresent;
|
||||
}
|
||||
|
||||
void CPostprocManager::Cleanup()
|
||||
|
|
@ -701,10 +699,9 @@ void CPostprocManager::ApplyPostproc(
|
|||
ENSURE(m_IsInitialized);
|
||||
|
||||
// Don't do anything if we are using the default effect and no AA.
|
||||
const bool hasEffects = m_PostProcEffect != L"default";
|
||||
const bool hasARB = m_Device->GetBackend() == Renderer::Backend::Backend::GL_ARB;
|
||||
const bool hasAA = m_AATech && !hasARB;
|
||||
const bool hasSharp = m_SharpTech && !hasARB;
|
||||
const bool hasEffects{m_PostProcEffect != L"default"};
|
||||
const bool hasAA{m_AATech};
|
||||
const bool hasSharp{m_SharpTech};
|
||||
if (!hasEffects && !hasAA && !hasSharp)
|
||||
return;
|
||||
|
||||
|
|
@ -773,7 +770,7 @@ void CPostprocManager::SetPostEffect(const CStrW& name)
|
|||
|
||||
void CPostprocManager::UpdateAntiAliasingTechnique()
|
||||
{
|
||||
if (m_Device->GetBackend() == Renderer::Backend::Backend::GL_ARB || !m_IsInitialized)
|
||||
if (!m_IsInitialized)
|
||||
return;
|
||||
|
||||
const std::string newAAName{g_ConfigDB.Get("antialiasing", std::string{})};
|
||||
|
|
@ -822,7 +819,7 @@ void CPostprocManager::UpdateAntiAliasingTechnique()
|
|||
|
||||
void CPostprocManager::UpdateSharpeningTechnique()
|
||||
{
|
||||
if (m_Device->GetBackend() == Renderer::Backend::Backend::GL_ARB || !m_IsInitialized)
|
||||
if (!m_IsInitialized)
|
||||
return;
|
||||
|
||||
const std::string newSharpName{g_ConfigDB.Get("sharpening", std::string{})};
|
||||
|
|
@ -943,11 +940,6 @@ void CPostprocManager::ResolveMultisampleFramebuffer(
|
|||
|
||||
void CPostprocManager::RecalculateSize(const uint32_t width, const uint32_t height)
|
||||
{
|
||||
if (m_Device->GetBackend() == Renderer::Backend::Backend::GL_ARB)
|
||||
{
|
||||
m_Scale = 1.0f;
|
||||
return;
|
||||
}
|
||||
m_Scale = g_ConfigDB.Get("renderer.scale", m_Scale);
|
||||
if (m_Scale < 0.25f || m_Scale > 2.0f)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (C) 2025 Wildfire Games.
|
||||
/* Copyright (C) 2026 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
|
|
@ -42,7 +42,7 @@ enum RenderPath
|
|||
// Classic fixed function.
|
||||
FIXED,
|
||||
|
||||
// Use new ARB/GLSL system
|
||||
// Use new GLSL system
|
||||
SHADER
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -214,15 +214,13 @@ CSceneRenderer::~CSceneRenderer()
|
|||
m.reset();
|
||||
}
|
||||
|
||||
void CSceneRenderer::ReloadShaders(Renderer::Backend::IDevice* device)
|
||||
void CSceneRenderer::ReloadShaders([[maybe_unused]] Renderer::Backend::IDevice* device)
|
||||
{
|
||||
m->globalContext = CShaderDefines();
|
||||
|
||||
if (g_RenderingOptions.GetShadows())
|
||||
{
|
||||
m->globalContext.Add(str_USE_SHADOW, str_1);
|
||||
if (device->GetBackend() == Renderer::Backend::Backend::GL_ARB)
|
||||
m->globalContext.Add(str_USE_FP_SHADOW, str_1);
|
||||
if (g_RenderingOptions.GetShadowPCF())
|
||||
m->globalContext.Add(str_USE_SHADOW_PCF, str_1);
|
||||
const int cascadeCount = m->shadow.GetCascadeCount();
|
||||
|
|
@ -245,7 +243,7 @@ void CSceneRenderer::ReloadShaders(Renderer::Backend::IDevice* device)
|
|||
|
||||
ENSURE(g_RenderingOptions.GetRenderPath() != RenderPath::FIXED);
|
||||
m->Model.VertexRendererShader = ModelVertexRendererPtr(new CPUSkinnedModelVertexRenderer());
|
||||
m->Model.VertexInstancingShader = ModelVertexRendererPtr(new InstancingModelRenderer(device->GetBackend() != Renderer::Backend::Backend::GL_ARB));
|
||||
m->Model.VertexInstancingShader = ModelVertexRendererPtr(new InstancingModelRenderer());
|
||||
|
||||
if (g_RenderingOptions.GetGPUSkinning())
|
||||
{
|
||||
|
|
|
|||
|
|
@ -139,7 +139,7 @@ void ShadowMapInternals::UpdateCascadesParameters()
|
|||
{
|
||||
CascadeCount = g_ConfigDB.Get("shadowscascadecount", 1);
|
||||
|
||||
if (CascadeCount < 1 || CascadeCount > MAX_CASCADE_COUNT || Device->GetBackend() == Renderer::Backend::Backend::GL_ARB)
|
||||
if (CascadeCount < 1 || CascadeCount > MAX_CASCADE_COUNT)
|
||||
CascadeCount = 1;
|
||||
|
||||
ShadowsCoverMap = g_ConfigDB.Get("shadowscovermap", false);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (C) 2025 Wildfire Games.
|
||||
/* Copyright (C) 2026 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
|
|
@ -1165,9 +1165,7 @@ void WaterManager::UpdateQuality()
|
|||
|
||||
bool WaterManager::WillRenderFancyWater() const
|
||||
{
|
||||
return
|
||||
m_RenderWater && m_Device->GetBackend() != Renderer::Backend::Backend::GL_ARB &&
|
||||
g_RenderingOptions.GetWaterEffects();
|
||||
return m_RenderWater && g_RenderingOptions.GetWaterEffects();
|
||||
}
|
||||
|
||||
size_t WaterManager::GetCurrentTextureIndex(const double& period) const
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (C) 2022 Wildfire Games.
|
||||
/* Copyright (C) 2026 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
|
|
@ -27,7 +27,6 @@ namespace Backend
|
|||
enum class Backend
|
||||
{
|
||||
GL,
|
||||
GL_ARB,
|
||||
VULKAN,
|
||||
DUMMY
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (C) 2025 Wildfire Games.
|
||||
/* Copyright (C) 2026 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
|
|
@ -225,7 +225,7 @@ void GLAD_API_PTR OnDebugMessage(
|
|||
} // anonymous namespace
|
||||
|
||||
// static
|
||||
std::unique_ptr<IDevice> CDevice::Create(SDL_Window* window, const bool arb)
|
||||
std::unique_ptr<IDevice> CDevice::Create(SDL_Window* window)
|
||||
{
|
||||
std::unique_ptr<CDevice> device(new CDevice());
|
||||
|
||||
|
|
@ -320,17 +320,8 @@ std::unique_ptr<IDevice> CDevice::Create(SDL_Window* window, const bool arb)
|
|||
#endif
|
||||
}
|
||||
|
||||
// If we don't have GL2.0 then we don't have GLSL in core.
|
||||
if (!arb && !ogl_HaveVersion(2, 0))
|
||||
return nullptr;
|
||||
|
||||
// We can't render without ARB shaders.
|
||||
if (arb && ogl_HaveExtensions(0, "GL_ARB_vertex_program", "GL_ARB_fragment_program", nullptr))
|
||||
return nullptr;
|
||||
|
||||
if ((ogl_HaveExtensions(0, "GL_ARB_vertex_program", "GL_ARB_fragment_program", nullptr) // ARB
|
||||
&& !ogl_HaveVersion(2, 0)) // GLSL
|
||||
|| !ogl_HaveExtension("GL_ARB_vertex_buffer_object") // VBO
|
||||
if (!ogl_HaveVersion(2, 0)
|
||||
|| !ogl_HaveExtension("GL_ARB_vertex_buffer_object")
|
||||
|| ogl_HaveExtensions(0, "GL_ARB_multitexture", "GL_EXT_draw_range_elements", nullptr)
|
||||
|| (!ogl_HaveExtension("GL_EXT_framebuffer_object") && !ogl_HaveExtension("GL_ARB_framebuffer_object")))
|
||||
{
|
||||
|
|
@ -344,8 +335,6 @@ std::unique_ptr<IDevice> CDevice::Create(SDL_Window* window, const bool arb)
|
|||
);
|
||||
}
|
||||
|
||||
device->m_ARB = arb;
|
||||
|
||||
device->m_Name = GetNameImpl();
|
||||
device->m_Version = GetVersionImpl();
|
||||
device->m_DriverInformation = GetDriverInformationImpl();
|
||||
|
|
@ -360,26 +349,18 @@ std::unique_ptr<IDevice> CDevice::Create(SDL_Window* window, const bool arb)
|
|||
// still support pre 2.0 drivers pretending to support 2.0.
|
||||
ogl_SquelchError(GL_INVALID_ENUM);
|
||||
|
||||
if (arb)
|
||||
{
|
||||
#if !CONFIG2_GLES
|
||||
glEnable(GL_VERTEX_PROGRAM_ARB);
|
||||
glEnable(GL_FRAGMENT_PROGRAM_ARB);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Some drivers might invalidate an incorrect surface which leads to artifacts.
|
||||
if (g_ConfigDB.Get("renderer.backend.gl.enableframebufferinvalidating", false))
|
||||
{
|
||||
#if CONFIG2_GLES
|
||||
device->m_UseFramebufferInvalidating = ogl_HaveExtension("GL_EXT_discard_framebuffer");
|
||||
#else
|
||||
device->m_UseFramebufferInvalidating = !arb && ogl_HaveExtension("GL_ARB_invalidate_subdata");
|
||||
device->m_UseFramebufferInvalidating = ogl_HaveExtension("GL_ARB_invalidate_subdata");
|
||||
#endif
|
||||
}
|
||||
|
||||
Capabilities& capabilities = device->m_Capabilities;
|
||||
capabilities.computeShaders = !device->m_ARB && ogl_HaveVersion(4, 3);
|
||||
capabilities.computeShaders = ogl_HaveVersion(4, 3);
|
||||
#if CONFIG2_GLES
|
||||
// Some GLES implementations have GL_EXT_texture_compression_dxt1
|
||||
// but that only supports DXT1 so we can't use it.
|
||||
|
|
@ -459,7 +440,6 @@ std::unique_ptr<IDevice> CDevice::Create(SDL_Window* window, const bool arb)
|
|||
capabilities.timestamps = false;
|
||||
#else
|
||||
capabilities.instancing =
|
||||
!device->m_ARB &&
|
||||
(ogl_HaveVersion(3, 3) ||
|
||||
(ogl_HaveExtension("GL_ARB_draw_instanced") &&
|
||||
ogl_HaveExtension("GL_ARB_instanced_arrays")));
|
||||
|
|
@ -480,7 +460,7 @@ std::unique_ptr<IDevice> CDevice::Create(SDL_Window* window, const bool arb)
|
|||
&& ogl_HaveExtension("GL_ARB_shader_storage_buffer_object")
|
||||
&& ogl_HaveExtension("GL_ARB_half_float_vertex")
|
||||
&& ogl_HaveExtension("GL_ARB_program_interface_query");
|
||||
capabilities.timestamps = !device->m_ARB && ogl_HaveExtension("GL_ARB_timer_query");
|
||||
capabilities.timestamps = ogl_HaveExtension("GL_ARB_timer_query");
|
||||
if (capabilities.timestamps)
|
||||
capabilities.timestampMultiplier = 1.0 / 1e9;
|
||||
#endif
|
||||
|
|
@ -509,7 +489,7 @@ void CDevice::Report(const ScriptRequest& rq, JS::HandleValue settings)
|
|||
{
|
||||
const char* errstr = "(error)";
|
||||
|
||||
Script::SetProperty(rq, settings, "name", m_ARB ? "glarb" : "gl");
|
||||
Script::SetProperty(rq, settings, "name", "gl");
|
||||
|
||||
#define INTEGER(id) do { \
|
||||
GLint i = -1; \
|
||||
|
|
@ -569,24 +549,6 @@ void CDevice::Report(const ScriptRequest& rq, JS::HandleValue settings)
|
|||
Script::SetProperty(rq, settings, "GL_" #target ".GL_" #pname, i); \
|
||||
} while (false)
|
||||
|
||||
#define VERTEXPROGRAM(id) do { \
|
||||
GLint i = -1; \
|
||||
glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_##id, &i); \
|
||||
if (ogl_SquelchError(GL_INVALID_ENUM)) \
|
||||
Script::SetProperty(rq, settings, "GL_VERTEX_PROGRAM_ARB.GL_" #id, errstr); \
|
||||
else \
|
||||
Script::SetProperty(rq, settings, "GL_VERTEX_PROGRAM_ARB.GL_" #id, i); \
|
||||
} while (false)
|
||||
|
||||
#define FRAGMENTPROGRAM(id) do { \
|
||||
GLint i = -1; \
|
||||
glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_##id, &i); \
|
||||
if (ogl_SquelchError(GL_INVALID_ENUM)) \
|
||||
Script::SetProperty(rq, settings, "GL_FRAGMENT_PROGRAM_ARB.GL_" #id, errstr); \
|
||||
else \
|
||||
Script::SetProperty(rq, settings, "GL_FRAGMENT_PROGRAM_ARB.GL_" #id, i); \
|
||||
} while (false)
|
||||
|
||||
#define BOOL(id) INTEGER(id)
|
||||
|
||||
ogl_WarnIfError();
|
||||
|
|
@ -728,75 +690,6 @@ void CDevice::Report(const ScriptRequest& rq, JS::HandleValue settings)
|
|||
INTEGER(MAX_RECTANGLE_TEXTURE_SIZE_ARB);
|
||||
}
|
||||
|
||||
if (m_ARB)
|
||||
{
|
||||
if (ogl_HaveExtension("GL_ARB_vertex_program") || ogl_HaveExtension("GL_ARB_fragment_program"))
|
||||
{
|
||||
INTEGER(MAX_PROGRAM_MATRICES_ARB);
|
||||
INTEGER(MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB);
|
||||
}
|
||||
|
||||
if (ogl_HaveExtension("GL_ARB_vertex_program"))
|
||||
{
|
||||
VERTEXPROGRAM(MAX_PROGRAM_ENV_PARAMETERS_ARB);
|
||||
VERTEXPROGRAM(MAX_PROGRAM_LOCAL_PARAMETERS_ARB);
|
||||
VERTEXPROGRAM(MAX_PROGRAM_INSTRUCTIONS_ARB);
|
||||
VERTEXPROGRAM(MAX_PROGRAM_TEMPORARIES_ARB);
|
||||
VERTEXPROGRAM(MAX_PROGRAM_PARAMETERS_ARB);
|
||||
VERTEXPROGRAM(MAX_PROGRAM_ATTRIBS_ARB);
|
||||
VERTEXPROGRAM(MAX_PROGRAM_ADDRESS_REGISTERS_ARB);
|
||||
VERTEXPROGRAM(MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB);
|
||||
VERTEXPROGRAM(MAX_PROGRAM_NATIVE_TEMPORARIES_ARB);
|
||||
VERTEXPROGRAM(MAX_PROGRAM_NATIVE_PARAMETERS_ARB);
|
||||
VERTEXPROGRAM(MAX_PROGRAM_NATIVE_ATTRIBS_ARB);
|
||||
VERTEXPROGRAM(MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB);
|
||||
|
||||
if (ogl_HaveExtension("GL_ARB_fragment_program"))
|
||||
{
|
||||
// The spec seems to say these should be supported, but
|
||||
// Mesa complains about them so let's not bother
|
||||
/*
|
||||
VERTEXPROGRAM(MAX_PROGRAM_ALU_INSTRUCTIONS_ARB);
|
||||
VERTEXPROGRAM(MAX_PROGRAM_TEX_INSTRUCTIONS_ARB);
|
||||
VERTEXPROGRAM(MAX_PROGRAM_TEX_INDIRECTIONS_ARB);
|
||||
VERTEXPROGRAM(MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB);
|
||||
VERTEXPROGRAM(MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB);
|
||||
VERTEXPROGRAM(MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB);
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
if (ogl_HaveExtension("GL_ARB_fragment_program"))
|
||||
{
|
||||
FRAGMENTPROGRAM(MAX_PROGRAM_ENV_PARAMETERS_ARB);
|
||||
FRAGMENTPROGRAM(MAX_PROGRAM_LOCAL_PARAMETERS_ARB);
|
||||
FRAGMENTPROGRAM(MAX_PROGRAM_INSTRUCTIONS_ARB);
|
||||
FRAGMENTPROGRAM(MAX_PROGRAM_ALU_INSTRUCTIONS_ARB);
|
||||
FRAGMENTPROGRAM(MAX_PROGRAM_TEX_INSTRUCTIONS_ARB);
|
||||
FRAGMENTPROGRAM(MAX_PROGRAM_TEX_INDIRECTIONS_ARB);
|
||||
FRAGMENTPROGRAM(MAX_PROGRAM_TEMPORARIES_ARB);
|
||||
FRAGMENTPROGRAM(MAX_PROGRAM_PARAMETERS_ARB);
|
||||
FRAGMENTPROGRAM(MAX_PROGRAM_ATTRIBS_ARB);
|
||||
FRAGMENTPROGRAM(MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB);
|
||||
FRAGMENTPROGRAM(MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB);
|
||||
FRAGMENTPROGRAM(MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB);
|
||||
FRAGMENTPROGRAM(MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB);
|
||||
FRAGMENTPROGRAM(MAX_PROGRAM_NATIVE_TEMPORARIES_ARB);
|
||||
FRAGMENTPROGRAM(MAX_PROGRAM_NATIVE_PARAMETERS_ARB);
|
||||
FRAGMENTPROGRAM(MAX_PROGRAM_NATIVE_ATTRIBS_ARB);
|
||||
|
||||
if (ogl_HaveExtension("GL_ARB_vertex_program"))
|
||||
{
|
||||
// The spec seems to say these should be supported, but
|
||||
// Intel drivers on Windows complain about them so let's not bother
|
||||
/*
|
||||
FRAGMENTPROGRAM(MAX_PROGRAM_ADDRESS_REGISTERS_ARB);
|
||||
FRAGMENTPROGRAM(MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB);
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ogl_HaveExtension("GL_ARB_geometry_shader4"))
|
||||
{
|
||||
INTEGER(MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_ARB);
|
||||
|
|
@ -1178,9 +1071,9 @@ void CDevice::InsertTimestampQuery(const uint32_t handle)
|
|||
#endif
|
||||
}
|
||||
|
||||
std::unique_ptr<IDevice> CreateDevice(SDL_Window* window, const bool arb)
|
||||
std::unique_ptr<IDevice> CreateDevice(SDL_Window* window)
|
||||
{
|
||||
return GL::CDevice::Create(window, arb);
|
||||
return GL::CDevice::Create(window);
|
||||
}
|
||||
|
||||
} // namespace GL
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (C) 2025 Wildfire Games.
|
||||
/* Copyright (C) 2026 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
|
|
@ -60,9 +60,9 @@ public:
|
|||
/**
|
||||
* Creates the GL device and the GL context for the window if it presents.
|
||||
*/
|
||||
static std::unique_ptr<IDevice> Create(SDL_Window* window, const bool arb);
|
||||
static std::unique_ptr<IDevice> Create(SDL_Window* window);
|
||||
|
||||
Backend GetBackend() const override { return m_ARB ? Backend::GL_ARB : Backend::GL; }
|
||||
Backend GetBackend() const override { return Backend::GL; }
|
||||
|
||||
const std::string& GetName() const override { return m_Name; }
|
||||
const std::string& GetVersion() const override { return m_Version; }
|
||||
|
|
@ -144,8 +144,6 @@ private:
|
|||
SDL_GLContext m_Context = nullptr;
|
||||
int m_SurfaceDrawableWidth = 0, m_SurfaceDrawableHeight = 0;
|
||||
|
||||
bool m_ARB = false;
|
||||
|
||||
std::string m_Name;
|
||||
std::string m_Version;
|
||||
std::string m_DriverInformation;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (C) 2022 Wildfire Games.
|
||||
/* Copyright (C) 2026 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
|
|
@ -33,7 +33,7 @@ class IDevice;
|
|||
namespace GL
|
||||
{
|
||||
|
||||
std::unique_ptr<IDevice> CreateDevice(SDL_Window* window, const bool arb);
|
||||
std::unique_ptr<IDevice> CreateDevice(SDL_Window* window);
|
||||
|
||||
} // namespace GL
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (C) 2025 Wildfire Games.
|
||||
/* Copyright (C) 2026 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
|
|
@ -21,13 +21,20 @@
|
|||
#include "lib/code_annotation.h"
|
||||
#include "lib/debug.h"
|
||||
#include "lib/ogl.h"
|
||||
#include "ps/containers/StaticVector.h"
|
||||
#include "ps/CStr.h"
|
||||
#include "ps/CStrIntern.h"
|
||||
#include "renderer/backend/Format.h"
|
||||
#include "renderer/backend/gl/Device.h"
|
||||
#include "renderer/backend/IBuffer.h"
|
||||
#include "renderer/backend/IShaderProgram.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <span>
|
||||
#include <tuple>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
class CShaderDefines;
|
||||
|
|
@ -70,19 +77,10 @@ private:
|
|||
|
||||
/**
|
||||
* A compiled vertex+fragment shader program.
|
||||
* The implementation may use GL_ARB_{vertex,fragment}_program (ARB assembly syntax)
|
||||
* or GL_ARB_{vertex,fragment}_shader (GLSL), or may use hard-coded fixed-function
|
||||
* multitexturing setup code; the difference is hidden from the caller.
|
||||
*
|
||||
* Texture/uniform IDs are typically strings, corresponding to the names defined in
|
||||
* the shader .xml file. Alternatively (and more efficiently, if used very frequently),
|
||||
* call GetBindingSlot and pass its return value as the ID.
|
||||
* Setting uniforms that the shader .xml doesn't support is harmless.
|
||||
*
|
||||
* For a high-level overview of shaders and materials, see
|
||||
* https://gitea.wildfiregames.com/0ad/0ad/wiki/MaterialSystem
|
||||
* Setting uniforms that the shader doesn't support is harmless.
|
||||
*/
|
||||
class CShaderProgram : public IShaderProgram
|
||||
class CShaderProgram final : public IShaderProgram
|
||||
{
|
||||
NONCOPYABLE(CShaderProgram);
|
||||
|
||||
|
|
@ -98,12 +96,14 @@ public:
|
|||
* Binds the shader into the GL context. Call this before calling Uniform()
|
||||
* or trying to render with it.
|
||||
*/
|
||||
virtual void Bind(CShaderProgram* previousShaderProgram) = 0;
|
||||
void Bind(CShaderProgram* previousShaderProgram);
|
||||
|
||||
/**
|
||||
* Unbinds the shader from the GL context. Call this after rendering with it.
|
||||
*/
|
||||
virtual void Unbind() = 0;
|
||||
void Unbind();
|
||||
|
||||
int32_t GetBindingSlot(const CStrIntern name) const override;
|
||||
|
||||
struct TextureUnit
|
||||
{
|
||||
|
|
@ -111,29 +111,29 @@ public:
|
|||
GLenum target;
|
||||
GLint unit;
|
||||
};
|
||||
virtual TextureUnit GetTextureUnit(const int32_t bindingSlot) = 0;
|
||||
TextureUnit GetTextureUnit(const int32_t bindingSlot);
|
||||
|
||||
virtual GLuint GetStorageBuffer(const int32_t bindingSlot) = 0;
|
||||
GLuint GetStorageBuffer(const int32_t bindingSlot);
|
||||
|
||||
virtual void SetUniform(
|
||||
void SetUniform(
|
||||
const int32_t bindingSlot,
|
||||
const float value) = 0;
|
||||
virtual void SetUniform(
|
||||
const float value);
|
||||
void SetUniform(
|
||||
const int32_t bindingSlot,
|
||||
const float valueX, const float valueY) = 0;
|
||||
virtual void SetUniform(
|
||||
const float valueX, const float valueY);
|
||||
void SetUniform(
|
||||
const int32_t bindingSlot,
|
||||
const float valueX, const float valueY,
|
||||
const float valueZ) = 0;
|
||||
virtual void SetUniform(
|
||||
const float valueZ);
|
||||
void SetUniform(
|
||||
const int32_t bindingSlot,
|
||||
const float valueX, const float valueY,
|
||||
const float valueZ, const float valueW) = 0;
|
||||
virtual void SetUniform(
|
||||
const int32_t bindingSlot, std::span<const float> values) = 0;
|
||||
const float valueZ, const float valueW);
|
||||
void SetUniform(
|
||||
const int32_t bindingSlot, std::span<const float> values);
|
||||
|
||||
// Vertex attribute pointers (equivalent to glVertexPointer etc).
|
||||
virtual void VertexAttribPointer(
|
||||
void VertexAttribPointer(
|
||||
const VertexAttributeStream stream, const Format format,
|
||||
const uint32_t offset, const uint32_t stride,
|
||||
const VertexAttributeRate rate, const void* data);
|
||||
|
|
@ -142,28 +142,69 @@ public:
|
|||
|
||||
bool HasImageUniforms() const { return m_HasImageUniforms; }
|
||||
|
||||
IDevice* GetDevice() override { return m_Device; }
|
||||
|
||||
std::vector<VfsPath> GetFileDependencies() const override;
|
||||
|
||||
/**
|
||||
* Checks that all the required vertex attributes have been set.
|
||||
* Call this before calling Draw/DrawIndexed etc to avoid potential crashes.
|
||||
*/
|
||||
void AssertPointersBound();
|
||||
|
||||
protected:
|
||||
CShaderProgram(int streamflags);
|
||||
private:
|
||||
CShaderProgram(
|
||||
CDevice* device, const CStr& name, const VfsPath& programPath,
|
||||
std::span<const std::tuple<VfsPath, GLenum>> shaderStages,
|
||||
const CShaderDefines& defines,
|
||||
const std::map<CStrIntern, int>& vertexAttribs,
|
||||
int streamflags);
|
||||
|
||||
void VertexPointer(const Renderer::Backend::Format format, GLsizei stride, const void* pointer);
|
||||
void NormalPointer(const Renderer::Backend::Format format, GLsizei stride, const void* pointer);
|
||||
void ColorPointer(const Renderer::Backend::Format format, GLsizei stride, const void* pointer);
|
||||
void TexCoordPointer(GLenum texture, const Renderer::Backend::Format format, GLsizei stride, const void* pointer);
|
||||
bool Link(const VfsPath& path);
|
||||
|
||||
int m_StreamFlags;
|
||||
|
||||
// Non-GLSL client state handling:
|
||||
void BindClientStates();
|
||||
void UnbindClientStates();
|
||||
int m_ValidStreams; // which streams have been specified via VertexPointer etc since the last Bind
|
||||
|
||||
bool m_HasImageUniforms{false};
|
||||
|
||||
struct ShaderStage
|
||||
{
|
||||
GLenum type;
|
||||
GLuint shader;
|
||||
};
|
||||
|
||||
CDevice* m_Device{nullptr};
|
||||
|
||||
CStr m_Name;
|
||||
std::vector<VfsPath> m_FileDependencies;
|
||||
|
||||
std::map<CStrIntern, int> m_VertexAttribs;
|
||||
// Sorted list of active vertex attributes.
|
||||
std::vector<int> m_ActiveVertexAttributes;
|
||||
|
||||
GLuint m_Program;
|
||||
// 5 = max(compute, vertex + tesselation (control + evaluation) + geometry + fragment).
|
||||
PS::StaticVector<ShaderStage, 5> m_ShaderStages;
|
||||
|
||||
struct BindingSlot
|
||||
{
|
||||
CStrIntern name;
|
||||
GLint location;
|
||||
GLint offset;
|
||||
GLint size;
|
||||
GLenum type;
|
||||
GLenum elementType;
|
||||
GLint elementCount;
|
||||
bool isTexture;
|
||||
bool isStorageBuffer;
|
||||
};
|
||||
std::vector<BindingSlot> m_BindingSlots;
|
||||
std::unordered_map<CStrIntern, int32_t> m_BindingSlotsMapping;
|
||||
|
||||
GLint m_UniformBufferLocation{-1};
|
||||
uint32_t m_UniformBufferSize{0};
|
||||
std::unique_ptr<IBuffer> m_UniformBuffer;
|
||||
};
|
||||
|
||||
} // namespace GL
|
||||
|
|
|
|||
Loading…
Reference in a new issue