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