1 /*=========================================================================
2
3 Program: Visualization Toolkit
4 Module: vtkShaderProperty.cxx
5
6 Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7 All rights reserved.
8 See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9
10 This software is distributed WITHOUT ANY WARRANTY; without even
11 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12 PURPOSE. See the above copyright notice for more information.
13
14 =========================================================================*/
15 #include "vtkOpenGLShaderProperty.h"
16
17 #include "vtkObjectFactory.h"
18 #include "vtkOpenGLUniforms.h"
19 #include <algorithm>
20
21 vtkStandardNewMacro(vtkOpenGLShaderProperty);
22
23 vtkOpenGLShaderProperty::vtkOpenGLShaderProperty() = default;
24
25 vtkOpenGLShaderProperty::~vtkOpenGLShaderProperty() = default;
26
DeepCopy(vtkOpenGLShaderProperty * p)27 void vtkOpenGLShaderProperty::DeepCopy(vtkOpenGLShaderProperty* p)
28 {
29 vtkShaderProperty::DeepCopy(p);
30 this->UserShaderReplacements = p->UserShaderReplacements;
31 }
32
AddVertexShaderReplacement(const std::string & originalValue,bool replaceFirst,const std::string & replacementValue,bool replaceAll)33 void vtkOpenGLShaderProperty::AddVertexShaderReplacement(const std::string& originalValue,
34 bool replaceFirst, // do this replacement before the default
35 const std::string& replacementValue, bool replaceAll)
36 {
37 this->AddShaderReplacement(
38 vtkShader::Vertex, originalValue, replaceFirst, replacementValue, replaceAll);
39 }
40
AddFragmentShaderReplacement(const std::string & originalValue,bool replaceFirst,const std::string & replacementValue,bool replaceAll)41 void vtkOpenGLShaderProperty::AddFragmentShaderReplacement(const std::string& originalValue,
42 bool replaceFirst, // do this replacement before the default
43 const std::string& replacementValue, bool replaceAll)
44 {
45 this->AddShaderReplacement(
46 vtkShader::Fragment, originalValue, replaceFirst, replacementValue, replaceAll);
47 }
48
AddGeometryShaderReplacement(const std::string & originalValue,bool replaceFirst,const std::string & replacementValue,bool replaceAll)49 void vtkOpenGLShaderProperty::AddGeometryShaderReplacement(const std::string& originalValue,
50 bool replaceFirst, // do this replacement before the default
51 const std::string& replacementValue, bool replaceAll)
52 {
53 this->AddShaderReplacement(
54 vtkShader::Geometry, originalValue, replaceFirst, replacementValue, replaceAll);
55 }
56
GetNumberOfShaderReplacements()57 int vtkOpenGLShaderProperty::GetNumberOfShaderReplacements()
58 {
59 return static_cast<int>(UserShaderReplacements.size());
60 }
61
GetNthShaderReplacementTypeAsString(vtkIdType index)62 std::string vtkOpenGLShaderProperty::GetNthShaderReplacementTypeAsString(vtkIdType index)
63 {
64 if (index >= static_cast<vtkIdType>(this->UserShaderReplacements.size()))
65 {
66 vtkErrorMacro(<< "Trying to access out of bound shader replacement.");
67 return std::string("");
68 }
69 ReplacementMap::iterator it = this->UserShaderReplacements.begin();
70 std::advance(it, index);
71 if (it->first.ShaderType == vtkShader::Vertex)
72 {
73 return std::string("Vertex");
74 }
75 else if (it->first.ShaderType == vtkShader::Fragment)
76 {
77 return std::string("Fragment");
78 }
79 else if (it->first.ShaderType == vtkShader::Geometry)
80 {
81 return std::string("Geometry");
82 }
83 return std::string("Unknown");
84 }
85
GetNthShaderReplacement(vtkIdType index,std::string & name,bool & replaceFirst,std::string & replacementValue,bool & replaceAll)86 void vtkOpenGLShaderProperty::GetNthShaderReplacement(vtkIdType index, std::string& name,
87 bool& replaceFirst, std::string& replacementValue, bool& replaceAll)
88 {
89 if (index >= static_cast<vtkIdType>(this->UserShaderReplacements.size()))
90 {
91 vtkErrorMacro(<< "Trying to access out of bound shader replacement.");
92 }
93 ReplacementMap::iterator it = this->UserShaderReplacements.begin();
94 std::advance(it, index);
95 name = it->first.OriginalValue;
96 replaceFirst = it->first.ReplaceFirst;
97 replacementValue = it->second.Replacement;
98 replaceAll = it->second.ReplaceAll;
99 }
100
ClearVertexShaderReplacement(const std::string & originalValue,bool replaceFirst)101 void vtkOpenGLShaderProperty::ClearVertexShaderReplacement(
102 const std::string& originalValue, bool replaceFirst)
103 {
104 this->ClearShaderReplacement(vtkShader::Vertex, originalValue, replaceFirst);
105 }
106
ClearFragmentShaderReplacement(const std::string & originalValue,bool replaceFirst)107 void vtkOpenGLShaderProperty::ClearFragmentShaderReplacement(
108 const std::string& originalValue, bool replaceFirst)
109 {
110 this->ClearShaderReplacement(vtkShader::Fragment, originalValue, replaceFirst);
111 }
112
ClearGeometryShaderReplacement(const std::string & originalValue,bool replaceFirst)113 void vtkOpenGLShaderProperty::ClearGeometryShaderReplacement(
114 const std::string& originalValue, bool replaceFirst)
115 {
116 this->ClearShaderReplacement(vtkShader::Geometry, originalValue, replaceFirst);
117 }
118
ClearAllVertexShaderReplacements()119 void vtkOpenGLShaderProperty::ClearAllVertexShaderReplacements()
120 {
121 this->ClearAllShaderReplacements(vtkShader::Vertex);
122 }
123
ClearAllFragmentShaderReplacements()124 void vtkOpenGLShaderProperty::ClearAllFragmentShaderReplacements()
125 {
126 this->ClearAllShaderReplacements(vtkShader::Fragment);
127 }
128
ClearAllGeometryShaderReplacements()129 void vtkOpenGLShaderProperty::ClearAllGeometryShaderReplacements()
130 {
131 this->ClearAllShaderReplacements(vtkShader::Geometry);
132 }
133
134 //------------------------------------------------------------------------------
ClearAllShaderReplacements()135 void vtkOpenGLShaderProperty::ClearAllShaderReplacements()
136 {
137 this->SetVertexShaderCode(nullptr);
138 this->SetFragmentShaderCode(nullptr);
139 this->SetGeometryShaderCode(nullptr);
140 this->UserShaderReplacements.clear();
141 this->Modified();
142 }
143
144 //------------------------------------------------------------------------------
AddShaderReplacement(vtkShader::Type shaderType,const std::string & originalValue,bool replaceFirst,const std::string & replacementValue,bool replaceAll)145 void vtkOpenGLShaderProperty::AddShaderReplacement(
146 vtkShader::Type shaderType, // vertex, fragment, etc
147 const std::string& originalValue,
148 bool replaceFirst, // do this replacement before the default
149 const std::string& replacementValue, bool replaceAll)
150 {
151 vtkShader::ReplacementSpec spec;
152 spec.ShaderType = shaderType;
153 spec.OriginalValue = originalValue;
154 spec.ReplaceFirst = replaceFirst;
155
156 vtkShader::ReplacementValue values;
157 values.Replacement = replacementValue;
158 values.ReplaceAll = replaceAll;
159
160 this->UserShaderReplacements[spec] = values;
161 this->Modified();
162 }
163
164 //------------------------------------------------------------------------------
ClearShaderReplacement(vtkShader::Type shaderType,const std::string & originalValue,bool replaceFirst)165 void vtkOpenGLShaderProperty::ClearShaderReplacement(
166 vtkShader::Type shaderType, // vertex, fragment, etc
167 const std::string& originalValue, bool replaceFirst)
168 {
169 vtkShader::ReplacementSpec spec;
170 spec.ShaderType = shaderType;
171 spec.OriginalValue = originalValue;
172 spec.ReplaceFirst = replaceFirst;
173
174 typedef std::map<vtkShader::ReplacementSpec, vtkShader::ReplacementValue>::iterator RIter;
175 RIter found = this->UserShaderReplacements.find(spec);
176 if (found != this->UserShaderReplacements.end())
177 {
178 this->UserShaderReplacements.erase(found);
179 this->Modified();
180 }
181 }
182
183 //------------------------------------------------------------------------------
ClearAllShaderReplacements(vtkShader::Type shaderType)184 void vtkOpenGLShaderProperty::ClearAllShaderReplacements(vtkShader::Type shaderType)
185 {
186 bool modified = false;
187 // First clear all shader code
188 if ((shaderType == vtkShader::Vertex) && this->VertexShaderCode)
189 {
190 this->SetVertexShaderCode(nullptr);
191 modified = true;
192 }
193 else if ((shaderType == vtkShader::Fragment) && this->FragmentShaderCode)
194 {
195 this->SetFragmentShaderCode(nullptr);
196 modified = true;
197 }
198
199 // Now clear custom tag replacements
200 std::map<vtkShader::ReplacementSpec, vtkShader::ReplacementValue>::iterator rIter;
201 for (rIter = this->UserShaderReplacements.begin(); rIter != this->UserShaderReplacements.end();)
202 {
203 if (rIter->first.ShaderType == shaderType)
204 {
205 this->UserShaderReplacements.erase(rIter++);
206 modified = true;
207 }
208 else
209 {
210 ++rIter;
211 }
212 }
213 if (modified)
214 {
215 this->Modified();
216 }
217 }
218
219 //------------------------------------------------------------------------------
PrintSelf(ostream & os,vtkIndent indent)220 void vtkOpenGLShaderProperty::PrintSelf(ostream& os, vtkIndent indent)
221 {
222 this->Superclass::PrintSelf(os, indent);
223 }
224