Samples update
[occt.git] / src / OpenGl / OpenGl_ShaderProgram.cxx
CommitLineData
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
31IMPLEMENT_STANDARD_HANDLE (OpenGl_ShaderProgram, OpenGl_Resource)
32IMPLEMENT_STANDARD_RTTIEXT(OpenGl_ShaderProgram, OpenGl_Resource)
33
34OpenGl_VariableSetterSelector OpenGl_ShaderProgram::mySetterSelector = OpenGl_VariableSetterSelector();
35
36// Declare OCCT-specific OpenGL/GLSL shader variables
37Standard_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// =======================================================================
193OpenGl_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// =======================================================================
211OpenGl_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// =======================================================================
225void 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// =======================================================================
239OpenGl_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// =======================================================================
254Standard_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// =======================================================================
431OpenGl_ShaderProgram::~OpenGl_ShaderProgram()
432{
433 Release (NULL);
434}
435
436// =======================================================================
437// function : AttachShader
438// purpose : Attaches shader object to the program object
439// =======================================================================
440Standard_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// =======================================================================
465Standard_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// =======================================================================
499Standard_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// =======================================================================
523Standard_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// =======================================================================
547void 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// =======================================================================
562Standard_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// =======================================================================
582Standard_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// =======================================================================
592void 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// =======================================================================
605Standard_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// =======================================================================
618void 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// =======================================================================
631GLint 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// =======================================================================
643GLint 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// =======================================================================
655GLint 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// =======================================================================
668Standard_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// =======================================================================
679Standard_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// =======================================================================
696Standard_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// =======================================================================
707Standard_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// =======================================================================
724Standard_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// =======================================================================
735Standard_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// =======================================================================
752Standard_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// =======================================================================
763Standard_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// =======================================================================
780Standard_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// =======================================================================
791Standard_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// =======================================================================
808Standard_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// =======================================================================
819Standard_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// =======================================================================
836Standard_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// =======================================================================
847Standard_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// =======================================================================
864Standard_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// =======================================================================
875Standard_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// =======================================================================
892Standard_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// =======================================================================
903Standard_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// =======================================================================
920Standard_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// =======================================================================
931Standard_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// =======================================================================
948Standard_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// =======================================================================
959Standard_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// =======================================================================
976Standard_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// =======================================================================
987Standard_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// =======================================================================
1004Standard_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// =======================================================================
1016Standard_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// =======================================================================
1034Standard_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// =======================================================================
1046Standard_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// =======================================================================
1064Standard_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// =======================================================================
1075Standard_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// =======================================================================
1092Standard_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// =======================================================================
1107void 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
ec2eeb2d 1123 if (theCtx->core20 != NULL
1124 && theCtx->IsValid())
30f0ad28 1125 {
1126 theCtx->core20->glDeleteProgram (myProgramID);
1127 }
1128
1129 myProgramID = NO_PROGRAM;
1130}