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