HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
RE_ShaderHandle.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: Render Library (C++)
7  *
8  * COMMENTS:
9  * Provides a handle to a shader and convenient methods for constructing
10  * shaders and testing for errors.
11  *
12  * Program files (.prog) are supported, with a limited syntax for
13  * constructing shaders. They contain shader files to be linked, in version
14  * blocks. A program file may have multiple version blocks. The highest
15  * supported GLSL version block is used.
16  *
17  * The directives are:
18  *
19  * #name <string> The name of the shader is "string"
20  * #version <ver> Specifies a base GLSL version (ie 110, 330, 410)
21  * #extension <ext> Extension ext must be supported (ie GL_ARB_shadows)
22  * #output <name> <num> Fragment output <name> is mapped to buffer <num>
23  *
24  * If either the #version check or any #extension check within the block
25  * fails, the entire block is discarded. A new block begins with #version.
26  *
27  * #name is used to specify an english name for the shader, otherwise
28  * the filename of the program is used. It resides outside of any version
29  * block.
30  *
31  * #output is used to connect fragment shader outputs to draw buffer
32  * indices. It is only used for GLSL versions >= 130.
33  *
34  * Comments are supported if the line begins with //. Comments are not
35  * supported elsewhere. All other non-blank lines are expected to be
36  * shader filenames. Indentation is supported but ignored.
37  *
38  * #name Blended Matte Shader
39  * // fallback shader
40  * #version 110
41  * basic/GL20/pos_transform.vert
42  * basic/GL20/const_color.frag
43  *
44  * #version 130
45  * #extension GL_ARB_draw_buffers
46  * #output fgcolor 0
47  * #output bgcolor 1
48  * basic/GL30/pos_transform.vert
49  * basic/GL30/blend_color.frag
50  *
51  * #version 400
52  * #output fgcolor 0
53  * #output bgcolor 1
54  * basic/GL40/pos_transform.vert
55  * basic/GL40/blend_color.frag
56  *
57  * If GLSL 4.0 is supported, the 400 block shaders (GL40) will be used.
58  * If GLSL 1.30 to 3.3 is supported along with the GL_ARB_draw_buffers
59  * extension, then 130 block shaders (GL30) are used.
60  * Otherwise, the 1.10 block's shaders will be used.
61  *
62  * You can determine the shader that was loaded via getCodeVersion().
63  */
64 #ifndef RE_ShaderHandle_h
65 #define RE_ShaderHandle_h
66 
67 #include "RE_Types.h"
68 #include <iosfwd>
69 #include <UT/UT_Lock.h>
70 #include <UT/UT_String.h>
71 #include <UT/UT_UniquePtr.h>
72 
73 class RE_Render;
74 class RE_Shader;
75 
76 /// Simple interface to building a shader from a .prog file.
78 {
79 public:
80  /// Create a shader handle using a .prog file.
81  RE_ShaderHandle(const char *program_file,
82  bool register_shader = true,
83  const char *defines = nullptr,
85 
86  /// Create a shader handle with source files. All source files must share
87  /// the same GLSL version (100,110,120,130,140,150,330,400,410...) and be
88  /// whitespace separated in the string.
89  RE_ShaderHandle(const char *program_name,
90  int code_version,
91  const char *files,
92  bool register_shader = true,
93  const char *defines = nullptr,
95 
97  virtual ~RE_ShaderHandle();
98 
100  {
101  UT_ASSERT(myShader);
102  return myShader.get();
103  }
104 
105  /// Set the defines for the program, overwriting existing ones.
106  void setProgramDefines(const char *defines)
107  { myDefines.harden(defines); }
108  /// Add more defines to the defines list
109  void appendProgramDefines(const char *defines)
110  { myDefines +="\n"; myDefines += defines; }
111 
112  /// Default language is GLSL.
113  void setShaderLanguage(RE_ShaderLanguage lang);
114 
115  /// Returns true if the shader was initialized. The shader still may be
116  /// invalid (compiled improperly).
117  bool isInitialized() const { return myInitFlag; }
118 
119  /// Returns true if the shader successfully compiled. This may force a
120  /// compile.
122  {
123  if(!myInitFlag)
124  return compile(r);
125  return (myShader != nullptr);
126  }
127 
128  /// Explicitly compile the shader. Has no effect if the shader is already
129  /// compiled. Returns true if the shader compiled successfully or was
130  /// already compiled, or false if the compile failed or previously failed.
131  bool compile(RE_Render *r, UT_WorkBuffer *msg = nullptr);
132 
133  /// Returns the GLSL or Cg version that the shader was compiled with.
134  int getCodeVersion() const { return myCodeVersion; }
135 
136  /// Returns the shader for this handle. Will return nullptr if the shader
137  /// did not compile.
138  RE_Shader *getShader() const { return myShader.get(); }
139 
140  /// Prints this shader's errors, warnings and messages.
141  void printErrors(std::ostream &os) const;
142 
143  /// Returns a NUL-terminated string of errors. Empty string if no errors
144  /// exist, or if the shader has not been compiled yet.
145  const char *getErrors() const { return myErrors.nonNullBuffer(); }
146 
147  /// Name of the shader (if any) or the .prog pathname
148  const char *getName() const;
149 
150  const char *getSourceFiles() const { return mySourceFiles; }
151  const char *getDefines() const { return myDefines; }
152 
153  /// Create a shader that is owner by the caller
154  /// If the shader failed to compile, then an empty pointer is returned.
156  createDetachedShader(RE_Render *r,
157  UT_String *errors = nullptr) const;
158 
159  /// Returns a list of #defines for platform, vendor, driver version.
160  static const char *getSystemDefines(RE_Render *r)
161  {
162  if(!theVendorDefines.isstring())
163  initializeDriverInformation(r);
164  return theVendorDefines;
165  }
166 
167 protected:
168  static void initializeDriverInformation(RE_Render *r);
169 
170  virtual UT_UniquePtr<RE_Shader>
171  compileImpl(RE_Render *r, UT_String *errors) const;
172 
182  mutable UT_Lock myLock;
185 };
186 
187 #endif
#define RE_API
Definition: RE_API.h:10
const char * getErrors() const
const char * getDefines() const
std::unique_ptr< T, Deleter > UT_UniquePtr
A smart pointer for unique ownership of dynamically allocated objects.
Definition: UT_UniquePtr.h:39
RE_ShaderLanguage myShaderLanguage
void appendProgramDefines(const char *defines)
Add more defines to the defines list.
PXL_API const char * getName(const ColorSpace *space)
Return the name of the color space.
RE_Shader * operator->()
UT_UniquePtr< RE_Shader > myShader
bool isInitialized() const
void setProgramDefines(const char *defines)
Set the defines for the program, overwriting existing ones.
static const char * getSystemDefines(RE_Render *r)
Returns a list of #defines for platform, vendor, driver version.
UT_String mySourceFiles
static UT_String theVendorDefines
const char * getSourceFiles() const
RE_Shader * getShader() const
#define UT_ASSERT(ZZ)
Definition: UT_Assert.h:156
int getCodeVersion() const
Returns the GLSL or Cg version that the shader was compiled with.
GLboolean r
Definition: glcorearb.h:1222
RE_ShaderLanguage
Definition: RE_Types.h:257
bool isValid(RE_Render *r)
Simple interface to building a shader from a .prog file.