Test bugs vis bug24130 should be OK when OpenCL is present, corrected
[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),
392ac980 241 myProxy (theProxy),
242 myShareCount(1)
30f0ad28 243{
244 memset (myCurrentState, 0, sizeof (myCurrentState));
245 for (GLint aVar = 0; aVar < OpenGl_OCCT_NUMBER_OF_STATE_VARIABLES; ++aVar)
246 {
247 myStateLocations[aVar] = INVALID_LOCATION;
248 }
249}
250
251// =======================================================================
252// function : Initialize
253// purpose : Initializes program object with the list of shader objects
254// =======================================================================
255Standard_Boolean OpenGl_ShaderProgram::Initialize (const Handle(OpenGl_Context)& theCtx,
256 const Graphic3d_ShaderObjectList& theShaders)
257{
258 if (theCtx.IsNull() || !Create (theCtx))
259 {
260 return Standard_False;
261 }
262
392ac980 263 OSD_File aDeclFile (Graphic3d_ShaderProgram::ShadersFolder() + "/Declarations.glsl");
30f0ad28 264 if (!aDeclFile.Exists())
265 {
392ac980 266 const TCollection_ExtendedString aMsg = "Error! Failed to load OCCT shader declarations file";
30f0ad28 267 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
268 GL_DEBUG_TYPE_ERROR_ARB,
269 0,
270 GL_DEBUG_SEVERITY_HIGH_ARB,
271 aMsg);
30f0ad28 272 return Standard_False;
273 }
274
275 TCollection_AsciiString aDeclarations;
276
277 aDeclFile.Open (OSD_ReadOnly, OSD_Protection());
bd0b3e60 278 aDeclFile.Read (aDeclarations, (int)aDeclFile.Size());
30f0ad28 279 aDeclFile.Close();
280
281 for (Graphic3d_ShaderObjectList::Iterator anIter (theShaders);
282 anIter.More(); anIter.Next())
283 {
284 if (!anIter.Value()->IsDone())
285 {
392ac980 286 const TCollection_ExtendedString aMsg = "Error! Failed to get shader source";
30f0ad28 287 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
288 GL_DEBUG_TYPE_ERROR_ARB,
289 0,
290 GL_DEBUG_SEVERITY_HIGH_ARB,
291 aMsg);
30f0ad28 292 return Standard_False;
293 }
294
295 Handle(OpenGl_ShaderObject) aShader;
296
297 // Note: Add support of other shader types here
298 switch (anIter.Value()->Type())
299 {
300 case Graphic3d_TOS_VERTEX:
301 aShader = new OpenGl_ShaderObject (GL_VERTEX_SHADER);
302 break;
303 case Graphic3d_TOS_FRAGMENT:
304 aShader = new OpenGl_ShaderObject (GL_FRAGMENT_SHADER);
305 break;
306 }
307
308 // Is unsupported shader type?
309 if (aShader.IsNull())
310 {
311 TCollection_ExtendedString aMsg = "Error! Unsupported shader type";
30f0ad28 312 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
313 GL_DEBUG_TYPE_ERROR_ARB,
314 0,
315 GL_DEBUG_SEVERITY_HIGH_ARB,
316 aMsg);
30f0ad28 317 return Standard_False;
318 }
319
320 if (!aShader->Create (theCtx))
321 {
392ac980 322 aShader->Release (theCtx.operator->());
30f0ad28 323 return Standard_False;
324 }
325
326 TCollection_AsciiString aSource = aDeclarations + anIter.Value()->Source();
30f0ad28 327 if (anIter.Value()->Type() == Graphic3d_TOS_VERTEX)
328 {
329 aSource = TCollection_AsciiString ("#define VERTEX_SHADER\n") + aSource;
330 }
331
332 if (!aShader->LoadSource (theCtx, aSource))
333 {
392ac980 334 const TCollection_ExtendedString aMsg = "Error! Failed to set shader source";
30f0ad28 335 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
336 GL_DEBUG_TYPE_ERROR_ARB,
337 0,
338 GL_DEBUG_SEVERITY_HIGH_ARB,
339 aMsg);
392ac980 340 aShader->Release (theCtx.operator->());
30f0ad28 341 return Standard_False;
342 }
343
344 if (!aShader->Compile (theCtx))
345 {
392ac980 346 TCollection_AsciiString aLog;
347 aShader->FetchInfoLog (theCtx, aLog);
348 if (aLog.IsEmpty())
349 {
350 aLog = "Compilation log is empty.";
351 }
30f0ad28 352 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
353 GL_DEBUG_TYPE_ERROR_ARB,
354 0,
355 GL_DEBUG_SEVERITY_HIGH_ARB,
392ac980 356 TCollection_ExtendedString ("Failed to compile shader object. Compilation log:\n") + aLog);
357 aShader->Release (theCtx.operator->());
358 return Standard_False;
359 }
360 else if (theCtx->caps->glslWarnings)
361 {
362 TCollection_AsciiString aLog;
363 aShader->FetchInfoLog (theCtx, aLog);
364 if (!aLog.IsEmpty()
365 && !aLog.IsEqual ("No errors.\n"))
30f0ad28 366 {
392ac980 367 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
368 GL_DEBUG_TYPE_PORTABILITY_ARB,
369 0,
370 GL_DEBUG_SEVERITY_LOW_ARB,
371 TCollection_ExtendedString ("Shader compilation log:\n") + aLog);
30f0ad28 372 }
30f0ad28 373 }
374
375 if (!AttachShader (theCtx, aShader))
376 {
392ac980 377 aShader->Release (theCtx.operator->());
30f0ad28 378 return Standard_False;
379 }
380 }
381
382 if (!Link (theCtx))
383 {
392ac980 384 TCollection_AsciiString aLog;
385 FetchInfoLog (theCtx, aLog);
386 if (aLog.IsEmpty())
387 {
388 aLog = "Linker log is empty.";
389 }
30f0ad28 390 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
391 GL_DEBUG_TYPE_ERROR_ARB,
392 0,
393 GL_DEBUG_SEVERITY_HIGH_ARB,
392ac980 394 TCollection_ExtendedString ("Failed to link program object! Linker log:\n"));
395 return Standard_False;
396 }
397 else if (theCtx->caps->glslWarnings)
398 {
399 TCollection_AsciiString aLog;
400 FetchInfoLog (theCtx, aLog);
401 if (!aLog.IsEmpty()
402 && !aLog.IsEqual ("No errors.\n"))
30f0ad28 403 {
392ac980 404 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
405 GL_DEBUG_TYPE_PORTABILITY_ARB,
406 0,
407 GL_DEBUG_SEVERITY_LOW_ARB,
408 TCollection_ExtendedString ("GLSL linker log:\n") + aLog);
30f0ad28 409 }
30f0ad28 410 }
411
412 return Standard_True;
413}
414
415// =======================================================================
416// function : ~OpenGl_ShaderProgram
417// purpose : Releases resources of shader program
418// =======================================================================
419OpenGl_ShaderProgram::~OpenGl_ShaderProgram()
420{
421 Release (NULL);
422}
423
424// =======================================================================
425// function : AttachShader
426// purpose : Attaches shader object to the program object
427// =======================================================================
428Standard_Boolean OpenGl_ShaderProgram::AttachShader (const Handle(OpenGl_Context)& theCtx,
429 const Handle(OpenGl_ShaderObject)& theShader)
430{
431 if (myProgramID == NO_PROGRAM || theShader.IsNull())
432 {
433 return Standard_False;
434 }
435
436 for (OpenGl_ShaderList::Iterator anIter (myShaderObjects); anIter.More(); anIter.Next())
437 {
438 if (theShader == anIter.Value())
439 {
440 return Standard_False;
441 }
442 }
443
444 myShaderObjects.Append (theShader);
445 theCtx->core20->glAttachShader (myProgramID, theShader->myShaderID);
446 return Standard_True;
447}
448
449// =======================================================================
450// function : DetachShader
451// purpose : Detaches shader object to the program object
452// =======================================================================
453Standard_Boolean OpenGl_ShaderProgram::DetachShader (const Handle(OpenGl_Context)& theCtx,
454 const Handle(OpenGl_ShaderObject)& theShader)
455{
456 if (myProgramID == NO_PROGRAM
457 || theShader.IsNull())
458 {
459 return Standard_False;
460 }
461
462 OpenGl_ShaderList::Iterator anIter (myShaderObjects);
463 while (anIter.More())
464 {
465 if (theShader == anIter.Value())
466 {
467 myShaderObjects.Remove (anIter);
468 break;
469 }
470
471 anIter.Next();
472 }
473
474 if (!anIter.More())
475 {
476 return Standard_False;
477 }
478
479 theCtx->core20->glDetachShader (myProgramID, theShader->myShaderID);
480 return Standard_True;
481}
482
483// =======================================================================
484// function : Link
485// purpose : Links the program object
486// =======================================================================
487Standard_Boolean OpenGl_ShaderProgram::Link (const Handle(OpenGl_Context)& theCtx)
488{
489 if (myProgramID == NO_PROGRAM)
490 {
491 return Standard_False;
492 }
493
494 theCtx->core20->glLinkProgram (myProgramID);
495
496 GLint aStatus = GL_FALSE;
497 theCtx->core20->glGetProgramiv (myProgramID, GL_LINK_STATUS, &aStatus);
498
499 for (GLint aVar = 0; aVar < OpenGl_OCCT_NUMBER_OF_STATE_VARIABLES; ++aVar)
500 {
501 myStateLocations[aVar] = GetUniformLocation (theCtx, PredefinedKeywords[aVar]);
502 }
503
504 return aStatus != GL_FALSE;
505}
506
507// =======================================================================
508// function : FetchInfoLog
509// purpose : Fetches information log of the last link operation
510// =======================================================================
511Standard_Boolean OpenGl_ShaderProgram::FetchInfoLog (const Handle(OpenGl_Context)& theCtx,
512 TCollection_AsciiString& theOutput)
513{
514 if (myProgramID == NO_PROGRAM)
515 {
516 return Standard_False;
517 }
518
519 GLint aLength = 0;
520 theCtx->core20->glGetProgramiv (myProgramID, GL_INFO_LOG_LENGTH, &aLength);
521 if (aLength > 0)
522 {
523 GLchar* aLog = (GLchar*) alloca (aLength);
524 memset (aLog, 0, aLength);
525 theCtx->core20->glGetProgramInfoLog (myProgramID, aLength, NULL, aLog);
526 theOutput = aLog;
527 }
528 return Standard_True;
529}
530
531// =======================================================================
532// function : Bind
533// purpose : Sets the program object as part of current rendering state
534// =======================================================================
535void OpenGl_ShaderProgram::Bind (const Handle(OpenGl_Context)& theCtx) const
536{
537 if (myProgramID == NO_PROGRAM)
538 {
539 return;
540 }
541
542 theCtx->core20->glUseProgram (myProgramID);
543 theCtx->ShaderManager()->myIsPP = Standard_True;
544}
545
546// =======================================================================
547// function : ApplyVariables
548// purpose : Fetches uniform variables from proxy shader program
549// =======================================================================
550Standard_Boolean OpenGl_ShaderProgram::ApplyVariables(const Handle(OpenGl_Context)& theCtx)
551{
552 if (myProxy.IsNull() || myProxy->Variables().IsEmpty())
553 {
554 return Standard_False;
555 }
556
557 for (Graphic3d_ShaderVariableList::Iterator anIter (myProxy->Variables()); anIter.More(); anIter.Next())
558 {
559 mySetterSelector.Set (theCtx, anIter.Value(), this);
560 }
561
562 myProxy->ClearVariables();
563 return Standard_True;
564}
565
566// =======================================================================
567// function : BindWithVariables
568// purpose : Binds the program object and applies variables
569// =======================================================================
570Standard_Boolean OpenGl_ShaderProgram::BindWithVariables (const Handle(OpenGl_Context)& theCtx)
571{
572 Bind (theCtx);
573 return ApplyVariables (theCtx);
574}
575
576// =======================================================================
577// function : Unbind
578// purpose : Reverts to fixed-function graphics pipeline (FFP)
579// =======================================================================
580void OpenGl_ShaderProgram::Unbind (const Handle(OpenGl_Context)& theCtx)
581{
582 if (theCtx->ShaderManager()->myIsPP)
583 {
584 theCtx->core20->glUseProgram (NO_PROGRAM);
585 theCtx->ShaderManager()->myIsPP = Standard_False;
586 }
587}
588
589// =======================================================================
590// function : ActiveState
591// purpose : Returns index of last modification for specified state type
592// =======================================================================
593Standard_Size OpenGl_ShaderProgram::ActiveState (const OpenGl_UniformStateType theType) const
594{
595 if (theType < MaxStateTypes)
596 {
597 return myCurrentState[theType];
598 }
599 return 0;
600}
601
602// =======================================================================
603// function : UpdateState
604// purpose : Updates index of last modification for specified state type
605// =======================================================================
606void OpenGl_ShaderProgram::UpdateState (const OpenGl_UniformStateType theType,
607 const Standard_Size theIndex)
608{
609 if (theType < MaxStateTypes)
610 {
611 myCurrentState[theType] = theIndex;
612 }
613}
614
615// =======================================================================
616// function : GetUniformLocation
617// purpose : Returns location (index) of the specific uniform variable
618// =======================================================================
619GLint OpenGl_ShaderProgram::GetUniformLocation (const Handle(OpenGl_Context)& theCtx,
620 const GLchar* theName) const
621{
622 return myProgramID != NO_PROGRAM
623 ? theCtx->core20->glGetUniformLocation (myProgramID, theName)
624 : INVALID_LOCATION;
625}
626
627// =======================================================================
628// function : GetAttributeLocation
629// purpose : Returns location (index) of the generic vertex attribute
630// =======================================================================
631GLint OpenGl_ShaderProgram::GetAttributeLocation (const Handle(OpenGl_Context)& theCtx,
632 const GLchar* theName) const
633{
634 return myProgramID != NO_PROGRAM
635 ? theCtx->core20->glGetAttribLocation (myProgramID, theName)
636 : INVALID_LOCATION;
637}
638
639// =======================================================================
640// function : GetStateLocation
641// purpose : Returns location of the OCCT state uniform variable
642// =======================================================================
643GLint OpenGl_ShaderProgram::GetStateLocation (const GLuint theVariable) const
644{
645 if (theVariable < OpenGl_OCCT_NUMBER_OF_STATE_VARIABLES)
646 {
647 return myStateLocations[theVariable];
648 }
649 return INVALID_LOCATION;
650}
651
652// =======================================================================
653// function : GetUniform
654// purpose : Returns the value of the integer uniform variable
655// =======================================================================
656Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx,
657 const GLchar* theName,
658 OpenGl_Vec4i& theValue) const
659{
660 return GetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
661}
662
663// =======================================================================
664// function : GetUniform
665// purpose : Returns the value of the integer uniform variable
666// =======================================================================
667Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx,
668 GLint theLocation,
669 OpenGl_Vec4i& theValue) const
670{
671 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
672 {
673 return Standard_False;
674 }
675
676 theCtx->core20->glGetUniformiv (myProgramID, theLocation, theValue);
677 return Standard_True;
678}
679
680// =======================================================================
681// function : GetUniform
682// purpose : Returns the value of the floating-point uniform variable
683// =======================================================================
684Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx,
685 const GLchar* theName,
686 OpenGl_Vec4& theValue) const
687{
688 return GetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
689}
690
691// =======================================================================
692// function : GetUniform
693// purpose : Returns the value of the floating-point uniform variable
694// =======================================================================
695Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx,
696 GLint theLocation,
697 OpenGl_Vec4& theValue) const
698{
699 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
700 {
701 return Standard_False;
702 }
703
704 theCtx->core20->glGetUniformfv (myProgramID, theLocation, theValue);
705 return Standard_True;
706}
707
708// =======================================================================
709// function : GetAttribute
710// purpose : Returns the integer vertex attribute
711// =======================================================================
712Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx,
713 const GLchar* theName,
714 OpenGl_Vec4i& theValue) const
715{
716 return GetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
717}
718
719// =======================================================================
720// function : GetAttribute
721// purpose : Returns the integer vertex attribute
722// =======================================================================
723Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx,
724 GLint theIndex,
725 OpenGl_Vec4i& theValue) const
726{
727 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
728 {
729 return Standard_False;
730 }
731
732 theCtx->core20->glGetVertexAttribiv (theIndex, GL_CURRENT_VERTEX_ATTRIB, theValue);
733 return Standard_True;
734}
735
736// =======================================================================
737// function : GetAttribute
738// purpose : Returns the floating-point vertex attribute
739// =======================================================================
740Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx,
741 const GLchar* theName,
742 OpenGl_Vec4& theValue) const
743{
744 return GetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
745}
746
747// =======================================================================
748// function : GetAttribute
749// purpose : Returns the floating-point vertex attribute
750// =======================================================================
751Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx,
752 GLint theIndex,
753 OpenGl_Vec4& theValue) const
754{
755 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
756 {
757 return Standard_False;
758 }
759
760 theCtx->core20->glGetVertexAttribfv (theIndex, GL_CURRENT_VERTEX_ATTRIB, theValue);
761 return Standard_True;
762}
763
764// =======================================================================
765// function : SetUniform
766// purpose : Specifies the value of the integer uniform variable
767// =======================================================================
768Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
769 const GLchar* theName,
770 GLint theValue)
771{
772 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
773}
774
775// =======================================================================
776// function : SetUniform
777// purpose : Specifies the value of the integer uniform variable
778// =======================================================================
779Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
780 GLint theLocation,
781 GLint theValue)
782{
783 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
784 {
785 return Standard_False;
786 }
787
788 theCtx->core20->glUniform1i (theLocation, theValue);
789 return Standard_True;
790}
791
792// =======================================================================
793// function : SetUniform
794// purpose : Specifies the value of the floating-point uniform variable
795// =======================================================================
796Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
797 const GLchar* theName,
798 GLfloat theValue)
799{
800 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
801}
802
803// =======================================================================
804// function : SetUniform
805// purpose : Specifies the value of the floating-point uniform variable
806// =======================================================================
807Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
808 GLint theLocation,
809 GLfloat theValue)
810{
811 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
812 {
813 return Standard_False;
814 }
815
816 theCtx->core20->glUniform1f (theLocation, theValue);
817 return Standard_True;
818}
819
820// =======================================================================
821// function : SetUniform
822// purpose : Specifies the value of the integer uniform 2D vector
823// =======================================================================
824Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
825 const GLchar* theName,
826 const OpenGl_Vec2i& theValue)
827{
828 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
829}
830
831// =======================================================================
832// function : SetUniform
833// purpose : Specifies the value of the integer uniform 2D vector
834// =======================================================================
835Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
836 GLint theLocation,
837 const OpenGl_Vec2i& theValue)
838{
839 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
840 {
841 return Standard_False;
842 }
843
844 theCtx->core20->glUniform2iv (theLocation, 1, theValue);
845 return Standard_True;
846}
847
848// =======================================================================
849// function : SetUniform
850// purpose : Specifies the value of the integer uniform 3D vector
851// =======================================================================
852Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
853 const GLchar* theName,
854 const OpenGl_Vec3i& theValue)
855{
856 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
857}
858
859// =======================================================================
860// function : SetUniform
861// purpose : Specifies the value of the integer uniform 3D vector
862// =======================================================================
863Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
864 GLint theLocation,
865 const OpenGl_Vec3i& theValue)
866{
867 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
868 {
869 return Standard_False;
870 }
871
872 theCtx->core20->glUniform3iv (theLocation, 1, theValue);
873 return Standard_True;
874}
875
876// =======================================================================
877// function : SetUniform
878// purpose : Specifies the value of the integer uniform 4D vector
879// =======================================================================
880Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
881 const GLchar* theName,
882 const OpenGl_Vec4i& theValue)
883{
884 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
885}
886
887// =======================================================================
888// function : SetUniform
889// purpose : Specifies the value of the integer uniform 4D vector
890// =======================================================================
891Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
892 GLint theLocation,
893 const OpenGl_Vec4i& theValue)
894{
895 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
896 {
897 return Standard_False;
898 }
899
900 theCtx->core20->glUniform4iv (theLocation, 1, theValue);
901 return Standard_True;
902}
903
904// =======================================================================
905// function : SetUniform
906// purpose : Specifies the value of the floating-point uniform 2D vector
907// =======================================================================
908Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
909 const GLchar* theName,
910 const OpenGl_Vec2& theValue)
911{
912 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
913}
914
915// =======================================================================
916// function : SetUniform
917// purpose : Specifies the value of the floating-point uniform 2D vector
918// =======================================================================
919Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
920 GLint theLocation,
921 const OpenGl_Vec2& theValue)
922{
923 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
924 {
925 return Standard_False;
926 }
927
928 theCtx->core20->glUniform2fv (theLocation, 1, theValue);
929 return Standard_True;
930}
931
932// =======================================================================
933// function : SetUniform
934// purpose : Specifies the value of the floating-point uniform 3D vector
935// =======================================================================
936Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
937 const GLchar* theName,
938 const OpenGl_Vec3& theValue)
939{
940 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
941}
942
943// =======================================================================
944// function : SetUniform
945// purpose : Specifies the value of the floating-point uniform 3D vector
946// =======================================================================
947Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
948 GLint theLocation,
949 const OpenGl_Vec3& theValue)
950{
951 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
952 {
953 return Standard_False;
954 }
955
956 theCtx->core20->glUniform3fv (theLocation, 1, theValue);
957 return Standard_True;
958}
959
960// =======================================================================
961// function : SetUniform
962// purpose : Specifies the value of the floating-point uniform 4D vector
963// =======================================================================
964Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
965 const GLchar* theName,
966 const OpenGl_Vec4& theValue)
967{
968 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
969}
970
971// =======================================================================
972// function : SetUniform
973// purpose : Specifies the value of the floating-point uniform 4D vector
974// =======================================================================
975Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
976 GLint theLocation,
977 const OpenGl_Vec4& theValue)
978{
979 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
980 {
981 return Standard_False;
982 }
983
984 theCtx->core20->glUniform4fv (theLocation, 1, theValue);
985 return Standard_True;
986}
987
988// =======================================================================
989// function : SetUniform
990// purpose : Specifies the value of the floating-point uniform 4x4 matrix
991// =======================================================================
992Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
993 const GLchar* theName,
994 const OpenGl_Matrix& theValue,
995 GLboolean theTranspose)
996{
997 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue, theTranspose);
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 GLint theLocation,
1006 const OpenGl_Matrix& theValue,
1007 GLboolean theTranspose)
1008{
1009 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1010 {
1011 return Standard_False;
1012 }
1013
1014 theCtx->core20->glUniformMatrix4fv (theLocation, 1, theTranspose, *theValue.mat);
1015 return Standard_True;
1016}
1017
1018// =======================================================================
1019// function : SetUniform
1020// purpose : Specifies the value of the floating-point uniform 4x4 matrix
1021// =======================================================================
1022Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1023 const GLchar* theName,
1024 const Tmatrix3& theValue,
1025 GLboolean theTranspose)
1026{
1027 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue, theTranspose);
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 GLint theLocation,
1036 const Tmatrix3& theValue,
1037 GLboolean theTranspose)
1038{
1039 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1040 {
1041 return Standard_False;
1042 }
1043
1044 theCtx->core20->glUniformMatrix4fv (theLocation, 1, theTranspose, *theValue);
1045 return Standard_True;
1046}
1047
1048// =======================================================================
1049// function : SetSampler
1050// purpose : Specifies the value of the sampler uniform variable
1051// =======================================================================
1052Standard_Boolean OpenGl_ShaderProgram::SetSampler (const Handle(OpenGl_Context)& theCtx,
1053 const GLchar* theName,
1054 const GLenum theTextureUnit)
1055{
1056 return SetSampler (theCtx, GetUniformLocation (theCtx, theName), theTextureUnit);
1057}
1058
1059// =======================================================================
1060// function : SetSampler
1061// purpose : Specifies the value of the sampler uniform variable
1062// =======================================================================
1063Standard_Boolean OpenGl_ShaderProgram::SetSampler (const Handle(OpenGl_Context)& theCtx,
1064 GLint theLocation,
1065 const GLenum theTextureUnit)
1066{
1067 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1068 {
1069 return Standard_False;
1070 }
1071
1072 theCtx->core20->glUniform1i (theLocation, theTextureUnit);
1073 return Standard_True;
1074}
1075
1076// =======================================================================
1077// function : Create
1078// purpose : Creates new empty shader program of specified type
1079// =======================================================================
1080Standard_Boolean OpenGl_ShaderProgram::Create (const Handle(OpenGl_Context)& theCtx)
1081{
1082 if (myProgramID == NO_PROGRAM
1083 && theCtx->core20 != NULL)
1084 {
1085 myProgramID = theCtx->core20->glCreateProgram();
1086 }
1087
1088 return myProgramID != NO_PROGRAM;
1089}
1090
1091// =======================================================================
1092// function : Release
1093// purpose : Destroys shader program
1094// =======================================================================
1095void OpenGl_ShaderProgram::Release (const OpenGl_Context* theCtx)
1096{
1097 if (myProgramID == NO_PROGRAM)
1098 {
1099 return;
1100 }
1101
1102 Standard_ASSERT_RETURN (theCtx != NULL,
1103 "OpenGl_ShaderProgram destroyed without GL context! Possible GPU memory leakage...",);
1104
1105 for (OpenGl_ShaderList::Iterator anIter (myShaderObjects); anIter.More(); anIter.Next())
1106 {
1107 anIter.ChangeValue()->Release (theCtx);
1108 anIter.ChangeValue().Nullify();
1109 }
1110
ec2eeb2d 1111 if (theCtx->core20 != NULL
1112 && theCtx->IsValid())
30f0ad28 1113 {
1114 theCtx->core20->glDeleteProgram (myProgramID);
1115 }
1116
1117 myProgramID = NO_PROGRAM;
1118}