30f0ad28 |
1 | // Created on: 2013-09-19 |
2 | // Created by: Denis BOGOLEPOV |
d5f74e42 |
3 | // Copyright (c) 2013-2014 OPEN CASCADE SAS |
30f0ad28 |
4 | // |
973c2be1 |
5 | // This file is part of Open CASCADE Technology software library. |
30f0ad28 |
6 | // |
d5f74e42 |
7 | // This library is free software; you can redistribute it and/or modify it under |
8 | // the terms of the GNU Lesser General Public License version 2.1 as published |
973c2be1 |
9 | // by the Free Software Foundation, with special exception defined in the file |
10 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT |
11 | // distribution for complete text of the license and disclaimer of any warranty. |
30f0ad28 |
12 | // |
973c2be1 |
13 | // Alternatively, this file may be used under the terms of Open CASCADE |
14 | // commercial license or contractual agreement. |
30f0ad28 |
15 | |
16 | #include <OSD_File.hxx> |
17 | #include <OSD_Protection.hxx> |
18 | |
7d3e64ef |
19 | #include <Graphic3d_Buffer.hxx> |
30f0ad28 |
20 | #include <Standard_Assert.hxx> |
21 | #include <Standard_Atomic.hxx> |
22 | #include <TCollection_ExtendedString.hxx> |
23 | |
24 | #include <OpenGl_Context.hxx> |
25 | #include <OpenGl_ShaderProgram.hxx> |
26 | #include <OpenGl_ShaderManager.hxx> |
25ef750e |
27 | #include <OpenGl_ArbTexBindless.hxx> |
30f0ad28 |
28 | |
47e9c178 |
29 | #include <OpenGl_GlCore32.hxx> |
30f0ad28 |
30 | |
ee5befae |
31 | #include "../Shaders/Shaders_DeclarationsImpl_glsl.pxx" |
32 | #include "../Shaders/Shaders_Declarations_glsl.pxx" |
33 | |
7c65581d |
34 | #ifdef _WIN32 |
35 | #include <malloc.h> // for alloca() |
36 | #endif |
37 | |
92efcf78 |
38 | IMPLEMENT_STANDARD_RTTIEXT(OpenGl_ShaderProgram,OpenGl_Resource) |
39 | |
30f0ad28 |
40 | OpenGl_VariableSetterSelector OpenGl_ShaderProgram::mySetterSelector = OpenGl_VariableSetterSelector(); |
41 | |
42 | // Declare OCCT-specific OpenGL/GLSL shader variables |
43 | Standard_CString OpenGl_ShaderProgram::PredefinedKeywords[] = |
44 | { |
12381341 |
45 | "occModelWorldMatrix", // OpenGl_OCC_MODEL_WORLD_MATRIX |
46 | "occWorldViewMatrix", // OpenGl_OCC_WORLD_VIEW_MATRIX |
47 | "occProjectionMatrix", // OpenGl_OCC_PROJECTION_MATRIX |
48 | "occModelWorldMatrixInverse", // OpenGl_OCC_MODEL_WORLD_MATRIX_INVERSE |
49 | "occWorldViewMatrixInverse", // OpenGl_OCC_WORLD_VIEW_MATRIX_INVERSE |
50 | "occProjectionMatrixInverse", // OpenGl_OCC_PROJECTION_MATRIX_INVERSE |
51 | "occModelWorldMatrixTranspose", // OpenGl_OCC_MODEL_WORLD_MATRIX_TRANSPOSE |
52 | "occWorldViewMatrixTranspose", // OpenGl_OCC_WORLD_VIEW_MATRIX_TRANSPOSE |
53 | "occProjectionMatrixTranspose", // OpenGl_OCC_PROJECTION_MATRIX_TRANSPOSE |
54 | "occModelWorldMatrixInverseTranspose", // OpenGl_OCC_MODEL_WORLD_MATRIX_INVERSE_TRANSPOSE |
55 | "occWorldViewMatrixInverseTranspose", // OpenGl_OCC_WORLD_VIEW_MATRIX_INVERSE_TRANSPOSE |
56 | "occProjectionMatrixInverseTranspose", // OpenGl_OCC_PROJECTION_MATRIX_INVERSE_TRANSPOSE |
57 | |
58 | "occClipPlaneEquations", // OpenGl_OCC_CLIP_PLANE_EQUATIONS |
5495fa7e |
59 | "occClipPlaneCount", // OpenGl_OCC_CLIP_PLANE_COUNT |
12381341 |
60 | |
61 | "occLightSourcesCount", // OpenGl_OCC_LIGHT_SOURCE_COUNT |
62 | "occLightSourcesTypes", // OpenGl_OCC_LIGHT_SOURCE_TYPES |
63 | "occLightSources", // OpenGl_OCC_LIGHT_SOURCE_PARAMS |
64 | "occLightAmbient", // OpenGl_OCC_LIGHT_AMBIENT |
65 | |
66 | "occActiveSampler", // OpenGl_OCCT_ACTIVE_SAMPLER |
67 | "occTextureEnable", // OpenGl_OCCT_TEXTURE_ENABLE |
68 | "occDistinguishingMode", // OpenGl_OCCT_DISTINGUISH_MODE |
69 | "occFrontMaterial", // OpenGl_OCCT_FRONT_MATERIAL |
8625ef7e |
70 | "occBackMaterial", // OpenGl_OCCT_BACK_MATERIAL |
71 | "occColor", // OpenGl_OCCT_COLOR |
72 | |
a1073ae2 |
73 | "occOitOutput", // OpenGl_OCCT_OIT_OUTPUT |
74 | "occOitDepthFactor", // OpenGl_OCCT_OIT_DEPTH_FACTOR |
75 | |
79f4f036 |
76 | "occTexTrsf2d", // OpenGl_OCCT_TEXTURE_TRSF2D |
8625ef7e |
77 | "occPointSize" // OpenGl_OCCT_POINT_SIZE |
30f0ad28 |
78 | }; |
79 | |
80 | // ======================================================================= |
81 | // function : OpenGl_VariableSetterSelector |
82 | // purpose : Creates new variable setter selector |
83 | // ======================================================================= |
84 | OpenGl_VariableSetterSelector::OpenGl_VariableSetterSelector() |
85 | { |
86 | // Note: Add new variable setters here |
87 | mySetterList = OpenGl_HashMapInitializer::CreateListOf<size_t, OpenGl_SetterInterface*> |
88 | (Graphic3d_UniformValueTypeID<int>::ID, new OpenGl_VariableSetter<int>()) |
89 | (Graphic3d_UniformValueTypeID<float>::ID, new OpenGl_VariableSetter<float>()) |
90 | (Graphic3d_UniformValueTypeID<OpenGl_Vec2>::ID, new OpenGl_VariableSetter<OpenGl_Vec2>()) |
91 | (Graphic3d_UniformValueTypeID<OpenGl_Vec3>::ID, new OpenGl_VariableSetter<OpenGl_Vec3>()) |
92 | (Graphic3d_UniformValueTypeID<OpenGl_Vec4>::ID, new OpenGl_VariableSetter<OpenGl_Vec4>()) |
93 | (Graphic3d_UniformValueTypeID<OpenGl_Vec2i>::ID, new OpenGl_VariableSetter<OpenGl_Vec2i>()) |
94 | (Graphic3d_UniformValueTypeID<OpenGl_Vec3i>::ID, new OpenGl_VariableSetter<OpenGl_Vec3i>()) |
95 | (Graphic3d_UniformValueTypeID<OpenGl_Vec4i>::ID, new OpenGl_VariableSetter<OpenGl_Vec4i>()); |
96 | } |
97 | |
98 | // ======================================================================= |
99 | // function : ~OpenGl_VariableSetterSelector |
100 | // purpose : Releases memory resources of variable setter selector |
101 | // ======================================================================= |
102 | OpenGl_VariableSetterSelector::~OpenGl_VariableSetterSelector() |
103 | { |
104 | for (OpenGl_SetterList::Iterator anIt (mySetterList); anIt.More(); anIt.Next()) |
105 | { |
106 | delete anIt.Value(); |
107 | } |
108 | |
109 | mySetterList.Clear(); |
110 | } |
111 | |
112 | // ======================================================================= |
113 | // function : Set |
114 | // purpose : Sets generic variable to specified shader program |
115 | // ======================================================================= |
116 | void OpenGl_VariableSetterSelector::Set (const Handle(OpenGl_Context)& theCtx, |
117 | const Handle(Graphic3d_ShaderVariable)& theVariable, |
118 | OpenGl_ShaderProgram* theProgram) const |
119 | { |
120 | Standard_ASSERT_RETURN (mySetterList.IsBound (theVariable->Value()->TypeID()), |
121 | "The type of user-defined uniform variable is not supported...", ); |
122 | |
123 | mySetterList.Find (theVariable->Value()->TypeID())->Set (theCtx, theVariable, theProgram); |
124 | } |
125 | |
126 | // ======================================================================= |
127 | // function : OpenGl_ShaderProgram |
128 | // purpose : Creates uninitialized shader program |
129 | // ======================================================================= |
130 | OpenGl_ShaderProgram::OpenGl_ShaderProgram (const Handle(Graphic3d_ShaderProgram)& theProxy) |
131 | : myProgramID (NO_PROGRAM), |
392ac980 |
132 | myProxy (theProxy), |
133 | myShareCount(1) |
30f0ad28 |
134 | { |
135 | memset (myCurrentState, 0, sizeof (myCurrentState)); |
136 | for (GLint aVar = 0; aVar < OpenGl_OCCT_NUMBER_OF_STATE_VARIABLES; ++aVar) |
137 | { |
138 | myStateLocations[aVar] = INVALID_LOCATION; |
139 | } |
140 | } |
141 | |
142 | // ======================================================================= |
143 | // function : Initialize |
144 | // purpose : Initializes program object with the list of shader objects |
145 | // ======================================================================= |
146 | Standard_Boolean OpenGl_ShaderProgram::Initialize (const Handle(OpenGl_Context)& theCtx, |
147 | const Graphic3d_ShaderObjectList& theShaders) |
148 | { |
149 | if (theCtx.IsNull() || !Create (theCtx)) |
150 | { |
151 | return Standard_False; |
152 | } |
153 | |
b86bb3df |
154 | TCollection_AsciiString aHeader = !myProxy.IsNull() && !myProxy->Header().IsEmpty() |
155 | ? (myProxy->Header() + "\n") |
156 | : TCollection_AsciiString(); |
157 | |
ee5befae |
158 | TCollection_AsciiString aDeclarations = Shaders_Declarations_glsl; |
159 | TCollection_AsciiString aDeclImpl = Shaders_DeclarationsImpl_glsl; |
30f0ad28 |
160 | |
12381341 |
161 | aDeclarations += aDeclImpl; |
162 | |
30f0ad28 |
163 | for (Graphic3d_ShaderObjectList::Iterator anIter (theShaders); |
164 | anIter.More(); anIter.Next()) |
165 | { |
166 | if (!anIter.Value()->IsDone()) |
167 | { |
392ac980 |
168 | const TCollection_ExtendedString aMsg = "Error! Failed to get shader source"; |
3b523c4c |
169 | theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, |
170 | GL_DEBUG_TYPE_ERROR, |
30f0ad28 |
171 | 0, |
3b523c4c |
172 | GL_DEBUG_SEVERITY_HIGH, |
30f0ad28 |
173 | aMsg); |
30f0ad28 |
174 | return Standard_False; |
175 | } |
176 | |
177 | Handle(OpenGl_ShaderObject) aShader; |
178 | |
179 | // Note: Add support of other shader types here |
180 | switch (anIter.Value()->Type()) |
181 | { |
182 | case Graphic3d_TOS_VERTEX: |
183 | aShader = new OpenGl_ShaderObject (GL_VERTEX_SHADER); |
184 | break; |
185 | case Graphic3d_TOS_FRAGMENT: |
186 | aShader = new OpenGl_ShaderObject (GL_FRAGMENT_SHADER); |
187 | break; |
188 | } |
189 | |
190 | // Is unsupported shader type? |
191 | if (aShader.IsNull()) |
192 | { |
193 | TCollection_ExtendedString aMsg = "Error! Unsupported shader type"; |
3b523c4c |
194 | theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, |
195 | GL_DEBUG_TYPE_ERROR, |
30f0ad28 |
196 | 0, |
3b523c4c |
197 | GL_DEBUG_SEVERITY_HIGH, |
30f0ad28 |
198 | aMsg); |
30f0ad28 |
199 | return Standard_False; |
200 | } |
201 | |
202 | if (!aShader->Create (theCtx)) |
203 | { |
392ac980 |
204 | aShader->Release (theCtx.operator->()); |
30f0ad28 |
205 | return Standard_False; |
206 | } |
207 | |
208 | TCollection_AsciiString aSource = aDeclarations + anIter.Value()->Source(); |
177781da |
209 | TCollection_AsciiString anExtensions = "// Enable extensions used in OCCT GLSL programs\n"; |
a1073ae2 |
210 | if (theCtx->hasDrawBuffers) |
211 | { |
212 | anExtensions += "#define OCC_ENABLE_draw_buffers\n"; |
213 | } |
214 | if (theCtx->hasDrawBuffers == OpenGl_FeatureInExtensions) |
215 | { |
216 | if (theCtx->arbDrawBuffers) |
217 | { |
218 | anExtensions += "#extension GL_ARB_draw_buffers : enable\n"; |
219 | } |
220 | else if (theCtx->extDrawBuffers) |
221 | { |
222 | anExtensions += "#extension GL_EXT_draw_buffers : enable\n"; |
223 | } |
224 | } |
225 | |
226 | if (theCtx->hasSampleVariables == OpenGl_FeatureInExtensions) |
227 | { |
228 | #if defined(GL_ES_VERSION_2_0) |
229 | if (theCtx->oesSampleVariables) |
230 | { |
231 | anExtensions += "#extension GL_OES_sample_variables : enable\n"; |
232 | } |
233 | #else |
234 | if (theCtx->arbSampleShading) |
235 | { |
236 | anExtensions += "#extension GL_ARB_sample_shading : enable\n"; |
237 | } |
238 | #endif |
239 | } |
240 | |
8625ef7e |
241 | switch (anIter.Value()->Type()) |
30f0ad28 |
242 | { |
8625ef7e |
243 | case Graphic3d_TOS_VERTEX: |
244 | { |
a1073ae2 |
245 | aSource = aHeader + TCollection_AsciiString ("#define VERTEX_SHADER\n") + anExtensions + aSource; |
8625ef7e |
246 | break; |
247 | } |
248 | case Graphic3d_TOS_FRAGMENT: |
249 | { |
250 | #if defined(GL_ES_VERSION_2_0) |
251 | TCollection_AsciiString aPrefix (theCtx->hasHighp |
252 | ? "precision highp float;\n" |
8a53d1c4 |
253 | "precision highp int;\n" |
254 | : "precision mediump float;\n" |
255 | "precision mediump int;\n"); |
177781da |
256 | aSource = aHeader + anExtensions + aPrefix + aSource; |
4e1523ef |
257 | #else |
a1073ae2 |
258 | aSource = aHeader + anExtensions + aSource; |
8625ef7e |
259 | #endif |
260 | break; |
261 | } |
30f0ad28 |
262 | } |
263 | |
264 | if (!aShader->LoadSource (theCtx, aSource)) |
265 | { |
a1073ae2 |
266 | theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, aSource); |
392ac980 |
267 | const TCollection_ExtendedString aMsg = "Error! Failed to set shader source"; |
3b523c4c |
268 | theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, |
269 | GL_DEBUG_TYPE_ERROR, |
30f0ad28 |
270 | 0, |
3b523c4c |
271 | GL_DEBUG_SEVERITY_HIGH, |
30f0ad28 |
272 | aMsg); |
392ac980 |
273 | aShader->Release (theCtx.operator->()); |
30f0ad28 |
274 | return Standard_False; |
275 | } |
276 | |
277 | if (!aShader->Compile (theCtx)) |
278 | { |
a1073ae2 |
279 | theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, aSource); |
392ac980 |
280 | TCollection_AsciiString aLog; |
281 | aShader->FetchInfoLog (theCtx, aLog); |
282 | if (aLog.IsEmpty()) |
283 | { |
284 | aLog = "Compilation log is empty."; |
285 | } |
3b523c4c |
286 | theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, |
287 | GL_DEBUG_TYPE_ERROR, |
30f0ad28 |
288 | 0, |
3b523c4c |
289 | GL_DEBUG_SEVERITY_HIGH, |
392ac980 |
290 | TCollection_ExtendedString ("Failed to compile shader object. Compilation log:\n") + aLog); |
291 | aShader->Release (theCtx.operator->()); |
292 | return Standard_False; |
293 | } |
294 | else if (theCtx->caps->glslWarnings) |
295 | { |
296 | TCollection_AsciiString aLog; |
297 | aShader->FetchInfoLog (theCtx, aLog); |
298 | if (!aLog.IsEmpty() |
299 | && !aLog.IsEqual ("No errors.\n")) |
30f0ad28 |
300 | { |
3b523c4c |
301 | theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, |
302 | GL_DEBUG_TYPE_PORTABILITY, |
392ac980 |
303 | 0, |
3b523c4c |
304 | GL_DEBUG_SEVERITY_LOW, |
392ac980 |
305 | TCollection_ExtendedString ("Shader compilation log:\n") + aLog); |
30f0ad28 |
306 | } |
30f0ad28 |
307 | } |
308 | |
309 | if (!AttachShader (theCtx, aShader)) |
310 | { |
392ac980 |
311 | aShader->Release (theCtx.operator->()); |
30f0ad28 |
312 | return Standard_False; |
313 | } |
314 | } |
315 | |
7d3e64ef |
316 | // bind locations for pre-defined Vertex Attributes |
317 | SetAttributeName (theCtx, Graphic3d_TOA_POS, "occVertex"); |
318 | SetAttributeName (theCtx, Graphic3d_TOA_NORM, "occNormal"); |
319 | SetAttributeName (theCtx, Graphic3d_TOA_UV, "occTexCoord"); |
8625ef7e |
320 | SetAttributeName (theCtx, Graphic3d_TOA_COLOR, "occVertColor"); |
7d3e64ef |
321 | |
4a535d3f |
322 | // bind custom Vertex Attributes |
323 | if (!myProxy.IsNull()) |
324 | { |
325 | for (Graphic3d_ShaderAttributeList::Iterator anAttribIter (myProxy->VertexAttributes()); |
326 | anAttribIter.More(); anAttribIter.Next()) |
327 | { |
328 | SetAttributeName (theCtx, anAttribIter.Value()->Location(), anAttribIter.Value()->Name().ToCString()); |
329 | } |
330 | } |
331 | |
30f0ad28 |
332 | if (!Link (theCtx)) |
333 | { |
392ac980 |
334 | TCollection_AsciiString aLog; |
335 | FetchInfoLog (theCtx, aLog); |
336 | if (aLog.IsEmpty()) |
337 | { |
338 | aLog = "Linker log is empty."; |
339 | } |
3b523c4c |
340 | theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, |
341 | GL_DEBUG_TYPE_ERROR, |
30f0ad28 |
342 | 0, |
3b523c4c |
343 | GL_DEBUG_SEVERITY_HIGH, |
12381341 |
344 | TCollection_ExtendedString ("Failed to link program object! Linker log:\n") + aLog); |
392ac980 |
345 | return Standard_False; |
346 | } |
347 | else if (theCtx->caps->glslWarnings) |
348 | { |
349 | TCollection_AsciiString aLog; |
350 | FetchInfoLog (theCtx, aLog); |
351 | if (!aLog.IsEmpty() |
352 | && !aLog.IsEqual ("No errors.\n")) |
30f0ad28 |
353 | { |
3b523c4c |
354 | theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, |
355 | GL_DEBUG_TYPE_PORTABILITY, |
392ac980 |
356 | 0, |
3b523c4c |
357 | GL_DEBUG_SEVERITY_LOW, |
392ac980 |
358 | TCollection_ExtendedString ("GLSL linker log:\n") + aLog); |
30f0ad28 |
359 | } |
30f0ad28 |
360 | } |
361 | |
299e0ab9 |
362 | // set uniform defaults |
363 | const GLint aLocSampler = GetStateLocation (OpenGl_OCCT_ACTIVE_SAMPLER); |
364 | const GLint aLocTexEnable = GetStateLocation (OpenGl_OCCT_TEXTURE_ENABLE); |
365 | if (aLocSampler != INVALID_LOCATION |
366 | || aLocTexEnable != INVALID_LOCATION) |
367 | { |
368 | const Handle(OpenGl_ShaderProgram)& anOldProgram = theCtx->ActiveProgram(); |
369 | theCtx->core20fwd->glUseProgram (myProgramID); |
370 | SetUniform (theCtx, aLocSampler, 0); // GL_TEXTURE0 |
371 | SetUniform (theCtx, aLocTexEnable, 0); // Off |
372 | theCtx->core20fwd->glUseProgram (!anOldProgram.IsNull() ? anOldProgram->ProgramId() : OpenGl_ShaderProgram::NO_PROGRAM); |
373 | } |
374 | |
30f0ad28 |
375 | return Standard_True; |
376 | } |
377 | |
378 | // ======================================================================= |
379 | // function : ~OpenGl_ShaderProgram |
380 | // purpose : Releases resources of shader program |
381 | // ======================================================================= |
382 | OpenGl_ShaderProgram::~OpenGl_ShaderProgram() |
383 | { |
384 | Release (NULL); |
385 | } |
386 | |
387 | // ======================================================================= |
388 | // function : AttachShader |
389 | // purpose : Attaches shader object to the program object |
390 | // ======================================================================= |
391 | Standard_Boolean OpenGl_ShaderProgram::AttachShader (const Handle(OpenGl_Context)& theCtx, |
392 | const Handle(OpenGl_ShaderObject)& theShader) |
393 | { |
394 | if (myProgramID == NO_PROGRAM || theShader.IsNull()) |
395 | { |
396 | return Standard_False; |
397 | } |
398 | |
399 | for (OpenGl_ShaderList::Iterator anIter (myShaderObjects); anIter.More(); anIter.Next()) |
400 | { |
401 | if (theShader == anIter.Value()) |
402 | { |
403 | return Standard_False; |
404 | } |
405 | } |
406 | |
407 | myShaderObjects.Append (theShader); |
4e1523ef |
408 | theCtx->core20fwd->glAttachShader (myProgramID, theShader->myShaderID); |
30f0ad28 |
409 | return Standard_True; |
410 | } |
411 | |
412 | // ======================================================================= |
413 | // function : DetachShader |
414 | // purpose : Detaches shader object to the program object |
415 | // ======================================================================= |
416 | Standard_Boolean OpenGl_ShaderProgram::DetachShader (const Handle(OpenGl_Context)& theCtx, |
417 | const Handle(OpenGl_ShaderObject)& theShader) |
418 | { |
419 | if (myProgramID == NO_PROGRAM |
420 | || theShader.IsNull()) |
421 | { |
422 | return Standard_False; |
423 | } |
424 | |
425 | OpenGl_ShaderList::Iterator anIter (myShaderObjects); |
426 | while (anIter.More()) |
427 | { |
428 | if (theShader == anIter.Value()) |
429 | { |
430 | myShaderObjects.Remove (anIter); |
431 | break; |
432 | } |
433 | |
434 | anIter.Next(); |
435 | } |
436 | |
437 | if (!anIter.More()) |
438 | { |
439 | return Standard_False; |
440 | } |
441 | |
4e1523ef |
442 | theCtx->core20fwd->glDetachShader (myProgramID, theShader->myShaderID); |
30f0ad28 |
443 | return Standard_True; |
444 | } |
445 | |
446 | // ======================================================================= |
447 | // function : Link |
448 | // purpose : Links the program object |
449 | // ======================================================================= |
450 | Standard_Boolean OpenGl_ShaderProgram::Link (const Handle(OpenGl_Context)& theCtx) |
451 | { |
452 | if (myProgramID == NO_PROGRAM) |
453 | { |
454 | return Standard_False; |
455 | } |
456 | |
30f0ad28 |
457 | GLint aStatus = GL_FALSE; |
4e1523ef |
458 | theCtx->core20fwd->glLinkProgram (myProgramID); |
459 | theCtx->core20fwd->glGetProgramiv (myProgramID, GL_LINK_STATUS, &aStatus); |
fc73a202 |
460 | if (aStatus == GL_FALSE) |
461 | { |
462 | return Standard_False; |
463 | } |
30f0ad28 |
464 | |
465 | for (GLint aVar = 0; aVar < OpenGl_OCCT_NUMBER_OF_STATE_VARIABLES; ++aVar) |
466 | { |
467 | myStateLocations[aVar] = GetUniformLocation (theCtx, PredefinedKeywords[aVar]); |
468 | } |
fc73a202 |
469 | return Standard_True; |
30f0ad28 |
470 | } |
471 | |
472 | // ======================================================================= |
473 | // function : FetchInfoLog |
474 | // purpose : Fetches information log of the last link operation |
475 | // ======================================================================= |
476 | Standard_Boolean OpenGl_ShaderProgram::FetchInfoLog (const Handle(OpenGl_Context)& theCtx, |
477 | TCollection_AsciiString& theOutput) |
478 | { |
479 | if (myProgramID == NO_PROGRAM) |
480 | { |
481 | return Standard_False; |
482 | } |
483 | |
484 | GLint aLength = 0; |
4e1523ef |
485 | theCtx->core20fwd->glGetProgramiv (myProgramID, GL_INFO_LOG_LENGTH, &aLength); |
30f0ad28 |
486 | if (aLength > 0) |
487 | { |
488 | GLchar* aLog = (GLchar*) alloca (aLength); |
489 | memset (aLog, 0, aLength); |
4e1523ef |
490 | theCtx->core20fwd->glGetProgramInfoLog (myProgramID, aLength, NULL, aLog); |
30f0ad28 |
491 | theOutput = aLog; |
492 | } |
493 | return Standard_True; |
494 | } |
495 | |
30f0ad28 |
496 | // ======================================================================= |
497 | // function : ApplyVariables |
498 | // purpose : Fetches uniform variables from proxy shader program |
499 | // ======================================================================= |
500 | Standard_Boolean OpenGl_ShaderProgram::ApplyVariables(const Handle(OpenGl_Context)& theCtx) |
501 | { |
502 | if (myProxy.IsNull() || myProxy->Variables().IsEmpty()) |
503 | { |
504 | return Standard_False; |
505 | } |
506 | |
507 | for (Graphic3d_ShaderVariableList::Iterator anIter (myProxy->Variables()); anIter.More(); anIter.Next()) |
508 | { |
509 | mySetterSelector.Set (theCtx, anIter.Value(), this); |
510 | } |
511 | |
512 | myProxy->ClearVariables(); |
513 | return Standard_True; |
514 | } |
515 | |
30f0ad28 |
516 | // ======================================================================= |
30f0ad28 |
517 | // function : GetUniformLocation |
518 | // purpose : Returns location (index) of the specific uniform variable |
519 | // ======================================================================= |
520 | GLint OpenGl_ShaderProgram::GetUniformLocation (const Handle(OpenGl_Context)& theCtx, |
521 | const GLchar* theName) const |
522 | { |
523 | return myProgramID != NO_PROGRAM |
4e1523ef |
524 | ? theCtx->core20fwd->glGetUniformLocation (myProgramID, theName) |
30f0ad28 |
525 | : INVALID_LOCATION; |
526 | } |
527 | |
528 | // ======================================================================= |
529 | // function : GetAttributeLocation |
530 | // purpose : Returns location (index) of the generic vertex attribute |
531 | // ======================================================================= |
532 | GLint OpenGl_ShaderProgram::GetAttributeLocation (const Handle(OpenGl_Context)& theCtx, |
533 | const GLchar* theName) const |
534 | { |
535 | return myProgramID != NO_PROGRAM |
4e1523ef |
536 | ? theCtx->core20fwd->glGetAttribLocation (myProgramID, theName) |
30f0ad28 |
537 | : INVALID_LOCATION; |
538 | } |
539 | |
540 | // ======================================================================= |
541 | // function : GetStateLocation |
542 | // purpose : Returns location of the OCCT state uniform variable |
543 | // ======================================================================= |
544 | GLint OpenGl_ShaderProgram::GetStateLocation (const GLuint theVariable) const |
545 | { |
546 | if (theVariable < OpenGl_OCCT_NUMBER_OF_STATE_VARIABLES) |
547 | { |
548 | return myStateLocations[theVariable]; |
549 | } |
550 | return INVALID_LOCATION; |
551 | } |
552 | |
553 | // ======================================================================= |
554 | // function : GetUniform |
555 | // purpose : Returns the value of the integer uniform variable |
556 | // ======================================================================= |
557 | Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx, |
558 | const GLchar* theName, |
559 | OpenGl_Vec4i& theValue) const |
560 | { |
561 | return GetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue); |
562 | } |
563 | |
564 | // ======================================================================= |
565 | // function : GetUniform |
566 | // purpose : Returns the value of the integer uniform variable |
567 | // ======================================================================= |
568 | Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx, |
569 | GLint theLocation, |
570 | OpenGl_Vec4i& theValue) const |
571 | { |
572 | if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION) |
573 | { |
574 | return Standard_False; |
575 | } |
576 | |
4e1523ef |
577 | theCtx->core20fwd->glGetUniformiv (myProgramID, theLocation, theValue); |
30f0ad28 |
578 | return Standard_True; |
579 | } |
580 | |
581 | // ======================================================================= |
582 | // function : GetUniform |
583 | // purpose : Returns the value of the floating-point uniform variable |
584 | // ======================================================================= |
585 | Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx, |
586 | const GLchar* theName, |
587 | OpenGl_Vec4& theValue) const |
588 | { |
589 | return GetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue); |
590 | } |
591 | |
592 | // ======================================================================= |
593 | // function : GetUniform |
594 | // purpose : Returns the value of the floating-point uniform variable |
595 | // ======================================================================= |
596 | Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx, |
597 | GLint theLocation, |
598 | OpenGl_Vec4& theValue) const |
599 | { |
600 | if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION) |
601 | { |
602 | return Standard_False; |
603 | } |
604 | |
4e1523ef |
605 | theCtx->core20fwd->glGetUniformfv (myProgramID, theLocation, theValue); |
30f0ad28 |
606 | return Standard_True; |
607 | } |
608 | |
609 | // ======================================================================= |
610 | // function : GetAttribute |
611 | // purpose : Returns the integer vertex attribute |
612 | // ======================================================================= |
613 | Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx, |
614 | const GLchar* theName, |
615 | OpenGl_Vec4i& theValue) const |
616 | { |
617 | return GetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue); |
618 | } |
619 | |
620 | // ======================================================================= |
621 | // function : GetAttribute |
622 | // purpose : Returns the integer vertex attribute |
623 | // ======================================================================= |
624 | Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx, |
625 | GLint theIndex, |
626 | OpenGl_Vec4i& theValue) const |
627 | { |
628 | if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION) |
629 | { |
630 | return Standard_False; |
631 | } |
632 | |
4e1523ef |
633 | theCtx->core20fwd->glGetVertexAttribiv (theIndex, GL_CURRENT_VERTEX_ATTRIB, theValue); |
30f0ad28 |
634 | return Standard_True; |
635 | } |
636 | |
637 | // ======================================================================= |
638 | // function : GetAttribute |
639 | // purpose : Returns the floating-point vertex attribute |
640 | // ======================================================================= |
641 | Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx, |
642 | const GLchar* theName, |
643 | OpenGl_Vec4& theValue) const |
644 | { |
645 | return GetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue); |
646 | } |
647 | |
648 | // ======================================================================= |
649 | // function : GetAttribute |
650 | // purpose : Returns the floating-point vertex attribute |
651 | // ======================================================================= |
652 | Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx, |
653 | GLint theIndex, |
654 | OpenGl_Vec4& theValue) const |
655 | { |
656 | if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION) |
657 | { |
658 | return Standard_False; |
659 | } |
660 | |
4e1523ef |
661 | theCtx->core20fwd->glGetVertexAttribfv (theIndex, GL_CURRENT_VERTEX_ATTRIB, theValue); |
30f0ad28 |
662 | return Standard_True; |
663 | } |
664 | |
fc73a202 |
665 | // ======================================================================= |
666 | // function : SetAttributeName |
667 | // purpose : |
668 | // ======================================================================= |
669 | Standard_Boolean OpenGl_ShaderProgram::SetAttributeName (const Handle(OpenGl_Context)& theCtx, |
670 | GLint theIndex, |
671 | const GLchar* theName) |
672 | { |
673 | theCtx->core20fwd->glBindAttribLocation (myProgramID, theIndex, theName); |
674 | return Standard_True; |
675 | } |
b86bb3df |
676 | |
fc73a202 |
677 | // ======================================================================= |
678 | // function : SetAttribute |
679 | // purpose : |
680 | // ======================================================================= |
681 | Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx, |
682 | const GLchar* theName, |
683 | GLfloat theValue) |
684 | { |
685 | return SetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue); |
686 | } |
687 | |
688 | // ======================================================================= |
689 | // function : SetAttribute |
690 | // purpose : |
691 | // ======================================================================= |
692 | Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx, |
693 | GLint theIndex, |
694 | GLfloat theValue) |
695 | { |
696 | if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION) |
697 | { |
698 | return Standard_False; |
699 | } |
700 | |
701 | theCtx->core20fwd->glVertexAttrib1f (theIndex, theValue); |
702 | return Standard_True; |
703 | } |
704 | |
705 | // ======================================================================= |
706 | // function : SetAttribute |
707 | // purpose : |
708 | // ======================================================================= |
709 | Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx, |
710 | const GLchar* theName, |
711 | const OpenGl_Vec2& theValue) |
712 | { |
713 | return SetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue); |
714 | } |
715 | |
716 | // ======================================================================= |
717 | // function : SetAttribute |
718 | // purpose : |
719 | // ======================================================================= |
720 | Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx, |
721 | GLint theIndex, |
722 | const OpenGl_Vec2& theValue) |
723 | { |
724 | if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION) |
725 | { |
726 | return Standard_False; |
727 | } |
728 | |
729 | theCtx->core20fwd->glVertexAttrib2fv (theIndex, theValue); |
730 | return Standard_True; |
731 | } |
732 | |
733 | // ======================================================================= |
734 | // function : SetAttribute |
735 | // purpose : |
736 | // ======================================================================= |
737 | Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx, |
738 | const GLchar* theName, |
739 | const OpenGl_Vec3& theValue) |
740 | { |
741 | return SetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue); |
742 | } |
743 | |
744 | // ======================================================================= |
745 | // function : SetAttribute |
746 | // purpose : |
747 | // ======================================================================= |
748 | Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx, |
749 | GLint theIndex, |
750 | const OpenGl_Vec3& theValue) |
751 | { |
752 | if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION) |
753 | { |
754 | return Standard_False; |
755 | } |
756 | |
757 | theCtx->core20fwd->glVertexAttrib3fv (theIndex, theValue); |
758 | return Standard_True; |
759 | } |
760 | |
761 | // ======================================================================= |
762 | // function : SetAttribute |
763 | // purpose : |
764 | // ======================================================================= |
765 | Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx, |
766 | const GLchar* theName, |
767 | const OpenGl_Vec4& theValue) |
768 | { |
769 | return SetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue); |
770 | } |
771 | |
772 | // ======================================================================= |
773 | // function : SetAttribute |
774 | // purpose : |
775 | // ======================================================================= |
776 | Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx, |
777 | GLint theIndex, |
778 | const OpenGl_Vec4& theValue) |
779 | { |
780 | if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION) |
781 | { |
782 | return Standard_False; |
783 | } |
784 | |
785 | theCtx->core20fwd->glVertexAttrib4fv (theIndex, theValue); |
786 | return Standard_True; |
787 | } |
788 | |
30f0ad28 |
789 | // ======================================================================= |
790 | // function : SetUniform |
791 | // purpose : Specifies the value of the integer uniform variable |
792 | // ======================================================================= |
793 | Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx, |
794 | const GLchar* theName, |
795 | GLint theValue) |
796 | { |
797 | return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue); |
798 | } |
799 | |
800 | // ======================================================================= |
801 | // function : SetUniform |
802 | // purpose : Specifies the value of the integer uniform variable |
803 | // ======================================================================= |
804 | Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx, |
805 | GLint theLocation, |
806 | GLint theValue) |
807 | { |
808 | if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION) |
809 | { |
810 | return Standard_False; |
811 | } |
812 | |
4e1523ef |
813 | theCtx->core20fwd->glUniform1i (theLocation, theValue); |
30f0ad28 |
814 | return Standard_True; |
815 | } |
816 | |
25ef750e |
817 | // ======================================================================= |
818 | // function : SetUniform |
47e9c178 |
819 | // purpose : |
25ef750e |
820 | // ======================================================================= |
821 | Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx, |
822 | const GLchar* theName, |
47e9c178 |
823 | const OpenGl_Vec2u& theValue) |
25ef750e |
824 | { |
825 | return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue); |
826 | } |
827 | |
828 | // ======================================================================= |
829 | // function : SetUniform |
47e9c178 |
830 | // purpose : |
25ef750e |
831 | // ======================================================================= |
832 | Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx, |
833 | GLint theLocation, |
47e9c178 |
834 | const OpenGl_Vec2u& theValue) |
25ef750e |
835 | { |
47e9c178 |
836 | if (theCtx->core32 == NULL || myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION) |
25ef750e |
837 | { |
838 | return Standard_False; |
839 | } |
840 | |
841 | #if !defined(GL_ES_VERSION_2_0) |
47e9c178 |
842 | theCtx->core32->glUniform2uiv (theLocation, 1, theValue.GetData()); |
25ef750e |
843 | return Standard_True; |
20aeeb7b |
844 | #else |
845 | (void )theValue; |
846 | return Standard_False; |
847 | #endif |
25ef750e |
848 | } |
849 | |
850 | // ======================================================================= |
851 | // function : SetUniform |
47e9c178 |
852 | // purpose : |
25ef750e |
853 | // ======================================================================= |
854 | Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx, |
855 | const GLchar* theName, |
856 | const GLsizei theCount, |
47e9c178 |
857 | const OpenGl_Vec2u* theValue) |
25ef750e |
858 | { |
859 | return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theCount, theValue); |
860 | } |
861 | |
862 | // ======================================================================= |
863 | // function : SetUniform |
47e9c178 |
864 | // purpose : |
25ef750e |
865 | // ======================================================================= |
866 | Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx, |
867 | GLint theLocation, |
868 | const GLsizei theCount, |
47e9c178 |
869 | const OpenGl_Vec2u* theValue) |
25ef750e |
870 | { |
47e9c178 |
871 | if (theCtx->core32 == NULL || myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION) |
25ef750e |
872 | { |
873 | return Standard_False; |
874 | } |
875 | |
876 | #if !defined(GL_ES_VERSION_2_0) |
47e9c178 |
877 | theCtx->core32->glUniform2uiv (theLocation, theCount, theValue->GetData()); |
25ef750e |
878 | return Standard_True; |
20aeeb7b |
879 | #else |
880 | (void )theCount; |
881 | (void )theValue; |
882 | return Standard_False; |
883 | #endif |
25ef750e |
884 | } |
885 | |
30f0ad28 |
886 | // ======================================================================= |
887 | // function : SetUniform |
888 | // purpose : Specifies the value of the floating-point uniform variable |
889 | // ======================================================================= |
890 | Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx, |
891 | const GLchar* theName, |
892 | GLfloat theValue) |
893 | { |
894 | return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue); |
895 | } |
896 | |
897 | // ======================================================================= |
898 | // function : SetUniform |
899 | // purpose : Specifies the value of the floating-point uniform variable |
900 | // ======================================================================= |
901 | Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx, |
902 | GLint theLocation, |
903 | GLfloat theValue) |
904 | { |
905 | if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION) |
906 | { |
907 | return Standard_False; |
908 | } |
909 | |
4e1523ef |
910 | theCtx->core20fwd->glUniform1f (theLocation, theValue); |
30f0ad28 |
911 | return Standard_True; |
912 | } |
913 | |
914 | // ======================================================================= |
915 | // function : SetUniform |
916 | // purpose : Specifies the value of the integer uniform 2D vector |
917 | // ======================================================================= |
918 | Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx, |
919 | const GLchar* theName, |
920 | const OpenGl_Vec2i& theValue) |
921 | { |
922 | return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue); |
923 | } |
924 | |
925 | // ======================================================================= |
926 | // function : SetUniform |
927 | // purpose : Specifies the value of the integer uniform 2D vector |
928 | // ======================================================================= |
929 | Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx, |
930 | GLint theLocation, |
931 | const OpenGl_Vec2i& theValue) |
932 | { |
933 | if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION) |
934 | { |
935 | return Standard_False; |
936 | } |
937 | |
4e1523ef |
938 | theCtx->core20fwd->glUniform2iv (theLocation, 1, theValue); |
30f0ad28 |
939 | return Standard_True; |
940 | } |
941 | |
942 | // ======================================================================= |
943 | // function : SetUniform |
944 | // purpose : Specifies the value of the integer uniform 3D vector |
945 | // ======================================================================= |
946 | Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx, |
947 | const GLchar* theName, |
948 | const OpenGl_Vec3i& theValue) |
949 | { |
950 | return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue); |
951 | } |
952 | |
953 | // ======================================================================= |
954 | // function : SetUniform |
955 | // purpose : Specifies the value of the integer uniform 3D vector |
956 | // ======================================================================= |
957 | Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx, |
958 | GLint theLocation, |
959 | const OpenGl_Vec3i& theValue) |
960 | { |
961 | if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION) |
962 | { |
963 | return Standard_False; |
964 | } |
965 | |
4e1523ef |
966 | theCtx->core20fwd->glUniform3iv (theLocation, 1, theValue); |
30f0ad28 |
967 | return Standard_True; |
968 | } |
969 | |
970 | // ======================================================================= |
971 | // function : SetUniform |
972 | // purpose : Specifies the value of the integer uniform 4D vector |
973 | // ======================================================================= |
974 | Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx, |
975 | const GLchar* theName, |
976 | const OpenGl_Vec4i& theValue) |
977 | { |
978 | return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue); |
979 | } |
980 | |
981 | // ======================================================================= |
982 | // function : SetUniform |
983 | // purpose : Specifies the value of the integer uniform 4D vector |
984 | // ======================================================================= |
985 | Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx, |
986 | GLint theLocation, |
987 | const OpenGl_Vec4i& theValue) |
988 | { |
989 | if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION) |
990 | { |
991 | return Standard_False; |
992 | } |
993 | |
4e1523ef |
994 | theCtx->core20fwd->glUniform4iv (theLocation, 1, theValue); |
30f0ad28 |
995 | return Standard_True; |
996 | } |
997 | |
998 | // ======================================================================= |
999 | // function : SetUniform |
1000 | // purpose : Specifies the value of the floating-point uniform 2D vector |
1001 | // ======================================================================= |
1002 | Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx, |
1003 | const GLchar* theName, |
1004 | const OpenGl_Vec2& theValue) |
1005 | { |
1006 | return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue); |
1007 | } |
1008 | |
1009 | // ======================================================================= |
1010 | // function : SetUniform |
1011 | // purpose : Specifies the value of the floating-point uniform 2D vector |
1012 | // ======================================================================= |
1013 | Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx, |
1014 | GLint theLocation, |
1015 | const OpenGl_Vec2& theValue) |
1016 | { |
1017 | if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION) |
1018 | { |
1019 | return Standard_False; |
1020 | } |
1021 | |
4e1523ef |
1022 | theCtx->core20fwd->glUniform2fv (theLocation, 1, theValue); |
30f0ad28 |
1023 | return Standard_True; |
1024 | } |
1025 | |
1026 | // ======================================================================= |
1027 | // function : SetUniform |
1028 | // purpose : Specifies the value of the floating-point uniform 3D vector |
1029 | // ======================================================================= |
1030 | Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx, |
1031 | const GLchar* theName, |
1032 | const OpenGl_Vec3& theValue) |
1033 | { |
1034 | return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue); |
1035 | } |
1036 | |
1037 | // ======================================================================= |
1038 | // function : SetUniform |
1039 | // purpose : Specifies the value of the floating-point uniform 3D vector |
1040 | // ======================================================================= |
1041 | Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx, |
1042 | GLint theLocation, |
1043 | const OpenGl_Vec3& theValue) |
1044 | { |
1045 | if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION) |
1046 | { |
1047 | return Standard_False; |
1048 | } |
1049 | |
4e1523ef |
1050 | theCtx->core20fwd->glUniform3fv (theLocation, 1, theValue); |
30f0ad28 |
1051 | return Standard_True; |
1052 | } |
1053 | |
1054 | // ======================================================================= |
1055 | // function : SetUniform |
1056 | // purpose : Specifies the value of the floating-point uniform 4D vector |
1057 | // ======================================================================= |
1058 | Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx, |
1059 | const GLchar* theName, |
1060 | const OpenGl_Vec4& theValue) |
1061 | { |
1062 | return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue); |
1063 | } |
1064 | |
1065 | // ======================================================================= |
1066 | // function : SetUniform |
1067 | // purpose : Specifies the value of the floating-point uniform 4D vector |
1068 | // ======================================================================= |
1069 | Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx, |
1070 | GLint theLocation, |
1071 | const OpenGl_Vec4& theValue) |
1072 | { |
1073 | if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION) |
1074 | { |
1075 | return Standard_False; |
1076 | } |
1077 | |
4e1523ef |
1078 | theCtx->core20fwd->glUniform4fv (theLocation, 1, theValue); |
30f0ad28 |
1079 | return Standard_True; |
1080 | } |
1081 | |
25ef750e |
1082 | // ======================================================================= |
1083 | // function : SetUniform |
1084 | // purpose : Specifies the value of the floating-point uniform 4x4 matrix |
1085 | // ======================================================================= |
1086 | Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx, |
1087 | const GLchar* theName, |
1088 | const OpenGl_Mat4& theValue, |
1089 | GLboolean theTranspose) |
1090 | { |
1091 | return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue, theTranspose); |
1092 | } |
1093 | |
1094 | // ======================================================================= |
1095 | // function : SetUniform |
1096 | // purpose : Specifies the value of the floating-point uniform 4x4 matrix |
1097 | // ======================================================================= |
1098 | Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx, |
1099 | GLint theLocation, |
1100 | const OpenGl_Mat4& theValue, |
1101 | GLboolean theTranspose) |
1102 | { |
1103 | if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION) |
1104 | { |
1105 | return Standard_False; |
1106 | } |
1107 | |
4e1523ef |
1108 | theCtx->core20fwd->glUniformMatrix4fv (theLocation, 1, GL_FALSE, theTranspose ? theValue.Transposed() : theValue); |
25ef750e |
1109 | return Standard_True; |
1110 | } |
1111 | |
30f0ad28 |
1112 | // ======================================================================= |
1113 | // function : SetUniform |
1114 | // purpose : Specifies the value of the floating-point uniform 4x4 matrix |
1115 | // ======================================================================= |
1116 | Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx, |
1117 | const GLchar* theName, |
1118 | const OpenGl_Matrix& theValue, |
1119 | GLboolean theTranspose) |
1120 | { |
1121 | return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue, theTranspose); |
1122 | } |
1123 | |
1124 | // ======================================================================= |
1125 | // function : SetUniform |
1126 | // purpose : Specifies the value of the floating-point uniform 4x4 matrix |
1127 | // ======================================================================= |
1128 | Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx, |
1129 | GLint theLocation, |
1130 | const OpenGl_Matrix& theValue, |
1131 | GLboolean theTranspose) |
1132 | { |
c827ea3a |
1133 | return SetUniform (theCtx, theLocation, OpenGl_Mat4::Map (*theValue.mat), theTranspose); |
30f0ad28 |
1134 | } |
1135 | |
4fe9ad57 |
1136 | // ======================================================================= |
1137 | // function : SetUniform |
1138 | // purpose : Specifies the value of the float uniform array |
1139 | // ======================================================================= |
1140 | Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx, |
1141 | GLint theLocation, |
1142 | GLuint theCount, |
1143 | const Standard_ShortReal* theData) |
1144 | { |
1145 | if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION) |
1146 | { |
1147 | return Standard_False; |
1148 | } |
1149 | |
4e1523ef |
1150 | theCtx->core20fwd->glUniform1fv (theLocation, theCount, theData); |
4fe9ad57 |
1151 | return Standard_True; |
1152 | } |
1153 | |
1154 | // ======================================================================= |
1155 | // function : SetUniform |
1156 | // purpose : Specifies the value of the float2 uniform array |
1157 | // ======================================================================= |
1158 | Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx, |
1159 | GLint theLocation, |
1160 | GLuint theCount, |
1161 | const OpenGl_Vec2* theData) |
1162 | { |
1163 | if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION) |
1164 | { |
1165 | return Standard_False; |
1166 | } |
1167 | |
4e1523ef |
1168 | theCtx->core20fwd->glUniform2fv (theLocation, theCount, theData[0].GetData()); |
4fe9ad57 |
1169 | return Standard_True; |
1170 | } |
1171 | |
1172 | // ======================================================================= |
1173 | // function : SetUniform |
1174 | // purpose : Specifies the value of the float3 uniform array |
1175 | // ======================================================================= |
1176 | Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx, |
1177 | GLint theLocation, |
1178 | GLuint theCount, |
1179 | const OpenGl_Vec3* theData) |
1180 | { |
1181 | if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION) |
1182 | { |
1183 | return Standard_False; |
1184 | } |
1185 | |
4e1523ef |
1186 | theCtx->core20fwd->glUniform3fv (theLocation, theCount, theData[0].GetData()); |
4fe9ad57 |
1187 | return Standard_True; |
1188 | } |
1189 | |
1190 | // ======================================================================= |
1191 | // function : SetUniform |
1192 | // purpose : Specifies the value of the float4 uniform array |
1193 | // ======================================================================= |
1194 | Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx, |
1195 | GLint theLocation, |
1196 | GLuint theCount, |
1197 | const OpenGl_Vec4* theData) |
1198 | { |
1199 | if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION) |
1200 | { |
1201 | return Standard_False; |
1202 | } |
1203 | |
4e1523ef |
1204 | theCtx->core20fwd->glUniform4fv (theLocation, theCount, theData[0].GetData()); |
4fe9ad57 |
1205 | return Standard_True; |
1206 | } |
1207 | |
1208 | // ======================================================================= |
1209 | // function : SetUniform |
1210 | // purpose : Specifies the value of the integer uniform array |
1211 | // ======================================================================= |
1212 | Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx, |
1213 | GLint theLocation, |
1214 | GLuint theCount, |
1215 | const Standard_Integer* theData) |
1216 | { |
1217 | if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION) |
1218 | { |
1219 | return Standard_False; |
1220 | } |
1221 | |
4e1523ef |
1222 | theCtx->core20fwd->glUniform1iv (theLocation, theCount, theData); |
4fe9ad57 |
1223 | return Standard_True; |
1224 | } |
1225 | |
1226 | // ======================================================================= |
1227 | // function : SetUniform |
1228 | // purpose : Specifies the value of the int2 uniform array |
1229 | // ======================================================================= |
1230 | Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx, |
1231 | GLint theLocation, |
1232 | GLuint theCount, |
1233 | const OpenGl_Vec2i* theData) |
1234 | { |
1235 | if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION) |
1236 | { |
1237 | return Standard_False; |
1238 | } |
1239 | |
4e1523ef |
1240 | theCtx->core20fwd->glUniform2iv (theLocation, theCount, theData[0].GetData()); |
4fe9ad57 |
1241 | return Standard_True; |
1242 | } |
1243 | |
1244 | // ======================================================================= |
1245 | // function : SetUniform |
1246 | // purpose : Specifies the value of the int3 uniform array |
1247 | // ======================================================================= |
1248 | Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx, |
1249 | GLint theLocation, |
1250 | GLuint theCount, |
1251 | const OpenGl_Vec3i* theData) |
1252 | { |
1253 | if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION) |
1254 | { |
1255 | return Standard_False; |
1256 | } |
1257 | |
4e1523ef |
1258 | theCtx->core20fwd->glUniform3iv (theLocation, theCount, theData[0].GetData()); |
4fe9ad57 |
1259 | return Standard_True; |
1260 | } |
1261 | |
1262 | // ======================================================================= |
1263 | // function : SetUniform |
1264 | // purpose : Specifies the value of the int4 uniform array |
1265 | // ======================================================================= |
1266 | Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx, |
1267 | GLint theLocation, |
1268 | GLuint theCount, |
1269 | const OpenGl_Vec4i* theData) |
1270 | { |
1271 | if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION) |
1272 | { |
1273 | return Standard_False; |
1274 | } |
1275 | |
4e1523ef |
1276 | theCtx->core20fwd->glUniform4iv (theLocation, theCount, theData[0].GetData()); |
4fe9ad57 |
1277 | return Standard_True; |
1278 | } |
1279 | |
30f0ad28 |
1280 | // ======================================================================= |
1281 | // function : SetSampler |
1282 | // purpose : Specifies the value of the sampler uniform variable |
1283 | // ======================================================================= |
1284 | Standard_Boolean OpenGl_ShaderProgram::SetSampler (const Handle(OpenGl_Context)& theCtx, |
1285 | const GLchar* theName, |
1286 | const GLenum theTextureUnit) |
1287 | { |
1288 | return SetSampler (theCtx, GetUniformLocation (theCtx, theName), theTextureUnit); |
1289 | } |
1290 | |
1291 | // ======================================================================= |
1292 | // function : SetSampler |
1293 | // purpose : Specifies the value of the sampler uniform variable |
1294 | // ======================================================================= |
1295 | Standard_Boolean OpenGl_ShaderProgram::SetSampler (const Handle(OpenGl_Context)& theCtx, |
1296 | GLint theLocation, |
1297 | const GLenum theTextureUnit) |
1298 | { |
1299 | if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION) |
1300 | { |
1301 | return Standard_False; |
1302 | } |
1303 | |
4e1523ef |
1304 | theCtx->core20fwd->glUniform1i (theLocation, theTextureUnit); |
30f0ad28 |
1305 | return Standard_True; |
1306 | } |
1307 | |
1308 | // ======================================================================= |
1309 | // function : Create |
1310 | // purpose : Creates new empty shader program of specified type |
1311 | // ======================================================================= |
1312 | Standard_Boolean OpenGl_ShaderProgram::Create (const Handle(OpenGl_Context)& theCtx) |
1313 | { |
1314 | if (myProgramID == NO_PROGRAM |
4e1523ef |
1315 | && theCtx->core20fwd != NULL) |
30f0ad28 |
1316 | { |
4e1523ef |
1317 | myProgramID = theCtx->core20fwd->glCreateProgram(); |
30f0ad28 |
1318 | } |
1319 | |
1320 | return myProgramID != NO_PROGRAM; |
1321 | } |
1322 | |
1323 | // ======================================================================= |
1324 | // function : Release |
1325 | // purpose : Destroys shader program |
1326 | // ======================================================================= |
10b9c7df |
1327 | void OpenGl_ShaderProgram::Release (OpenGl_Context* theCtx) |
30f0ad28 |
1328 | { |
1329 | if (myProgramID == NO_PROGRAM) |
1330 | { |
1331 | return; |
1332 | } |
1333 | |
1334 | Standard_ASSERT_RETURN (theCtx != NULL, |
1335 | "OpenGl_ShaderProgram destroyed without GL context! Possible GPU memory leakage...",); |
1336 | |
1337 | for (OpenGl_ShaderList::Iterator anIter (myShaderObjects); anIter.More(); anIter.Next()) |
1338 | { |
fc73a202 |
1339 | if (!anIter.Value().IsNull()) |
1340 | { |
1341 | anIter.ChangeValue()->Release (theCtx); |
1342 | anIter.ChangeValue().Nullify(); |
1343 | } |
30f0ad28 |
1344 | } |
1345 | |
4e1523ef |
1346 | if (theCtx->core20fwd != NULL |
ec2eeb2d |
1347 | && theCtx->IsValid()) |
30f0ad28 |
1348 | { |
4e1523ef |
1349 | theCtx->core20fwd->glDeleteProgram (myProgramID); |
30f0ad28 |
1350 | } |
1351 | |
1352 | myProgramID = NO_PROGRAM; |
1353 | } |