30f0ad28 |
1 | // Created on: 2013-09-19 |
2 | // Created by: Denis BOGOLEPOV |
3 | // Copyright (c) 2013 OPEN CASCADE SAS |
4 | // |
5 | // The content of this file is subject to the Open CASCADE Technology Public |
6 | // License Version 6.5 (the "License"). You may not use the content of this file |
7 | // except in compliance with the License. Please obtain a copy of the License |
8 | // at http://www.opencascade.org and read it completely before using this file. |
9 | // |
10 | // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its |
11 | // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France. |
12 | // |
13 | // The Original Code and all software distributed under the License is |
14 | // distributed on an "AS IS" basis, without warranty of any kind, and the |
15 | // Initial Developer hereby disclaims all such warranties, including without |
16 | // limitation, any warranties of merchantability, fitness for a particular |
17 | // purpose or non-infringement. Please see the License for the specific terms |
18 | // and conditions governing the rights and limitations under the License. |
19 | |
20 | #include <OSD_File.hxx> |
21 | #include <OSD_Protection.hxx> |
22 | |
23 | #include <Standard_Assert.hxx> |
24 | #include <Standard_Atomic.hxx> |
25 | #include <TCollection_ExtendedString.hxx> |
26 | |
27 | #include <OpenGl_Context.hxx> |
28 | #include <OpenGl_ShaderProgram.hxx> |
29 | #include <OpenGl_ShaderManager.hxx> |
30 | |
31 | IMPLEMENT_STANDARD_HANDLE (OpenGl_ShaderProgram, OpenGl_Resource) |
32 | IMPLEMENT_STANDARD_RTTIEXT(OpenGl_ShaderProgram, OpenGl_Resource) |
33 | |
34 | OpenGl_VariableSetterSelector OpenGl_ShaderProgram::mySetterSelector = OpenGl_VariableSetterSelector(); |
35 | |
36 | // Declare OCCT-specific OpenGL/GLSL shader variables |
37 | Standard_CString OpenGl_ShaderProgram::PredefinedKeywords[] = |
38 | { |
39 | /* OpenGl_OCC_MODEL_WORLD_MATRIX */ "occModelWorldMatrix", |
40 | /* OpenGl_OCC_WORLD_VIEW_MATRIX */ "occWorldViewMatrix", |
41 | /* OpenGl_OCC_PROJECTION_MATRIX */ "occProjectionMatrix", |
42 | /* OpenGl_OCC_MODEL_WORLD_MATRIX_INVERSE */ "occModelWorldMatrixInverse", |
43 | /* OpenGl_OCC_WORLD_VIEW_MATRIX_INVERSE */ "occWorldViewMatrixInverse", |
44 | /* OpenGl_OCC_PROJECTION_MATRIX_INVERSE */ "occProjectionMatrixInverse", |
45 | /* OpenGl_OCC_MODEL_WORLD_MATRIX_TRANSPOSE */ "occModelWorldMatrixTranspose", |
46 | /* OpenGl_OCC_WORLD_VIEW_MATRIX_TRANSPOSE */ "occWorldViewMatrixTranspose", |
47 | /* OpenGl_OCC_PROJECTION_MATRIX_TRANSPOSE */ "occProjectionMatrixTranspose", |
48 | /* OpenGl_OCC_MODEL_WORLD_MATRIX_INVERSE_TRANSPOSE */ "occModelWorldMatrixInverseTranspose", |
49 | /* OpenGl_OCC_WORLD_VIEW_MATRIX_INVERSE_TRANSPOSE */ "occWorldViewMatrixInverseTranspose", |
50 | /* OpenGl_OCC_PROJECTION_MATRIX_INVERSE_TRANSPOSE */ "occProjectionMatrixInverseTranspose", |
51 | |
52 | /* OpenGl_OCC_CLIP_PLANE_0_EQUATION */ "occClipPlanes[0].Equation", |
53 | /* OpenGl_OCC_CLIP_PLANE_1_EQUATION */ "occClipPlanes[1].Equation", |
54 | /* OpenGl_OCC_CLIP_PLANE_2_EQUATION */ "occClipPlanes[2].Equation", |
55 | /* OpenGl_OCC_CLIP_PLANE_3_EQUATION */ "occClipPlanes[3].Equation", |
56 | /* OpenGl_OCC_CLIP_PLANE_4_EQUATION */ "occClipPlanes[4].Equation", |
57 | /* OpenGl_OCC_CLIP_PLANE_5_EQUATION */ "occClipPlanes[5].Equation", |
58 | /* OpenGl_OCC_CLIP_PLANE_6_EQUATION */ "occClipPlanes[6].Equation", |
59 | /* OpenGl_OCC_CLIP_PLANE_7_EQUATION */ "occClipPlanes[7].Equation", |
60 | |
61 | /* OpenGl_OCC_CLIP_PLANE_0_SPACE */ "occClipPlanes[0].Space", |
62 | /* OpenGl_OCC_CLIP_PLANE_1_SPACE */ "occClipPlanes[1].Space", |
63 | /* OpenGl_OCC_CLIP_PLANE_2_SPACE */ "occClipPlanes[2].Space", |
64 | /* OpenGl_OCC_CLIP_PLANE_3_SPACE */ "occClipPlanes[3].Space", |
65 | /* OpenGl_OCC_CLIP_PLANE_4_SPACE */ "occClipPlanes[4].Space", |
66 | /* OpenGl_OCC_CLIP_PLANE_5_SPACE */ "occClipPlanes[5].Space", |
67 | /* OpenGl_OCC_CLIP_PLANE_6_SPACE */ "occClipPlanes[6].Space", |
68 | /* OpenGl_OCC_CLIP_PLANE_7_SPACE */ "occClipPlanes[7].Space", |
69 | |
70 | /* OpenGl_OCC_LIGHT_SOURCE_COUNT */ "occLightSourcesCount", |
71 | |
72 | /* OpenGl_OCC_LIGHT_SOURCE_0_TYPE */ "occLightSources[0].Type", |
73 | /* OpenGl_OCC_LIGHT_SOURCE_1_TYPE */ "occLightSources[1].Type", |
74 | /* OpenGl_OCC_LIGHT_SOURCE_2_TYPE */ "occLightSources[2].Type", |
75 | /* OpenGl_OCC_LIGHT_SOURCE_3_TYPE */ "occLightSources[3].Type", |
76 | /* OpenGl_OCC_LIGHT_SOURCE_4_TYPE */ "occLightSources[4].Type", |
77 | /* OpenGl_OCC_LIGHT_SOURCE_5_TYPE */ "occLightSources[5].Type", |
78 | /* OpenGl_OCC_LIGHT_SOURCE_6_TYPE */ "occLightSources[6].Type", |
79 | /* OpenGl_OCC_LIGHT_SOURCE_7_TYPE */ "occLightSources[7].Type", |
80 | |
81 | /* OpenGl_OCC_LIGHT_SOURCE_0_HEAD */ "occLightSources[0].Head", |
82 | /* OpenGl_OCC_LIGHT_SOURCE_1_HEAD */ "occLightSources[1].Head", |
83 | /* OpenGl_OCC_LIGHT_SOURCE_2_HEAD */ "occLightSources[2].Head", |
84 | /* OpenGl_OCC_LIGHT_SOURCE_3_HEAD */ "occLightSources[3].Head", |
85 | /* OpenGl_OCC_LIGHT_SOURCE_4_HEAD */ "occLightSources[4].Head", |
86 | /* OpenGl_OCC_LIGHT_SOURCE_5_HEAD */ "occLightSources[5].Head", |
87 | /* OpenGl_OCC_LIGHT_SOURCE_6_HEAD */ "occLightSources[6].Head", |
88 | /* OpenGl_OCC_LIGHT_SOURCE_7_HEAD */ "occLightSources[7].Head", |
89 | |
90 | /* OpenGl_OCC_LIGHT_SOURCE_0_AMBIENT */ "occLightSources[0].Ambient", |
91 | /* OpenGl_OCC_LIGHT_SOURCE_1_AMBIENT */ "occLightSources[1].Ambient", |
92 | /* OpenGl_OCC_LIGHT_SOURCE_2_AMBIENT */ "occLightSources[2].Ambient", |
93 | /* OpenGl_OCC_LIGHT_SOURCE_3_AMBIENT */ "occLightSources[3].Ambient", |
94 | /* OpenGl_OCC_LIGHT_SOURCE_4_AMBIENT */ "occLightSources[4].Ambient", |
95 | /* OpenGl_OCC_LIGHT_SOURCE_5_AMBIENT */ "occLightSources[5].Ambient", |
96 | /* OpenGl_OCC_LIGHT_SOURCE_6_AMBIENT */ "occLightSources[6].Ambient", |
97 | /* OpenGl_OCC_LIGHT_SOURCE_7_AMBIENT */ "occLightSources[7].Ambient", |
98 | |
99 | /* OpenGl_OCC_LIGHT_SOURCE_0_DIFFUSE */ "occLightSources[0].Diffuse", |
100 | /* OpenGl_OCC_LIGHT_SOURCE_1_DIFFUSE */ "occLightSources[1].Diffuse", |
101 | /* OpenGl_OCC_LIGHT_SOURCE_2_DIFFUSE */ "occLightSources[2].Diffuse", |
102 | /* OpenGl_OCC_LIGHT_SOURCE_3_DIFFUSE */ "occLightSources[3].Diffuse", |
103 | /* OpenGl_OCC_LIGHT_SOURCE_4_DIFFUSE */ "occLightSources[4].Diffuse", |
104 | /* OpenGl_OCC_LIGHT_SOURCE_5_DIFFUSE */ "occLightSources[5].Diffuse", |
105 | /* OpenGl_OCC_LIGHT_SOURCE_6_DIFFUSE */ "occLightSources[6].Diffuse", |
106 | /* OpenGl_OCC_LIGHT_SOURCE_7_DIFFUSE */ "occLightSources[7].Diffuse", |
107 | |
108 | /* OpenGl_OCC_LIGHT_SOURCE_0_SPECULAR */ "occLightSources[0].Specular", |
109 | /* OpenGl_OCC_LIGHT_SOURCE_1_SPECULAR */ "occLightSources[1].Specular", |
110 | /* OpenGl_OCC_LIGHT_SOURCE_2_SPECULAR */ "occLightSources[2].Specular", |
111 | /* OpenGl_OCC_LIGHT_SOURCE_3_SPECULAR */ "occLightSources[3].Specular", |
112 | /* OpenGl_OCC_LIGHT_SOURCE_4_SPECULAR */ "occLightSources[4].Specular", |
113 | /* OpenGl_OCC_LIGHT_SOURCE_5_SPECULAR */ "occLightSources[5].Specular", |
114 | /* OpenGl_OCC_LIGHT_SOURCE_6_SPECULAR */ "occLightSources[6].Specular", |
115 | /* OpenGl_OCC_LIGHT_SOURCE_7_SPECULAR */ "occLightSources[7].Specular", |
116 | |
117 | /* OpenGl_OCC_LIGHT_SOURCE_0_POSITION */ "occLightSources[0].Position", |
118 | /* OpenGl_OCC_LIGHT_SOURCE_1_POSITION */ "occLightSources[1].Position", |
119 | /* OpenGl_OCC_LIGHT_SOURCE_2_POSITION */ "occLightSources[2].Position", |
120 | /* OpenGl_OCC_LIGHT_SOURCE_3_POSITION */ "occLightSources[3].Position", |
121 | /* OpenGl_OCC_LIGHT_SOURCE_4_POSITION */ "occLightSources[4].Position", |
122 | /* OpenGl_OCC_LIGHT_SOURCE_5_POSITION */ "occLightSources[5].Position", |
123 | /* OpenGl_OCC_LIGHT_SOURCE_6_POSITION */ "occLightSources[6].Position", |
124 | /* OpenGl_OCC_LIGHT_SOURCE_7_POSITION */ "occLightSources[7].Position", |
125 | |
126 | /* OpenGl_OCC_LIGHT_SOURCE_0_SPOT_CUTOFF */ "occLightSources[0].SpotCutoff", |
127 | /* OpenGl_OCC_LIGHT_SOURCE_1_SPOT_CUTOFF */ "occLightSources[1].SpotCutoff", |
128 | /* OpenGl_OCC_LIGHT_SOURCE_2_SPOT_CUTOFF */ "occLightSources[2].SpotCutoff", |
129 | /* OpenGl_OCC_LIGHT_SOURCE_3_SPOT_CUTOFF */ "occLightSources[3].SpotCutoff", |
130 | /* OpenGl_OCC_LIGHT_SOURCE_4_SPOT_CUTOFF */ "occLightSources[4].SpotCutoff", |
131 | /* OpenGl_OCC_LIGHT_SOURCE_5_SPOT_CUTOFF */ "occLightSources[5].SpotCutoff", |
132 | /* OpenGl_OCC_LIGHT_SOURCE_6_SPOT_CUTOFF */ "occLightSources[6].SpotCutoff", |
133 | /* OpenGl_OCC_LIGHT_SOURCE_7_SPOT_CUTOFF */ "occLightSources[7].SpotCutoff", |
134 | |
135 | /* OpenGl_OCC_LIGHT_SOURCE_0_SPOT_EXPONENT */ "occLightSources[0].SpotExponent", |
136 | /* OpenGl_OCC_LIGHT_SOURCE_1_SPOT_EXPONENT */ "occLightSources[1].SpotExponent", |
137 | /* OpenGl_OCC_LIGHT_SOURCE_2_SPOT_EXPONENT */ "occLightSources[2].SpotExponent", |
138 | /* OpenGl_OCC_LIGHT_SOURCE_3_SPOT_EXPONENT */ "occLightSources[3].SpotExponent", |
139 | /* OpenGl_OCC_LIGHT_SOURCE_4_SPOT_EXPONENT */ "occLightSources[4].SpotExponent", |
140 | /* OpenGl_OCC_LIGHT_SOURCE_5_SPOT_EXPONENT */ "occLightSources[5].SpotExponent", |
141 | /* OpenGl_OCC_LIGHT_SOURCE_6_SPOT_EXPONENT */ "occLightSources[6].SpotExponent", |
142 | /* OpenGl_OCC_LIGHT_SOURCE_7_SPOT_EXPONENT */ "occLightSources[7].SpotExponent", |
143 | |
144 | /* OpenGl_OCC_LIGHT_SOURCE_0_SPOT_DIRECTION */ "occLightSources[0].SpotDirection", |
145 | /* OpenGl_OCC_LIGHT_SOURCE_1_SPOT_DIRECTION */ "occLightSources[1].SpotDirection", |
146 | /* OpenGl_OCC_LIGHT_SOURCE_2_SPOT_DIRECTION */ "occLightSources[2].SpotDirection", |
147 | /* OpenGl_OCC_LIGHT_SOURCE_3_SPOT_DIRECTION */ "occLightSources[3].SpotDirection", |
148 | /* OpenGl_OCC_LIGHT_SOURCE_4_SPOT_DIRECTION */ "occLightSources[4].SpotDirection", |
149 | /* OpenGl_OCC_LIGHT_SOURCE_5_SPOT_DIRECTION */ "occLightSources[5].SpotDirection", |
150 | /* OpenGl_OCC_LIGHT_SOURCE_6_SPOT_DIRECTION */ "occLightSources[6].SpotDirection", |
151 | /* OpenGl_OCC_LIGHT_SOURCE_7_SPOT_DIRECTION */ "occLightSources[7].SpotDirection", |
152 | |
153 | /* OpenGl_OCC_LIGHT_SOURCE_0_CONST_ATTENUATION */ "occLightSources[0].ConstAttenuation", |
154 | /* OpenGl_OCC_LIGHT_SOURCE_1_CONST_ATTENUATION */ "occLightSources[1].ConstAttenuation", |
155 | /* OpenGl_OCC_LIGHT_SOURCE_2_CONST_ATTENUATION */ "occLightSources[2].ConstAttenuation", |
156 | /* OpenGl_OCC_LIGHT_SOURCE_3_CONST_ATTENUATION */ "occLightSources[3].ConstAttenuation", |
157 | /* OpenGl_OCC_LIGHT_SOURCE_4_CONST_ATTENUATION */ "occLightSources[4].ConstAttenuation", |
158 | /* OpenGl_OCC_LIGHT_SOURCE_5_CONST_ATTENUATION */ "occLightSources[5].ConstAttenuation", |
159 | /* OpenGl_OCC_LIGHT_SOURCE_6_CONST_ATTENUATION */ "occLightSources[6].ConstAttenuation", |
160 | /* OpenGl_OCC_LIGHT_SOURCE_7_CONST_ATTENUATION */ "occLightSources[7].ConstAttenuation", |
161 | |
162 | /* OpenGl_OCC_LIGHT_SOURCE_0_LINEAR_ATTENUATION */ "occLightSources[0].LinearAttenuation", |
163 | /* OpenGl_OCC_LIGHT_SOURCE_1_LINEAR_ATTENUATION */ "occLightSources[1].LinearAttenuation", |
164 | /* OpenGl_OCC_LIGHT_SOURCE_2_LINEAR_ATTENUATION */ "occLightSources[2].LinearAttenuation", |
165 | /* OpenGl_OCC_LIGHT_SOURCE_3_LINEAR_ATTENUATION */ "occLightSources[3].LinearAttenuation", |
166 | /* OpenGl_OCC_LIGHT_SOURCE_4_LINEAR_ATTENUATION */ "occLightSources[4].LinearAttenuation", |
167 | /* OpenGl_OCC_LIGHT_SOURCE_5_LINEAR_ATTENUATION */ "occLightSources[5].LinearAttenuation", |
168 | /* OpenGl_OCC_LIGHT_SOURCE_6_LINEAR_ATTENUATION */ "occLightSources[6].LinearAttenuation", |
169 | /* OpenGl_OCC_LIGHT_SOURCE_7_LINEAR_ATTENUATION */ "occLightSources[7].LinearAttenuation", |
170 | |
171 | /* OpenGl_OCCT_ACTIVE_SAMPLER */ "occActiveSampler", |
172 | /* OpenGl_OCCT_TEXTURE_ENABLE */ "occTextureEnable", |
173 | /* OpenGl_OCCT_DISTINGUISH_MODE */ "occDistinguishingMode", |
174 | /* OpenGl_OCCT_FRONT_MATERIAL_AMBIENT */ "occFrontMaterial.Ambient", |
175 | /* OpenGl_OCCT_BACK_MATERIAL_AMBIENT */ "occBackMaterial.Ambient", |
176 | /* OpenGl_OCCT_FRONT_MATERIAL_DIFFUSE */ "occFrontMaterial.Diffuse", |
177 | /* OpenGl_OCCT_BACK_MATERIAL_DIFFUSE */ "occBackMaterial.Diffuse", |
178 | /* OpenGl_OCCT_FRONT_MATERIAL_SPECULAR */ "occFrontMaterial.Specular", |
179 | /* OpenGl_OCCT_BACK_MATERIAL_SPECULAR */ "occBackMaterial.Specular", |
180 | /* OpenGl_OCCT_FRONT_MATERIAL_EMISSION */ "occFrontMaterial.Emission", |
181 | /* OpenGl_OCCT_BACK_MATERIAL_EMISSION */ "occBackMaterial.Emission", |
182 | /* OpenGl_OCCT_FRONT_MATERIAL_SHININESS */ "occFrontMaterial.Shininess", |
183 | /* OpenGl_OCCT_BACK_MATERIAL_SHININESS */ "occBackMaterial.Shininess", |
184 | /* OpenGl_OCCT_FRONT_MATERIAL_TRANSPARENCY */ "occFrontMaterial.Transparency", |
185 | /* OpenGl_OCCT_BACK_MATERIAL_TRANSPARENCY */ "occBackMaterial.Transparency" |
186 | |
187 | }; |
188 | |
189 | // ======================================================================= |
190 | // function : OpenGl_VariableSetterSelector |
191 | // purpose : Creates new variable setter selector |
192 | // ======================================================================= |
193 | OpenGl_VariableSetterSelector::OpenGl_VariableSetterSelector() |
194 | { |
195 | // Note: Add new variable setters here |
196 | mySetterList = OpenGl_HashMapInitializer::CreateListOf<size_t, OpenGl_SetterInterface*> |
197 | (Graphic3d_UniformValueTypeID<int>::ID, new OpenGl_VariableSetter<int>()) |
198 | (Graphic3d_UniformValueTypeID<float>::ID, new OpenGl_VariableSetter<float>()) |
199 | (Graphic3d_UniformValueTypeID<OpenGl_Vec2>::ID, new OpenGl_VariableSetter<OpenGl_Vec2>()) |
200 | (Graphic3d_UniformValueTypeID<OpenGl_Vec3>::ID, new OpenGl_VariableSetter<OpenGl_Vec3>()) |
201 | (Graphic3d_UniformValueTypeID<OpenGl_Vec4>::ID, new OpenGl_VariableSetter<OpenGl_Vec4>()) |
202 | (Graphic3d_UniformValueTypeID<OpenGl_Vec2i>::ID, new OpenGl_VariableSetter<OpenGl_Vec2i>()) |
203 | (Graphic3d_UniformValueTypeID<OpenGl_Vec3i>::ID, new OpenGl_VariableSetter<OpenGl_Vec3i>()) |
204 | (Graphic3d_UniformValueTypeID<OpenGl_Vec4i>::ID, new OpenGl_VariableSetter<OpenGl_Vec4i>()); |
205 | } |
206 | |
207 | // ======================================================================= |
208 | // function : ~OpenGl_VariableSetterSelector |
209 | // purpose : Releases memory resources of variable setter selector |
210 | // ======================================================================= |
211 | OpenGl_VariableSetterSelector::~OpenGl_VariableSetterSelector() |
212 | { |
213 | for (OpenGl_SetterList::Iterator anIt (mySetterList); anIt.More(); anIt.Next()) |
214 | { |
215 | delete anIt.Value(); |
216 | } |
217 | |
218 | mySetterList.Clear(); |
219 | } |
220 | |
221 | // ======================================================================= |
222 | // function : Set |
223 | // purpose : Sets generic variable to specified shader program |
224 | // ======================================================================= |
225 | void OpenGl_VariableSetterSelector::Set (const Handle(OpenGl_Context)& theCtx, |
226 | const Handle(Graphic3d_ShaderVariable)& theVariable, |
227 | OpenGl_ShaderProgram* theProgram) const |
228 | { |
229 | Standard_ASSERT_RETURN (mySetterList.IsBound (theVariable->Value()->TypeID()), |
230 | "The type of user-defined uniform variable is not supported...", ); |
231 | |
232 | mySetterList.Find (theVariable->Value()->TypeID())->Set (theCtx, theVariable, theProgram); |
233 | } |
234 | |
235 | // ======================================================================= |
236 | // function : OpenGl_ShaderProgram |
237 | // purpose : Creates uninitialized shader program |
238 | // ======================================================================= |
239 | OpenGl_ShaderProgram::OpenGl_ShaderProgram (const Handle(Graphic3d_ShaderProgram)& theProxy) |
240 | : myProgramID (NO_PROGRAM), |
241 | myProxy (theProxy) |
242 | { |
243 | memset (myCurrentState, 0, sizeof (myCurrentState)); |
244 | for (GLint aVar = 0; aVar < OpenGl_OCCT_NUMBER_OF_STATE_VARIABLES; ++aVar) |
245 | { |
246 | myStateLocations[aVar] = INVALID_LOCATION; |
247 | } |
248 | } |
249 | |
250 | // ======================================================================= |
251 | // function : Initialize |
252 | // purpose : Initializes program object with the list of shader objects |
253 | // ======================================================================= |
254 | Standard_Boolean OpenGl_ShaderProgram::Initialize (const Handle(OpenGl_Context)& theCtx, |
255 | const Graphic3d_ShaderObjectList& theShaders) |
256 | { |
257 | if (theCtx.IsNull() || !Create (theCtx)) |
258 | { |
259 | return Standard_False; |
260 | } |
261 | |
262 | GLchar *aShaderDir = getenv ("CSF_ShadersDirectory"); |
263 | if (aShaderDir == NULL) |
264 | { |
265 | TCollection_ExtendedString aMsg = "Error! Failed to get OCCT shaders directory"; |
266 | |
267 | theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB, |
268 | GL_DEBUG_TYPE_ERROR_ARB, |
269 | 0, |
270 | GL_DEBUG_SEVERITY_HIGH_ARB, |
271 | aMsg); |
272 | |
273 | return Standard_False; |
274 | } |
275 | |
276 | OSD_File aDeclFile (TCollection_AsciiString (aShaderDir) + "/Declarations.glsl"); |
277 | if (!aDeclFile.Exists()) |
278 | { |
279 | TCollection_ExtendedString aMsg = "Error! Failed to load OCCT shader declarations file"; |
280 | |
281 | theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB, |
282 | GL_DEBUG_TYPE_ERROR_ARB, |
283 | 0, |
284 | GL_DEBUG_SEVERITY_HIGH_ARB, |
285 | aMsg); |
286 | |
287 | return Standard_False; |
288 | } |
289 | |
290 | TCollection_AsciiString aDeclarations; |
291 | |
292 | aDeclFile.Open (OSD_ReadOnly, OSD_Protection()); |
bd0b3e60 |
293 | aDeclFile.Read (aDeclarations, (int)aDeclFile.Size()); |
30f0ad28 |
294 | aDeclFile.Close(); |
295 | |
296 | for (Graphic3d_ShaderObjectList::Iterator anIter (theShaders); |
297 | anIter.More(); anIter.Next()) |
298 | { |
299 | if (!anIter.Value()->IsDone()) |
300 | { |
301 | TCollection_ExtendedString aMsg = "Error! Failed to get shader source"; |
302 | |
303 | theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB, |
304 | GL_DEBUG_TYPE_ERROR_ARB, |
305 | 0, |
306 | GL_DEBUG_SEVERITY_HIGH_ARB, |
307 | aMsg); |
308 | |
309 | return Standard_False; |
310 | } |
311 | |
312 | Handle(OpenGl_ShaderObject) aShader; |
313 | |
314 | // Note: Add support of other shader types here |
315 | switch (anIter.Value()->Type()) |
316 | { |
317 | case Graphic3d_TOS_VERTEX: |
318 | aShader = new OpenGl_ShaderObject (GL_VERTEX_SHADER); |
319 | break; |
320 | case Graphic3d_TOS_FRAGMENT: |
321 | aShader = new OpenGl_ShaderObject (GL_FRAGMENT_SHADER); |
322 | break; |
323 | } |
324 | |
325 | // Is unsupported shader type? |
326 | if (aShader.IsNull()) |
327 | { |
328 | TCollection_ExtendedString aMsg = "Error! Unsupported shader type"; |
329 | |
330 | theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB, |
331 | GL_DEBUG_TYPE_ERROR_ARB, |
332 | 0, |
333 | GL_DEBUG_SEVERITY_HIGH_ARB, |
334 | aMsg); |
335 | |
336 | return Standard_False; |
337 | } |
338 | |
339 | if (!aShader->Create (theCtx)) |
340 | { |
341 | return Standard_False; |
342 | } |
343 | |
344 | TCollection_AsciiString aSource = aDeclarations + anIter.Value()->Source(); |
345 | |
346 | if (anIter.Value()->Type() == Graphic3d_TOS_VERTEX) |
347 | { |
348 | aSource = TCollection_AsciiString ("#define VERTEX_SHADER\n") + aSource; |
349 | } |
350 | |
351 | if (!aShader->LoadSource (theCtx, aSource)) |
352 | { |
353 | TCollection_ExtendedString aMsg = "Error! Failed to set shader source"; |
354 | |
355 | theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB, |
356 | GL_DEBUG_TYPE_ERROR_ARB, |
357 | 0, |
358 | GL_DEBUG_SEVERITY_HIGH_ARB, |
359 | aMsg); |
360 | |
361 | return Standard_False; |
362 | } |
363 | |
364 | if (!aShader->Compile (theCtx)) |
365 | { |
366 | TCollection_ExtendedString aMsg = "Error! Failed to compile shader object"; |
367 | |
368 | theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB, |
369 | GL_DEBUG_TYPE_ERROR_ARB, |
370 | 0, |
371 | GL_DEBUG_SEVERITY_HIGH_ARB, |
372 | aMsg); |
373 | |
374 | if (theCtx->caps->contextDebug) |
375 | { |
376 | TCollection_AsciiString aLog; |
377 | aShader->FetchInfoLog (theCtx, aLog); |
378 | if (!aLog.IsEmpty()) |
379 | { |
380 | std::cout << aLog.ToCString() << std::endl << std::flush; |
381 | } |
382 | else |
383 | { |
384 | std::cout << "Information log is empty" << std::endl; |
385 | } |
386 | } |
387 | |
388 | return Standard_False; |
389 | } |
390 | |
391 | if (!AttachShader (theCtx, aShader)) |
392 | { |
393 | return Standard_False; |
394 | } |
395 | } |
396 | |
397 | if (!Link (theCtx)) |
398 | { |
399 | TCollection_ExtendedString aMsg = "Error! Failed to link program object"; |
400 | |
401 | theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB, |
402 | GL_DEBUG_TYPE_ERROR_ARB, |
403 | 0, |
404 | GL_DEBUG_SEVERITY_HIGH_ARB, |
405 | aMsg); |
406 | |
407 | if (theCtx->caps->contextDebug) |
408 | { |
409 | TCollection_AsciiString aLog; |
410 | FetchInfoLog (theCtx, aLog); |
411 | if (!aLog.IsEmpty()) |
412 | { |
413 | std::cout << aLog.ToCString() << std::endl; |
414 | } |
415 | else |
416 | { |
417 | std::cout << "Information log is empty" << std::endl; |
418 | } |
419 | } |
420 | |
421 | return Standard_False; |
422 | } |
423 | |
424 | return Standard_True; |
425 | } |
426 | |
427 | // ======================================================================= |
428 | // function : ~OpenGl_ShaderProgram |
429 | // purpose : Releases resources of shader program |
430 | // ======================================================================= |
431 | OpenGl_ShaderProgram::~OpenGl_ShaderProgram() |
432 | { |
433 | Release (NULL); |
434 | } |
435 | |
436 | // ======================================================================= |
437 | // function : AttachShader |
438 | // purpose : Attaches shader object to the program object |
439 | // ======================================================================= |
440 | Standard_Boolean OpenGl_ShaderProgram::AttachShader (const Handle(OpenGl_Context)& theCtx, |
441 | const Handle(OpenGl_ShaderObject)& theShader) |
442 | { |
443 | if (myProgramID == NO_PROGRAM || theShader.IsNull()) |
444 | { |
445 | return Standard_False; |
446 | } |
447 | |
448 | for (OpenGl_ShaderList::Iterator anIter (myShaderObjects); anIter.More(); anIter.Next()) |
449 | { |
450 | if (theShader == anIter.Value()) |
451 | { |
452 | return Standard_False; |
453 | } |
454 | } |
455 | |
456 | myShaderObjects.Append (theShader); |
457 | theCtx->core20->glAttachShader (myProgramID, theShader->myShaderID); |
458 | return Standard_True; |
459 | } |
460 | |
461 | // ======================================================================= |
462 | // function : DetachShader |
463 | // purpose : Detaches shader object to the program object |
464 | // ======================================================================= |
465 | Standard_Boolean OpenGl_ShaderProgram::DetachShader (const Handle(OpenGl_Context)& theCtx, |
466 | const Handle(OpenGl_ShaderObject)& theShader) |
467 | { |
468 | if (myProgramID == NO_PROGRAM |
469 | || theShader.IsNull()) |
470 | { |
471 | return Standard_False; |
472 | } |
473 | |
474 | OpenGl_ShaderList::Iterator anIter (myShaderObjects); |
475 | while (anIter.More()) |
476 | { |
477 | if (theShader == anIter.Value()) |
478 | { |
479 | myShaderObjects.Remove (anIter); |
480 | break; |
481 | } |
482 | |
483 | anIter.Next(); |
484 | } |
485 | |
486 | if (!anIter.More()) |
487 | { |
488 | return Standard_False; |
489 | } |
490 | |
491 | theCtx->core20->glDetachShader (myProgramID, theShader->myShaderID); |
492 | return Standard_True; |
493 | } |
494 | |
495 | // ======================================================================= |
496 | // function : Link |
497 | // purpose : Links the program object |
498 | // ======================================================================= |
499 | Standard_Boolean OpenGl_ShaderProgram::Link (const Handle(OpenGl_Context)& theCtx) |
500 | { |
501 | if (myProgramID == NO_PROGRAM) |
502 | { |
503 | return Standard_False; |
504 | } |
505 | |
506 | theCtx->core20->glLinkProgram (myProgramID); |
507 | |
508 | GLint aStatus = GL_FALSE; |
509 | theCtx->core20->glGetProgramiv (myProgramID, GL_LINK_STATUS, &aStatus); |
510 | |
511 | for (GLint aVar = 0; aVar < OpenGl_OCCT_NUMBER_OF_STATE_VARIABLES; ++aVar) |
512 | { |
513 | myStateLocations[aVar] = GetUniformLocation (theCtx, PredefinedKeywords[aVar]); |
514 | } |
515 | |
516 | return aStatus != GL_FALSE; |
517 | } |
518 | |
519 | // ======================================================================= |
520 | // function : FetchInfoLog |
521 | // purpose : Fetches information log of the last link operation |
522 | // ======================================================================= |
523 | Standard_Boolean OpenGl_ShaderProgram::FetchInfoLog (const Handle(OpenGl_Context)& theCtx, |
524 | TCollection_AsciiString& theOutput) |
525 | { |
526 | if (myProgramID == NO_PROGRAM) |
527 | { |
528 | return Standard_False; |
529 | } |
530 | |
531 | GLint aLength = 0; |
532 | theCtx->core20->glGetProgramiv (myProgramID, GL_INFO_LOG_LENGTH, &aLength); |
533 | if (aLength > 0) |
534 | { |
535 | GLchar* aLog = (GLchar*) alloca (aLength); |
536 | memset (aLog, 0, aLength); |
537 | theCtx->core20->glGetProgramInfoLog (myProgramID, aLength, NULL, aLog); |
538 | theOutput = aLog; |
539 | } |
540 | return Standard_True; |
541 | } |
542 | |
543 | // ======================================================================= |
544 | // function : Bind |
545 | // purpose : Sets the program object as part of current rendering state |
546 | // ======================================================================= |
547 | void OpenGl_ShaderProgram::Bind (const Handle(OpenGl_Context)& theCtx) const |
548 | { |
549 | if (myProgramID == NO_PROGRAM) |
550 | { |
551 | return; |
552 | } |
553 | |
554 | theCtx->core20->glUseProgram (myProgramID); |
555 | theCtx->ShaderManager()->myIsPP = Standard_True; |
556 | } |
557 | |
558 | // ======================================================================= |
559 | // function : ApplyVariables |
560 | // purpose : Fetches uniform variables from proxy shader program |
561 | // ======================================================================= |
562 | Standard_Boolean OpenGl_ShaderProgram::ApplyVariables(const Handle(OpenGl_Context)& theCtx) |
563 | { |
564 | if (myProxy.IsNull() || myProxy->Variables().IsEmpty()) |
565 | { |
566 | return Standard_False; |
567 | } |
568 | |
569 | for (Graphic3d_ShaderVariableList::Iterator anIter (myProxy->Variables()); anIter.More(); anIter.Next()) |
570 | { |
571 | mySetterSelector.Set (theCtx, anIter.Value(), this); |
572 | } |
573 | |
574 | myProxy->ClearVariables(); |
575 | return Standard_True; |
576 | } |
577 | |
578 | // ======================================================================= |
579 | // function : BindWithVariables |
580 | // purpose : Binds the program object and applies variables |
581 | // ======================================================================= |
582 | Standard_Boolean OpenGl_ShaderProgram::BindWithVariables (const Handle(OpenGl_Context)& theCtx) |
583 | { |
584 | Bind (theCtx); |
585 | return ApplyVariables (theCtx); |
586 | } |
587 | |
588 | // ======================================================================= |
589 | // function : Unbind |
590 | // purpose : Reverts to fixed-function graphics pipeline (FFP) |
591 | // ======================================================================= |
592 | void OpenGl_ShaderProgram::Unbind (const Handle(OpenGl_Context)& theCtx) |
593 | { |
594 | if (theCtx->ShaderManager()->myIsPP) |
595 | { |
596 | theCtx->core20->glUseProgram (NO_PROGRAM); |
597 | theCtx->ShaderManager()->myIsPP = Standard_False; |
598 | } |
599 | } |
600 | |
601 | // ======================================================================= |
602 | // function : ActiveState |
603 | // purpose : Returns index of last modification for specified state type |
604 | // ======================================================================= |
605 | Standard_Size OpenGl_ShaderProgram::ActiveState (const OpenGl_UniformStateType theType) const |
606 | { |
607 | if (theType < MaxStateTypes) |
608 | { |
609 | return myCurrentState[theType]; |
610 | } |
611 | return 0; |
612 | } |
613 | |
614 | // ======================================================================= |
615 | // function : UpdateState |
616 | // purpose : Updates index of last modification for specified state type |
617 | // ======================================================================= |
618 | void OpenGl_ShaderProgram::UpdateState (const OpenGl_UniformStateType theType, |
619 | const Standard_Size theIndex) |
620 | { |
621 | if (theType < MaxStateTypes) |
622 | { |
623 | myCurrentState[theType] = theIndex; |
624 | } |
625 | } |
626 | |
627 | // ======================================================================= |
628 | // function : GetUniformLocation |
629 | // purpose : Returns location (index) of the specific uniform variable |
630 | // ======================================================================= |
631 | GLint OpenGl_ShaderProgram::GetUniformLocation (const Handle(OpenGl_Context)& theCtx, |
632 | const GLchar* theName) const |
633 | { |
634 | return myProgramID != NO_PROGRAM |
635 | ? theCtx->core20->glGetUniformLocation (myProgramID, theName) |
636 | : INVALID_LOCATION; |
637 | } |
638 | |
639 | // ======================================================================= |
640 | // function : GetAttributeLocation |
641 | // purpose : Returns location (index) of the generic vertex attribute |
642 | // ======================================================================= |
643 | GLint OpenGl_ShaderProgram::GetAttributeLocation (const Handle(OpenGl_Context)& theCtx, |
644 | const GLchar* theName) const |
645 | { |
646 | return myProgramID != NO_PROGRAM |
647 | ? theCtx->core20->glGetAttribLocation (myProgramID, theName) |
648 | : INVALID_LOCATION; |
649 | } |
650 | |
651 | // ======================================================================= |
652 | // function : GetStateLocation |
653 | // purpose : Returns location of the OCCT state uniform variable |
654 | // ======================================================================= |
655 | GLint OpenGl_ShaderProgram::GetStateLocation (const GLuint theVariable) const |
656 | { |
657 | if (theVariable < OpenGl_OCCT_NUMBER_OF_STATE_VARIABLES) |
658 | { |
659 | return myStateLocations[theVariable]; |
660 | } |
661 | return INVALID_LOCATION; |
662 | } |
663 | |
664 | // ======================================================================= |
665 | // function : GetUniform |
666 | // purpose : Returns the value of the integer uniform variable |
667 | // ======================================================================= |
668 | Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx, |
669 | const GLchar* theName, |
670 | OpenGl_Vec4i& theValue) const |
671 | { |
672 | return GetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue); |
673 | } |
674 | |
675 | // ======================================================================= |
676 | // function : GetUniform |
677 | // purpose : Returns the value of the integer uniform variable |
678 | // ======================================================================= |
679 | Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx, |
680 | GLint theLocation, |
681 | OpenGl_Vec4i& theValue) const |
682 | { |
683 | if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION) |
684 | { |
685 | return Standard_False; |
686 | } |
687 | |
688 | theCtx->core20->glGetUniformiv (myProgramID, theLocation, theValue); |
689 | return Standard_True; |
690 | } |
691 | |
692 | // ======================================================================= |
693 | // function : GetUniform |
694 | // purpose : Returns the value of the floating-point uniform variable |
695 | // ======================================================================= |
696 | Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx, |
697 | const GLchar* theName, |
698 | OpenGl_Vec4& theValue) const |
699 | { |
700 | return GetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue); |
701 | } |
702 | |
703 | // ======================================================================= |
704 | // function : GetUniform |
705 | // purpose : Returns the value of the floating-point uniform variable |
706 | // ======================================================================= |
707 | Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx, |
708 | GLint theLocation, |
709 | OpenGl_Vec4& theValue) const |
710 | { |
711 | if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION) |
712 | { |
713 | return Standard_False; |
714 | } |
715 | |
716 | theCtx->core20->glGetUniformfv (myProgramID, theLocation, theValue); |
717 | return Standard_True; |
718 | } |
719 | |
720 | // ======================================================================= |
721 | // function : GetAttribute |
722 | // purpose : Returns the integer vertex attribute |
723 | // ======================================================================= |
724 | Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx, |
725 | const GLchar* theName, |
726 | OpenGl_Vec4i& theValue) const |
727 | { |
728 | return GetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue); |
729 | } |
730 | |
731 | // ======================================================================= |
732 | // function : GetAttribute |
733 | // purpose : Returns the integer vertex attribute |
734 | // ======================================================================= |
735 | Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx, |
736 | GLint theIndex, |
737 | OpenGl_Vec4i& theValue) const |
738 | { |
739 | if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION) |
740 | { |
741 | return Standard_False; |
742 | } |
743 | |
744 | theCtx->core20->glGetVertexAttribiv (theIndex, GL_CURRENT_VERTEX_ATTRIB, theValue); |
745 | return Standard_True; |
746 | } |
747 | |
748 | // ======================================================================= |
749 | // function : GetAttribute |
750 | // purpose : Returns the floating-point vertex attribute |
751 | // ======================================================================= |
752 | Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx, |
753 | const GLchar* theName, |
754 | OpenGl_Vec4& theValue) const |
755 | { |
756 | return GetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue); |
757 | } |
758 | |
759 | // ======================================================================= |
760 | // function : GetAttribute |
761 | // purpose : Returns the floating-point vertex attribute |
762 | // ======================================================================= |
763 | Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx, |
764 | GLint theIndex, |
765 | OpenGl_Vec4& theValue) const |
766 | { |
767 | if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION) |
768 | { |
769 | return Standard_False; |
770 | } |
771 | |
772 | theCtx->core20->glGetVertexAttribfv (theIndex, GL_CURRENT_VERTEX_ATTRIB, theValue); |
773 | return Standard_True; |
774 | } |
775 | |
776 | // ======================================================================= |
777 | // function : SetUniform |
778 | // purpose : Specifies the value of the integer uniform variable |
779 | // ======================================================================= |
780 | Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx, |
781 | const GLchar* theName, |
782 | GLint theValue) |
783 | { |
784 | return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue); |
785 | } |
786 | |
787 | // ======================================================================= |
788 | // function : SetUniform |
789 | // purpose : Specifies the value of the integer uniform variable |
790 | // ======================================================================= |
791 | Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx, |
792 | GLint theLocation, |
793 | GLint theValue) |
794 | { |
795 | if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION) |
796 | { |
797 | return Standard_False; |
798 | } |
799 | |
800 | theCtx->core20->glUniform1i (theLocation, theValue); |
801 | return Standard_True; |
802 | } |
803 | |
804 | // ======================================================================= |
805 | // function : SetUniform |
806 | // purpose : Specifies the value of the floating-point uniform variable |
807 | // ======================================================================= |
808 | Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx, |
809 | const GLchar* theName, |
810 | GLfloat theValue) |
811 | { |
812 | return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue); |
813 | } |
814 | |
815 | // ======================================================================= |
816 | // function : SetUniform |
817 | // purpose : Specifies the value of the floating-point uniform variable |
818 | // ======================================================================= |
819 | Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx, |
820 | GLint theLocation, |
821 | GLfloat theValue) |
822 | { |
823 | if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION) |
824 | { |
825 | return Standard_False; |
826 | } |
827 | |
828 | theCtx->core20->glUniform1f (theLocation, theValue); |
829 | return Standard_True; |
830 | } |
831 | |
832 | // ======================================================================= |
833 | // function : SetUniform |
834 | // purpose : Specifies the value of the integer uniform 2D vector |
835 | // ======================================================================= |
836 | Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx, |
837 | const GLchar* theName, |
838 | const OpenGl_Vec2i& theValue) |
839 | { |
840 | return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue); |
841 | } |
842 | |
843 | // ======================================================================= |
844 | // function : SetUniform |
845 | // purpose : Specifies the value of the integer uniform 2D vector |
846 | // ======================================================================= |
847 | Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx, |
848 | GLint theLocation, |
849 | const OpenGl_Vec2i& theValue) |
850 | { |
851 | if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION) |
852 | { |
853 | return Standard_False; |
854 | } |
855 | |
856 | theCtx->core20->glUniform2iv (theLocation, 1, theValue); |
857 | return Standard_True; |
858 | } |
859 | |
860 | // ======================================================================= |
861 | // function : SetUniform |
862 | // purpose : Specifies the value of the integer uniform 3D vector |
863 | // ======================================================================= |
864 | Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx, |
865 | const GLchar* theName, |
866 | const OpenGl_Vec3i& theValue) |
867 | { |
868 | return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue); |
869 | } |
870 | |
871 | // ======================================================================= |
872 | // function : SetUniform |
873 | // purpose : Specifies the value of the integer uniform 3D vector |
874 | // ======================================================================= |
875 | Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx, |
876 | GLint theLocation, |
877 | const OpenGl_Vec3i& theValue) |
878 | { |
879 | if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION) |
880 | { |
881 | return Standard_False; |
882 | } |
883 | |
884 | theCtx->core20->glUniform3iv (theLocation, 1, theValue); |
885 | return Standard_True; |
886 | } |
887 | |
888 | // ======================================================================= |
889 | // function : SetUniform |
890 | // purpose : Specifies the value of the integer uniform 4D vector |
891 | // ======================================================================= |
892 | Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx, |
893 | const GLchar* theName, |
894 | const OpenGl_Vec4i& theValue) |
895 | { |
896 | return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue); |
897 | } |
898 | |
899 | // ======================================================================= |
900 | // function : SetUniform |
901 | // purpose : Specifies the value of the integer uniform 4D vector |
902 | // ======================================================================= |
903 | Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx, |
904 | GLint theLocation, |
905 | const OpenGl_Vec4i& theValue) |
906 | { |
907 | if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION) |
908 | { |
909 | return Standard_False; |
910 | } |
911 | |
912 | theCtx->core20->glUniform4iv (theLocation, 1, theValue); |
913 | return Standard_True; |
914 | } |
915 | |
916 | // ======================================================================= |
917 | // function : SetUniform |
918 | // purpose : Specifies the value of the floating-point uniform 2D vector |
919 | // ======================================================================= |
920 | Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx, |
921 | const GLchar* theName, |
922 | const OpenGl_Vec2& theValue) |
923 | { |
924 | return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue); |
925 | } |
926 | |
927 | // ======================================================================= |
928 | // function : SetUniform |
929 | // purpose : Specifies the value of the floating-point uniform 2D vector |
930 | // ======================================================================= |
931 | Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx, |
932 | GLint theLocation, |
933 | const OpenGl_Vec2& theValue) |
934 | { |
935 | if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION) |
936 | { |
937 | return Standard_False; |
938 | } |
939 | |
940 | theCtx->core20->glUniform2fv (theLocation, 1, theValue); |
941 | return Standard_True; |
942 | } |
943 | |
944 | // ======================================================================= |
945 | // function : SetUniform |
946 | // purpose : Specifies the value of the floating-point uniform 3D vector |
947 | // ======================================================================= |
948 | Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx, |
949 | const GLchar* theName, |
950 | const OpenGl_Vec3& theValue) |
951 | { |
952 | return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue); |
953 | } |
954 | |
955 | // ======================================================================= |
956 | // function : SetUniform |
957 | // purpose : Specifies the value of the floating-point uniform 3D vector |
958 | // ======================================================================= |
959 | Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx, |
960 | GLint theLocation, |
961 | const OpenGl_Vec3& theValue) |
962 | { |
963 | if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION) |
964 | { |
965 | return Standard_False; |
966 | } |
967 | |
968 | theCtx->core20->glUniform3fv (theLocation, 1, theValue); |
969 | return Standard_True; |
970 | } |
971 | |
972 | // ======================================================================= |
973 | // function : SetUniform |
974 | // purpose : Specifies the value of the floating-point uniform 4D vector |
975 | // ======================================================================= |
976 | Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx, |
977 | const GLchar* theName, |
978 | const OpenGl_Vec4& theValue) |
979 | { |
980 | return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue); |
981 | } |
982 | |
983 | // ======================================================================= |
984 | // function : SetUniform |
985 | // purpose : Specifies the value of the floating-point uniform 4D vector |
986 | // ======================================================================= |
987 | Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx, |
988 | GLint theLocation, |
989 | const OpenGl_Vec4& theValue) |
990 | { |
991 | if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION) |
992 | { |
993 | return Standard_False; |
994 | } |
995 | |
996 | theCtx->core20->glUniform4fv (theLocation, 1, theValue); |
997 | return Standard_True; |
998 | } |
999 | |
1000 | // ======================================================================= |
1001 | // function : SetUniform |
1002 | // purpose : Specifies the value of the floating-point uniform 4x4 matrix |
1003 | // ======================================================================= |
1004 | Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx, |
1005 | const GLchar* theName, |
1006 | const OpenGl_Matrix& theValue, |
1007 | GLboolean theTranspose) |
1008 | { |
1009 | return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue, theTranspose); |
1010 | } |
1011 | |
1012 | // ======================================================================= |
1013 | // function : SetUniform |
1014 | // purpose : Specifies the value of the floating-point uniform 4x4 matrix |
1015 | // ======================================================================= |
1016 | Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx, |
1017 | GLint theLocation, |
1018 | const OpenGl_Matrix& theValue, |
1019 | GLboolean theTranspose) |
1020 | { |
1021 | if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION) |
1022 | { |
1023 | return Standard_False; |
1024 | } |
1025 | |
1026 | theCtx->core20->glUniformMatrix4fv (theLocation, 1, theTranspose, *theValue.mat); |
1027 | return Standard_True; |
1028 | } |
1029 | |
1030 | // ======================================================================= |
1031 | // function : SetUniform |
1032 | // purpose : Specifies the value of the floating-point uniform 4x4 matrix |
1033 | // ======================================================================= |
1034 | Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx, |
1035 | const GLchar* theName, |
1036 | const Tmatrix3& theValue, |
1037 | GLboolean theTranspose) |
1038 | { |
1039 | return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue, theTranspose); |
1040 | } |
1041 | |
1042 | // ======================================================================= |
1043 | // function : SetUniform |
1044 | // purpose : Specifies the value of the floating-point uniform 4x4 matrix |
1045 | // ======================================================================= |
1046 | Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx, |
1047 | GLint theLocation, |
1048 | const Tmatrix3& theValue, |
1049 | GLboolean theTranspose) |
1050 | { |
1051 | if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION) |
1052 | { |
1053 | return Standard_False; |
1054 | } |
1055 | |
1056 | theCtx->core20->glUniformMatrix4fv (theLocation, 1, theTranspose, *theValue); |
1057 | return Standard_True; |
1058 | } |
1059 | |
1060 | // ======================================================================= |
1061 | // function : SetSampler |
1062 | // purpose : Specifies the value of the sampler uniform variable |
1063 | // ======================================================================= |
1064 | Standard_Boolean OpenGl_ShaderProgram::SetSampler (const Handle(OpenGl_Context)& theCtx, |
1065 | const GLchar* theName, |
1066 | const GLenum theTextureUnit) |
1067 | { |
1068 | return SetSampler (theCtx, GetUniformLocation (theCtx, theName), theTextureUnit); |
1069 | } |
1070 | |
1071 | // ======================================================================= |
1072 | // function : SetSampler |
1073 | // purpose : Specifies the value of the sampler uniform variable |
1074 | // ======================================================================= |
1075 | Standard_Boolean OpenGl_ShaderProgram::SetSampler (const Handle(OpenGl_Context)& theCtx, |
1076 | GLint theLocation, |
1077 | const GLenum theTextureUnit) |
1078 | { |
1079 | if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION) |
1080 | { |
1081 | return Standard_False; |
1082 | } |
1083 | |
1084 | theCtx->core20->glUniform1i (theLocation, theTextureUnit); |
1085 | return Standard_True; |
1086 | } |
1087 | |
1088 | // ======================================================================= |
1089 | // function : Create |
1090 | // purpose : Creates new empty shader program of specified type |
1091 | // ======================================================================= |
1092 | Standard_Boolean OpenGl_ShaderProgram::Create (const Handle(OpenGl_Context)& theCtx) |
1093 | { |
1094 | if (myProgramID == NO_PROGRAM |
1095 | && theCtx->core20 != NULL) |
1096 | { |
1097 | myProgramID = theCtx->core20->glCreateProgram(); |
1098 | } |
1099 | |
1100 | return myProgramID != NO_PROGRAM; |
1101 | } |
1102 | |
1103 | // ======================================================================= |
1104 | // function : Release |
1105 | // purpose : Destroys shader program |
1106 | // ======================================================================= |
1107 | void OpenGl_ShaderProgram::Release (const OpenGl_Context* theCtx) |
1108 | { |
1109 | if (myProgramID == NO_PROGRAM) |
1110 | { |
1111 | return; |
1112 | } |
1113 | |
1114 | Standard_ASSERT_RETURN (theCtx != NULL, |
1115 | "OpenGl_ShaderProgram destroyed without GL context! Possible GPU memory leakage...",); |
1116 | |
1117 | for (OpenGl_ShaderList::Iterator anIter (myShaderObjects); anIter.More(); anIter.Next()) |
1118 | { |
1119 | anIter.ChangeValue()->Release (theCtx); |
1120 | anIter.ChangeValue().Nullify(); |
1121 | } |
1122 | |
1123 | if (theCtx->core20 != NULL) |
1124 | { |
1125 | theCtx->core20->glDeleteProgram (myProgramID); |
1126 | } |
1127 | |
1128 | myProgramID = NO_PROGRAM; |
1129 | } |