Add API to delete shader materials

This commit is contained in:
sfan5 2024-02-20 21:27:15 +01:00
parent e60921f0cb
commit c83f28431b
4 changed files with 47 additions and 3 deletions

@ -5,6 +5,8 @@
#ifndef __E_MATERIAL_TYPES_H_INCLUDED__
#define __E_MATERIAL_TYPES_H_INCLUDED__
#include "irrTypes.h"
namespace irr
{
namespace video
@ -67,6 +69,9 @@ namespace video
0
};
constexpr u32 numBuiltInMaterials =
sizeof(sBuiltInMaterialTypeNames) / sizeof(char*) - 1;
} // end namespace video
} // end namespace irr

@ -356,6 +356,15 @@ public:
scene::EPT_TRIANGLES, scene::EPT_TRIANGLE_STRIP, 0,
callback, baseMaterial, userData);
}
//! Delete a shader material and associated data.
/**
After you have deleted a material it is invalid to still use and doing
so might result in a crash. The ID may be reused in the future when new
materials are added.
\param material Number of the material type. Must not be a built-in
material. */
virtual void deleteShaderMaterial(s32 material) = 0;
};

@ -41,6 +41,14 @@ IImageWriter* createImageWriterJPG();
//! creates a writer which is able to save png images
IImageWriter* createImageWriterPNG();
namespace {
//! no-op material renderer
class CDummyMaterialRenderer : public IMaterialRenderer {
public:
CDummyMaterialRenderer() {}
};
}
//! constructor
CNullDriver::CNullDriver(io::IFileSystem* io, const core::dimension2d<u32>& screenSize)
@ -1525,7 +1533,7 @@ s32 CNullDriver::addMaterialRenderer(IMaterialRenderer* renderer, const char* na
r.Renderer = renderer;
r.Name = name;
if (name == 0 && (MaterialRenderers.size() < (sizeof(sBuiltInMaterialTypeNames) / sizeof(char*))-1 ))
if (name == 0 && MaterialRenderers.size() < numBuiltInMaterials)
{
// set name of built in renderer so that we don't have to implement name
// setting in all available renderers.
@ -1542,8 +1550,7 @@ s32 CNullDriver::addMaterialRenderer(IMaterialRenderer* renderer, const char* na
//! Sets the name of a material renderer.
void CNullDriver::setMaterialRendererName(u32 idx, const char* name)
{
if (idx < (sizeof(sBuiltInMaterialTypeNames) / sizeof(char*))-1 ||
idx >= MaterialRenderers.size())
if (idx < numBuiltInMaterials || idx >= MaterialRenderers.size())
return;
MaterialRenderers[idx].Name = name;
@ -1786,6 +1793,27 @@ s32 CNullDriver::addHighLevelShaderMaterialFromFiles(
return result;
}
void CNullDriver::deleteShaderMaterial(s32 material)
{
const u32 idx = (u32)material;
if (idx < numBuiltInMaterials || idx >= MaterialRenderers.size())
return;
// if this is the last material we can drop it without consequence
if (idx == MaterialRenderers.size() - 1) {
if (MaterialRenderers[idx].Renderer)
MaterialRenderers[idx].Renderer->drop();
MaterialRenderers.erase(idx);
return;
}
// otherwise replace with a dummy renderer, we have to preserve the IDs
auto &ref = MaterialRenderers[idx];
if (ref.Renderer)
ref.Renderer->drop();
ref.Renderer = new CDummyMaterialRenderer();
ref.Name.clear();
}
//! Creates a render target texture.
ITexture* CNullDriver::addRenderTargetTexture(const core::dimension2d<u32>& size,

@ -525,6 +525,8 @@ namespace video
E_MATERIAL_TYPE baseMaterial = video::EMT_SOLID,
s32 userData = 0) override;
virtual void deleteShaderMaterial(s32 material) override;
//! Returns a pointer to the mesh manipulator.
scene::IMeshManipulator* getMeshManipulator() override;