summaryrefslogtreecommitdiff
path: root/Runtime/Graphics/ProceduralTexture.h
diff options
context:
space:
mode:
Diffstat (limited to 'Runtime/Graphics/ProceduralTexture.h')
-rw-r--r--Runtime/Graphics/ProceduralTexture.h190
1 files changed, 190 insertions, 0 deletions
diff --git a/Runtime/Graphics/ProceduralTexture.h b/Runtime/Graphics/ProceduralTexture.h
new file mode 100644
index 0000000..94740a7
--- /dev/null
+++ b/Runtime/Graphics/ProceduralTexture.h
@@ -0,0 +1,190 @@
+#pragma once
+
+#include "Configuration/UnityConfigure.h"
+#include "Runtime/Utilities/dynamic_array.h"
+#include "Texture.h"
+#include "External/Allegorithmic/builds/Engines/include/substance/handle.h"
+
+class ColorRGBAf;
+class ColorRGBA32;
+class ProceduralMaterial;
+
+enum ProceduralOutputType
+{
+ Substance_OType_Unknown = 0,
+ Substance_OType_Diffuse,
+ Substance_OType_Normal,
+ Substance_OType_Height,
+ Substance_OType_Emissive,
+ Substance_OType_Specular,
+ Substance_OType_Opacity,
+ ProceduralOutputType_Count
+};
+
+enum SubstanceOutputFormat
+{
+ Substance_OFormat_Compressed = 0,
+ Substance_OFormat_Raw
+};
+
+/* A ProceduralTexture is a dynamic texture generated by the Substance engine.
+ * It's part of a Substance graph hierarchy, compound of ProceduralMaterial, SubstanceArchive.
+ */
+
+
+class ProceduralTexture : public Texture
+{
+public:
+
+ // Uploaded texture parameters
+ struct TextureParameters
+ {
+ DECLARE_SERIALIZE(TextureParameters)
+
+ int width;
+ int height;
+ int mipLevels;
+ TextureFormat textureFormat;
+
+ bool IsValid () const { return width != 0; }
+ friend bool operator == (const TextureParameters& lhs, const TextureParameters& rhs)
+ {
+ return lhs.width == rhs.width && lhs.height == rhs.height && lhs.mipLevels == rhs.mipLevels && lhs.textureFormat == rhs.textureFormat;
+ }
+
+ TextureParameters ();
+ TextureParameters (int inWidth, int inHeight, int inMipLevels, TextureFormat inFormat);
+
+ void Invalidate() { *this = TextureParameters(); }
+ };
+
+ // Flags
+ enum Flag
+ {
+ Flag_Binded = 1<<0, // the output is altered by an input
+ Flag_Uploaded = 1<<1, // the data has been uploaded
+ Flag_AwakeClone = 1<<2, // the texture need awake from clone
+ Flag_Cached = 1<<3 // the texture has been cached, editor flag only
+ };
+
+ // Upload State
+ enum UploadState
+ {
+ UploadState_None, // no data has been uploaded
+ UploadState_Waiting, // blue waiting texture
+ UploadState_Valid, // lower states indicate the current uploaded data isn't valid
+ UploadState_Baked, // baked texture
+ UploadState_Generated // generated texture
+ };
+
+protected: // FIELDS
+
+ PPtr<ProceduralMaterial> m_SubstanceMaterial; // The parent procedural material from which we get generated
+ ProceduralMaterial* m_PingedMaterial; // The pinged procedural material
+ UInt64 m_SubstanceTextureUID; // The index of this texture (i.e. Substance output) WORD[shuffledID,baseID]
+ unsigned int m_SubstancePreShuffleUID; // This ID is required to use substanceLinkerHandleSelectOutputs
+ ProceduralOutputType m_Type;
+ ProceduralOutputType m_AlphaSource;
+ unsigned int m_Flags;
+ UploadState m_UploadState;
+ SubstanceOutputFormat m_Format;
+ TextureFormat m_SubstanceFormat; // Platform dependant format required for substance generation
+ TextureParameters m_TextureParameters;
+ std::vector<UInt8> m_BakedData; // Baked texture if substance isn't supported
+ TextureParameters m_BakedParameters;
+ TextureID m_ClonedID; // Link to the source ID when cloned and not generated
+
+public: // METHODS
+
+ REGISTER_DERIVED_CLASS( ProceduralTexture, Texture )
+ DECLARE_OBJECT_SERIALIZE( ProceduralTexture )
+
+ ProceduralTexture( MemLabelId label, ObjectCreationMode mode );
+
+#if ENABLE_SUBSTANCE
+ ProceduralTexture* Clone(ProceduralMaterial* owner);
+ void AwakeClone();
+#endif
+
+ virtual int GetDataWidth() const { return m_TextureParameters.width; }
+ virtual int GetDataHeight() const { return m_TextureParameters.height; }
+ TextureFormat GetDataFormat() const { return m_TextureParameters.textureFormat; }
+ int GetDataMipLevels() const { return m_TextureParameters.mipLevels; }
+ virtual TextureDimension GetDimension () const { return kTexDim2D; }
+ virtual bool HasMipMap () const { return m_TextureParameters.mipLevels != 1; }
+ virtual int CountMipmaps() const { return m_TextureParameters.mipLevels; }
+
+ const ProceduralOutputType& GetType() const { return m_Type; }
+ const ProceduralOutputType& GetAlphaSource() const { return m_AlphaSource; }
+ bool IsFlagEnabled(const Flag& flag) const { return m_Flags & (unsigned int)flag; }
+ void EnableFlag(const Flag& flag, bool enabled=true) { if (enabled) m_Flags |= (unsigned int)flag; else m_Flags &= ~(unsigned int)flag; }
+
+#if ENABLE_PROFILER
+ virtual int GetStorageMemorySize() const { return m_TextureParameters.width * m_TextureParameters.height; }
+#endif
+ virtual bool ExtractImage (ImageReference* image, int imageIndex = 0) const { return false; }
+
+ virtual void UnloadFromGfxDevice(bool forceUnloadAll);
+ virtual void UploadToGfxDevice();
+ void RemoveTexture ();
+ void UploadWaitingTexture ();
+ void UploadBakedTexture ();
+
+ // Gets the output texture UID (i.e. output UID for the Substance engine)
+ unsigned int GetSubstanceTextureUID() const { return m_SubstanceTextureUID & 0xffffffff; }
+ unsigned int GetSubstanceBaseTextureUID() const { return (m_SubstanceTextureUID >> 32); }
+
+ void SetSubstancePreShuffleUID(unsigned int id) { m_SubstancePreShuffleUID = id; }
+ unsigned int GetSubstancePreShuffleUID() const { return m_SubstancePreShuffleUID; }
+
+ // Set the UIDs
+ // (Don't call externally though !)
+ void SetSubstanceShuffledUID(unsigned int textureUID);
+ void SetSubstanceFormat(TextureFormat format) { m_SubstanceFormat = format; }
+ TextureFormat GetSubstanceFormat() const { return m_SubstanceFormat; }
+
+ virtual void AwakeFromLoadThreaded();
+ virtual void AwakeFromLoad( AwakeFromLoadMode awakeMode );
+
+ virtual bool ShouldIgnoreInGarbageDependencyTracking () { return false; }
+
+ // (Don't call externally though !)
+ void UploadSubstanceTexture(SubstanceTexture& outputTexture);
+
+ bool HasBeenGenerated() const { return m_UploadState==UploadState_Generated; }
+ bool HasBeenUploaded() const { return (m_UploadState==UploadState_Generated) || (m_UploadState==UploadState_Baked); }
+
+#if UNITY_EDITOR
+ // Creates the texture (one time call only by importer)
+ void Init( ProceduralMaterial& _Parent, int _TextureIndex, ProceduralOutputType type, SubstanceOutputFormat format, ProceduralOutputType alphaSource, bool requireCompressed );
+ const TextureParameters& GetTextureParameters() const { return m_TextureParameters; }
+ TextureParameters& GetTextureParameters() { return m_TextureParameters; }
+
+ virtual TextureFormat GetEditorUITextureFormat () const { return m_TextureParameters.textureFormat; }
+#endif
+
+ bool IsBaked() const;
+ std::vector<UInt8>& GetBakedData() { return m_BakedData; }
+ const TextureParameters& GetBakedParameters() const { return m_BakedParameters; }
+ TextureParameters& GetBakedParameters() { return m_BakedParameters; }
+
+ bool GetPixels32(int x, int y, int width, int height, ColorRGBA32* data);
+
+ bool IsValid() { return m_TextureParameters.IsValid(); }
+ void Invalidate();
+
+ void SetOwner(ProceduralMaterial* material);
+ ProceduralMaterial* GetSubstanceMaterial() { return m_PingedMaterial; }
+#if UNITY_EDITOR
+ PPtr<ProceduralMaterial>& GetSubstanceMaterialPtr() { return m_SubstanceMaterial; }
+#endif
+};
+
+template<class T>
+void ProceduralTexture::TextureParameters::Transfer(T& transfer)
+{
+ TRANSFER(width);
+ TRANSFER(height);
+ TRANSFER(mipLevels);
+ transfer.Transfer(reinterpret_cast<int&> (textureFormat), "textureFormat");
+}