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> |
d95f5ce1 |
17 | #include <OSD_Environment.hxx> |
30f0ad28 |
18 | |
19 | #include <OpenGl_Context.hxx> |
20 | #include <OpenGl_ShaderProgram.hxx> |
21 | #include <OpenGl_ShaderManager.hxx> |
25ef750e |
22 | #include <OpenGl_ArbTexBindless.hxx> |
30f0ad28 |
23 | |
47e9c178 |
24 | #include <OpenGl_GlCore32.hxx> |
30f0ad28 |
25 | |
ee5befae |
26 | #include "../Shaders/Shaders_DeclarationsImpl_glsl.pxx" |
27 | #include "../Shaders/Shaders_Declarations_glsl.pxx" |
28 | |
7c65581d |
29 | #ifdef _WIN32 |
30 | #include <malloc.h> // for alloca() |
31 | #endif |
32 | |
cc8cbabe |
33 | IMPLEMENT_STANDARD_RTTIEXT(OpenGl_ShaderProgram, OpenGl_NamedResource) |
92efcf78 |
34 | |
30f0ad28 |
35 | OpenGl_VariableSetterSelector OpenGl_ShaderProgram::mySetterSelector = OpenGl_VariableSetterSelector(); |
36 | |
37 | // Declare OCCT-specific OpenGL/GLSL shader variables |
38 | Standard_CString OpenGl_ShaderProgram::PredefinedKeywords[] = |
39 | { |
12381341 |
40 | "occModelWorldMatrix", // OpenGl_OCC_MODEL_WORLD_MATRIX |
41 | "occWorldViewMatrix", // OpenGl_OCC_WORLD_VIEW_MATRIX |
42 | "occProjectionMatrix", // OpenGl_OCC_PROJECTION_MATRIX |
43 | "occModelWorldMatrixInverse", // OpenGl_OCC_MODEL_WORLD_MATRIX_INVERSE |
44 | "occWorldViewMatrixInverse", // OpenGl_OCC_WORLD_VIEW_MATRIX_INVERSE |
45 | "occProjectionMatrixInverse", // OpenGl_OCC_PROJECTION_MATRIX_INVERSE |
46 | "occModelWorldMatrixTranspose", // OpenGl_OCC_MODEL_WORLD_MATRIX_TRANSPOSE |
47 | "occWorldViewMatrixTranspose", // OpenGl_OCC_WORLD_VIEW_MATRIX_TRANSPOSE |
48 | "occProjectionMatrixTranspose", // OpenGl_OCC_PROJECTION_MATRIX_TRANSPOSE |
49 | "occModelWorldMatrixInverseTranspose", // OpenGl_OCC_MODEL_WORLD_MATRIX_INVERSE_TRANSPOSE |
50 | "occWorldViewMatrixInverseTranspose", // OpenGl_OCC_WORLD_VIEW_MATRIX_INVERSE_TRANSPOSE |
51 | "occProjectionMatrixInverseTranspose", // OpenGl_OCC_PROJECTION_MATRIX_INVERSE_TRANSPOSE |
52 | |
67312b79 |
53 | "occClipPlaneEquations", // OpenGl_OCC_CLIP_PLANE_EQUATIONS |
54 | "occClipPlaneChains", // OpenGl_OCC_CLIP_PLANE_CHAINS |
55 | "occClipPlaneCount", // OpenGl_OCC_CLIP_PLANE_COUNT |
56 | |
57 | "occLightSourcesCount", // OpenGl_OCC_LIGHT_SOURCE_COUNT |
58 | "occLightSourcesTypes", // OpenGl_OCC_LIGHT_SOURCE_TYPES |
59 | "occLightSources", // OpenGl_OCC_LIGHT_SOURCE_PARAMS |
60 | "occLightAmbient", // OpenGl_OCC_LIGHT_AMBIENT |
d84e8669 |
61 | "occShadowMapSizeBias", // OpenGl_OCC_LIGHT_SHADOWMAP_SIZE_BIAS |
62 | "occShadowMapSamplers", // OpenGl_OCC_LIGHT_SHADOWMAP_SAMPLERS, |
63 | "occShadowMapMatrices", // OpenGl_OCC_LIGHT_SHADOWMAP_MATRICES, |
67312b79 |
64 | |
65 | "occTextureEnable", // OpenGl_OCCT_TEXTURE_ENABLE |
66 | "occDistinguishingMode", // OpenGl_OCCT_DISTINGUISH_MODE |
941f6cae |
67 | "occPbrMaterial", // OpenGl_OCCT_PBR_MATERIAL |
68 | "occCommonMaterial", // OpenGl_OCCT_COMMON_MATERIAL |
67312b79 |
69 | "occAlphaCutoff", // OpenGl_OCCT_ALPHA_CUTOFF |
70 | "occColor", // OpenGl_OCCT_COLOR |
71 | |
72 | "occOitOutput", // OpenGl_OCCT_OIT_OUTPUT |
73 | "occOitDepthFactor", // OpenGl_OCCT_OIT_DEPTH_FACTOR |
74 | |
75 | "occTexTrsf2d", // OpenGl_OCCT_TEXTURE_TRSF2D |
76 | "occPointSize", // OpenGl_OCCT_POINT_SIZE |
77 | |
78 | "occViewport", // OpenGl_OCCT_VIEWPORT |
79 | "occLineWidth", // OpenGl_OCCT_LINE_WIDTH |
80 | "occLineFeather", // OpenGl_OCCT_LINE_FEATHER |
81 | "occStipplePattern", // OpenGl_OCCT_LINE_STIPPLE_PATTERN |
82 | "occStippleFactor", // OpenGl_OCCT_LINE_STIPPLE_FACTOR |
83 | "occWireframeColor", // OpenGl_OCCT_WIREFRAME_COLOR |
84 | "occIsQuadMode", // OpenGl_OCCT_QUAD_MODE_STATE |
85 | |
86 | "occOrthoScale", // OpenGl_OCCT_ORTHO_SCALE |
87 | "occSilhouetteThickness", // OpenGl_OCCT_SILHOUETTE_THICKNESS |
88 | |
89 | "occNbSpecIBLLevels" // OpenGl_OCCT_NB_SPEC_IBL_LEVELS |
30f0ad28 |
90 | }; |
91 | |
8e0a2b19 |
92 | namespace |
93 | { |
94 | //! Convert Graphic3d_TypeOfShaderObject enumeration into OpenGL enumeration. |
95 | static GLenum shaderTypeToGl (Graphic3d_TypeOfShaderObject theType) |
96 | { |
97 | switch (theType) |
98 | { |
99 | case Graphic3d_TOS_VERTEX: return GL_VERTEX_SHADER; |
100 | case Graphic3d_TOS_FRAGMENT: return GL_FRAGMENT_SHADER; |
101 | case Graphic3d_TOS_GEOMETRY: return GL_GEOMETRY_SHADER; |
102 | case Graphic3d_TOS_TESS_CONTROL: return GL_TESS_CONTROL_SHADER; |
103 | case Graphic3d_TOS_TESS_EVALUATION: return GL_TESS_EVALUATION_SHADER; |
104 | case Graphic3d_TOS_COMPUTE: return GL_COMPUTE_SHADER; |
105 | } |
106 | return 0; |
107 | } |
108 | } |
109 | |
30f0ad28 |
110 | // ======================================================================= |
111 | // function : OpenGl_VariableSetterSelector |
112 | // purpose : Creates new variable setter selector |
113 | // ======================================================================= |
114 | OpenGl_VariableSetterSelector::OpenGl_VariableSetterSelector() |
115 | { |
116 | // Note: Add new variable setters here |
117 | mySetterList = OpenGl_HashMapInitializer::CreateListOf<size_t, OpenGl_SetterInterface*> |
118 | (Graphic3d_UniformValueTypeID<int>::ID, new OpenGl_VariableSetter<int>()) |
119 | (Graphic3d_UniformValueTypeID<float>::ID, new OpenGl_VariableSetter<float>()) |
120 | (Graphic3d_UniformValueTypeID<OpenGl_Vec2>::ID, new OpenGl_VariableSetter<OpenGl_Vec2>()) |
121 | (Graphic3d_UniformValueTypeID<OpenGl_Vec3>::ID, new OpenGl_VariableSetter<OpenGl_Vec3>()) |
122 | (Graphic3d_UniformValueTypeID<OpenGl_Vec4>::ID, new OpenGl_VariableSetter<OpenGl_Vec4>()) |
123 | (Graphic3d_UniformValueTypeID<OpenGl_Vec2i>::ID, new OpenGl_VariableSetter<OpenGl_Vec2i>()) |
124 | (Graphic3d_UniformValueTypeID<OpenGl_Vec3i>::ID, new OpenGl_VariableSetter<OpenGl_Vec3i>()) |
125 | (Graphic3d_UniformValueTypeID<OpenGl_Vec4i>::ID, new OpenGl_VariableSetter<OpenGl_Vec4i>()); |
126 | } |
127 | |
128 | // ======================================================================= |
129 | // function : ~OpenGl_VariableSetterSelector |
130 | // purpose : Releases memory resources of variable setter selector |
131 | // ======================================================================= |
132 | OpenGl_VariableSetterSelector::~OpenGl_VariableSetterSelector() |
133 | { |
134 | for (OpenGl_SetterList::Iterator anIt (mySetterList); anIt.More(); anIt.Next()) |
135 | { |
136 | delete anIt.Value(); |
137 | } |
138 | |
139 | mySetterList.Clear(); |
140 | } |
141 | |
142 | // ======================================================================= |
143 | // function : Set |
144 | // purpose : Sets generic variable to specified shader program |
145 | // ======================================================================= |
146 | void OpenGl_VariableSetterSelector::Set (const Handle(OpenGl_Context)& theCtx, |
147 | const Handle(Graphic3d_ShaderVariable)& theVariable, |
148 | OpenGl_ShaderProgram* theProgram) const |
149 | { |
150 | Standard_ASSERT_RETURN (mySetterList.IsBound (theVariable->Value()->TypeID()), |
151 | "The type of user-defined uniform variable is not supported...", ); |
152 | |
153 | mySetterList.Find (theVariable->Value()->TypeID())->Set (theCtx, theVariable, theProgram); |
154 | } |
155 | |
156 | // ======================================================================= |
157 | // function : OpenGl_ShaderProgram |
158 | // purpose : Creates uninitialized shader program |
159 | // ======================================================================= |
d95f5ce1 |
160 | OpenGl_ShaderProgram::OpenGl_ShaderProgram (const Handle(Graphic3d_ShaderProgram)& theProxy, |
161 | const TCollection_AsciiString& theId) |
162 | : OpenGl_NamedResource (!theProxy.IsNull() ? theProxy->GetId() : theId), |
cc8cbabe |
163 | myProgramID (NO_PROGRAM), |
392ac980 |
164 | myProxy (theProxy), |
8e0a2b19 |
165 | myShareCount(1), |
daf73ab7 |
166 | myNbLightsMax (0), |
d84e8669 |
167 | myNbShadowMaps (0), |
daf73ab7 |
168 | myNbClipPlanesMax (0), |
b17e5bae |
169 | myNbFragOutputs (1), |
72f6dc61 |
170 | myTextureSetBits (Graphic3d_TextureSetBits_NONE), |
78c4e836 |
171 | myOitOutput (Graphic3d_RTM_BLEND_UNORDERED), |
c40eb6b9 |
172 | myHasAlphaTest (false), |
8e0a2b19 |
173 | myHasTessShader (false) |
30f0ad28 |
174 | { |
175 | memset (myCurrentState, 0, sizeof (myCurrentState)); |
30f0ad28 |
176 | } |
177 | |
178 | // ======================================================================= |
179 | // function : Initialize |
180 | // purpose : Initializes program object with the list of shader objects |
181 | // ======================================================================= |
182 | Standard_Boolean OpenGl_ShaderProgram::Initialize (const Handle(OpenGl_Context)& theCtx, |
183 | const Graphic3d_ShaderObjectList& theShaders) |
184 | { |
8e0a2b19 |
185 | myHasTessShader = false; |
30f0ad28 |
186 | if (theCtx.IsNull() || !Create (theCtx)) |
187 | { |
188 | return Standard_False; |
189 | } |
190 | |
8e0a2b19 |
191 | TCollection_AsciiString aHeaderVer = !myProxy.IsNull() ? myProxy->Header() : TCollection_AsciiString(); |
192 | int aShaderMask = 0; |
193 | for (Graphic3d_ShaderObjectList::Iterator anIter (theShaders); anIter.More(); anIter.Next()) |
194 | { |
195 | aShaderMask |= anIter.Value()->Type(); |
196 | } |
197 | myHasTessShader = (aShaderMask & (Graphic3d_TOS_TESS_CONTROL | Graphic3d_TOS_TESS_EVALUATION)) != 0; |
b17e5bae |
198 | myNbFragOutputs = !myProxy.IsNull() ? myProxy->NbFragmentOutputs() : 1; |
72f6dc61 |
199 | myTextureSetBits = Graphic3d_TextureSetBits_NONE; |
c40eb6b9 |
200 | myHasAlphaTest = !myProxy.IsNull() && myProxy->HasAlphaTest(); |
78c4e836 |
201 | myOitOutput = !myProxy.IsNull() ? myProxy->OitOutput() : Graphic3d_RTM_BLEND_UNORDERED; |
202 | if (myOitOutput == Graphic3d_RTM_BLEND_OIT |
203 | && myNbFragOutputs < 2) |
204 | { |
205 | myOitOutput = Graphic3d_RTM_BLEND_UNORDERED; |
206 | } |
207 | else if (myOitOutput == Graphic3d_RTM_DEPTH_PEELING_OIT |
208 | && myNbFragOutputs < 3) |
209 | { |
210 | myOitOutput = Graphic3d_RTM_BLEND_UNORDERED; |
211 | } |
30f0ad28 |
212 | |
8e0a2b19 |
213 | // detect the minimum GLSL version required for defined Shader Objects |
8f7159cb |
214 | if (theCtx->GraphicsLibrary() == Aspect_GraphicsLibrary_OpenGLES) |
8e0a2b19 |
215 | { |
8f7159cb |
216 | if (myHasTessShader) |
8e0a2b19 |
217 | { |
8f7159cb |
218 | if (!theCtx->IsGlGreaterEqual (3, 2)) |
2a332745 |
219 | { |
220 | theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, |
8f7159cb |
221 | "Error! Tessellation shader requires OpenGL ES 3.2+"); |
2a332745 |
222 | return false; |
223 | } |
8f7159cb |
224 | else if (aHeaderVer.IsEmpty()) |
2a332745 |
225 | { |
8f7159cb |
226 | aHeaderVer = "#version 320 es"; |
2a332745 |
227 | } |
8f7159cb |
228 | } |
229 | else if ((aShaderMask & Graphic3d_TOS_GEOMETRY) != 0) |
230 | { |
231 | switch (theCtx->hasGeometryStage) |
2a332745 |
232 | { |
8f7159cb |
233 | case OpenGl_FeatureNotAvailable: |
234 | { |
235 | theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, |
236 | "Error! Geometry shader requires OpenGL ES 3.2+ or GL_EXT_geometry_shader"); |
237 | return false; |
238 | } |
239 | case OpenGl_FeatureInExtensions: |
2a332745 |
240 | { |
8f7159cb |
241 | if (aHeaderVer.IsEmpty()) |
242 | { |
243 | aHeaderVer = "#version 310 es"; |
244 | } |
245 | break; |
246 | } |
247 | case OpenGl_FeatureInCore: |
248 | { |
249 | if (aHeaderVer.IsEmpty()) |
250 | { |
251 | aHeaderVer = "#version 320 es"; |
252 | } |
253 | break; |
2a332745 |
254 | } |
2a332745 |
255 | } |
256 | } |
8f7159cb |
257 | else if ((aShaderMask & Graphic3d_TOS_COMPUTE) != 0) |
8e0a2b19 |
258 | { |
8f7159cb |
259 | if (!theCtx->IsGlGreaterEqual (3, 1)) |
260 | { |
261 | theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, |
262 | "Error! Compute shaders require OpenGL ES 3.1+"); |
263 | return false; |
264 | } |
265 | else if (aHeaderVer.IsEmpty()) |
266 | { |
267 | aHeaderVer = "#version 310 es"; |
268 | } |
8e0a2b19 |
269 | } |
270 | } |
8f7159cb |
271 | else |
8e0a2b19 |
272 | { |
8f7159cb |
273 | if ((aShaderMask & Graphic3d_TOS_COMPUTE) != 0) |
8e0a2b19 |
274 | { |
8f7159cb |
275 | if (!theCtx->IsGlGreaterEqual (4, 3)) |
276 | { |
277 | theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, |
278 | "Error! Compute shaders require OpenGL 4.3+"); |
279 | return 0; |
280 | } |
281 | else if (aHeaderVer.IsEmpty()) |
282 | { |
283 | aHeaderVer = "#version 430"; |
284 | } |
8e0a2b19 |
285 | } |
8f7159cb |
286 | else if (myHasTessShader) |
8e0a2b19 |
287 | { |
8f7159cb |
288 | if (!theCtx->IsGlGreaterEqual (4, 0)) |
289 | { |
290 | theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, |
291 | "Error! Tessellation shaders require OpenGL 4.0+"); |
292 | return 0; |
293 | } |
294 | else if (aHeaderVer.IsEmpty()) |
295 | { |
296 | aHeaderVer = "#version 400"; |
297 | } |
8e0a2b19 |
298 | } |
8f7159cb |
299 | else if ((aShaderMask & Graphic3d_TOS_GEOMETRY) != 0) |
8e0a2b19 |
300 | { |
8f7159cb |
301 | if (!theCtx->IsGlGreaterEqual (3, 2)) |
302 | { |
303 | theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, |
304 | "Error! Geometry shaders require OpenGL 3.2+"); |
305 | return 0; |
306 | } |
307 | else if (aHeaderVer.IsEmpty()) |
308 | { |
309 | aHeaderVer = "#version 150"; |
310 | } |
8e0a2b19 |
311 | } |
312 | } |
12381341 |
313 | |
8e0a2b19 |
314 | for (Graphic3d_ShaderObjectList::Iterator anIter (theShaders); anIter.More(); anIter.Next()) |
30f0ad28 |
315 | { |
316 | if (!anIter.Value()->IsDone()) |
317 | { |
392ac980 |
318 | const TCollection_ExtendedString aMsg = "Error! Failed to get shader source"; |
8e0a2b19 |
319 | theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, aMsg); |
30f0ad28 |
320 | return Standard_False; |
321 | } |
322 | |
8e0a2b19 |
323 | const GLenum aShaderType = shaderTypeToGl (anIter.Value()->Type()); |
324 | if (aShaderType == 0) |
30f0ad28 |
325 | { |
30f0ad28 |
326 | return Standard_False; |
327 | } |
328 | |
8e0a2b19 |
329 | Handle(OpenGl_ShaderObject) aShader = new OpenGl_ShaderObject (aShaderType); |
30f0ad28 |
330 | if (!aShader->Create (theCtx)) |
331 | { |
392ac980 |
332 | aShader->Release (theCtx.operator->()); |
30f0ad28 |
333 | return Standard_False; |
334 | } |
335 | |
177781da |
336 | TCollection_AsciiString anExtensions = "// Enable extensions used in OCCT GLSL programs\n"; |
b17e5bae |
337 | if (myNbFragOutputs > 1) |
a1073ae2 |
338 | { |
b17e5bae |
339 | if (theCtx->hasDrawBuffers) |
a1073ae2 |
340 | { |
b17e5bae |
341 | anExtensions += "#define OCC_ENABLE_draw_buffers\n"; |
78c4e836 |
342 | switch (myOitOutput) |
b17e5bae |
343 | { |
78c4e836 |
344 | case Graphic3d_RTM_BLEND_UNORDERED: |
345 | break; |
346 | case Graphic3d_RTM_BLEND_OIT: |
347 | anExtensions += "#define OCC_WRITE_WEIGHT_OIT_COVERAGE\n"; |
348 | break; |
349 | case Graphic3d_RTM_DEPTH_PEELING_OIT: |
350 | anExtensions += "#define OCC_DEPTH_PEEL_OIT\n"; |
351 | break; |
b17e5bae |
352 | } |
a1073ae2 |
353 | } |
b17e5bae |
354 | else |
355 | { |
356 | theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, |
357 | "Error! Multiple draw buffers required by the program, but aren't supported by OpenGL"); |
358 | return Standard_False; |
359 | } |
360 | |
361 | if (theCtx->hasDrawBuffers == OpenGl_FeatureInExtensions) |
a1073ae2 |
362 | { |
b17e5bae |
363 | if (theCtx->arbDrawBuffers) |
364 | { |
365 | anExtensions += "#extension GL_ARB_draw_buffers : enable\n"; |
366 | } |
367 | else if (theCtx->extDrawBuffers) |
368 | { |
369 | anExtensions += "#extension GL_EXT_draw_buffers : enable\n"; |
370 | } |
a1073ae2 |
371 | } |
372 | } |
c40eb6b9 |
373 | if (myHasAlphaTest) |
374 | { |
375 | anExtensions += "#define OCC_ALPHA_TEST\n"; |
376 | } |
a1073ae2 |
377 | |
378 | if (theCtx->hasSampleVariables == OpenGl_FeatureInExtensions) |
379 | { |
8f7159cb |
380 | if (theCtx->GraphicsLibrary() == Aspect_GraphicsLibrary_OpenGLES |
381 | && theCtx->oesSampleVariables) |
a1073ae2 |
382 | { |
383 | anExtensions += "#extension GL_OES_sample_variables : enable\n"; |
384 | } |
8f7159cb |
385 | else if (theCtx->GraphicsLibrary() == Aspect_GraphicsLibrary_OpenGL |
386 | && theCtx->arbSampleShading) |
a1073ae2 |
387 | { |
388 | anExtensions += "#extension GL_ARB_sample_shading : enable\n"; |
389 | } |
a1073ae2 |
390 | } |
8f7159cb |
391 | |
392 | if (theCtx->GraphicsLibrary() == Aspect_GraphicsLibrary_OpenGLES |
393 | && theCtx->hasGeometryStage == OpenGl_FeatureInExtensions) |
2a332745 |
394 | { |
395 | anExtensions += "#extension GL_EXT_geometry_shader : enable\n" |
396 | "#extension GL_EXT_shader_io_blocks : enable\n"; |
397 | } |
a1073ae2 |
398 | |
8e0a2b19 |
399 | TCollection_AsciiString aPrecisionHeader; |
8f7159cb |
400 | if (anIter.Value()->Type() == Graphic3d_TOS_FRAGMENT |
401 | && theCtx->GraphicsLibrary() == Aspect_GraphicsLibrary_OpenGLES) |
8e0a2b19 |
402 | { |
8e0a2b19 |
403 | aPrecisionHeader = theCtx->hasHighp |
404 | ? "precision highp float;\n" |
405 | "precision highp int;\n" |
406 | : "precision mediump float;\n" |
407 | "precision mediump int;\n"; |
8e0a2b19 |
408 | } |
409 | |
410 | TCollection_AsciiString aHeaderType; |
8625ef7e |
411 | switch (anIter.Value()->Type()) |
30f0ad28 |
412 | { |
8e0a2b19 |
413 | case Graphic3d_TOS_COMPUTE: { aHeaderType = "#define COMPUTE_SHADER\n"; break; } |
414 | case Graphic3d_TOS_VERTEX: { aHeaderType = "#define VERTEX_SHADER\n"; break; } |
415 | case Graphic3d_TOS_TESS_CONTROL: { aHeaderType = "#define TESS_CONTROL_SHADER\n"; break; } |
416 | case Graphic3d_TOS_TESS_EVALUATION: { aHeaderType = "#define TESS_EVALUATION_SHADER\n"; break; } |
417 | case Graphic3d_TOS_GEOMETRY: { aHeaderType = "#define GEOMETRY_SHADER\n"; break; } |
418 | case Graphic3d_TOS_FRAGMENT: { aHeaderType = "#define FRAGMENT_SHADER\n"; break; } |
30f0ad28 |
419 | } |
420 | |
daf73ab7 |
421 | TCollection_AsciiString aHeaderConstants; |
422 | myNbLightsMax = !myProxy.IsNull() ? myProxy->NbLightsMax() : 0; |
d84e8669 |
423 | myNbShadowMaps = !myProxy.IsNull() ? myProxy->NbShadowMaps() : 0; |
daf73ab7 |
424 | myNbClipPlanesMax = !myProxy.IsNull() ? myProxy->NbClipPlanesMax() : 0; |
05fb2b05 |
425 | aHeaderConstants += TCollection_AsciiString("#define THE_MAX_LIGHTS ") + myNbLightsMax + "\n"; |
426 | aHeaderConstants += TCollection_AsciiString("#define THE_MAX_CLIP_PLANES ") + myNbClipPlanesMax + "\n"; |
b17e5bae |
427 | aHeaderConstants += TCollection_AsciiString("#define THE_NB_FRAG_OUTPUTS ") + myNbFragOutputs + "\n"; |
d84e8669 |
428 | if (myNbShadowMaps > 0) |
429 | { |
430 | aHeaderConstants += TCollection_AsciiString("#define THE_NB_SHADOWMAPS ") + myNbShadowMaps + "\n"; |
431 | } |
e70625d6 |
432 | if (theCtx->caps->useZeroToOneDepth |
433 | && theCtx->arbClipControl) |
434 | { |
435 | aHeaderConstants += "#define THE_ZERO_TO_ONE_DEPTH\n"; |
436 | } |
737e9a8d |
437 | if (!myProxy.IsNull() |
438 | && myProxy->HasDefaultSampler()) |
439 | { |
440 | aHeaderConstants += "#define THE_HAS_DEFAULT_SAMPLER\n"; |
441 | } |
72f6dc61 |
442 | if (!myProxy.IsNull()) |
67312b79 |
443 | { |
72f6dc61 |
444 | if (myProxy->IsPBR()) |
445 | { |
446 | aHeaderConstants += "#define THE_IS_PBR\n"; |
447 | } |
448 | if ((myProxy->TextureSetBits() & Graphic3d_TextureSetBits_BaseColor) != 0) |
449 | { |
450 | aHeaderConstants += "#define THE_HAS_TEXTURE_COLOR\n"; |
451 | } |
452 | if ((myProxy->TextureSetBits() & Graphic3d_TextureSetBits_Emissive) != 0) |
453 | { |
454 | aHeaderConstants += "#define THE_HAS_TEXTURE_EMISSIVE\n"; |
455 | } |
456 | if ((myProxy->TextureSetBits() & Graphic3d_TextureSetBits_Normal) != 0) |
457 | { |
458 | aHeaderConstants += "#define THE_HAS_TEXTURE_NORMAL\n"; |
459 | } |
460 | if ((myProxy->TextureSetBits() & Graphic3d_TextureSetBits_Occlusion) != 0) |
461 | { |
462 | aHeaderConstants += "#define THE_HAS_TEXTURE_OCCLUSION\n"; |
463 | } |
464 | if ((myProxy->TextureSetBits() & Graphic3d_TextureSetBits_MetallicRoughness) != 0) |
465 | { |
466 | aHeaderConstants += "#define THE_HAS_TEXTURE_METALROUGHNESS\n"; |
467 | } |
67312b79 |
468 | } |
daf73ab7 |
469 | |
8e0a2b19 |
470 | const TCollection_AsciiString aSource = aHeaderVer // #version - header defining GLSL version, should be first |
471 | + (!aHeaderVer.IsEmpty() ? "\n" : "") |
472 | + anExtensions // #extension - list of enabled extensions, should be second |
473 | + aPrecisionHeader // precision - default precision qualifiers, should be before any code |
474 | + aHeaderType // auxiliary macros defining a shader stage (type) |
daf73ab7 |
475 | + aHeaderConstants |
8e0a2b19 |
476 | + Shaders_Declarations_glsl // common declarations (global constants and Vertex Shader inputs) |
477 | + Shaders_DeclarationsImpl_glsl |
478 | + anIter.Value()->Source(); // the source code itself (defining main() function) |
737e9a8d |
479 | if (!aShader->LoadAndCompile (theCtx, myResourceId, aSource)) |
30f0ad28 |
480 | { |
d95f5ce1 |
481 | aShader->Release (theCtx.operator->()); |
392ac980 |
482 | return Standard_False; |
483 | } |
30f0ad28 |
484 | |
84e84755 |
485 | if (theCtx->caps->glslDumpLevel) |
486 | { |
84e84755 |
487 | TCollection_AsciiString anOutputSource = aSource; |
488 | if (theCtx->caps->glslDumpLevel == OpenGl_ShaderProgramDumpLevel_Short) |
489 | { |
490 | anOutputSource = aHeaderVer |
491 | + (!aHeaderVer.IsEmpty() ? "\n" : "") |
492 | + anExtensions |
493 | + aPrecisionHeader |
494 | + aHeaderType |
495 | + aHeaderConstants |
496 | + anIter.Value()->Source(); |
497 | } |
737e9a8d |
498 | aShader->DumpSourceCode (theCtx, myResourceId, anOutputSource); |
84e84755 |
499 | } |
500 | |
30f0ad28 |
501 | if (!AttachShader (theCtx, aShader)) |
502 | { |
392ac980 |
503 | aShader->Release (theCtx.operator->()); |
30f0ad28 |
504 | return Standard_False; |
505 | } |
506 | } |
507 | |
7d3e64ef |
508 | // bind locations for pre-defined Vertex Attributes |
509 | SetAttributeName (theCtx, Graphic3d_TOA_POS, "occVertex"); |
510 | SetAttributeName (theCtx, Graphic3d_TOA_NORM, "occNormal"); |
511 | SetAttributeName (theCtx, Graphic3d_TOA_UV, "occTexCoord"); |
8625ef7e |
512 | SetAttributeName (theCtx, Graphic3d_TOA_COLOR, "occVertColor"); |
7d3e64ef |
513 | |
4a535d3f |
514 | // bind custom Vertex Attributes |
515 | if (!myProxy.IsNull()) |
516 | { |
517 | for (Graphic3d_ShaderAttributeList::Iterator anAttribIter (myProxy->VertexAttributes()); |
518 | anAttribIter.More(); anAttribIter.Next()) |
519 | { |
520 | SetAttributeName (theCtx, anAttribIter.Value()->Location(), anAttribIter.Value()->Name().ToCString()); |
521 | } |
522 | } |
523 | |
30f0ad28 |
524 | if (!Link (theCtx)) |
525 | { |
392ac980 |
526 | return Standard_False; |
527 | } |
30f0ad28 |
528 | |
299e0ab9 |
529 | // set uniform defaults |
cc8cbabe |
530 | const Handle(OpenGl_ShaderProgram)& anOldProgram = theCtx->ActiveProgram(); |
531 | theCtx->core20fwd->glUseProgram (myProgramID); |
2a332745 |
532 | if (const OpenGl_ShaderUniformLocation aLocTexEnable = GetStateLocation (OpenGl_OCCT_TEXTURE_ENABLE)) |
299e0ab9 |
533 | { |
2a332745 |
534 | SetUniform (theCtx, aLocTexEnable, 0); // Off |
cc8cbabe |
535 | } |
2a332745 |
536 | if (const OpenGl_ShaderUniformLocation aLocSampler = GetUniformLocation (theCtx, "occActiveSampler")) |
cc8cbabe |
537 | { |
2a332745 |
538 | SetUniform (theCtx, aLocSampler, GLint(Graphic3d_TextureUnit_0)); |
cc8cbabe |
539 | } |
737e9a8d |
540 | if (const OpenGl_ShaderUniformLocation aLocSampler = GetUniformLocation (theCtx, "occSamplerBaseColor")) |
541 | { |
72f6dc61 |
542 | myTextureSetBits |= Graphic3d_TextureSetBits_BaseColor; |
737e9a8d |
543 | SetUniform (theCtx, aLocSampler, GLint(Graphic3d_TextureUnit_BaseColor)); |
544 | } |
545 | if (const OpenGl_ShaderUniformLocation aLocSampler = GetUniformLocation (theCtx, "occSamplerPointSprite")) |
546 | { |
72f6dc61 |
547 | // Graphic3d_TextureUnit_PointSprite |
548 | //myTextureSetBits |= Graphic3d_TextureSetBits_PointSprite; |
737e9a8d |
549 | SetUniform (theCtx, aLocSampler, GLint(theCtx->SpriteTextureUnit())); |
550 | } |
72f6dc61 |
551 | if (const OpenGl_ShaderUniformLocation aLocSampler = GetUniformLocation (theCtx, "occSamplerMetallicRoughness")) |
552 | { |
553 | myTextureSetBits |= Graphic3d_TextureSetBits_MetallicRoughness; |
554 | SetUniform (theCtx, aLocSampler, GLint(Graphic3d_TextureUnit_MetallicRoughness)); |
555 | } |
556 | if (const OpenGl_ShaderUniformLocation aLocSampler = GetUniformLocation (theCtx, "occSamplerEmissive")) |
557 | { |
558 | myTextureSetBits |= Graphic3d_TextureSetBits_Emissive; |
559 | SetUniform (theCtx, aLocSampler, GLint(Graphic3d_TextureUnit_Emissive)); |
560 | } |
561 | if (const OpenGl_ShaderUniformLocation aLocSampler = GetUniformLocation (theCtx, "occSamplerOcclusion")) |
562 | { |
563 | myTextureSetBits |= Graphic3d_TextureSetBits_Occlusion; |
564 | SetUniform (theCtx, aLocSampler, GLint(Graphic3d_TextureUnit_Occlusion)); |
565 | } |
566 | if (const OpenGl_ShaderUniformLocation aLocSampler = GetUniformLocation (theCtx, "occSamplerNormal")) |
567 | { |
568 | myTextureSetBits |= Graphic3d_TextureSetBits_Normal; |
569 | SetUniform (theCtx, aLocSampler, GLint(Graphic3d_TextureUnit_Normal)); |
570 | } |
67312b79 |
571 | if (const OpenGl_ShaderUniformLocation aLocSampler = GetUniformLocation (theCtx, "occDiffIBLMapSHCoeffs")) |
572 | { |
573 | SetUniform (theCtx, aLocSampler, GLint(theCtx->PBRDiffIBLMapSHTexUnit())); |
574 | } |
575 | if (const OpenGl_ShaderUniformLocation aLocSampler = GetUniformLocation (theCtx, "occSpecIBLMap")) |
576 | { |
577 | SetUniform (theCtx, aLocSampler, GLint(theCtx->PBRSpecIBLMapTexUnit())); |
578 | } |
579 | if (const OpenGl_ShaderUniformLocation aLocSampler = GetUniformLocation (theCtx, "occEnvLUT")) |
580 | { |
581 | SetUniform (theCtx, aLocSampler, GLint(theCtx->PBREnvLUTTexUnit())); |
582 | } |
d84e8669 |
583 | if (const OpenGl_ShaderUniformLocation aLocSampler = GetUniformLocation (theCtx, "occShadowMapSamplers")) |
584 | { |
585 | std::vector<GLint> aShadowSamplers (myNbShadowMaps); |
586 | const GLint aSamplFrom = GLint(theCtx->ShadowMapTexUnit()) - myNbShadowMaps + 1; |
587 | for (Standard_Integer aSamplerIter = 0; aSamplerIter < myNbShadowMaps; ++aSamplerIter) |
588 | { |
589 | aShadowSamplers[aSamplerIter] = aSamplFrom + aSamplerIter; |
590 | } |
591 | SetUniform (theCtx, aLocSampler, myNbShadowMaps, &aShadowSamplers.front()); |
592 | } |
cc8cbabe |
593 | |
78c4e836 |
594 | if (const OpenGl_ShaderUniformLocation aLocSampler = GetUniformLocation (theCtx, "occDepthPeelingDepth")) |
595 | { |
596 | SetUniform (theCtx, aLocSampler, GLint(theCtx->DepthPeelingDepthTexUnit())); |
597 | } |
598 | if (const OpenGl_ShaderUniformLocation aLocSampler = GetUniformLocation (theCtx, "occDepthPeelingFrontColor")) |
599 | { |
600 | SetUniform (theCtx, aLocSampler, GLint(theCtx->DepthPeelingFrontColorTexUnit())); |
601 | } |
602 | |
cc8cbabe |
603 | const TCollection_AsciiString aSamplerNamePrefix ("occSampler"); |
604 | const Standard_Integer aNbUnitsMax = Max (theCtx->MaxCombinedTextureUnits(), Graphic3d_TextureUnit_NB); |
605 | for (GLint aUnitIter = 0; aUnitIter < aNbUnitsMax; ++aUnitIter) |
606 | { |
607 | const TCollection_AsciiString aName = aSamplerNamePrefix + aUnitIter; |
2a332745 |
608 | if (const OpenGl_ShaderUniformLocation aLocSampler = GetUniformLocation (theCtx, aName.ToCString())) |
cc8cbabe |
609 | { |
610 | SetUniform (theCtx, aLocSampler, aUnitIter); |
611 | } |
299e0ab9 |
612 | } |
613 | |
cc8cbabe |
614 | theCtx->core20fwd->glUseProgram (!anOldProgram.IsNull() ? anOldProgram->ProgramId() : OpenGl_ShaderProgram::NO_PROGRAM); |
30f0ad28 |
615 | return Standard_True; |
616 | } |
617 | |
618 | // ======================================================================= |
619 | // function : ~OpenGl_ShaderProgram |
620 | // purpose : Releases resources of shader program |
621 | // ======================================================================= |
622 | OpenGl_ShaderProgram::~OpenGl_ShaderProgram() |
623 | { |
624 | Release (NULL); |
625 | } |
626 | |
627 | // ======================================================================= |
628 | // function : AttachShader |
629 | // purpose : Attaches shader object to the program object |
630 | // ======================================================================= |
631 | Standard_Boolean OpenGl_ShaderProgram::AttachShader (const Handle(OpenGl_Context)& theCtx, |
632 | const Handle(OpenGl_ShaderObject)& theShader) |
633 | { |
634 | if (myProgramID == NO_PROGRAM || theShader.IsNull()) |
635 | { |
636 | return Standard_False; |
637 | } |
638 | |
639 | for (OpenGl_ShaderList::Iterator anIter (myShaderObjects); anIter.More(); anIter.Next()) |
640 | { |
641 | if (theShader == anIter.Value()) |
642 | { |
643 | return Standard_False; |
644 | } |
645 | } |
646 | |
647 | myShaderObjects.Append (theShader); |
4e1523ef |
648 | theCtx->core20fwd->glAttachShader (myProgramID, theShader->myShaderID); |
30f0ad28 |
649 | return Standard_True; |
650 | } |
651 | |
652 | // ======================================================================= |
653 | // function : DetachShader |
654 | // purpose : Detaches shader object to the program object |
655 | // ======================================================================= |
656 | Standard_Boolean OpenGl_ShaderProgram::DetachShader (const Handle(OpenGl_Context)& theCtx, |
657 | const Handle(OpenGl_ShaderObject)& theShader) |
658 | { |
659 | if (myProgramID == NO_PROGRAM |
660 | || theShader.IsNull()) |
661 | { |
662 | return Standard_False; |
663 | } |
664 | |
665 | OpenGl_ShaderList::Iterator anIter (myShaderObjects); |
666 | while (anIter.More()) |
667 | { |
668 | if (theShader == anIter.Value()) |
669 | { |
670 | myShaderObjects.Remove (anIter); |
671 | break; |
672 | } |
673 | |
674 | anIter.Next(); |
675 | } |
676 | |
677 | if (!anIter.More()) |
678 | { |
679 | return Standard_False; |
680 | } |
681 | |
4e1523ef |
682 | theCtx->core20fwd->glDetachShader (myProgramID, theShader->myShaderID); |
30f0ad28 |
683 | return Standard_True; |
684 | } |
685 | |
686 | // ======================================================================= |
687 | // function : Link |
688 | // purpose : Links the program object |
689 | // ======================================================================= |
2bda8346 |
690 | Standard_Boolean OpenGl_ShaderProgram::link (const Handle(OpenGl_Context)& theCtx) |
30f0ad28 |
691 | { |
692 | if (myProgramID == NO_PROGRAM) |
693 | { |
694 | return Standard_False; |
695 | } |
696 | |
30f0ad28 |
697 | GLint aStatus = GL_FALSE; |
4e1523ef |
698 | theCtx->core20fwd->glLinkProgram (myProgramID); |
699 | theCtx->core20fwd->glGetProgramiv (myProgramID, GL_LINK_STATUS, &aStatus); |
fc73a202 |
700 | if (aStatus == GL_FALSE) |
701 | { |
702 | return Standard_False; |
703 | } |
30f0ad28 |
704 | |
d95f5ce1 |
705 | memset (myCurrentState, 0, sizeof (myCurrentState)); |
30f0ad28 |
706 | for (GLint aVar = 0; aVar < OpenGl_OCCT_NUMBER_OF_STATE_VARIABLES; ++aVar) |
707 | { |
708 | myStateLocations[aVar] = GetUniformLocation (theCtx, PredefinedKeywords[aVar]); |
709 | } |
fc73a202 |
710 | return Standard_True; |
30f0ad28 |
711 | } |
712 | |
2bda8346 |
713 | // ======================================================================= |
714 | // function : Link |
715 | // purpose : |
716 | // ======================================================================= |
717 | Standard_Boolean OpenGl_ShaderProgram::Link (const Handle(OpenGl_Context)& theCtx, |
718 | bool theIsVerbose) |
719 | { |
720 | if (!theIsVerbose) |
721 | { |
722 | return link (theCtx); |
723 | } |
724 | |
725 | if (!link (theCtx)) |
726 | { |
727 | TCollection_AsciiString aLog; |
728 | FetchInfoLog (theCtx, aLog); |
729 | if (aLog.IsEmpty()) |
730 | { |
731 | aLog = "Linker log is empty."; |
732 | } |
733 | theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, |
737e9a8d |
734 | TCollection_AsciiString ("Failed to link program object [") + myResourceId + "]! Linker log:\n" + aLog); |
2bda8346 |
735 | return false; |
736 | } |
737 | else if (theCtx->caps->glslWarnings) |
738 | { |
739 | TCollection_AsciiString aLog; |
740 | FetchInfoLog (theCtx, aLog); |
741 | if (!aLog.IsEmpty() |
742 | && !aLog.IsEqual ("No errors.\n")) |
743 | { |
744 | theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_LOW, |
737e9a8d |
745 | TCollection_AsciiString ("GLSL linker log [") + myResourceId +"]:\n" + aLog); |
2bda8346 |
746 | } |
747 | } |
748 | return true; |
749 | } |
750 | |
30f0ad28 |
751 | // ======================================================================= |
752 | // function : FetchInfoLog |
753 | // purpose : Fetches information log of the last link operation |
754 | // ======================================================================= |
755 | Standard_Boolean OpenGl_ShaderProgram::FetchInfoLog (const Handle(OpenGl_Context)& theCtx, |
756 | TCollection_AsciiString& theOutput) |
757 | { |
758 | if (myProgramID == NO_PROGRAM) |
759 | { |
760 | return Standard_False; |
761 | } |
762 | |
763 | GLint aLength = 0; |
4e1523ef |
764 | theCtx->core20fwd->glGetProgramiv (myProgramID, GL_INFO_LOG_LENGTH, &aLength); |
30f0ad28 |
765 | if (aLength > 0) |
766 | { |
767 | GLchar* aLog = (GLchar*) alloca (aLength); |
768 | memset (aLog, 0, aLength); |
4e1523ef |
769 | theCtx->core20fwd->glGetProgramInfoLog (myProgramID, aLength, NULL, aLog); |
30f0ad28 |
770 | theOutput = aLog; |
771 | } |
772 | return Standard_True; |
773 | } |
774 | |
30f0ad28 |
775 | // ======================================================================= |
776 | // function : ApplyVariables |
777 | // purpose : Fetches uniform variables from proxy shader program |
778 | // ======================================================================= |
779 | Standard_Boolean OpenGl_ShaderProgram::ApplyVariables(const Handle(OpenGl_Context)& theCtx) |
780 | { |
781 | if (myProxy.IsNull() || myProxy->Variables().IsEmpty()) |
782 | { |
783 | return Standard_False; |
784 | } |
785 | |
786 | for (Graphic3d_ShaderVariableList::Iterator anIter (myProxy->Variables()); anIter.More(); anIter.Next()) |
787 | { |
788 | mySetterSelector.Set (theCtx, anIter.Value(), this); |
789 | } |
790 | |
791 | myProxy->ClearVariables(); |
792 | return Standard_True; |
793 | } |
794 | |
30f0ad28 |
795 | // ======================================================================= |
30f0ad28 |
796 | // function : GetUniformLocation |
797 | // purpose : Returns location (index) of the specific uniform variable |
798 | // ======================================================================= |
2a332745 |
799 | OpenGl_ShaderUniformLocation OpenGl_ShaderProgram::GetUniformLocation (const Handle(OpenGl_Context)& theCtx, |
800 | const GLchar* theName) const |
30f0ad28 |
801 | { |
2a332745 |
802 | return OpenGl_ShaderUniformLocation (myProgramID != NO_PROGRAM |
803 | ? theCtx->core20fwd->glGetUniformLocation (myProgramID, theName) |
804 | : INVALID_LOCATION); |
30f0ad28 |
805 | } |
806 | |
807 | // ======================================================================= |
808 | // function : GetAttributeLocation |
809 | // purpose : Returns location (index) of the generic vertex attribute |
810 | // ======================================================================= |
811 | GLint OpenGl_ShaderProgram::GetAttributeLocation (const Handle(OpenGl_Context)& theCtx, |
812 | const GLchar* theName) const |
813 | { |
814 | return myProgramID != NO_PROGRAM |
4e1523ef |
815 | ? theCtx->core20fwd->glGetAttribLocation (myProgramID, theName) |
30f0ad28 |
816 | : INVALID_LOCATION; |
817 | } |
818 | |
30f0ad28 |
819 | // ======================================================================= |
820 | // function : GetUniform |
821 | // purpose : Returns the value of the integer uniform variable |
822 | // ======================================================================= |
823 | Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx, |
824 | GLint theLocation, |
825 | OpenGl_Vec4i& theValue) const |
826 | { |
827 | if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION) |
828 | { |
829 | return Standard_False; |
830 | } |
831 | |
4e1523ef |
832 | theCtx->core20fwd->glGetUniformiv (myProgramID, theLocation, theValue); |
30f0ad28 |
833 | return Standard_True; |
834 | } |
835 | |
30f0ad28 |
836 | // ======================================================================= |
837 | // function : GetUniform |
838 | // purpose : Returns the value of the floating-point uniform variable |
839 | // ======================================================================= |
840 | Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx, |
841 | GLint theLocation, |
842 | OpenGl_Vec4& theValue) const |
843 | { |
844 | if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION) |
845 | { |
846 | return Standard_False; |
847 | } |
848 | |
4e1523ef |
849 | theCtx->core20fwd->glGetUniformfv (myProgramID, theLocation, theValue); |
30f0ad28 |
850 | return Standard_True; |
851 | } |
852 | |
30f0ad28 |
853 | // ======================================================================= |
854 | // function : GetAttribute |
855 | // purpose : Returns the integer vertex attribute |
856 | // ======================================================================= |
857 | Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx, |
858 | GLint theIndex, |
859 | OpenGl_Vec4i& theValue) const |
860 | { |
861 | if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION) |
862 | { |
863 | return Standard_False; |
864 | } |
865 | |
4e1523ef |
866 | theCtx->core20fwd->glGetVertexAttribiv (theIndex, GL_CURRENT_VERTEX_ATTRIB, theValue); |
30f0ad28 |
867 | return Standard_True; |
868 | } |
869 | |
30f0ad28 |
870 | // ======================================================================= |
871 | // function : GetAttribute |
872 | // purpose : Returns the floating-point vertex attribute |
873 | // ======================================================================= |
874 | Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx, |
875 | GLint theIndex, |
876 | OpenGl_Vec4& theValue) const |
877 | { |
878 | if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION) |
879 | { |
880 | return Standard_False; |
881 | } |
882 | |
4e1523ef |
883 | theCtx->core20fwd->glGetVertexAttribfv (theIndex, GL_CURRENT_VERTEX_ATTRIB, theValue); |
30f0ad28 |
884 | return Standard_True; |
885 | } |
886 | |
fc73a202 |
887 | // ======================================================================= |
888 | // function : SetAttributeName |
889 | // purpose : |
890 | // ======================================================================= |
891 | Standard_Boolean OpenGl_ShaderProgram::SetAttributeName (const Handle(OpenGl_Context)& theCtx, |
892 | GLint theIndex, |
893 | const GLchar* theName) |
894 | { |
895 | theCtx->core20fwd->glBindAttribLocation (myProgramID, theIndex, theName); |
896 | return Standard_True; |
897 | } |
b86bb3df |
898 | |
fc73a202 |
899 | // ======================================================================= |
900 | // function : SetAttribute |
901 | // purpose : |
902 | // ======================================================================= |
903 | Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx, |
904 | GLint theIndex, |
905 | GLfloat theValue) |
906 | { |
907 | if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION) |
908 | { |
909 | return Standard_False; |
910 | } |
911 | |
912 | theCtx->core20fwd->glVertexAttrib1f (theIndex, theValue); |
913 | return Standard_True; |
914 | } |
915 | |
fc73a202 |
916 | // ======================================================================= |
917 | // function : SetAttribute |
918 | // purpose : |
919 | // ======================================================================= |
920 | Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx, |
921 | GLint theIndex, |
922 | const OpenGl_Vec2& theValue) |
923 | { |
924 | if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION) |
925 | { |
926 | return Standard_False; |
927 | } |
928 | |
929 | theCtx->core20fwd->glVertexAttrib2fv (theIndex, theValue); |
930 | return Standard_True; |
931 | } |
932 | |
fc73a202 |
933 | // ======================================================================= |
934 | // function : SetAttribute |
935 | // purpose : |
936 | // ======================================================================= |
937 | Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx, |
938 | GLint theIndex, |
939 | const OpenGl_Vec3& theValue) |
940 | { |
941 | if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION) |
942 | { |
943 | return Standard_False; |
944 | } |
945 | |
946 | theCtx->core20fwd->glVertexAttrib3fv (theIndex, theValue); |
947 | return Standard_True; |
948 | } |
949 | |
fc73a202 |
950 | // ======================================================================= |
951 | // function : SetAttribute |
952 | // purpose : |
953 | // ======================================================================= |
954 | Standard_Boolean OpenGl_ShaderProgram::SetAttribute (const Handle(OpenGl_Context)& theCtx, |
955 | GLint theIndex, |
956 | const OpenGl_Vec4& theValue) |
957 | { |
958 | if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION) |
959 | { |
960 | return Standard_False; |
961 | } |
962 | |
963 | theCtx->core20fwd->glVertexAttrib4fv (theIndex, theValue); |
964 | return Standard_True; |
965 | } |
966 | |
30f0ad28 |
967 | // ======================================================================= |
968 | // function : SetUniform |
969 | // purpose : Specifies the value of the integer uniform variable |
970 | // ======================================================================= |
971 | Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx, |
972 | GLint theLocation, |
973 | GLint theValue) |
974 | { |
975 | if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION) |
976 | { |
977 | return Standard_False; |
978 | } |
979 | |
4e1523ef |
980 | theCtx->core20fwd->glUniform1i (theLocation, theValue); |
30f0ad28 |
981 | return Standard_True; |
982 | } |
983 | |
25ef750e |
984 | // ======================================================================= |
985 | // function : SetUniform |
47e9c178 |
986 | // purpose : |
25ef750e |
987 | // ======================================================================= |
988 | Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx, |
989 | GLint theLocation, |
47e9c178 |
990 | const OpenGl_Vec2u& theValue) |
25ef750e |
991 | { |
872f98d9 |
992 | if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION) |
25ef750e |
993 | { |
872f98d9 |
994 | return false; |
25ef750e |
995 | } |
996 | |
8f7159cb |
997 | if (theCtx->GraphicsLibrary() == Aspect_GraphicsLibrary_OpenGLES) |
872f98d9 |
998 | { |
8f7159cb |
999 | if (theCtx->core30 != NULL) |
1000 | { |
1001 | theCtx->core30->glUniform2uiv (theLocation, 1, theValue.GetData()); |
1002 | return true; |
1003 | } |
872f98d9 |
1004 | } |
8f7159cb |
1005 | else |
872f98d9 |
1006 | { |
8f7159cb |
1007 | if (theCtx->core32 != NULL) |
1008 | { |
1009 | theCtx->core32->glUniform2uiv (theLocation, 1, theValue.GetData()); |
1010 | return true; |
1011 | } |
872f98d9 |
1012 | } |
8f7159cb |
1013 | |
872f98d9 |
1014 | return false; |
25ef750e |
1015 | } |
1016 | |
1017 | // ======================================================================= |
1018 | // function : SetUniform |
47e9c178 |
1019 | // purpose : |
25ef750e |
1020 | // ======================================================================= |
1021 | Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx, |
1022 | const GLchar* theName, |
1023 | const GLsizei theCount, |
47e9c178 |
1024 | const OpenGl_Vec2u* theValue) |
25ef750e |
1025 | { |
1026 | return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theCount, theValue); |
1027 | } |
1028 | |
1029 | // ======================================================================= |
1030 | // function : SetUniform |
47e9c178 |
1031 | // purpose : |
25ef750e |
1032 | // ======================================================================= |
1033 | Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx, |
1034 | GLint theLocation, |
1035 | const GLsizei theCount, |
47e9c178 |
1036 | const OpenGl_Vec2u* theValue) |
25ef750e |
1037 | { |
872f98d9 |
1038 | if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION) |
25ef750e |
1039 | { |
872f98d9 |
1040 | return false; |
25ef750e |
1041 | } |
1042 | |
8f7159cb |
1043 | if (theCtx->GraphicsLibrary() == Aspect_GraphicsLibrary_OpenGLES) |
872f98d9 |
1044 | { |
8f7159cb |
1045 | if (theCtx->core30 != NULL) |
1046 | { |
1047 | theCtx->core30->glUniform2uiv (theLocation, theCount, theValue->GetData()); |
1048 | return true; |
1049 | } |
872f98d9 |
1050 | } |
8f7159cb |
1051 | else |
872f98d9 |
1052 | { |
8f7159cb |
1053 | if (theCtx->core32 != NULL) |
1054 | { |
1055 | theCtx->core32->glUniform2uiv (theLocation, theCount, theValue->GetData()); |
1056 | return true; |
1057 | } |
872f98d9 |
1058 | } |
872f98d9 |
1059 | return false; |
25ef750e |
1060 | } |
1061 | |
30f0ad28 |
1062 | // ======================================================================= |
1063 | // function : SetUniform |
1064 | // purpose : Specifies the value of the floating-point uniform variable |
1065 | // ======================================================================= |
1066 | Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx, |
1067 | GLint theLocation, |
1068 | GLfloat theValue) |
1069 | { |
1070 | if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION) |
1071 | { |
1072 | return Standard_False; |
1073 | } |
1074 | |
4e1523ef |
1075 | theCtx->core20fwd->glUniform1f (theLocation, theValue); |
30f0ad28 |
1076 | return Standard_True; |
1077 | } |
1078 | |
30f0ad28 |
1079 | // ======================================================================= |
1080 | // function : SetUniform |
1081 | // purpose : Specifies the value of the integer uniform 2D vector |
1082 | // ======================================================================= |
1083 | Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx, |
1084 | GLint theLocation, |
1085 | const OpenGl_Vec2i& theValue) |
1086 | { |
1087 | if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION) |
1088 | { |
1089 | return Standard_False; |
1090 | } |
1091 | |
4e1523ef |
1092 | theCtx->core20fwd->glUniform2iv (theLocation, 1, theValue); |
30f0ad28 |
1093 | return Standard_True; |
1094 | } |
1095 | |
30f0ad28 |
1096 | // ======================================================================= |
1097 | // function : SetUniform |
1098 | // purpose : Specifies the value of the integer uniform 3D vector |
1099 | // ======================================================================= |
1100 | Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx, |
1101 | GLint theLocation, |
1102 | const OpenGl_Vec3i& theValue) |
1103 | { |
1104 | if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION) |
1105 | { |
1106 | return Standard_False; |
1107 | } |
1108 | |
4e1523ef |
1109 | theCtx->core20fwd->glUniform3iv (theLocation, 1, theValue); |
30f0ad28 |
1110 | return Standard_True; |
1111 | } |
1112 | |
30f0ad28 |
1113 | // ======================================================================= |
1114 | // function : SetUniform |
1115 | // purpose : Specifies the value of the integer uniform 4D vector |
1116 | // ======================================================================= |
1117 | Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx, |
1118 | GLint theLocation, |
1119 | const OpenGl_Vec4i& theValue) |
1120 | { |
1121 | if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION) |
1122 | { |
1123 | return Standard_False; |
1124 | } |
1125 | |
4e1523ef |
1126 | theCtx->core20fwd->glUniform4iv (theLocation, 1, theValue); |
30f0ad28 |
1127 | return Standard_True; |
1128 | } |
1129 | |
30f0ad28 |
1130 | // ======================================================================= |
1131 | // function : SetUniform |
1132 | // purpose : Specifies the value of the floating-point uniform 2D vector |
1133 | // ======================================================================= |
1134 | Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx, |
1135 | GLint theLocation, |
1136 | const OpenGl_Vec2& theValue) |
1137 | { |
1138 | if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION) |
1139 | { |
1140 | return Standard_False; |
1141 | } |
1142 | |
4e1523ef |
1143 | theCtx->core20fwd->glUniform2fv (theLocation, 1, theValue); |
30f0ad28 |
1144 | return Standard_True; |
1145 | } |
1146 | |
30f0ad28 |
1147 | // ======================================================================= |
1148 | // function : SetUniform |
1149 | // purpose : Specifies the value of the floating-point uniform 3D vector |
1150 | // ======================================================================= |
1151 | Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx, |
1152 | GLint theLocation, |
1153 | const OpenGl_Vec3& theValue) |
1154 | { |
1155 | if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION) |
1156 | { |
1157 | return Standard_False; |
1158 | } |
1159 | |
4e1523ef |
1160 | theCtx->core20fwd->glUniform3fv (theLocation, 1, theValue); |
30f0ad28 |
1161 | return Standard_True; |
1162 | } |
1163 | |
30f0ad28 |
1164 | // ======================================================================= |
1165 | // function : SetUniform |
1166 | // purpose : Specifies the value of the floating-point uniform 4D vector |
1167 | // ======================================================================= |
1168 | Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx, |
1169 | GLint theLocation, |
1170 | const OpenGl_Vec4& theValue) |
1171 | { |
1172 | if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION) |
1173 | { |
1174 | return Standard_False; |
1175 | } |
1176 | |
4e1523ef |
1177 | theCtx->core20fwd->glUniform4fv (theLocation, 1, theValue); |
30f0ad28 |
1178 | return Standard_True; |
1179 | } |
1180 | |
25ef750e |
1181 | // ======================================================================= |
1182 | // function : SetUniform |
a2af24d1 |
1183 | // purpose : |
25ef750e |
1184 | // ======================================================================= |
a2af24d1 |
1185 | Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx, |
1186 | GLint theLocation, |
1187 | GLuint theCount, |
1188 | const NCollection_Mat3<float>* theData) |
25ef750e |
1189 | { |
a2af24d1 |
1190 | if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION) |
1191 | { |
1192 | return Standard_False; |
1193 | } |
1194 | |
1195 | theCtx->core20fwd->glUniformMatrix3fv (theLocation, theCount, GL_FALSE, theData->GetData()); |
1196 | return Standard_True; |
25ef750e |
1197 | } |
1198 | |
1199 | // ======================================================================= |
1200 | // function : SetUniform |
1201 | // purpose : Specifies the value of the floating-point uniform 4x4 matrix |
1202 | // ======================================================================= |
1203 | Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx, |
1204 | GLint theLocation, |
1205 | const OpenGl_Mat4& theValue, |
1206 | GLboolean theTranspose) |
1207 | { |
1208 | if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION) |
1209 | { |
1210 | return Standard_False; |
1211 | } |
1212 | |
a2af24d1 |
1213 | theCtx->core20fwd->glUniformMatrix4fv (theLocation, 1, GL_FALSE, theTranspose ? theValue.Transposed().GetData() : theValue.GetData()); |
25ef750e |
1214 | return Standard_True; |
1215 | } |
1216 | |
d84e8669 |
1217 | // ======================================================================= |
1218 | // function : SetUniform |
1219 | // purpose : |
1220 | // ======================================================================= |
1221 | Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx, |
1222 | GLint theLocation, |
1223 | GLuint theCount, |
1224 | const OpenGl_Mat4* theData) |
1225 | { |
1226 | if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION) |
1227 | { |
1228 | return Standard_False; |
1229 | } |
1230 | |
1231 | theCtx->core20fwd->glUniformMatrix4fv (theLocation, theCount, GL_FALSE, theData->GetData()); |
1232 | return Standard_True; |
1233 | } |
1234 | |
4fe9ad57 |
1235 | // ======================================================================= |
1236 | // function : SetUniform |
1237 | // purpose : Specifies the value of the float uniform array |
1238 | // ======================================================================= |
1239 | Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx, |
1240 | GLint theLocation, |
1241 | GLuint theCount, |
1242 | const Standard_ShortReal* theData) |
1243 | { |
1244 | if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION) |
1245 | { |
1246 | return Standard_False; |
1247 | } |
1248 | |
4e1523ef |
1249 | theCtx->core20fwd->glUniform1fv (theLocation, theCount, theData); |
4fe9ad57 |
1250 | return Standard_True; |
1251 | } |
1252 | |
1253 | // ======================================================================= |
1254 | // function : SetUniform |
1255 | // purpose : Specifies the value of the float2 uniform array |
1256 | // ======================================================================= |
1257 | Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx, |
1258 | GLint theLocation, |
1259 | GLuint theCount, |
1260 | const OpenGl_Vec2* theData) |
1261 | { |
1262 | if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION) |
1263 | { |
1264 | return Standard_False; |
1265 | } |
1266 | |
4e1523ef |
1267 | theCtx->core20fwd->glUniform2fv (theLocation, theCount, theData[0].GetData()); |
4fe9ad57 |
1268 | return Standard_True; |
1269 | } |
1270 | |
1271 | // ======================================================================= |
1272 | // function : SetUniform |
1273 | // purpose : Specifies the value of the float3 uniform array |
1274 | // ======================================================================= |
1275 | Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx, |
1276 | GLint theLocation, |
1277 | GLuint theCount, |
1278 | const OpenGl_Vec3* theData) |
1279 | { |
1280 | if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION) |
1281 | { |
1282 | return Standard_False; |
1283 | } |
1284 | |
4e1523ef |
1285 | theCtx->core20fwd->glUniform3fv (theLocation, theCount, theData[0].GetData()); |
4fe9ad57 |
1286 | return Standard_True; |
1287 | } |
1288 | |
1289 | // ======================================================================= |
1290 | // function : SetUniform |
1291 | // purpose : Specifies the value of the float4 uniform array |
1292 | // ======================================================================= |
1293 | Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx, |
1294 | GLint theLocation, |
1295 | GLuint theCount, |
1296 | const OpenGl_Vec4* theData) |
1297 | { |
1298 | if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION) |
1299 | { |
1300 | return Standard_False; |
1301 | } |
1302 | |
4e1523ef |
1303 | theCtx->core20fwd->glUniform4fv (theLocation, theCount, theData[0].GetData()); |
4fe9ad57 |
1304 | return Standard_True; |
1305 | } |
1306 | |
1307 | // ======================================================================= |
1308 | // function : SetUniform |
1309 | // purpose : Specifies the value of the integer uniform array |
1310 | // ======================================================================= |
1311 | Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx, |
1312 | GLint theLocation, |
1313 | GLuint theCount, |
1314 | const Standard_Integer* theData) |
1315 | { |
1316 | if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION) |
1317 | { |
1318 | return Standard_False; |
1319 | } |
1320 | |
4e1523ef |
1321 | theCtx->core20fwd->glUniform1iv (theLocation, theCount, theData); |
4fe9ad57 |
1322 | return Standard_True; |
1323 | } |
1324 | |
1325 | // ======================================================================= |
1326 | // function : SetUniform |
1327 | // purpose : Specifies the value of the int2 uniform array |
1328 | // ======================================================================= |
1329 | Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx, |
1330 | GLint theLocation, |
1331 | GLuint theCount, |
1332 | const OpenGl_Vec2i* theData) |
1333 | { |
1334 | if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION) |
1335 | { |
1336 | return Standard_False; |
1337 | } |
1338 | |
4e1523ef |
1339 | theCtx->core20fwd->glUniform2iv (theLocation, theCount, theData[0].GetData()); |
4fe9ad57 |
1340 | return Standard_True; |
1341 | } |
1342 | |
1343 | // ======================================================================= |
1344 | // function : SetUniform |
1345 | // purpose : Specifies the value of the int3 uniform array |
1346 | // ======================================================================= |
1347 | Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx, |
1348 | GLint theLocation, |
1349 | GLuint theCount, |
1350 | const OpenGl_Vec3i* theData) |
1351 | { |
1352 | if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION) |
1353 | { |
1354 | return Standard_False; |
1355 | } |
1356 | |
4e1523ef |
1357 | theCtx->core20fwd->glUniform3iv (theLocation, theCount, theData[0].GetData()); |
4fe9ad57 |
1358 | return Standard_True; |
1359 | } |
1360 | |
1361 | // ======================================================================= |
1362 | // function : SetUniform |
1363 | // purpose : Specifies the value of the int4 uniform array |
1364 | // ======================================================================= |
1365 | Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx, |
1366 | GLint theLocation, |
1367 | GLuint theCount, |
1368 | const OpenGl_Vec4i* theData) |
1369 | { |
1370 | if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION) |
1371 | { |
1372 | return Standard_False; |
1373 | } |
1374 | |
4e1523ef |
1375 | theCtx->core20fwd->glUniform4iv (theLocation, theCount, theData[0].GetData()); |
4fe9ad57 |
1376 | return Standard_True; |
1377 | } |
1378 | |
30f0ad28 |
1379 | // ======================================================================= |
1380 | // function : SetSampler |
1381 | // purpose : Specifies the value of the sampler uniform variable |
1382 | // ======================================================================= |
1383 | Standard_Boolean OpenGl_ShaderProgram::SetSampler (const Handle(OpenGl_Context)& theCtx, |
1384 | GLint theLocation, |
cc8cbabe |
1385 | const Graphic3d_TextureUnit theTextureUnit) |
30f0ad28 |
1386 | { |
1387 | if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION) |
1388 | { |
1389 | return Standard_False; |
1390 | } |
1391 | |
4e1523ef |
1392 | theCtx->core20fwd->glUniform1i (theLocation, theTextureUnit); |
30f0ad28 |
1393 | return Standard_True; |
1394 | } |
1395 | |
1396 | // ======================================================================= |
1397 | // function : Create |
1398 | // purpose : Creates new empty shader program of specified type |
1399 | // ======================================================================= |
1400 | Standard_Boolean OpenGl_ShaderProgram::Create (const Handle(OpenGl_Context)& theCtx) |
1401 | { |
1402 | if (myProgramID == NO_PROGRAM |
4e1523ef |
1403 | && theCtx->core20fwd != NULL) |
30f0ad28 |
1404 | { |
4e1523ef |
1405 | myProgramID = theCtx->core20fwd->glCreateProgram(); |
30f0ad28 |
1406 | } |
1407 | |
1408 | return myProgramID != NO_PROGRAM; |
1409 | } |
1410 | |
1411 | // ======================================================================= |
1412 | // function : Release |
1413 | // purpose : Destroys shader program |
1414 | // ======================================================================= |
10b9c7df |
1415 | void OpenGl_ShaderProgram::Release (OpenGl_Context* theCtx) |
30f0ad28 |
1416 | { |
1417 | if (myProgramID == NO_PROGRAM) |
1418 | { |
1419 | return; |
1420 | } |
1421 | |
1422 | Standard_ASSERT_RETURN (theCtx != NULL, |
1423 | "OpenGl_ShaderProgram destroyed without GL context! Possible GPU memory leakage...",); |
1424 | |
1425 | for (OpenGl_ShaderList::Iterator anIter (myShaderObjects); anIter.More(); anIter.Next()) |
1426 | { |
fc73a202 |
1427 | if (!anIter.Value().IsNull()) |
1428 | { |
1429 | anIter.ChangeValue()->Release (theCtx); |
1430 | anIter.ChangeValue().Nullify(); |
1431 | } |
30f0ad28 |
1432 | } |
1433 | |
4e1523ef |
1434 | if (theCtx->core20fwd != NULL |
ec2eeb2d |
1435 | && theCtx->IsValid()) |
30f0ad28 |
1436 | { |
4e1523ef |
1437 | theCtx->core20fwd->glDeleteProgram (myProgramID); |
30f0ad28 |
1438 | } |
1439 | |
1440 | myProgramID = NO_PROGRAM; |
1441 | } |
d95f5ce1 |
1442 | |
1443 | // ======================================================================= |
1444 | // function : UpdateDebugDump |
1445 | // purpose : |
1446 | // ======================================================================= |
1447 | Standard_Boolean OpenGl_ShaderProgram::UpdateDebugDump (const Handle(OpenGl_Context)& theCtx, |
1448 | const TCollection_AsciiString& theFolder, |
1449 | Standard_Boolean theToBeautify, |
1450 | Standard_Boolean theToReset) |
1451 | { |
1452 | if (myProgramID == NO_PROGRAM) |
1453 | { |
1454 | return Standard_False; |
1455 | } |
1456 | |
1457 | TCollection_AsciiString aFolder = theFolder; |
1458 | if (aFolder.IsEmpty()) |
1459 | { |
1460 | OSD_Environment aShaderVar ("CSF_ShadersDirectoryDump"); |
1461 | aFolder = aShaderVar.Value(); |
1462 | if (aFolder.IsEmpty()) |
1463 | { |
1464 | aFolder = "."; |
1465 | } |
1466 | } |
1467 | |
1468 | bool hasUpdates = false; |
1469 | for (OpenGl_ShaderList::Iterator anIter (myShaderObjects); anIter.More(); anIter.Next()) |
1470 | { |
1471 | if (!anIter.Value().IsNull()) |
1472 | { |
1473 | // desktop OpenGL (but not OpenGL ES) allows multiple shaders of the same stage to be attached, |
1474 | // but here we expect only single source per stage |
1475 | hasUpdates = anIter.ChangeValue()->updateDebugDump (theCtx, myResourceId, aFolder, theToBeautify, theToReset) || hasUpdates; |
1476 | } |
1477 | } |
1478 | if (hasUpdates) |
1479 | { |
1480 | return Link (theCtx); |
1481 | } |
1482 | return Standard_False; |
1483 | } |