1
0
forked from 0ad/0ad

Decouples renderer code from VideoMode to get backend device.

Differential Revision: https://code.wildfiregames.com/D5043
This was SVN commit r27693.
This commit is contained in:
Vladislav Belov 2023-06-14 07:06:22 +00:00
parent 5893c4bc85
commit 8f78ac1ef8
25 changed files with 146 additions and 140 deletions

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2022 Wildfire Games.
/* Copyright (C) 2023 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@ -67,13 +67,13 @@ class CGameViewImpl
{
NONCOPYABLE(CGameViewImpl);
public:
CGameViewImpl(CGame* game)
CGameViewImpl(Renderer::Backend::IDevice* device, CGame* game)
: Game(game),
ColladaManager(g_VFS), MeshManager(ColladaManager), SkeletonAnimManager(ColladaManager),
ObjectManager(MeshManager, SkeletonAnimManager, *game->GetSimulation2()),
LOSTexture(*game->GetSimulation2()),
TerritoryTexture(*game->GetSimulation2()),
MiniMapTexture(*game->GetSimulation2()),
MiniMapTexture(device, *game->GetSimulation2()),
ViewCamera(),
CullCamera(),
LockCullCamera(false),
@ -158,8 +158,8 @@ void CGameView::SetConstrainCameraEnabled(bool enabled)
#undef IMPLEMENT_BOOLEAN_SETTING
CGameView::CGameView(CGame *pGame):
m(new CGameViewImpl(pGame))
CGameView::CGameView(Renderer::Backend::IDevice* device, CGame *pGame):
m(new CGameViewImpl(device, pGame))
{
m->CullCamera = m->ViewCamera;
g_Renderer.GetSceneRenderer().SetSceneCamera(m->ViewCamera, m->CullCamera);

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2022 Wildfire Games.
/* Copyright (C) 2023 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 @@ class CGameView : private Scene
{
NONCOPYABLE(CGameView);
public:
CGameView(CGame *pGame);
CGameView(Renderer::Backend::IDevice* device, CGame *pGame);
~CGameView() override;
void SetViewport(const SViewPort& vp);

View File

@ -190,7 +190,7 @@ bool CMiniMapTexture::CellIconKeyEqual::operator()(
lhs.b == rhs.b;
}
CMiniMapTexture::CMiniMapTexture(CSimulation2& simulation)
CMiniMapTexture::CMiniMapTexture(Renderer::Backend::IDevice* device, CSimulation2& simulation)
: m_Simulation(simulation), m_IndexArray(false),
m_VertexArray(Renderer::Backend::IBuffer::Type::VERTEX, true),
m_InstanceVertexArray(Renderer::Backend::IBuffer::Type::VERTEX, false)
@ -252,7 +252,6 @@ CMiniMapTexture::CMiniMapTexture(CSimulation2& simulation)
}};
m_QuadVertexInputLayout = g_Renderer.GetVertexInputLayout(attributes);
Renderer::Backend::IDevice* device = g_VideoMode.GetBackendDevice();
m_Flipped = device->GetBackend() == Renderer::Backend::Backend::VULKAN;
const uint32_t stride = m_VertexArray.GetStride();

View File

@ -41,7 +41,7 @@ class CMiniMapTexture
{
NONCOPYABLE(CMiniMapTexture);
public:
CMiniMapTexture(CSimulation2& simulation);
CMiniMapTexture(Renderer::Backend::IDevice* device, CSimulation2& simulation);
~CMiniMapTexture();
/**

View File

@ -31,10 +31,7 @@
#include "ps/Filesystem.h"
#include "ps/Profile.h"
#include "ps/XML/Xeromyces.h"
#include "ps/VideoMode.h"
#include "renderer/backend/IDevice.h"
#include "renderer/Renderer.h"
#include "renderer/RenderingOptions.h"
#define USE_SHADER_XML_VALIDATION 1
@ -48,7 +45,8 @@
TIMER_ADD_CLIENT(tc_ShaderValidation);
CShaderManager::CShaderManager()
CShaderManager::CShaderManager(Renderer::Backend::IDevice* device)
: m_Device(device)
{
#if USE_SHADER_XML_VALIDATION
{
@ -75,7 +73,7 @@ CShaderProgramPtr CShaderManager::LoadProgram(const CStr& name, const CShaderDef
if (it != m_ProgramCache.end())
return it->second;
CShaderProgramPtr program = CShaderProgram::Create(name, defines);
CShaderProgramPtr program = CShaderProgram::Create(m_Device, name, defines);
if (program)
{
for (const VfsPath& path : program->GetFileDependencies())
@ -156,10 +154,8 @@ bool CShaderManager::LoadTechnique(CShaderTechniquePtr& tech)
if (ret != PSRETURN_OK)
return false;
Renderer::Backend::IDevice* device = g_VideoMode.GetBackendDevice();
// By default we assume that we have techinques for every dummy shader.
if (device->GetBackend() == Renderer::Backend::Backend::DUMMY)
if (m_Device->GetBackend() == Renderer::Backend::Backend::DUMMY)
{
CShaderProgramPtr shaderProgram = LoadProgram(str_dummy.string(), tech->GetShaderDefines());
std::vector<CShaderPass> techPasses;
@ -167,7 +163,7 @@ bool CShaderManager::LoadTechnique(CShaderTechniquePtr& tech)
Renderer::Backend::MakeDefaultGraphicsPipelineStateDesc();
passPipelineStateDesc.shaderProgram = shaderProgram->GetBackendShaderProgram();
techPasses.emplace_back(
device->CreateGraphicsPipelineState(passPipelineStateDesc), shaderProgram);
m_Device->CreateGraphicsPipelineState(passPipelineStateDesc), shaderProgram);
tech->SetPasses(std::move(techPasses));
return true;
}
@ -233,20 +229,20 @@ bool CShaderManager::LoadTechnique(CShaderTechniquePtr& tech)
{
if (attrs.GetNamedItem(at_shaders) == "arb")
{
if (device->GetBackend() != Renderer::Backend::Backend::GL_ARB ||
!device->GetCapabilities().ARBShaders)
if (m_Device->GetBackend() != Renderer::Backend::Backend::GL_ARB ||
!m_Device->GetCapabilities().ARBShaders)
{
isUsable = false;
}
}
else if (attrs.GetNamedItem(at_shaders) == "glsl")
{
if (device->GetBackend() != Renderer::Backend::Backend::GL)
if (m_Device->GetBackend() != Renderer::Backend::Backend::GL)
isUsable = false;
}
else if (attrs.GetNamedItem(at_shaders) == "spirv")
{
if (device->GetBackend() != Renderer::Backend::Backend::VULKAN)
if (m_Device->GetBackend() != Renderer::Backend::Backend::VULKAN)
isUsable = false;
}
else if (!attrs.GetNamedItem(at_context).empty())
@ -443,7 +439,7 @@ bool CShaderManager::LoadTechnique(CShaderTechniquePtr& tech)
tech->GetPipelineStateDescCallback()(passPipelineStateDesc);
passPipelineStateDesc.shaderProgram = shaderProgram->GetBackendShaderProgram();
techPasses.emplace_back(
device->CreateGraphicsPipelineState(passPipelineStateDesc), shaderProgram);
m_Device->CreateGraphicsPipelineState(passPipelineStateDesc), shaderProgram);
}
}
}

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2022 Wildfire Games.
/* Copyright (C) 2023 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 @@
class CShaderManager
{
public:
CShaderManager();
CShaderManager(Renderer::Backend::IDevice* device);
~CShaderManager();
/**
@ -81,6 +81,8 @@ private:
}
};
Renderer::Backend::IDevice* m_Device = nullptr;
// A CShaderProgram contains expensive backend state, so we ought to cache it.
// The compiled state depends solely on the filename and list of defines,
// so we store that in CacheKey.

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2022 Wildfire Games.
/* Copyright (C) 2023 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@ -19,18 +19,19 @@
#include "ShaderProgram.h"
#include "ps/VideoMode.h"
#include "renderer/backend/IDevice.h"
CShaderProgram::CShaderProgram(const CStr& name, const CShaderDefines& defines)
: m_Name(name), m_Defines(defines)
CShaderProgram::CShaderProgram(
Renderer::Backend::IDevice* device, const CStr& name, const CShaderDefines& defines)
: m_Device(device), m_Name(name), m_Defines(defines)
{
}
// static
CShaderProgramPtr CShaderProgram::Create(const CStr& name, const CShaderDefines& defines)
CShaderProgramPtr CShaderProgram::Create(
Renderer::Backend::IDevice* device, const CStr& name, const CShaderDefines& defines)
{
CShaderProgramPtr shaderProgram(new CShaderProgram(name, defines));
CShaderProgramPtr shaderProgram(new CShaderProgram(device, name, defines));
shaderProgram->Reload();
return shaderProgram->m_BackendShaderProgram ? shaderProgram : nullptr;
}
@ -38,7 +39,7 @@ CShaderProgramPtr CShaderProgram::Create(const CStr& name, const CShaderDefines&
void CShaderProgram::Reload()
{
std::unique_ptr<Renderer::Backend::IShaderProgram> backendShaderProgram =
g_VideoMode.GetBackendDevice()->CreateShaderProgram(m_Name, m_Defines);
m_Device->CreateShaderProgram(m_Name, m_Defines);
if (backendShaderProgram)
m_BackendShaderProgram = std::move(backendShaderProgram);
}

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2022 Wildfire Games.
/* Copyright (C) 2023 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@ -35,7 +35,8 @@ class CShaderProgram
NONCOPYABLE(CShaderProgram);
public:
static CShaderProgramPtr Create(const CStr& name, const CShaderDefines& defines);
static CShaderProgramPtr Create(
Renderer::Backend::IDevice* device, const CStr& name, const CShaderDefines& defines);
void Reload();
@ -46,8 +47,10 @@ public:
// TODO: add reloadable handles.
protected:
CShaderProgram(const CStr& name, const CShaderDefines& defines);
CShaderProgram(
Renderer::Backend::IDevice* device, const CStr& name, const CShaderDefines& defines);
Renderer::Backend::IDevice* m_Device = nullptr;
CStr m_Name;
CShaderDefines m_Defines;
std::unique_ptr<Renderer::Backend::IShaderProgram> m_BackendShaderProgram;

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2022 Wildfire Games.
/* Copyright (C) 2023 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@ -28,7 +28,6 @@
#include "lib/timer.h"
#include "ps/CLogger.h"
#include "ps/Filesystem.h"
#include "ps/VideoMode.h"
#include "ps/XML/Xeromyces.h"
#include "renderer/backend/IDevice.h"
#include "renderer/Renderer.h"
@ -37,8 +36,8 @@
#include <boost/algorithm/string.hpp>
#include <vector>
CTerrainTextureManager::CTerrainTextureManager()
: m_LastGroupIndex(0)
CTerrainTextureManager::CTerrainTextureManager(Renderer::Backend::IDevice* device)
: m_Device(device)
{
if (!VfsDirectoryExists(L"art/terrains/"))
return;
@ -292,7 +291,7 @@ CTerrainTextureManager::LoadAlphaMap(const VfsPath& alphaMapType)
ignore_result(da_free(&da));
#endif
result.m_CompositeAlphaMap = g_VideoMode.GetBackendDevice()->CreateTexture2D("CompositeAlphaMap",
result.m_CompositeAlphaMap = m_Device->CreateTexture2D("CompositeAlphaMap",
Renderer::Backend::ITexture::Usage::TRANSFER_DST |
Renderer::Backend::ITexture::Usage::SAMPLED,
Renderer::Backend::Format::A8_UNORM, totalWidth, totalHeight,

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2022 Wildfire Games.
/* Copyright (C) 2023 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@ -94,7 +94,7 @@ public:
using TerrainAlphaMap = std::map<VfsPath, TerrainAlpha>;
// constructor, destructor
CTerrainTextureManager();
CTerrainTextureManager(Renderer::Backend::IDevice* device);
~CTerrainTextureManager();
// Find all XML's in the directory (with subdirs) and try to load them as
@ -124,6 +124,8 @@ public:
void UploadResourcesIfNeeded(Renderer::Backend::IDeviceCommandContext* deviceCommandContext);
private:
Renderer::Backend::IDevice* m_Device = nullptr;
// All texture entries created by this class, for easy freeing now that
// textures may be in several STextureType's
std::vector<CTerrainTextureEntry*> m_TextureEntries;
@ -132,7 +134,7 @@ private:
TerrainAlphaMap m_TerrainAlphas;
size_t m_LastGroupIndex;
size_t m_LastGroupIndex = 0;
// A way to separate file loading and uploading to GPU to not stall uploading.
// Once we get a properly threaded loading we might optimize that.

View File

@ -57,7 +57,7 @@ public:
g_VideoMode.InitNonSDL();
g_VideoMode.CreateBackendDevice(false);
m_Viewer = new CProfileViewer;
m_Renderer = new CRenderer;
m_Renderer = new CRenderer(g_VideoMode.GetBackendDevice());
}
void tearDown()

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2022 Wildfire Games.
/* Copyright (C) 2023 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@ -32,12 +32,13 @@
#include "ps/CConsole.h"
#include "ps/CLogger.h"
#include "ps/CStr.h"
#include "ps/GameSetup/GameSetup.h"
#include "ps/Loader.h"
#include "ps/LoaderThunks.h"
#include "ps/Profile.h"
#include "ps/Replay.h"
#include "ps/World.h"
#include "ps/GameSetup/GameSetup.h"
#include "ps/VideoMode.h"
#include "renderer/Renderer.h"
#include "renderer/SceneRenderer.h"
#include "renderer/TimeManager.h"
@ -70,7 +71,9 @@ const CStr CGame::EventNameSimulationUpdate = "SimulationUpdate";
CGame::CGame(bool replayLog):
m_World(new CWorld(this)),
m_Simulation2(new CSimulation2(&m_World->GetUnitManager(), g_ScriptContext, m_World->GetTerrain())),
m_GameView(CRenderer::IsInitialised() ? new CGameView(this) : nullptr),
// TODO: we need to remove that global dependency. Maybe the game view
// should be created outside only if needed.
m_GameView(CRenderer::IsInitialised() ? new CGameView(g_VideoMode.GetBackendDevice(), this) : nullptr),
m_GameStarted(false),
m_Paused(false),
m_SimRate(1.0f),

View File

@ -677,7 +677,7 @@ void InitGraphics(const CmdLineArgs& args, int flags, const std::vector<CStr>& i
g_RenderingOptions.ReadConfigAndSetupHooks();
// create renderer
new CRenderer;
new CRenderer(g_VideoMode.GetBackendDevice());
InitInput();

View File

@ -29,7 +29,6 @@
#include "ps/CStrInternStatic.h"
#include "ps/Filesystem.h"
#include "ps/Game.h"
#include "ps/VideoMode.h"
#include "ps/World.h"
#include "renderer/backend/IDevice.h"
#include "renderer/Renderer.h"
@ -82,9 +81,10 @@ void DrawFullscreenQuad(
} // anonymous namespace
CPostprocManager::CPostprocManager()
: m_IsInitialized(false), m_PostProcEffect(L"default"), m_WhichBuffer(true),
m_Sharpness(0.3f), m_UsingMultisampleBuffer(false), m_MultisampleCount(0)
CPostprocManager::CPostprocManager(Renderer::Backend::IDevice* device)
: m_Device(device), m_IsInitialized(false), m_PostProcEffect(L"default"),
m_WhichBuffer(true), m_Sharpness(0.3f), m_UsingMultisampleBuffer(false),
m_MultisampleCount(0)
{
}
@ -95,14 +95,13 @@ CPostprocManager::~CPostprocManager()
bool CPostprocManager::IsEnabled() const
{
Renderer::Backend::IDevice* device = g_VideoMode.GetBackendDevice();
const bool isDepthStencilFormatPresent =
device->GetPreferredDepthStencilFormat(
m_Device->GetPreferredDepthStencilFormat(
Renderer::Backend::ITexture::Usage::DEPTH_STENCIL_ATTACHMENT, true, true)
!= Renderer::Backend::Format::UNDEFINED;
return
g_RenderingOptions.GetPostProc() &&
device->GetBackend() != Renderer::Backend::Backend::GL_ARB &&
m_Device->GetBackend() != Renderer::Backend::Backend::GL_ARB &&
isDepthStencilFormatPresent;
}
@ -145,7 +144,7 @@ void CPostprocManager::Initialize()
}};
m_VertexInputLayout = g_Renderer.GetVertexInputLayout(attributes);
const uint32_t maxSamples = g_VideoMode.GetBackendDevice()->GetCapabilities().maxSampleCount;
const uint32_t maxSamples = m_Device->GetCapabilities().maxSampleCount;
const uint32_t possibleSampleCounts[] = {2, 4, 8, 16};
std::copy_if(
std::begin(possibleSampleCounts), std::end(possibleSampleCounts),
@ -182,10 +181,8 @@ void CPostprocManager::RecreateBuffers()
{
Cleanup();
Renderer::Backend::IDevice* backendDevice = g_VideoMode.GetBackendDevice();
#define GEN_BUFFER_RGBA(name, w, h) \
name = backendDevice->CreateTexture2D( \
name = m_Device->CreateTexture2D( \
"PostProc" #name, \
Renderer::Backend::ITexture::Usage::SAMPLED | \
Renderer::Backend::ITexture::Usage::COLOR_ATTACHMENT | \
@ -215,7 +212,7 @@ void CPostprocManager::RecreateBuffers()
colorAttachment.loadOp = Renderer::Backend::AttachmentLoadOp::LOAD;
colorAttachment.storeOp = Renderer::Backend::AttachmentStoreOp::STORE;
colorAttachment.clearColor = CColor{0.0f, 0.0f, 0.0f, 0.0f};
step.framebuffer = backendDevice->CreateFramebuffer(
step.framebuffer = m_Device->CreateFramebuffer(
"BlurScaleSteoFramebuffer", &colorAttachment, nullptr);
}
width /= 2;
@ -225,10 +222,10 @@ void CPostprocManager::RecreateBuffers()
#undef GEN_BUFFER_RGBA
// Allocate the Depth/Stencil texture.
m_DepthTex = backendDevice->CreateTexture2D("PostProcDepthTexture",
m_DepthTex = m_Device->CreateTexture2D("PostProcDepthTexture",
Renderer::Backend::ITexture::Usage::SAMPLED |
Renderer::Backend::ITexture::Usage::DEPTH_STENCIL_ATTACHMENT,
backendDevice->GetPreferredDepthStencilFormat(
m_Device->GetPreferredDepthStencilFormat(
Renderer::Backend::ITexture::Usage::SAMPLED |
Renderer::Backend::ITexture::Usage::DEPTH_STENCIL_ATTACHMENT,
true, true),
@ -249,17 +246,17 @@ void CPostprocManager::RecreateBuffers()
depthStencilAttachment.loadOp = Renderer::Backend::AttachmentLoadOp::CLEAR;
depthStencilAttachment.storeOp = Renderer::Backend::AttachmentStoreOp::STORE;
m_CaptureFramebuffer = backendDevice->CreateFramebuffer("PostprocCaptureFramebuffer",
m_CaptureFramebuffer = m_Device->CreateFramebuffer("PostprocCaptureFramebuffer",
&colorAttachment, &depthStencilAttachment);
colorAttachment.texture = m_ColorTex1.get();
colorAttachment.loadOp = Renderer::Backend::AttachmentLoadOp::LOAD;
colorAttachment.storeOp = Renderer::Backend::AttachmentStoreOp::STORE;
m_PingFramebuffer = backendDevice->CreateFramebuffer("PostprocPingFramebuffer",
m_PingFramebuffer = m_Device->CreateFramebuffer("PostprocPingFramebuffer",
&colorAttachment, nullptr);
colorAttachment.texture = m_ColorTex2.get();
m_PongFramebuffer = backendDevice->CreateFramebuffer("PostprocPongFramebuffer",
m_PongFramebuffer = m_Device->CreateFramebuffer("PostprocPongFramebuffer",
&colorAttachment, nullptr);
if (!m_CaptureFramebuffer || !m_PingFramebuffer || !m_PongFramebuffer)
@ -479,7 +476,7 @@ void CPostprocManager::ApplyPostproc(
// Don't do anything if we are using the default effect and no AA.
const bool hasEffects = m_PostProcEffect != L"default";
const bool hasARB = g_VideoMode.GetBackendDevice()->GetBackend() == Renderer::Backend::Backend::GL_ARB;
const bool hasARB = m_Device->GetBackend() == Renderer::Backend::Backend::GL_ARB;
const bool hasAA = m_AATech && !hasARB;
const bool hasSharp = m_SharpTech && !hasARB;
if (!hasEffects && !hasAA && !hasSharp)
@ -549,8 +546,7 @@ void CPostprocManager::SetPostEffect(const CStrW& name)
void CPostprocManager::UpdateAntiAliasingTechnique()
{
Renderer::Backend::IDevice* device = g_VideoMode.GetBackendDevice();
if (device->GetBackend() == Renderer::Backend::Backend::GL_ARB || !m_IsInitialized)
if (m_Device->GetBackend() == Renderer::Backend::Backend::GL_ARB || !m_IsInitialized)
return;
CStr newAAName;
@ -580,7 +576,7 @@ void CPostprocManager::UpdateAntiAliasingTechnique()
// We don't want to enable MSAA in Atlas, because it uses wxWidgets and its canvas.
if (g_AtlasGameLoop && g_AtlasGameLoop->running)
return;
if (!device->GetCapabilities().multisampling || m_AllowedSampleCounts.empty())
if (!m_Device->GetCapabilities().multisampling || m_AllowedSampleCounts.empty())
{
LOGWARNING("MSAA is unsupported.");
return;
@ -590,7 +586,7 @@ void CPostprocManager::UpdateAntiAliasingTechnique()
if (std::find(std::begin(m_AllowedSampleCounts), std::end(m_AllowedSampleCounts), m_MultisampleCount) ==
std::end(m_AllowedSampleCounts))
{
m_MultisampleCount = std::min(4u, device->GetCapabilities().maxSampleCount);
m_MultisampleCount = std::min(4u, m_Device->GetCapabilities().maxSampleCount);
LOGWARNING("Wrong MSAA sample count: %s.", m_AAName.EscapeToPrintableASCII().c_str());
}
m_UsingMultisampleBuffer = true;
@ -600,7 +596,7 @@ void CPostprocManager::UpdateAntiAliasingTechnique()
void CPostprocManager::UpdateSharpeningTechnique()
{
if (g_VideoMode.GetBackendDevice()->GetBackend() == Renderer::Backend::Backend::GL_ARB || !m_IsInitialized)
if (m_Device->GetBackend() == Renderer::Backend::Backend::GL_ARB || !m_IsInitialized)
return;
CStr newSharpName;
@ -629,9 +625,7 @@ void CPostprocManager::SetDepthBufferClipPlanes(float nearPlane, float farPlane)
void CPostprocManager::CreateMultisampleBuffer()
{
Renderer::Backend::IDevice* backendDevice = g_VideoMode.GetBackendDevice();
m_MultisampleColorTex = backendDevice->CreateTexture("PostProcColorMS",
m_MultisampleColorTex = m_Device->CreateTexture("PostProcColorMS",
Renderer::Backend::ITexture::Type::TEXTURE_2D_MULTISAMPLE,
Renderer::Backend::ITexture::Usage::COLOR_ATTACHMENT |
Renderer::Backend::ITexture::Usage::TRANSFER_SRC,
@ -641,11 +635,11 @@ void CPostprocManager::CreateMultisampleBuffer()
Renderer::Backend::Sampler::AddressMode::CLAMP_TO_EDGE), 1, m_MultisampleCount);
// Allocate the Depth/Stencil texture.
m_MultisampleDepthTex = backendDevice->CreateTexture("PostProcDepthMS",
m_MultisampleDepthTex = m_Device->CreateTexture("PostProcDepthMS",
Renderer::Backend::ITexture::Type::TEXTURE_2D_MULTISAMPLE,
Renderer::Backend::ITexture::Usage::DEPTH_STENCIL_ATTACHMENT |
Renderer::Backend::ITexture::Usage::TRANSFER_SRC,
backendDevice->GetPreferredDepthStencilFormat(
m_Device->GetPreferredDepthStencilFormat(
Renderer::Backend::ITexture::Usage::DEPTH_STENCIL_ATTACHMENT |
Renderer::Backend::ITexture::Usage::TRANSFER_SRC,
true, true),
@ -666,7 +660,7 @@ void CPostprocManager::CreateMultisampleBuffer()
depthStencilAttachment.loadOp = Renderer::Backend::AttachmentLoadOp::CLEAR;
depthStencilAttachment.storeOp = Renderer::Backend::AttachmentStoreOp::STORE;
m_MultisampleFramebuffer = backendDevice->CreateFramebuffer(
m_MultisampleFramebuffer = m_Device->CreateFramebuffer(
"PostprocMultisampleFramebuffer", &colorAttachment, &depthStencilAttachment);
if (!m_MultisampleFramebuffer)

View File

@ -31,7 +31,7 @@
class CPostprocManager
{
public:
CPostprocManager();
CPostprocManager(Renderer::Backend::IDevice* device);
~CPostprocManager();
// Returns true if the the manager can be used.
@ -91,6 +91,8 @@ private:
void CreateMultisampleBuffer();
void DestroyMultisampleBuffer();
Renderer::Backend::IDevice* m_Device = nullptr;
std::unique_ptr<Renderer::Backend::IFramebuffer> m_CaptureFramebuffer;
// Two framebuffers, that we flip between at each shader pass.

View File

@ -243,6 +243,8 @@ class CRenderer::Internals
{
NONCOPYABLE(Internals);
public:
Renderer::Backend::IDevice* device;
std::unique_ptr<Renderer::Backend::IDeviceCommandContext> deviceCommandContext;
/// true if CRenderer::Open has been called
@ -281,10 +283,12 @@ public:
std::vector<Renderer::Backend::SVertexAttributeFormat>,
std::unique_ptr<Renderer::Backend::IVertexInputLayout>, VertexAttributesHash> vertexInputLayouts;
Internals() :
Internals(Renderer::Backend::IDevice* device) :
device(device),
deviceCommandContext(device->CreateCommandContext()),
IsOpen(false), ShadersDirty(true), profileTable(g_Renderer.m_Stats),
deviceCommandContext(g_VideoMode.GetBackendDevice()->CreateCommandContext()),
textureManager(g_VFS, false, g_VideoMode.GetBackendDevice())
shaderManager(device), textureManager(g_VFS, false, device),
postprocManager(device), sceneRenderer(device)
{
}
};
@ -306,11 +310,11 @@ size_t CRenderer::Internals::VertexAttributesHash::operator()(
return seed;
}
CRenderer::CRenderer()
CRenderer::CRenderer(Renderer::Backend::IDevice* device)
{
TIMER(L"InitRenderer");
m = std::make_unique<Internals>();
m = std::make_unique<Internals>(device);
g_ProfileViewer.AddRootTable(&m->profileTable);
@ -320,7 +324,7 @@ CRenderer::CRenderer()
m_Stats.Reset();
// Create terrain related stuff.
new CTerrainTextureManager;
new CTerrainTextureManager(device);
Open(g_xres, g_yres);
@ -348,7 +352,7 @@ void CRenderer::ReloadShaders()
{
ENSURE(m->IsOpen);
m->sceneRenderer.ReloadShaders();
m->sceneRenderer.ReloadShaders(m->device);
m->ShadersDirty = false;
}
@ -393,8 +397,8 @@ void CRenderer::SetRenderPath(RenderPath rp)
// Renderer has been opened, so validate the selected renderpath
const bool hasShadersSupport =
g_VideoMode.GetBackendDevice()->GetCapabilities().ARBShaders ||
g_VideoMode.GetBackendDevice()->GetBackend() != Renderer::Backend::Backend::GL_ARB;
m->device->GetCapabilities().ARBShaders ||
m->device->GetBackend() != Renderer::Backend::Backend::GL_ARB;
if (rp == RenderPath::DEFAULT)
{
if (hasShadersSupport)
@ -443,7 +447,7 @@ void CRenderer::RenderFrame(const bool needsPresent)
if (needsPresent)
{
// In case of no acquired backbuffer we have nothing render to.
if (!g_VideoMode.GetBackendDevice()->AcquireNextBackbuffer())
if (!m->device->AcquireNextBackbuffer())
return;
}
@ -458,7 +462,7 @@ void CRenderer::RenderFrame(const bool needsPresent)
m->deviceCommandContext->Flush();
if (needsPresent)
g_VideoMode.GetBackendDevice()->Present();
m->device->Present();
}
}
@ -651,7 +655,7 @@ void CRenderer::RenderScreenShot(const bool needsPresent)
const size_t width = static_cast<size_t>(g_xres), height = static_cast<size_t>(g_yres);
const size_t bpp = 24;
if (needsPresent && !g_VideoMode.GetBackendDevice()->AcquireNextBackbuffer())
if (needsPresent && !m->device->AcquireNextBackbuffer())
return;
// Hide log messages and re-render
@ -669,7 +673,7 @@ void CRenderer::RenderScreenShot(const bool needsPresent)
m->deviceCommandContext->ReadbackFramebufferSync(0, 0, width, height, img);
m->deviceCommandContext->Flush();
if (needsPresent)
g_VideoMode.GetBackendDevice()->Present();
m->device->Present();
if (tex_write(&t, filename) == INFO::OK)
{
@ -768,7 +772,7 @@ void CRenderer::RenderBigScreenShot(const bool needsPresent)
}
g_Game->GetView()->GetCamera()->SetProjection(projection);
if (!needsPresent || g_VideoMode.GetBackendDevice()->AcquireNextBackbuffer())
if (!needsPresent || m->device->AcquireNextBackbuffer())
{
RenderFrameImpl(false, false);
@ -776,7 +780,7 @@ void CRenderer::RenderBigScreenShot(const bool needsPresent)
m->deviceCommandContext->Flush();
if (needsPresent)
g_VideoMode.GetBackendDevice()->Present();
m->device->Present();
}
// Copy the tile pixels into the main image
@ -896,6 +900,6 @@ Renderer::Backend::IVertexInputLayout* CRenderer::GetVertexInputLayout(
const auto [it, inserted] = m->vertexInputLayouts.emplace(
std::vector<Renderer::Backend::SVertexAttributeFormat>{attributes.begin(), attributes.end()}, nullptr);
if (inserted)
it->second = g_VideoMode.GetBackendDevice()->CreateVertexInputLayout(attributes);
it->second = m->device->CreateVertexInputLayout(attributes);
return it->second.get();
}

View File

@ -77,7 +77,7 @@ public:
};
public:
CRenderer();
CRenderer(Renderer::Backend::IDevice* device);
~CRenderer();
// open up the renderer: performs any necessary initialisation

View File

@ -42,7 +42,6 @@
#include "ps/CStrInternStatic.h"
#include "ps/Game.h"
#include "ps/Profile.h"
#include "ps/VideoMode.h"
#include "ps/World.h"
#include "renderer/backend/IDevice.h"
#include "renderer/DebugRenderer.h"
@ -76,7 +75,11 @@ class CSceneRenderer::Internals
{
NONCOPYABLE(Internals);
public:
Internals() = default;
Internals(Renderer::Backend::IDevice* device)
: waterManager(device), shadow(device)
{
}
~Internals() = default;
/// Water manager
@ -186,9 +189,9 @@ public:
}
};
CSceneRenderer::CSceneRenderer()
CSceneRenderer::CSceneRenderer(Renderer::Backend::IDevice* device)
{
m = std::make_unique<Internals>();
m = std::make_unique<Internals>(device);
m_TerrainRenderMode = SOLID;
m_WaterRenderMode = SOLID;
@ -210,12 +213,10 @@ CSceneRenderer::~CSceneRenderer()
m.reset();
}
void CSceneRenderer::ReloadShaders()
void CSceneRenderer::ReloadShaders(Renderer::Backend::IDevice* device)
{
m->globalContext = CShaderDefines();
Renderer::Backend::IDevice* device = g_VideoMode.GetBackendDevice();
if (g_RenderingOptions.GetShadows())
{
m->globalContext.Add(str_USE_SHADOW, str_1);
@ -567,7 +568,7 @@ void CSceneRenderer::RenderReflections(
// Save the model-view-projection matrix so the shaders can use it for projective texturing
wm.m_ReflectionMatrix = m_ViewCamera.GetViewProjection();
if (g_VideoMode.GetBackendDevice()->GetBackend() == Renderer::Backend::Backend::VULKAN)
if (deviceCommandContext->GetDevice()->GetBackend() == Renderer::Backend::Backend::VULKAN)
{
CMatrix3D flip;
flip.SetIdentity();
@ -650,7 +651,7 @@ void CSceneRenderer::RenderRefractions(
wm.m_RefractionProjInvMatrix = m_ViewCamera.GetProjection().GetInverse();
wm.m_RefractionViewInvMatrix = m_ViewCamera.GetOrientation();
if (g_VideoMode.GetBackendDevice()->GetBackend() == Renderer::Backend::Backend::VULKAN)
if (deviceCommandContext->GetDevice()->GetBackend() == Renderer::Backend::Backend::VULKAN)
{
CMatrix3D flip;
flip.SetIdentity();

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2022 Wildfire Games.
/* Copyright (C) 2023 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,7 @@ public:
CULL_MAX
};
CSceneRenderer();
CSceneRenderer(Renderer::Backend::IDevice* device);
~CSceneRenderer();
void Initialize();
@ -195,7 +195,7 @@ public:
*/
void ResetState();
void ReloadShaders();
void ReloadShaders(Renderer::Backend::IDevice* device);
protected:
void Submit(CPatch* patch) override;

View File

@ -32,7 +32,6 @@
#include "ps/ConfigDB.h"
#include "ps/CStrInternStatic.h"
#include "ps/Profile.h"
#include "ps/VideoMode.h"
#include "renderer/backend/IDevice.h"
#include "renderer/backend/ITexture.h"
#include "renderer/DebugRenderer.h"
@ -57,6 +56,8 @@ constexpr float DEFAULT_CASCADE_DISTANCE_RATIO = 1.7f;
*/
struct ShadowMapInternals
{
Renderer::Backend::IDevice* Device = nullptr;
std::unique_ptr<Renderer::Backend::IFramebuffer> Framebuffer;
std::unique_ptr<Renderer::Backend::ITexture> Texture;
@ -124,7 +125,7 @@ void ShadowMapInternals::UpdateCascadesParameters()
CascadeCount = 1;
CFG_GET_VAL("shadowscascadecount", CascadeCount);
if (CascadeCount < 1 || CascadeCount > MAX_CASCADE_COUNT || g_VideoMode.GetBackendDevice()->GetBackend() == Renderer::Backend::Backend::GL_ARB)
if (CascadeCount < 1 || CascadeCount > MAX_CASCADE_COUNT || Device->GetBackend() == Renderer::Backend::Backend::GL_ARB)
CascadeCount = 1;
ShadowsCoverMap = false;
@ -183,9 +184,10 @@ void CalculateBoundsForCascade(
bbaa->Expand(insets);
}
ShadowMap::ShadowMap()
ShadowMap::ShadowMap(Renderer::Backend::IDevice* device)
{
m = new ShadowMapInternals;
m->Device = device;
m->Framebuffer = 0;
m->Width = 0;
m->Height = 0;
@ -460,7 +462,7 @@ void ShadowMapInternals::CalculateShadowMatrices(const int cascade)
lightToTex._34 = -shadowRenderBound[0].Z * texscalez;
lightToTex._44 = 1.0;
if (g_VideoMode.GetBackendDevice()->GetBackend() == Renderer::Backend::Backend::VULKAN)
if (Device->GetBackend() == Renderer::Backend::Backend::VULKAN)
{
CMatrix3D flip;
flip.SetIdentity();
@ -480,8 +482,6 @@ void ShadowMapInternals::CreateTexture()
Texture.reset();
DummyTexture.reset();
Renderer::Backend::IDevice* backendDevice = g_VideoMode.GetBackendDevice();
CFG_GET_VAL("shadowquality", QualityLevel);
// Get shadow map size as next power of two up from view width/height.
@ -508,7 +508,7 @@ void ShadowMapInternals::CreateTexture()
// Clamp to the maximum texture size.
shadowMapSize = std::min(
shadowMapSize, static_cast<int>(backendDevice->GetCapabilities().maxTextureSize));
shadowMapSize, static_cast<int>(Device->GetCapabilities().maxTextureSize));
Width = Height = shadowMapSize;
@ -529,7 +529,7 @@ void ShadowMapInternals::CreateTexture()
case 32: formatName = "Format::D32_SFLOAT"; backendFormat = Renderer::Backend::Format::D32_SFLOAT; break;
default:
formatName = "Default";
backendFormat = backendDevice->GetPreferredDepthStencilFormat(
backendFormat = Device->GetPreferredDepthStencilFormat(
Renderer::Backend::ITexture::Usage::SAMPLED |
Renderer::Backend::ITexture::Usage::DEPTH_STENCIL_ATTACHMENT,
true, false);
@ -543,7 +543,7 @@ void ShadowMapInternals::CreateTexture()
if (g_RenderingOptions.GetShadowAlphaFix())
{
DummyTexture = backendDevice->CreateTexture2D("ShadowMapDummy",
DummyTexture = Device->CreateTexture2D("ShadowMapDummy",
Renderer::Backend::ITexture::Usage::COLOR_ATTACHMENT,
Renderer::Backend::Format::R8G8B8A8_UNORM, Width, Height,
Renderer::Backend::Sampler::MakeDefaultSampler(
@ -566,7 +566,7 @@ void ShadowMapInternals::CreateTexture()
samplerDesc.compareEnabled = true;
samplerDesc.compareOp = Renderer::Backend::CompareOp::LESS_OR_EQUAL;
Texture = backendDevice->CreateTexture2D("ShadowMapDepth",
Texture = Device->CreateTexture2D("ShadowMapDepth",
Renderer::Backend::ITexture::Usage::SAMPLED |
Renderer::Backend::ITexture::Usage::DEPTH_STENCIL_ATTACHMENT,
backendFormat, Width, Height, samplerDesc);
@ -587,7 +587,7 @@ void ShadowMapInternals::CreateTexture()
depthStencilAttachment.loadOp = Renderer::Backend::AttachmentLoadOp::CLEAR;
depthStencilAttachment.storeOp = Renderer::Backend::AttachmentStoreOp::STORE;
Framebuffer = backendDevice->CreateFramebuffer("ShadowMapFramebuffer",
Framebuffer = Device->CreateFramebuffer("ShadowMapFramebuffer",
useDummyTexture ? &colorAttachment : nullptr, &depthStencilAttachment);
if (!Framebuffer)
{

View File

@ -38,7 +38,7 @@ struct ShadowMapInternals;
class ShadowMap
{
public:
ShadowMap();
ShadowMap(Renderer::Backend::IDevice* device);
~ShadowMap();
/**

View File

@ -32,7 +32,6 @@
#include "ps/CStrInternStatic.h"
#include "ps/Filesystem.h"
#include "ps/Game.h"
#include "ps/VideoMode.h"
#include "renderer/backend/IDevice.h"
#include "renderer/Renderer.h"
#include "renderer/SceneRenderer.h"
@ -121,7 +120,7 @@ void SkyManager::LoadAndUploadSkyTexturesIfNeeded(
}
std::unique_ptr<Renderer::Backend::ITexture> skyCubeMap =
g_VideoMode.GetBackendDevice()->CreateTexture("SkyCubeMap",
deviceCommandContext->GetDevice()->CreateTexture("SkyCubeMap",
Renderer::Backend::ITexture::Type::TEXTURE_CUBE,
Renderer::Backend::ITexture::Usage::TRANSFER_DST |
Renderer::Backend::ITexture::Usage::SAMPLED,

View File

@ -28,7 +28,6 @@
#include "ps/CLogger.h"
#include "ps/CStrInternStatic.h"
#include "ps/Game.h"
#include "ps/VideoMode.h"
#include "ps/World.h"
#include "renderer/backend/IDevice.h"
#include "renderer/Renderer.h"
@ -69,7 +68,8 @@ struct WaveObject
float m_TimeDiff;
};
WaterManager::WaterManager()
WaterManager::WaterManager(Renderer::Backend::IDevice* device)
: m_Device(device)
{
// water
m_RenderWater = false; // disabled until textures are successfully loaded
@ -214,8 +214,6 @@ int WaterManager::LoadWaterTextures()
void WaterManager::RecreateOrLoadTexturesIfNeeded()
{
Renderer::Backend::IDevice* backendDevice = g_VideoMode.GetBackendDevice();
// Use screen-sized textures for minimum artifacts.
const size_t newRefTextureSize = round_up_to_pow2(g_Renderer.GetHeight());
@ -233,7 +231,7 @@ void WaterManager::RecreateOrLoadTexturesIfNeeded()
}
const Renderer::Backend::Format depthFormat =
backendDevice->GetPreferredDepthStencilFormat(
m_Device->GetPreferredDepthStencilFormat(
Renderer::Backend::ITexture::Usage::SAMPLED |
Renderer::Backend::ITexture::Usage::DEPTH_STENCIL_ATTACHMENT,
true, false);
@ -244,7 +242,7 @@ void WaterManager::RecreateOrLoadTexturesIfNeeded()
g_RenderingOptions.GetWaterReflection();
if (needsReflectionTextures && !m_ReflectionTexture)
{
m_ReflectionTexture = backendDevice->CreateTexture2D("WaterReflectionTexture",
m_ReflectionTexture = m_Device->CreateTexture2D("WaterReflectionTexture",
Renderer::Backend::ITexture::Usage::SAMPLED |
Renderer::Backend::ITexture::Usage::COLOR_ATTACHMENT,
Renderer::Backend::Format::R8G8B8A8_UNORM, m_RefTextureSize, m_RefTextureSize,
@ -252,7 +250,7 @@ void WaterManager::RecreateOrLoadTexturesIfNeeded()
Renderer::Backend::Sampler::Filter::LINEAR,
Renderer::Backend::Sampler::AddressMode::MIRRORED_REPEAT));
m_ReflFboDepthTexture = backendDevice->CreateTexture2D("WaterReflectionDepthTexture",
m_ReflFboDepthTexture = m_Device->CreateTexture2D("WaterReflectionDepthTexture",
Renderer::Backend::ITexture::Usage::SAMPLED |
Renderer::Backend::ITexture::Usage::DEPTH_STENCIL_ATTACHMENT,
depthFormat, m_RefTextureSize, m_RefTextureSize,
@ -271,7 +269,7 @@ void WaterManager::RecreateOrLoadTexturesIfNeeded()
depthStencilAttachment.loadOp = Renderer::Backend::AttachmentLoadOp::CLEAR;
depthStencilAttachment.storeOp = Renderer::Backend::AttachmentStoreOp::STORE;
m_ReflectionFramebuffer = backendDevice->CreateFramebuffer("ReflectionFramebuffer",
m_ReflectionFramebuffer = m_Device->CreateFramebuffer("ReflectionFramebuffer",
&colorAttachment, &depthStencilAttachment);
if (!m_ReflectionFramebuffer)
{
@ -286,7 +284,7 @@ void WaterManager::RecreateOrLoadTexturesIfNeeded()
g_RenderingOptions.GetWaterRefraction();
if (needsRefractionTextures && !m_RefractionTexture)
{
m_RefractionTexture = backendDevice->CreateTexture2D("WaterRefractionTexture",
m_RefractionTexture = m_Device->CreateTexture2D("WaterRefractionTexture",
Renderer::Backend::ITexture::Usage::SAMPLED |
Renderer::Backend::ITexture::Usage::COLOR_ATTACHMENT,
Renderer::Backend::Format::R8G8B8A8_UNORM, m_RefTextureSize, m_RefTextureSize,
@ -294,7 +292,7 @@ void WaterManager::RecreateOrLoadTexturesIfNeeded()
Renderer::Backend::Sampler::Filter::LINEAR,
Renderer::Backend::Sampler::AddressMode::MIRRORED_REPEAT));
m_RefrFboDepthTexture = backendDevice->CreateTexture2D("WaterRefractionDepthTexture",
m_RefrFboDepthTexture = m_Device->CreateTexture2D("WaterRefractionDepthTexture",
Renderer::Backend::ITexture::Usage::SAMPLED |
Renderer::Backend::ITexture::Usage::DEPTH_STENCIL_ATTACHMENT,
depthFormat, m_RefTextureSize, m_RefTextureSize,
@ -313,7 +311,7 @@ void WaterManager::RecreateOrLoadTexturesIfNeeded()
depthStencilAttachment.loadOp = Renderer::Backend::AttachmentLoadOp::CLEAR;
depthStencilAttachment.storeOp = Renderer::Backend::AttachmentStoreOp::STORE;
m_RefractionFramebuffer = backendDevice->CreateFramebuffer("RefractionFramebuffer",
m_RefractionFramebuffer = m_Device->CreateFramebuffer("RefractionFramebuffer",
&colorAttachment, &depthStencilAttachment);
if (!m_RefractionFramebuffer)
{
@ -338,7 +336,7 @@ void WaterManager::RecreateOrLoadTexturesIfNeeded()
g_RenderingOptions.GetWaterFancyEffects();
if (needsFancyTextures && !m_FancyTexture)
{
m_FancyTexture = backendDevice->CreateTexture2D("WaterFancyTexture",
m_FancyTexture = m_Device->CreateTexture2D("WaterFancyTexture",
Renderer::Backend::ITexture::Usage::SAMPLED |
Renderer::Backend::ITexture::Usage::COLOR_ATTACHMENT,
Renderer::Backend::Format::R8G8B8A8_UNORM, g_Renderer.GetWidth(), g_Renderer.GetHeight(),
@ -346,7 +344,7 @@ void WaterManager::RecreateOrLoadTexturesIfNeeded()
Renderer::Backend::Sampler::Filter::LINEAR,
Renderer::Backend::Sampler::AddressMode::REPEAT));
m_FancyTextureDepth = backendDevice->CreateTexture2D("WaterFancyDepthTexture",
m_FancyTextureDepth = m_Device->CreateTexture2D("WaterFancyDepthTexture",
Renderer::Backend::ITexture::Usage::DEPTH_STENCIL_ATTACHMENT,
depthFormat, g_Renderer.GetWidth(), g_Renderer.GetHeight(),
Renderer::Backend::Sampler::MakeDefaultSampler(
@ -365,7 +363,7 @@ void WaterManager::RecreateOrLoadTexturesIfNeeded()
// We need to store depth for later rendering occluders.
depthStencilAttachment.storeOp = Renderer::Backend::AttachmentStoreOp::STORE;
m_FancyEffectsFramebuffer = backendDevice->CreateFramebuffer("FancyEffectsFramebuffer",
m_FancyEffectsFramebuffer = m_Device->CreateFramebuffer("FancyEffectsFramebuffer",
&colorAttachment, &depthStencilAttachment);
Renderer::Backend::SColorAttachment occludersColorAttachment{};
@ -379,7 +377,7 @@ void WaterManager::RecreateOrLoadTexturesIfNeeded()
occludersDepthStencilAttachment.loadOp = Renderer::Backend::AttachmentLoadOp::LOAD;
occludersDepthStencilAttachment.storeOp = Renderer::Backend::AttachmentStoreOp::DONT_CARE;
m_FancyEffectsOccludersFramebuffer = backendDevice->CreateFramebuffer("FancyEffectsOccludersFramebuffer",
m_FancyEffectsOccludersFramebuffer = m_Device->CreateFramebuffer("FancyEffectsOccludersFramebuffer",
&occludersColorAttachment, &occludersDepthStencilAttachment);
if (!m_FancyEffectsFramebuffer || !m_FancyEffectsOccludersFramebuffer)
{
@ -1129,7 +1127,7 @@ void WaterManager::UpdateQuality()
bool WaterManager::WillRenderFancyWater() const
{
return
m_RenderWater && g_VideoMode.GetBackendDevice()->GetBackend() != Renderer::Backend::Backend::GL_ARB &&
m_RenderWater && m_Device->GetBackend() != Renderer::Backend::Backend::GL_ARB &&
g_RenderingOptions.GetWaterEffects();
}

View File

@ -130,7 +130,7 @@ public:
float m_WindAngle; // In which direction the water waves go.
public:
WaterManager();
WaterManager(Renderer::Backend::IDevice* device);
~WaterManager();
void Initialize();
@ -207,6 +207,9 @@ public:
*/
size_t GetCurrentTextureIndex(const double& period) const;
size_t GetNextTextureIndex(const double& period) const;
private:
Renderer::Backend::IDevice* m_Device = nullptr;
};

View File

@ -81,7 +81,7 @@ public:
ObjectManager(MeshManager, SkeletonAnimManager, Simulation2),
LOSTexture(Simulation2),
TerritoryTexture(Simulation2),
MiniMapTexture(Simulation2)
MiniMapTexture(g_VideoMode.GetBackendDevice(), Simulation2)
{
UnitManager.SetObjectManager(ObjectManager);
}