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