1 /*=========================================================================
2 
3   Program:   Visualization Toolkit
4 
5   Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
6   All rights reserved.
7   See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
8 
9      This software is distributed WITHOUT ANY WARRANTY; without even
10      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
11      PURPOSE.  See the above copyright notice for more information.
12 
13 =========================================================================*/
14 // .NAME vtkShaderProgram - a glsl shader program
15 // .SECTION Description
16 // This class contains the vertex, fragment, geometry shaders that combine to make a shader program
17 #ifndef vtkShaderProgram_h
18 #define vtkShaderProgram_h
19 
20 #include "vtkRenderingOpenGL2Module.h" // for export macro
21 #include "vtkObject.h"
22 
23 #include <string> // For member variables.
24 #include <map>    // For member variables.
25 
26 class vtkMatrix3x3;
27 class vtkMatrix4x4;
28 class vtkShader;
29 class VertexArrayObject;
30 class vtkWindow;
31 
32 /**
33  * @brief The ShaderProgram uses one or more Shader objects.
34  *
35  * This class creates a Vertex or Fragment shader, that can be attached to a
36  * ShaderProgram in order to render geometry etc.
37  */
38 
39 class VTKRENDERINGOPENGL2_EXPORT vtkShaderProgram : public vtkObject
40 {
41 public:
42   static vtkShaderProgram *New();
43   vtkTypeMacro(vtkShaderProgram, vtkObject);
44   void PrintSelf(ostream& os, vtkIndent indent);
45 
46   // Description:
47   // Get the vertex shader for this program
48   vtkGetObjectMacro(VertexShader, vtkShader);
49 
50   // Description:
51   // Get the fragment shader for this program
52   vtkGetObjectMacro(FragmentShader, vtkShader);
53 
54   // Description:
55   // Get the geometry shader for this program
56   vtkGetObjectMacro(GeometryShader, vtkShader);
57 
58   // Description:
59   // Set/Get flag for if this program is compiled
60   vtkGetMacro(Compiled, bool);
61   vtkSetMacro(Compiled, bool);
62   vtkBooleanMacro(Compiled, bool);
63 
64   // Description:
65   // Set/Get the md5 hash of this program
GetMD5Hash()66   std::string GetMD5Hash() const { return this->MD5Hash; }
SetMD5Hash(const std::string & hash)67   void SetMD5Hash(const std::string &hash) { this->MD5Hash = hash; }
68 
69 
70   /** Options for attribute normalization. */
71   enum NormalizeOption {
72     /// The values range across the limits of the numeric type.
73     /// This option instructs the rendering engine to normalize them to
74     /// the range [0.0, 1.0] for unsigned types, and [-1.0, 1.0] for signed
75     /// types.
76     /// For example, unsigned char values will be mapped so that 0 = 0.0,
77     /// and 255 = 1.0.
78     /// The resulting floating point numbers will be passed into
79     /// the shader program.
80     Normalize,
81     /// The values should be used as-is. Do not perform any normalization.
82     NoNormalize
83   };
84 
85 
86   /**
87    * Check if the program is currently bound, or not.
88    * @return True if the program is bound, false otherwise.
89    */
isBound()90   bool isBound() const { return this->Bound; }
91 
92   // Description:
93   // release any graphics resources this class is using.
94   void ReleaseGraphicsResources(vtkWindow *win);
95 
96   /** Get the handle of the shader program. */
GetHandle()97   int GetHandle() const { return Handle; }
98 
99   /** Get the error message (empty if none) for the shader program. */
GetError()100   std::string GetError() const { return Error; }
101 
102   /**
103    * Enable the named attribute array. Return false if the attribute array is
104    * not contained in the linked shader program.
105    */
106   bool EnableAttributeArray(const char *name);
107 
108   /**
109    * Disable the named attribute array. Return false if the attribute array is
110    * not contained in the linked shader program.
111    */
112   bool DisableAttributeArray(const char *name);
113 
114   /**
115    * Use the named attribute array with the bound BufferObject.
116    * @param name of the attribute (as seen in the shader program).
117    * @param offset into the bound BufferObject.
118    * @param stride The stride of the element access (i.e. the size of each
119    * element in the currently bound BufferObject). 0 may be used to indicate
120    * tightly packed data.
121    * @param elementType Tag identifying the memory representation of the
122    * element.
123    * @param elementTupleSize The number of elements per vertex (e.g. a 3D
124    * position attribute would be 3).
125    * @param normalize Indicates the range used by the attribute data.
126    * See NormalizeOption for more information.
127    * @return false if the attribute array does not exist.
128    */
129   bool UseAttributeArray(const char *name, int offset, size_t stride,
130                          int elementType, int elementTupleSize,
131                          NormalizeOption normalize);
132 
133   /**
134    * Upload the supplied array of tightly packed values to the named attribute.
135    * BufferObject attributes should be preferred and this may be removed in
136    * future.
137    *
138    * @param name Attribute name
139    * @param array Container of data. See note.
140    * @param tupleSize The number of elements per vertex, e.g. a 3D coordinate
141    * array will have a tuple size of 3.
142    * @param  normalize Indicates the range used by the attribute data.
143    * See NormalizeOption for more information.
144    *
145    * @note The T type must have tightly packed values of
146    * T::value_type accessible by reference via T::operator[].
147    * Additionally, the standard size() and empty() methods must be implemented.
148    * The std::vector classes is an example of such a container.
149    */
150   template <class T>
151   bool SetAttributeArray(const char *name, const T &array,
152                          int tupleSize, NormalizeOption normalize);
153 
154   /** Set the @p name uniform value to int @p v. */
155   bool SetUniformi(const char *name, int v);
156   bool SetUniformf(const char *name, float v);
157   bool SetUniform2i(const char *name, const int v[2]);
158   bool SetUniform2f(const char *name, const float v[2]);
159   bool SetUniform3f(const char *name, const float v[3]);
160   bool SetUniform4f(const char *name, const float v[4]);
161   bool SetUniform3uc(const char *name, const unsigned char v[3]); // maybe remove
162   bool SetUniform4uc(const char *name, const unsigned char v[4]); // maybe remove
163   bool SetUniformMatrix(const char *name, vtkMatrix3x3 *v);
164   bool SetUniformMatrix(const char *name, vtkMatrix4x4 *v);
165   bool SetUniformMatrix3x3(const char *name, float *v);
166   bool SetUniformMatrix4x4(const char *name, float *v);
167 
168   /** Set the @p name uniform array to @p f with @p count elements */
169   bool SetUniform1iv(const char *name, const int count, const int *f);
170   bool SetUniform1fv(const char *name, const int count, const float *f);
171   bool SetUniform2fv(const char *name, const int count, const float (*f)[2]);
172   bool SetUniform3fv(const char *name, const int count, const float (*f)[3]);
173   bool SetUniform4fv(const char *name, const int count, const float (*f)[4]);
174 
175 protected:
176   vtkShaderProgram();
177   ~vtkShaderProgram();
178 
179   /***************************************************************
180    * The following functions are only for use by the shader cache
181    * which is why they are protected and that class is a friend
182    * you need to use the shader cache to compile/link/bind your shader
183    * do not try to do it yourself as it will screw up the cache
184    ***************************************************************/
185    friend class vtkOpenGLShaderCache;
186 
187     /**
188    * Attach the supplied shader to this program.
189    * @note A maximum of one Vertex shader and one Fragment shader can be
190    * attached to a shader program.
191    * @return true on success.
192    */
193   bool AttachShader(const vtkShader *shader);
194 
195   /** Detach the supplied shader from this program.
196    * @note A maximum of one Vertex shader and one Fragment shader can be
197    * attached to a shader program.
198    * @return true on success.
199    */
200   bool DetachShader(const vtkShader *shader);
201 
202   // Description:
203   // Compile this shader program and attached shaders
204   virtual int CompileShader();
205 
206   /**
207    * Attempt to link the shader program.
208    * @return false on failure. Query error to get the reason.
209    * @note The shaders attached to the program must have been compiled.
210    */
211   bool Link();
212 
213   /**
214    * Bind the program in order to use it. If the program has not been linked
215    * then link() will be called.
216    */
217   bool Bind();
218 
219   /** Releases the shader program from the current context. */
220   void Release();
221 
222   /************* end **************************************/
223 
224   vtkShader *VertexShader;
225   vtkShader *FragmentShader;
226   vtkShader *GeometryShader;
227 
228   // hash of the shader program
229   std::string MD5Hash;
230 
231   bool SetAttributeArrayInternal(const char *name, void *buffer,
232                                  int type, int tupleSize,
233                                  NormalizeOption normalize);
234   int Handle;
235   int VertexShaderHandle;
236   int FragmentShaderHandle;
237 
238   bool Linked;
239   bool Bound;
240   bool Compiled;
241 
242   std::string Error;
243 
244   std::map<std::string, int> Attributes;
245 
246   friend class VertexArrayObject;
247 
248 private:
249   int FindAttributeArray(const char *name);
250   int FindUniform(const char *name);
251 
252   vtkShaderProgram(const vtkShaderProgram&);  // Not implemented.
253   void operator=(const vtkShaderProgram&);  // Not implemented.
254 };
255 
256 
257 #endif
258