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