Add SMaterial::IUserData to make it easier passing additional values to shaders

Irrlicht generally avoided user pointers in the past, but after trying all kind of ugly workarounds - this is just easier and
not that much downsides really. Tiny speed costs due to additional SMaterial memory size and new comparison tests. 
But allows to keep SMaterial alive and useful for a while longer without needing a complete rewrite and it can now be used for stuff like writing PBR shaders.
Using a new interface io::IUserData for this which also allows serialization the user data (that part is untested so far, sorry)


git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@6567 dfc29bdd-3216-0410-991c-e03cc46cb475
This commit is contained in:
cutealien
2023-11-07 15:43:49 +00:00
parent d0605cf397
commit 3c9a856e6d
20 changed files with 155 additions and 6 deletions

53
include/IUserData.h Normal file
View File

@ -0,0 +1,53 @@
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#ifndef IRR_I_USER_DATA_H_INCLUDED
#define IRR_I_USER_DATA_H_INCLUDED
#include "irrTypes.h"
namespace irr
{
namespace io
{
class IAttributes;
struct SAttributeReadWriteOptions;
//! Irrlicht may allow users to set their own data via those pointers
//! Irrlicht has no memory control over IUserData, the user is completely responsible for that
class IUserData
{
public:
//! To identify the class type.
//! You can for example use MAKE_IRR_ID to create four CC codes
virtual irr::u32 getType() const { return 0; }
//! To be overloaded if comparisons matter
//! You can then cast other to your derived class
virtual bool compare(const IUserData& other) const
{
return getType() == other.getType();
}
//! Writes data attributes
virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const {}
//! Reads data attributes
virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0) {}
//! Used internally by Irrlicht to check if data has changed
bool operator!=(const IUserData& other) const
{
return !compare(other);
}
protected:
// Irrlicht is never allowed to delete this
// If users want to delete such objects they should go over derived classes
~IUserData() {}
};
} // end namespace io
} // end namespace irr
#endif // IRR_I_USER_DATA_H_INCLUDED

View File

@ -11,6 +11,7 @@
#include "EMaterialTypes.h"
#include "EMaterialFlags.h"
#include "SMaterialLayer.h"
#include "IUserData.h"
namespace irr
{
@ -313,7 +314,8 @@ namespace video
PolygonOffsetFactor(0), PolygonOffsetDirection(EPO_FRONT),
Wireframe(false), PointCloud(false), GouraudShading(true),
Lighting(true), ZWriteEnable(EZW_AUTO), BackfaceCulling(true), FrontfaceCulling(false),
FogEnable(false), NormalizeNormals(false), UseMipMaps(true)
FogEnable(false), NormalizeNormals(false), UseMipMaps(true),
UserData(0)
{ }
//! Texture layer array.
@ -493,6 +495,11 @@ namespace video
/** Sometimes, disabling mipmap usage can be useful. Default: true */
bool UseMipMaps:1;
//! Allow users to add their own material data
//! User is resonsible for the memory of this pointer
//! You should override IUserData::compare for user custom data, so SMaterial knows when it changes
io::IUserData* UserData;
//! Gets the texture transformation matrix for level i
/** \param i The desired level. Must not be larger than MATERIAL_MAX_TEXTURES
\return Texture matrix for texture level i. */
@ -713,7 +720,8 @@ namespace video
PolygonOffsetSlopeScale != b.PolygonOffsetSlopeScale ||
PolygonOffsetFactor != b.PolygonOffsetFactor ||
PolygonOffsetDirection != b.PolygonOffsetDirection ||
UseMipMaps != b.UseMipMaps
UseMipMaps != b.UseMipMaps ||
UserData != b.UserData || (UserData && b.UserData && *UserData != *b.UserData)
;
for (u32 i=0; (i<MATERIAL_MAX_TEXTURES_USED) && !different; ++i)
{

View File

@ -154,6 +154,7 @@
#include "ITexture.h"
#include "ITimer.h"
#include "ITriangleSelector.h"
#include "IUserData.h"
#include "IVertexBuffer.h"
#include "IVideoDriver.h"
#include "IVideoModeList.h"