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);
84 
85  /// Create a shader handle with source files. All source files must share
86  /// the same GLSL version (100,110,120,130,140,150,330,400,410...) and be
87  /// whitespace separated in the string.
88  RE_ShaderHandle(const char *program_name,
89  int code_version,
90  const char *files,
91  bool register_shader = true,
92  const char *defines = nullptr);
93 
94  RE_ShaderHandle(const RE_ShaderHandle &handle);
95  ~RE_ShaderHandle();
96 
98  {
99  UT_ASSERT(myShader);
100  return myShader.get();
101  }
102 
103  /// Set the defines for the program, overwriting existing ones.
104  void setProgramDefines(const char *defines)
105  { myDefines.harden(defines); }
106  /// Add more defines to the defines list
107  void appendProgramDefines(const char *defines)
108  { myDefines +="\n"; myDefines += defines; }
109 
110  /// Default language is GLSL.
111  void setShaderLanguage(RE_ShaderLanguage lang);
112 
113  /// Returns true if the shader was initialized. The shader still may be
114  /// invalid (compiled improperly).
115  bool isInitialized() const { return myInitFlag; }
116 
117  /// Returns true if the shader successfully compiled. This may force a
118  /// compile.
120  {
121  if(!myInitFlag)
122  return compile(r);
123  return (myShader != nullptr);
124  }
125 
126  /// Explicitly compile the shader. Has no effect if the shader is already
127  /// compiled. Returns true if the shader compiled successfully or was
128  /// already compiled, or false if the compile failed or previously failed.
129  bool compile(RE_Render *r);
130 
131  /// Returns the GLSL or Cg version that the shader was compiled with.
132  int getCodeVersion() const { return myCodeVersion; }
133 
134  /// Returns the shader for this handle. Will return nullptr if the shader
135  /// did not compile.
136  RE_Shader *getShader() const { return myShader.get(); }
137 
138  /// Prints this shader's errors, warnings and messages.
139  void printErrors(std::ostream &os) const;
140 
141  /// Returns a NUL-terminated string of errors. Empty string if no errors
142  /// exist, or if the shader has not been compiled yet.
143  const char *getErrors() const { return myErrors.nonNullBuffer(); }
144 
145  /// Name of the shader (if any) or the .prog pathname
146  const char *getName() const;
147 
148  const char *getSourceFiles() const { return mySourceFiles; }
149  const char *getDefines() const { return myDefines; }
150 
151  /// Create a shader that is owner by the caller
152  /// If the shader failed to compile, then an empty pointer is returned.
154  createDetachedShader(RE_Render *r,
155  UT_String *errors = nullptr) const;
156 
157  /// Returns a list of #defines for platform, vendor, driver version.
158  static const char *getSystemDefines(RE_Render *r)
159  {
160  if(!theVendorDefines.isstring())
161  initializeDriverInformation(r);
162  return theVendorDefines;
163  }
164 
165 private:
166  static void initializeDriverInformation(RE_Render *r);
167 
169  compileImpl(RE_Render *r, UT_String *errors) const;
170 
171  UT_String myName;
172  RE_ShaderLanguage myShaderLanguage;
173  int myCodeVersion;
174  UT_String mySourceFiles;
175  UT_String myDefines;
177  myShader;
178  bool myInitFlag;
179  UT_String myErrors;
180  mutable UT_Lock myLock;
181  bool myRegisterFlag;
182  static UT_String theVendorDefines;
183 };
184 
185 #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
void appendProgramDefines(const char *defines)
Add more defines to the defines list.
RE_Shader * operator->()
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.
const char * getSourceFiles() const
RE_Shader * getShader() const
#define UT_ASSERT(ZZ)
Definition: UT_Assert.h:153
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:242
bool isValid(RE_Render *r)
Simple interface to building a shader from a .prog file.