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