HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GR_Material.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  * NAME: GR_Material.h (GR Library, C++)
7  *
8  * COMMENTS:
9  */
10 #ifndef GR_Material_h
11 #define GR_Material_h
12 
13 #include "GR_API.h"
14 #include "GR_Defines.h"
15 #include "GR_DrawParms.h"
16 #include "GR_SceneItem.h"
17 
18 #include <UT/UT_IntrusivePtr.h>
19 #include <UT/UT_Map.h>
20 #include <UT/UT_NonCopyable.h>
21 #include <UT/UT_OptionEntry.h>
22 #include <UT/UT_RWLock.h>
23 #include <UT/UT_Set.h>
24 #include <UT/UT_StringMap.h>
25 #include <UT/UT_StringHolder.h>
26 #include <UT/UT_UniquePtr.h>
27 #include <UT/UT_VectorTypes.h>
28 #include <UT/UT_Vector2.h>
29 #include <UT/UT_Vector3.h>
30 #include <UT/UT_Matrix4.h>
31 #include <UT/UT_Debug.h>
32 #include <DEP/DEP_MicroNode.h>
33 
34 #ifdef USE_VULKAN
35 #include <RV/RV_ShaderProgram.h>
36 #include <RV/RV_TextureCache.h>
37 #endif
38 
39 class UT_Options;
41 class RV_Render;
42 class RV_ShaderProgram;
43 class RV_ShaderCompute;
44 class GR_MaterialParms;
45 class GR_DisplayOption;
46 
48 {
49 public:
50  // Alpha blend/cutout modes, meant to mirror the enum in RE_Material.h
51  // also defined in glsl/block/VK/glH_Material.blk
52  enum AlphaMode
53  {
54  ALPHA_BLEND = 0, // normal alpha blending C*A + Cbg*(1-A)
55  ALPHA_CUTOUT, // (A >= cutoff) ? C : 0
57  };
59  {
66  MATCAP_SURFACE
67  };
68 
69  static GR_MaterialPtr create(MaterialType type,
70  const UT_StringHolder &name);
71  MaterialType type() const { return myType; }
72 
73  // Some materials may be defined by nodes; this is the ID of that node.
74  int getNodeID() const { return myNodeID; }
75  void setNodeID(int id) { myNodeID = id; }
76  UT_StringHolder getNodePath() const;
77 
78  void setTimeDependent(bool timedep, fpreal t = 0.0);
79  void setOPTimeDependent(bool timedep, fpreal t = 0.0);
80  bool isTimeDependent() const { return myTimeDep; }
81  bool isOPTimeDependent() const { return myOPTimeDep; }
82  fpreal getCurrentTime() const { return myTime; }
83 
84 
86  {
87  if(isTextured())
88  {
89  exint cache_version = 0;
90 #ifdef USE_VULKAN
91  cache_version = RV_TextureCache::cacheRefresh();
92 #endif
93  if(myTexCacheVersion != cache_version)
94  return true;
95  }
96  if(myDirtyFlag || myDepNode.isDirty())
97  return true;
98  if(myTimeDep && !SYSisEqual(time, myTime))
99  return true;
100  return false;
101  }
102  void dirty(bool dirty = true)
103  {
104  myDirtyFlag = dirty;
105  if(!dirty)
106  {
107  myDepNode.update(myTime);
108 #ifdef USE_VULKAN
109  myTexCacheVersion = RV_TextureCache::cacheRefresh();
110 #endif
111  }
112  }
113 
114  virtual void dirtyTextures() {}
115 
116  // Returns true if this material has a texture map (diffuse, bump, etc).
117  bool isTextured() const { return myIsTextured; }
118  void setTextured(bool has_tex) { myIsTextured = has_tex; }
119 
120  bool hasUDIM() const { return myHasUDIM; }
121  void setHasUDIM(bool has_udim) { myHasUDIM = has_udim; }
122 
123  bool hasDisplacement() const { return myHasDisplacement; }
124  void setHasDisplacement(bool has_disp) {myHasDisplacement=has_disp;}
125 
126  // Requires UVs outside of texturing
127  bool needsUVs() const { return myNeedsUVs; }
128  void setNeedsUVs(bool uvs) { myNeedsUVs = uvs; }
129 
130  // Requires tangents for tangent-space generation
131  bool needsTangents() const { return myNeedsTangents; }
132  void setNeedsTangents(bool tan) { myNeedsTangents = tan; }
133 
134  bool isTransparent() const { return myIsTransparent; }
135  void setTransparent(bool has_tex) { myIsTransparent = has_tex; }
136 
137  bool texturesLoaded() const { return myTexturesLoaded; }
138  void setTexturesLoaded(bool loaded) { myTexturesLoaded = loaded; }
139 
141  const GR_DisplayOption *opts, bool for_curve = false)
142  {
143  return bindSets(r, shader, for_curve);
144  }
145 
147  const GR_DisplayOption *opts, bool for_curve = false)
148  {
149  bool created = false;
150  return (initMaterialSetForRender(r, shader, created) &&
151  initBlocks(r, opts) &&
152  bindSets(r, shader, for_curve));
153  }
154  virtual bool bindForCompute(RV_Render *r,
156  const GR_DisplayOption &opts);
157 
158  virtual void update(const GR_MaterialParms &options) = 0;
159 
160  virtual bool initMaterialSetForRender(RV_Render *r,
162  bool &created)=0;
163  virtual bool initBlocks(RV_Render *r, const GR_DisplayOption *opts) = 0;
164  bool checkCompatible(RV_Render* r, RV_ShaderProgramBase* sh, bool for_curve = false) const;
165  bool bindSets(RV_Render *r, RV_ShaderProgramBase *shader, bool for_curve);
166 
167  DEP_MicroNode &dependencies() { return myDepNode; }
168 
169  virtual RV_ShaderProgram *getSurfaceShader() const { return nullptr; }
170  virtual RV_ShaderProgram *getCurveShader() const { return nullptr; }
171  virtual RV_ShaderCompute *getDisplaceShader() const { return nullptr; }
172 
173  bool opDependenciesDirty() const { return myOpDepsDirty; }
174  void clearOpDependenciesDirty() { myOpDepsDirty = false; }
175  const UT_Set<int> opDependencies() const { return myOpNodes; }
176 
177  // Attribute overrides (mapping an attribute to a shader input)
178  void setOverrides(const UT_Options *overrides);
179  const UT_Options *getOverrides() const { return myOverrides.get(); }
180  // Attribute fallback (value to use if attribute does not exist)
181  void setFallbacks(const UT_Options *attrib_fallbacks);
182  const UT_Options *getFallbacks() const { return myFallbacks.get(); }
183 
185  {
190  IN_VEC4
191  };
192  void setExtraInputs(const UT_StringMap<InputType> &extra_inputs)
193  { myExtraInputs = extra_inputs; }
194  const UT_StringMap<InputType> &extraInputs() const { return myExtraInputs; }
195 
196  static exint getUniqueMaterialID();
197 
198 protected:
200  MaterialType type);
201  ~GR_Material() override;
203 
204  void clearOpIDs() { myOpNodes.clear(); myOpDepsDirty = true; }
205  void addOpID(int id);
206 
207  bool timeChangeCheck() const;
208 
209 #ifdef USE_VULKAN
211  UT_UniquePtr<RV_ShaderVariableSet> myTexMaterialSet;
212  UT_UniquePtr<RV_ShaderVariableSet> myTexCurveMaterialSet;
213 
214  void initTextureParms(RV_TextureParms &parms,
215  const GR_DisplayOption *opts,
216  RV_ImageDim tex_type);
217 
218 #endif
219 
222 
223 private:
224 
225  UT_Set<int> myOpNodes;
226  DEP_MicroNode myDepNode;
227  MaterialType myType;
228  int myNodeID = -999;
229  exint myTexCacheVersion = 0;
230  unsigned myTimeDep : 1,
231  myOPTimeDep : 1,
232  myIsTextured : 1,
233  myNeedsUVs : 1,
234  myHasUDIM : 1,
235  myHasDisplacement : 1,
236  myIsTransparent : 1,
237  myNeedsTangents : 1,
238  myTexturesLoaded : 1,
239  myOpDepsDirty : 1;
240  fpreal myTime = 0.0;
241  UT_UniquePtr<UT_Options> myOverrides;
242  UT_UniquePtr<UT_Options> myFallbacks;
243  UT_StringMap<InputType> myExtraInputs;
244 };
245 
246 static inline void intrusive_ptr_add_ref(GR_Material *m) { m->incref(); }
247 static inline void intrusive_ptr_release(GR_Material *m) { m->decref(); }
248 
249 
250 class GR_API GR_MaterialAtlas : public UT_Map<int,GR_MaterialPtr>
251 {
252 public:
253  // Default material for unassigned prims.
255  { return myDefault; }
256 
257  // Factory default material if materials are disabled.
259  { return myFactory; }
260 
261  // True if any of the materials in the atlas are dirty.
262  bool isDirty(fpreal time) const;
263 
264  // Fetch a material by its ID.
265  GR_MaterialPtr get(int material_id) const
266  {
267  if(myAltAtlas && material_id < 0)
268  return myAltAtlas->get(-material_id);
269  if(material_id == 0)
270  return myDefault ? myDefault : myFactory;
271  const_iterator entry = find(material_id);
272  if(entry != end())
273  return entry->second;
274  return nullptr;
275  }
276  // Fetch a material by ID, and if it doesn't exist, check the draw parms
277  // default material, then fallback to the default or factory if there is
278  // no draw parms default.
279  GR_MaterialPtr get(int material_id, const GR_DrawParms &dp) const
280  {
281  if(myAltAtlas && material_id < 0)
282  return myAltAtlas->get(-material_id);
283 
284  if(material_id == 0 && dp.vk_default_mat_id != 0)
285  material_id = dp.vk_default_mat_id;
286 
287  if(material_id == 0)
288  return myDefault ? myDefault : myFactory;
289 
290  const_iterator entry = find(material_id);
291  if(entry != end())
292  return entry->second;
293  return nullptr;
294  }
295 
296  // Add a new material to the atlas
297  void add(const GR_MaterialPtr &material)
298  { (*this)[ material->id() ] = material; }
299 
300  // Set the default material, which will be used if no other material
301  // assignments are present.
302  void setDefaultMaterial(const GR_MaterialPtr &material,bool add_list=true)
303  { myDefault = material; if(add_list && material) add(material); }
304 
305  // Sets the factory default material, which is used when all materials
306  // are turned off (as the default material may be the object material).
307  void setFactoryMaterial(const GR_MaterialPtr &material,bool add_list=true)
308  { myFactory = material; if(add_list && material) add(material); }
309 
310  // Provide another material atlas to use for material lookups. This is used
311  // for LOP materials when rendering SOPs.
313  { myAltAtlas = atlas; }
314  GR_MaterialAtlas *alternateMaterials() { return myAltAtlas; }
315  const GR_MaterialAtlas *alternateMaterials() const { return myAltAtlas; }
316 
317  bool hasMaterial(int material_id) const
318  {
319  const_iterator entry = find(material_id);
320  return (entry != end());
321  }
322 
323 private:
324  GR_MaterialPtr myDefault;
325  GR_MaterialPtr myFactory;
326 
327  GR_MaterialAtlas *myAltAtlas = nullptr;
328 };
329 
330 /// This is a fast, non-string access and cut-down version of UT_Options.
332 {
333 public:
335 
336  void setParmI(exint ptype, int value);
337  void setParm(exint ptype, fpreal value);
338  void setParm(exint ptype, const UT_Vector2 &value);
339  void setParm(exint ptype, const UT_Vector3 &value);
340  void setParm(exint ptype, const UT_Vector4 &value);
341  void setParm(exint ptype, const UT_Matrix4 &value);
342  void setParm(exint ptype, const UT_StringHolder &value);
343 
344  bool hasParm(exint ptype) const;
345 
346  int getParmI(exint ptype, int defval = 0) const;
347  fpreal getParmF(exint ptype, fpreal defval = 0.0) const;
348  UT_Vector2 getParmV2(exint ptype, UT_Vector2 defval = {0,0}) const;
349  UT_Vector3 getParmV3(exint ptype, UT_Vector3 defval = {0,0,0}) const;
350  UT_Vector4 getParmV4(exint ptype, UT_Vector4 defval = {0,0,0,0}) const;
351  UT_Matrix4 getParmM4(exint ptype,
353  UT_StringHolder getParmS(exint ptype, UT_StringHolder = UT_StringHolder()) const;
354 
355  void dump();
356 
357 private:
359 };
360 
361 // Cache for auto-generated shaders (MatX)
363 {
364 public:
366  ~GR_ShaderCache();
368 
369  static void initCache();
370  static void destroyCache();
371  static void clearCache();
372 
373  // return the ID assoicated with this name (0 if it doesn't exist).
374  static exint getShaderID(const UT_StringHolder &name);
375  static exint getComputeID(const UT_StringHolder &name);
376 
377  // Return the shader program assoicated with this id (nullptr if not cached)
378  static RV_ShaderProgram *getShader(exint id);
379  static RV_ShaderCompute *getComputeShader(exint id);
380 
381  // Create a cache entry to store a shader with cacheShader().
382  static exint createEntryID(const UT_StringHolder &name);
383  static exint createComputeEntryID(const UT_StringHolder &name);
384 
385  // Cache the shader by ID, handling over ownership to the cache.
386  static void cacheShader(exint entry, const GR_Material &for_material,
388  static void cacheComputeShader(exint entry, const GR_Material &for_material,
390 
391  // Add a reference to a cached shader. It must exist in the cache.
392  static void addShaderRef(exint id, const GR_Material &material);
393  static void addComputeRef(exint id, const GR_Material &material);
394 
395  // Remove the shader from the cache with the given name
396  static bool removeShader(const UT_StringHolder &name,
397  const GR_Material &for_material);
398  static bool removeComputeShader(const UT_StringHolder &name,
399  const GR_Material &for_material);
400 
401 private:
402  UT_StringMap<exint> myNameMap;
403  UT_StringMap<exint> myComputeNameMap;
404 #ifdef USE_VULKAN
405  UT_Map<exint,
406  std::pair<UT_Set<int>,UT_UniquePtr<RV_ShaderProgram>> > myShaders;
407  UT_Map<exint,
408  std::pair<UT_Set<int>,UT_UniquePtr<RV_ShaderCompute>> > myComputeShaders;
409 #endif
410  UT_RWLock myShaderLock;
411  exint myCurrentID = 1;
412 };
413 
414 #endif
void setFactoryMaterial(const GR_MaterialPtr &material, bool add_list=true)
Definition: GR_Material.h:307
void dirty(bool dirty=true)
Definition: GR_Material.h:102
virtual RV_ShaderProgram * getSurfaceShader() const
Definition: GR_Material.h:169
virtual void dirtyTextures()
Definition: GR_Material.h:114
Unsorted map container.
Definition: UT_Map.h:109
const GR_MaterialPtr & getFactoryMaterial() const
Definition: GR_Material.h:258
Base class for various things that can appear in a scene outside of geometry.
Definition: GR_SceneItem.h:19
bool isTimeDependent() const
Definition: GR_Material.h:80
bool opDependenciesDirty() const
Definition: GR_Material.h:173
GT_API const UT_StringHolder time
bool myBlockDirtyFlag
Definition: GR_Material.h:221
int getNodeID() const
Definition: GR_Material.h:74
const UT_Options * getOverrides() const
Definition: GR_Material.h:179
GLsizei const GLfloat * value
Definition: glcorearb.h:824
void decref()
Definition: GR_SceneItem.h:33
int64 exint
Definition: SYS_Types.h:125
bool isOPTimeDependent() const
Definition: GR_Material.h:81
FMT_CONSTEXPR auto find(Ptr first, Ptr last, T value, Ptr &out) -> bool
Definition: core.h:2138
UT_NON_COPYABLE(GR_SceneItem)
std::unique_ptr< T, Deleter > UT_UniquePtr
A smart pointer for unique ownership of dynamically allocated objects.
Definition: UT_UniquePtr.h:39
bool texturesLoaded() const
Definition: GR_Material.h:137
const GR_MaterialAtlas * alternateMaterials() const
Definition: GR_Material.h:315
fpreal getCurrentTime() const
Definition: GR_Material.h:82
void setTransparent(bool has_tex)
Definition: GR_Material.h:135
bool isTransparent() const
Definition: GR_Material.h:134
GLint GLint GLsizei GLint GLenum GLenum type
Definition: glcorearb.h:108
Compute shader object.
bool bindWithoutUpdate(RV_Render *r, RV_ShaderProgramBase *shader, const GR_DisplayOption *opts, bool for_curve=false)
Definition: GR_Material.h:140
bool hasUDIM() const
Definition: GR_Material.h:120
bool needsTangents() const
Definition: GR_Material.h:131
const UT_StringMap< InputType > & extraInputs() const
Definition: GR_Material.h:194
const UT_Options * getFallbacks() const
Definition: GR_Material.h:182
static const UT_Matrix4T< float > & getIdentityMatrix()
MaterialType type() const
Definition: GR_Material.h:71
GLuint GLuint end
Definition: glcorearb.h:475
void setHasDisplacement(bool has_disp)
Definition: GR_Material.h:124
#define UT_NON_COPYABLE(CLASS)
Define deleted copy constructor and assignment operator inside a class.
const UT_Set< int > opDependencies() const
Definition: GR_Material.h:175
void add(const GR_MaterialPtr &material)
Definition: GR_Material.h:297
virtual RV_ShaderCompute * getDisplaceShader() const
Definition: GR_Material.h:171
#define GR_API
Definition: GR_API.h:10
void setNeedsTangents(bool tan)
Definition: GR_Material.h:132
static exint cacheRefresh()
bool needsUVs() const
Definition: GR_Material.h:127
bool myDirtyFlag
Definition: GR_Material.h:220
bool isDirty(fpreal time)
Definition: GR_Material.h:85
GLuint const GLchar * name
Definition: glcorearb.h:786
void setNodeID(int id)
Definition: GR_Material.h:75
bool bind(RV_Render *r, RV_ShaderProgramBase *shader, const GR_DisplayOption *opts, bool for_curve=false)
Definition: GR_Material.h:146
void clearOpDependenciesDirty()
Definition: GR_Material.h:174
GLdouble t
Definition: glad.h:2397
SYS_API double tan(double x)
GLuint shader
Definition: glcorearb.h:785
A map of string to various well defined value types.
Definition: UT_Options.h:84
GA_API const UT_StringHolder parms
DEP_MicroNode & dependencies()
Definition: GR_Material.h:167
void setTextured(bool has_tex)
Definition: GR_Material.h:118
void setNeedsUVs(bool uvs)
Definition: GR_Material.h:128
void setHasUDIM(bool has_udim)
Definition: GR_Material.h:121
fpreal64 fpreal
Definition: SYS_Types.h:278
void setTexturesLoaded(bool loaded)
Definition: GR_Material.h:138
virtual RV_ShaderProgram * getCurveShader() const
Definition: GR_Material.h:170
void setDefaultMaterial(const GR_MaterialPtr &material, bool add_list=true)
Definition: GR_Material.h:302
void clearOpIDs()
Definition: GR_Material.h:204
bool hasMaterial(int material_id) const
Definition: GR_Material.h:317
bool hasDisplacement() const
Definition: GR_Material.h:123
GR_MaterialAtlas * alternateMaterials()
Definition: GR_Material.h:314
bool isTextured() const
Definition: GR_Material.h:117
ImageBuf OIIO_API add(Image_or_Const A, Image_or_Const B, ROI roi={}, int nthreads=0)
GLboolean r
Definition: glcorearb.h:1222
This is a fast, non-string access and cut-down version of UT_Options.
Definition: GR_Material.h:331
void setAlternateMaterials(GR_MaterialAtlas *atlas)
Definition: GR_Material.h:312
bool SYSisEqual(const UT_Vector2T< T > &a, const UT_Vector2T< T > &b, S tol=SYS_FTOLERANCE)
Componentwise equality.
Definition: UT_Vector2.h:674
const GR_MaterialPtr & getDefaultMaterial() const
Definition: GR_Material.h:254
Reader/Writer mutex class.
Definition: UT_RWLock.h:48
RV_ImageDim
Definition: RV_Type.h:120
Base::const_iterator const_iterator
Definition: UT_Map.h:120
void incref()
Definition: GR_SceneItem.h:31
exint id() const
Definition: GR_SceneItem.h:24
void setExtraInputs(const UT_StringMap< InputType > &extra_inputs)
Definition: GR_Material.h:192