0024166: Unable to create file with "Save" menu of voxeldemo Qt sample
[occt.git] / src / OpenGl / OpenGl_ShaderProgram.cxx
... / ...
CommitLineData
1// Created on: 2013-09-19
2// Created by: Denis BOGOLEPOV
3// Copyright (c) 2013 OPEN CASCADE SAS
4//
5// The content of this file is subject to the Open CASCADE Technology Public
6// License Version 6.5 (the "License"). You may not use the content of this file
7// except in compliance with the License. Please obtain a copy of the License
8// at http://www.opencascade.org and read it completely before using this file.
9//
10// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
11// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
12//
13// The Original Code and all software distributed under the License is
14// distributed on an "AS IS" basis, without warranty of any kind, and the
15// Initial Developer hereby disclaims all such warranties, including without
16// limitation, any warranties of merchantability, fitness for a particular
17// purpose or non-infringement. Please see the License for the specific terms
18// and conditions governing the rights and limitations under the License.
19
20#include <OSD_File.hxx>
21#include <OSD_Protection.hxx>
22
23#include <Standard_Assert.hxx>
24#include <Standard_Atomic.hxx>
25#include <TCollection_ExtendedString.hxx>
26
27#include <OpenGl_Context.hxx>
28#include <OpenGl_ShaderProgram.hxx>
29#include <OpenGl_ShaderManager.hxx>
30
31IMPLEMENT_STANDARD_HANDLE (OpenGl_ShaderProgram, OpenGl_Resource)
32IMPLEMENT_STANDARD_RTTIEXT(OpenGl_ShaderProgram, OpenGl_Resource)
33
34OpenGl_VariableSetterSelector OpenGl_ShaderProgram::mySetterSelector = OpenGl_VariableSetterSelector();
35
36// Declare OCCT-specific OpenGL/GLSL shader variables
37Standard_CString OpenGl_ShaderProgram::PredefinedKeywords[] =
38{
39 "occModelWorldMatrix", // OpenGl_OCC_MODEL_WORLD_MATRIX
40 "occWorldViewMatrix", // OpenGl_OCC_WORLD_VIEW_MATRIX
41 "occProjectionMatrix", // OpenGl_OCC_PROJECTION_MATRIX
42 "occModelWorldMatrixInverse", // OpenGl_OCC_MODEL_WORLD_MATRIX_INVERSE
43 "occWorldViewMatrixInverse", // OpenGl_OCC_WORLD_VIEW_MATRIX_INVERSE
44 "occProjectionMatrixInverse", // OpenGl_OCC_PROJECTION_MATRIX_INVERSE
45 "occModelWorldMatrixTranspose", // OpenGl_OCC_MODEL_WORLD_MATRIX_TRANSPOSE
46 "occWorldViewMatrixTranspose", // OpenGl_OCC_WORLD_VIEW_MATRIX_TRANSPOSE
47 "occProjectionMatrixTranspose", // OpenGl_OCC_PROJECTION_MATRIX_TRANSPOSE
48 "occModelWorldMatrixInverseTranspose", // OpenGl_OCC_MODEL_WORLD_MATRIX_INVERSE_TRANSPOSE
49 "occWorldViewMatrixInverseTranspose", // OpenGl_OCC_WORLD_VIEW_MATRIX_INVERSE_TRANSPOSE
50 "occProjectionMatrixInverseTranspose", // OpenGl_OCC_PROJECTION_MATRIX_INVERSE_TRANSPOSE
51
52 "occClipPlaneEquations", // OpenGl_OCC_CLIP_PLANE_EQUATIONS
53 "occClipPlaneSpaces", // OpenGl_OCC_CLIP_PLANE_SPACES
54
55 "occLightSourcesCount", // OpenGl_OCC_LIGHT_SOURCE_COUNT
56 "occLightSourcesTypes", // OpenGl_OCC_LIGHT_SOURCE_TYPES
57 "occLightSources", // OpenGl_OCC_LIGHT_SOURCE_PARAMS
58 "occLightAmbient", // OpenGl_OCC_LIGHT_AMBIENT
59
60 "occActiveSampler", // OpenGl_OCCT_ACTIVE_SAMPLER
61 "occTextureEnable", // OpenGl_OCCT_TEXTURE_ENABLE
62 "occDistinguishingMode", // OpenGl_OCCT_DISTINGUISH_MODE
63 "occFrontMaterial", // OpenGl_OCCT_FRONT_MATERIAL
64 "occBackMaterial" // OpenGl_OCCT_BACK_MATERIAL
65
66};
67
68// =======================================================================
69// function : OpenGl_VariableSetterSelector
70// purpose : Creates new variable setter selector
71// =======================================================================
72OpenGl_VariableSetterSelector::OpenGl_VariableSetterSelector()
73{
74 // Note: Add new variable setters here
75 mySetterList = OpenGl_HashMapInitializer::CreateListOf<size_t, OpenGl_SetterInterface*>
76 (Graphic3d_UniformValueTypeID<int>::ID, new OpenGl_VariableSetter<int>())
77 (Graphic3d_UniformValueTypeID<float>::ID, new OpenGl_VariableSetter<float>())
78 (Graphic3d_UniformValueTypeID<OpenGl_Vec2>::ID, new OpenGl_VariableSetter<OpenGl_Vec2>())
79 (Graphic3d_UniformValueTypeID<OpenGl_Vec3>::ID, new OpenGl_VariableSetter<OpenGl_Vec3>())
80 (Graphic3d_UniformValueTypeID<OpenGl_Vec4>::ID, new OpenGl_VariableSetter<OpenGl_Vec4>())
81 (Graphic3d_UniformValueTypeID<OpenGl_Vec2i>::ID, new OpenGl_VariableSetter<OpenGl_Vec2i>())
82 (Graphic3d_UniformValueTypeID<OpenGl_Vec3i>::ID, new OpenGl_VariableSetter<OpenGl_Vec3i>())
83 (Graphic3d_UniformValueTypeID<OpenGl_Vec4i>::ID, new OpenGl_VariableSetter<OpenGl_Vec4i>());
84}
85
86// =======================================================================
87// function : ~OpenGl_VariableSetterSelector
88// purpose : Releases memory resources of variable setter selector
89// =======================================================================
90OpenGl_VariableSetterSelector::~OpenGl_VariableSetterSelector()
91{
92 for (OpenGl_SetterList::Iterator anIt (mySetterList); anIt.More(); anIt.Next())
93 {
94 delete anIt.Value();
95 }
96
97 mySetterList.Clear();
98}
99
100// =======================================================================
101// function : Set
102// purpose : Sets generic variable to specified shader program
103// =======================================================================
104void OpenGl_VariableSetterSelector::Set (const Handle(OpenGl_Context)& theCtx,
105 const Handle(Graphic3d_ShaderVariable)& theVariable,
106 OpenGl_ShaderProgram* theProgram) const
107{
108 Standard_ASSERT_RETURN (mySetterList.IsBound (theVariable->Value()->TypeID()),
109 "The type of user-defined uniform variable is not supported...", );
110
111 mySetterList.Find (theVariable->Value()->TypeID())->Set (theCtx, theVariable, theProgram);
112}
113
114// =======================================================================
115// function : OpenGl_ShaderProgram
116// purpose : Creates uninitialized shader program
117// =======================================================================
118OpenGl_ShaderProgram::OpenGl_ShaderProgram (const Handle(Graphic3d_ShaderProgram)& theProxy)
119: myProgramID (NO_PROGRAM),
120 myProxy (theProxy),
121 myShareCount(1)
122{
123 memset (myCurrentState, 0, sizeof (myCurrentState));
124 for (GLint aVar = 0; aVar < OpenGl_OCCT_NUMBER_OF_STATE_VARIABLES; ++aVar)
125 {
126 myStateLocations[aVar] = INVALID_LOCATION;
127 }
128}
129
130// =======================================================================
131// function : Initialize
132// purpose : Initializes program object with the list of shader objects
133// =======================================================================
134Standard_Boolean OpenGl_ShaderProgram::Initialize (const Handle(OpenGl_Context)& theCtx,
135 const Graphic3d_ShaderObjectList& theShaders)
136{
137 if (theCtx.IsNull() || !Create (theCtx))
138 {
139 return Standard_False;
140 }
141
142 OSD_File aDeclFile (Graphic3d_ShaderProgram::ShadersFolder() + "/Declarations.glsl");
143 OSD_File aDeclImplFile (Graphic3d_ShaderProgram::ShadersFolder() + "/DeclarationsImpl.glsl");
144 if (!aDeclFile.Exists()
145 || !aDeclImplFile.Exists())
146 {
147 const TCollection_ExtendedString aMsg = "Error! Failed to load OCCT shader declarations file";
148 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
149 GL_DEBUG_TYPE_ERROR_ARB,
150 0,
151 GL_DEBUG_SEVERITY_HIGH_ARB,
152 aMsg);
153 return Standard_False;
154 }
155
156 TCollection_AsciiString aDeclarations;
157 aDeclFile.Open (OSD_ReadOnly, OSD_Protection());
158 aDeclFile.Read (aDeclarations, (int)aDeclFile.Size());
159 aDeclFile.Close();
160
161 TCollection_AsciiString aDeclImpl;
162 aDeclImplFile.Open (OSD_ReadOnly, OSD_Protection());
163 aDeclImplFile.Read (aDeclImpl, (int)aDeclImplFile.Size());
164 aDeclImplFile.Close();
165 aDeclarations += aDeclImpl;
166
167 for (Graphic3d_ShaderObjectList::Iterator anIter (theShaders);
168 anIter.More(); anIter.Next())
169 {
170 if (!anIter.Value()->IsDone())
171 {
172 const TCollection_ExtendedString aMsg = "Error! Failed to get shader source";
173 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
174 GL_DEBUG_TYPE_ERROR_ARB,
175 0,
176 GL_DEBUG_SEVERITY_HIGH_ARB,
177 aMsg);
178 return Standard_False;
179 }
180
181 Handle(OpenGl_ShaderObject) aShader;
182
183 // Note: Add support of other shader types here
184 switch (anIter.Value()->Type())
185 {
186 case Graphic3d_TOS_VERTEX:
187 aShader = new OpenGl_ShaderObject (GL_VERTEX_SHADER);
188 break;
189 case Graphic3d_TOS_FRAGMENT:
190 aShader = new OpenGl_ShaderObject (GL_FRAGMENT_SHADER);
191 break;
192 }
193
194 // Is unsupported shader type?
195 if (aShader.IsNull())
196 {
197 TCollection_ExtendedString aMsg = "Error! Unsupported shader type";
198 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
199 GL_DEBUG_TYPE_ERROR_ARB,
200 0,
201 GL_DEBUG_SEVERITY_HIGH_ARB,
202 aMsg);
203 return Standard_False;
204 }
205
206 if (!aShader->Create (theCtx))
207 {
208 aShader->Release (theCtx.operator->());
209 return Standard_False;
210 }
211
212 TCollection_AsciiString aSource = aDeclarations + anIter.Value()->Source();
213 if (anIter.Value()->Type() == Graphic3d_TOS_VERTEX)
214 {
215 aSource = TCollection_AsciiString ("#define VERTEX_SHADER\n") + aSource;
216 }
217
218 if (!aShader->LoadSource (theCtx, aSource))
219 {
220 const TCollection_ExtendedString aMsg = "Error! Failed to set shader source";
221 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
222 GL_DEBUG_TYPE_ERROR_ARB,
223 0,
224 GL_DEBUG_SEVERITY_HIGH_ARB,
225 aMsg);
226 aShader->Release (theCtx.operator->());
227 return Standard_False;
228 }
229
230 if (!aShader->Compile (theCtx))
231 {
232 TCollection_AsciiString aLog;
233 aShader->FetchInfoLog (theCtx, aLog);
234 if (aLog.IsEmpty())
235 {
236 aLog = "Compilation log is empty.";
237 }
238 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
239 GL_DEBUG_TYPE_ERROR_ARB,
240 0,
241 GL_DEBUG_SEVERITY_HIGH_ARB,
242 TCollection_ExtendedString ("Failed to compile shader object. Compilation log:\n") + aLog);
243 aShader->Release (theCtx.operator->());
244 return Standard_False;
245 }
246 else if (theCtx->caps->glslWarnings)
247 {
248 TCollection_AsciiString aLog;
249 aShader->FetchInfoLog (theCtx, aLog);
250 if (!aLog.IsEmpty()
251 && !aLog.IsEqual ("No errors.\n"))
252 {
253 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
254 GL_DEBUG_TYPE_PORTABILITY_ARB,
255 0,
256 GL_DEBUG_SEVERITY_LOW_ARB,
257 TCollection_ExtendedString ("Shader compilation log:\n") + aLog);
258 }
259 }
260
261 if (!AttachShader (theCtx, aShader))
262 {
263 aShader->Release (theCtx.operator->());
264 return Standard_False;
265 }
266 }
267
268 if (!Link (theCtx))
269 {
270 TCollection_AsciiString aLog;
271 FetchInfoLog (theCtx, aLog);
272 if (aLog.IsEmpty())
273 {
274 aLog = "Linker log is empty.";
275 }
276 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
277 GL_DEBUG_TYPE_ERROR_ARB,
278 0,
279 GL_DEBUG_SEVERITY_HIGH_ARB,
280 TCollection_ExtendedString ("Failed to link program object! Linker log:\n") + aLog);
281 return Standard_False;
282 }
283 else if (theCtx->caps->glslWarnings)
284 {
285 TCollection_AsciiString aLog;
286 FetchInfoLog (theCtx, aLog);
287 if (!aLog.IsEmpty()
288 && !aLog.IsEqual ("No errors.\n"))
289 {
290 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
291 GL_DEBUG_TYPE_PORTABILITY_ARB,
292 0,
293 GL_DEBUG_SEVERITY_LOW_ARB,
294 TCollection_ExtendedString ("GLSL linker log:\n") + aLog);
295 }
296 }
297
298 return Standard_True;
299}
300
301// =======================================================================
302// function : ~OpenGl_ShaderProgram
303// purpose : Releases resources of shader program
304// =======================================================================
305OpenGl_ShaderProgram::~OpenGl_ShaderProgram()
306{
307 Release (NULL);
308}
309
310// =======================================================================
311// function : AttachShader
312// purpose : Attaches shader object to the program object
313// =======================================================================
314Standard_Boolean OpenGl_ShaderProgram::AttachShader (const Handle(OpenGl_Context)& theCtx,
315 const Handle(OpenGl_ShaderObject)& theShader)
316{
317 if (myProgramID == NO_PROGRAM || theShader.IsNull())
318 {
319 return Standard_False;
320 }
321
322 for (OpenGl_ShaderList::Iterator anIter (myShaderObjects); anIter.More(); anIter.Next())
323 {
324 if (theShader == anIter.Value())
325 {
326 return Standard_False;
327 }
328 }
329
330 myShaderObjects.Append (theShader);
331 theCtx->core20->glAttachShader (myProgramID, theShader->myShaderID);
332 return Standard_True;
333}
334
335// =======================================================================
336// function : DetachShader
337// purpose : Detaches shader object to the program object
338// =======================================================================
339Standard_Boolean OpenGl_ShaderProgram::DetachShader (const Handle(OpenGl_Context)& theCtx,
340 const Handle(OpenGl_ShaderObject)& theShader)
341{
342 if (myProgramID == NO_PROGRAM
343 || theShader.IsNull())
344 {
345 return Standard_False;
346 }
347
348 OpenGl_ShaderList::Iterator anIter (myShaderObjects);
349 while (anIter.More())
350 {
351 if (theShader == anIter.Value())
352 {
353 myShaderObjects.Remove (anIter);
354 break;
355 }
356
357 anIter.Next();
358 }
359
360 if (!anIter.More())
361 {
362 return Standard_False;
363 }
364
365 theCtx->core20->glDetachShader (myProgramID, theShader->myShaderID);
366 return Standard_True;
367}
368
369// =======================================================================
370// function : Link
371// purpose : Links the program object
372// =======================================================================
373Standard_Boolean OpenGl_ShaderProgram::Link (const Handle(OpenGl_Context)& theCtx)
374{
375 if (myProgramID == NO_PROGRAM)
376 {
377 return Standard_False;
378 }
379
380 theCtx->core20->glLinkProgram (myProgramID);
381
382 GLint aStatus = GL_FALSE;
383 theCtx->core20->glGetProgramiv (myProgramID, GL_LINK_STATUS, &aStatus);
384
385 for (GLint aVar = 0; aVar < OpenGl_OCCT_NUMBER_OF_STATE_VARIABLES; ++aVar)
386 {
387 myStateLocations[aVar] = GetUniformLocation (theCtx, PredefinedKeywords[aVar]);
388 }
389
390 return aStatus != GL_FALSE;
391}
392
393// =======================================================================
394// function : FetchInfoLog
395// purpose : Fetches information log of the last link operation
396// =======================================================================
397Standard_Boolean OpenGl_ShaderProgram::FetchInfoLog (const Handle(OpenGl_Context)& theCtx,
398 TCollection_AsciiString& theOutput)
399{
400 if (myProgramID == NO_PROGRAM)
401 {
402 return Standard_False;
403 }
404
405 GLint aLength = 0;
406 theCtx->core20->glGetProgramiv (myProgramID, GL_INFO_LOG_LENGTH, &aLength);
407 if (aLength > 0)
408 {
409 GLchar* aLog = (GLchar*) alloca (aLength);
410 memset (aLog, 0, aLength);
411 theCtx->core20->glGetProgramInfoLog (myProgramID, aLength, NULL, aLog);
412 theOutput = aLog;
413 }
414 return Standard_True;
415}
416
417// =======================================================================
418// function : Bind
419// purpose : Sets the program object as part of current rendering state
420// =======================================================================
421void OpenGl_ShaderProgram::Bind (const Handle(OpenGl_Context)& theCtx) const
422{
423 if (myProgramID == NO_PROGRAM)
424 {
425 return;
426 }
427
428 theCtx->core20->glUseProgram (myProgramID);
429 theCtx->ShaderManager()->myIsPP = Standard_True;
430}
431
432// =======================================================================
433// function : ApplyVariables
434// purpose : Fetches uniform variables from proxy shader program
435// =======================================================================
436Standard_Boolean OpenGl_ShaderProgram::ApplyVariables(const Handle(OpenGl_Context)& theCtx)
437{
438 if (myProxy.IsNull() || myProxy->Variables().IsEmpty())
439 {
440 return Standard_False;
441 }
442
443 for (Graphic3d_ShaderVariableList::Iterator anIter (myProxy->Variables()); anIter.More(); anIter.Next())
444 {
445 mySetterSelector.Set (theCtx, anIter.Value(), this);
446 }
447
448 myProxy->ClearVariables();
449 return Standard_True;
450}
451
452// =======================================================================
453// function : BindWithVariables
454// purpose : Binds the program object and applies variables
455// =======================================================================
456Standard_Boolean OpenGl_ShaderProgram::BindWithVariables (const Handle(OpenGl_Context)& theCtx)
457{
458 Bind (theCtx);
459 return ApplyVariables (theCtx);
460}
461
462// =======================================================================
463// function : Unbind
464// purpose : Reverts to fixed-function graphics pipeline (FFP)
465// =======================================================================
466void OpenGl_ShaderProgram::Unbind (const Handle(OpenGl_Context)& theCtx)
467{
468 if (theCtx->ShaderManager()->myIsPP)
469 {
470 theCtx->core20->glUseProgram (NO_PROGRAM);
471 theCtx->ShaderManager()->myIsPP = Standard_False;
472 }
473}
474
475// =======================================================================
476// function : ActiveState
477// purpose : Returns index of last modification for specified state type
478// =======================================================================
479Standard_Size OpenGl_ShaderProgram::ActiveState (const OpenGl_UniformStateType theType) const
480{
481 if (theType < MaxStateTypes)
482 {
483 return myCurrentState[theType];
484 }
485 return 0;
486}
487
488// =======================================================================
489// function : UpdateState
490// purpose : Updates index of last modification for specified state type
491// =======================================================================
492void OpenGl_ShaderProgram::UpdateState (const OpenGl_UniformStateType theType,
493 const Standard_Size theIndex)
494{
495 if (theType < MaxStateTypes)
496 {
497 myCurrentState[theType] = theIndex;
498 }
499}
500
501// =======================================================================
502// function : GetUniformLocation
503// purpose : Returns location (index) of the specific uniform variable
504// =======================================================================
505GLint OpenGl_ShaderProgram::GetUniformLocation (const Handle(OpenGl_Context)& theCtx,
506 const GLchar* theName) const
507{
508 return myProgramID != NO_PROGRAM
509 ? theCtx->core20->glGetUniformLocation (myProgramID, theName)
510 : INVALID_LOCATION;
511}
512
513// =======================================================================
514// function : GetAttributeLocation
515// purpose : Returns location (index) of the generic vertex attribute
516// =======================================================================
517GLint OpenGl_ShaderProgram::GetAttributeLocation (const Handle(OpenGl_Context)& theCtx,
518 const GLchar* theName) const
519{
520 return myProgramID != NO_PROGRAM
521 ? theCtx->core20->glGetAttribLocation (myProgramID, theName)
522 : INVALID_LOCATION;
523}
524
525// =======================================================================
526// function : GetStateLocation
527// purpose : Returns location of the OCCT state uniform variable
528// =======================================================================
529GLint OpenGl_ShaderProgram::GetStateLocation (const GLuint theVariable) const
530{
531 if (theVariable < OpenGl_OCCT_NUMBER_OF_STATE_VARIABLES)
532 {
533 return myStateLocations[theVariable];
534 }
535 return INVALID_LOCATION;
536}
537
538// =======================================================================
539// function : GetUniform
540// purpose : Returns the value of the integer uniform variable
541// =======================================================================
542Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx,
543 const GLchar* theName,
544 OpenGl_Vec4i& theValue) const
545{
546 return GetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
547}
548
549// =======================================================================
550// function : GetUniform
551// purpose : Returns the value of the integer uniform variable
552// =======================================================================
553Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx,
554 GLint theLocation,
555 OpenGl_Vec4i& theValue) const
556{
557 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
558 {
559 return Standard_False;
560 }
561
562 theCtx->core20->glGetUniformiv (myProgramID, theLocation, theValue);
563 return Standard_True;
564}
565
566// =======================================================================
567// function : GetUniform
568// purpose : Returns the value of the floating-point uniform variable
569// =======================================================================
570Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx,
571 const GLchar* theName,
572 OpenGl_Vec4& theValue) const
573{
574 return GetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
575}
576
577// =======================================================================
578// function : GetUniform
579// purpose : Returns the value of the floating-point uniform variable
580// =======================================================================
581Standard_Boolean OpenGl_ShaderProgram::GetUniform (const Handle(OpenGl_Context)& theCtx,
582 GLint theLocation,
583 OpenGl_Vec4& theValue) const
584{
585 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
586 {
587 return Standard_False;
588 }
589
590 theCtx->core20->glGetUniformfv (myProgramID, theLocation, theValue);
591 return Standard_True;
592}
593
594// =======================================================================
595// function : GetAttribute
596// purpose : Returns the integer vertex attribute
597// =======================================================================
598Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx,
599 const GLchar* theName,
600 OpenGl_Vec4i& theValue) const
601{
602 return GetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
603}
604
605// =======================================================================
606// function : GetAttribute
607// purpose : Returns the integer vertex attribute
608// =======================================================================
609Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx,
610 GLint theIndex,
611 OpenGl_Vec4i& theValue) const
612{
613 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
614 {
615 return Standard_False;
616 }
617
618 theCtx->core20->glGetVertexAttribiv (theIndex, GL_CURRENT_VERTEX_ATTRIB, theValue);
619 return Standard_True;
620}
621
622// =======================================================================
623// function : GetAttribute
624// purpose : Returns the floating-point vertex attribute
625// =======================================================================
626Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx,
627 const GLchar* theName,
628 OpenGl_Vec4& theValue) const
629{
630 return GetAttribute (theCtx, GetAttributeLocation (theCtx, theName), theValue);
631}
632
633// =======================================================================
634// function : GetAttribute
635// purpose : Returns the floating-point vertex attribute
636// =======================================================================
637Standard_Boolean OpenGl_ShaderProgram::GetAttribute (const Handle(OpenGl_Context)& theCtx,
638 GLint theIndex,
639 OpenGl_Vec4& theValue) const
640{
641 if (myProgramID == NO_PROGRAM || theIndex == INVALID_LOCATION)
642 {
643 return Standard_False;
644 }
645
646 theCtx->core20->glGetVertexAttribfv (theIndex, GL_CURRENT_VERTEX_ATTRIB, theValue);
647 return Standard_True;
648}
649
650// =======================================================================
651// function : SetUniform
652// purpose : Specifies the value of the integer uniform variable
653// =======================================================================
654Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
655 const GLchar* theName,
656 GLint theValue)
657{
658 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
659}
660
661// =======================================================================
662// function : SetUniform
663// purpose : Specifies the value of the integer uniform variable
664// =======================================================================
665Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
666 GLint theLocation,
667 GLint theValue)
668{
669 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
670 {
671 return Standard_False;
672 }
673
674 theCtx->core20->glUniform1i (theLocation, theValue);
675 return Standard_True;
676}
677
678// =======================================================================
679// function : SetUniform
680// purpose : Specifies the value of the floating-point uniform variable
681// =======================================================================
682Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
683 const GLchar* theName,
684 GLfloat theValue)
685{
686 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
687}
688
689// =======================================================================
690// function : SetUniform
691// purpose : Specifies the value of the floating-point uniform variable
692// =======================================================================
693Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
694 GLint theLocation,
695 GLfloat theValue)
696{
697 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
698 {
699 return Standard_False;
700 }
701
702 theCtx->core20->glUniform1f (theLocation, theValue);
703 return Standard_True;
704}
705
706// =======================================================================
707// function : SetUniform
708// purpose : Specifies the value of the integer uniform 2D vector
709// =======================================================================
710Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
711 const GLchar* theName,
712 const OpenGl_Vec2i& theValue)
713{
714 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
715}
716
717// =======================================================================
718// function : SetUniform
719// purpose : Specifies the value of the integer uniform 2D vector
720// =======================================================================
721Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
722 GLint theLocation,
723 const OpenGl_Vec2i& theValue)
724{
725 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
726 {
727 return Standard_False;
728 }
729
730 theCtx->core20->glUniform2iv (theLocation, 1, theValue);
731 return Standard_True;
732}
733
734// =======================================================================
735// function : SetUniform
736// purpose : Specifies the value of the integer uniform 3D vector
737// =======================================================================
738Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
739 const GLchar* theName,
740 const OpenGl_Vec3i& theValue)
741{
742 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
743}
744
745// =======================================================================
746// function : SetUniform
747// purpose : Specifies the value of the integer uniform 3D vector
748// =======================================================================
749Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
750 GLint theLocation,
751 const OpenGl_Vec3i& theValue)
752{
753 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
754 {
755 return Standard_False;
756 }
757
758 theCtx->core20->glUniform3iv (theLocation, 1, theValue);
759 return Standard_True;
760}
761
762// =======================================================================
763// function : SetUniform
764// purpose : Specifies the value of the integer uniform 4D vector
765// =======================================================================
766Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
767 const GLchar* theName,
768 const OpenGl_Vec4i& theValue)
769{
770 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
771}
772
773// =======================================================================
774// function : SetUniform
775// purpose : Specifies the value of the integer uniform 4D vector
776// =======================================================================
777Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
778 GLint theLocation,
779 const OpenGl_Vec4i& theValue)
780{
781 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
782 {
783 return Standard_False;
784 }
785
786 theCtx->core20->glUniform4iv (theLocation, 1, theValue);
787 return Standard_True;
788}
789
790// =======================================================================
791// function : SetUniform
792// purpose : Specifies the value of the floating-point uniform 2D vector
793// =======================================================================
794Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
795 const GLchar* theName,
796 const OpenGl_Vec2& theValue)
797{
798 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
799}
800
801// =======================================================================
802// function : SetUniform
803// purpose : Specifies the value of the floating-point uniform 2D vector
804// =======================================================================
805Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
806 GLint theLocation,
807 const OpenGl_Vec2& theValue)
808{
809 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
810 {
811 return Standard_False;
812 }
813
814 theCtx->core20->glUniform2fv (theLocation, 1, theValue);
815 return Standard_True;
816}
817
818// =======================================================================
819// function : SetUniform
820// purpose : Specifies the value of the floating-point uniform 3D vector
821// =======================================================================
822Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
823 const GLchar* theName,
824 const OpenGl_Vec3& theValue)
825{
826 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
827}
828
829// =======================================================================
830// function : SetUniform
831// purpose : Specifies the value of the floating-point uniform 3D vector
832// =======================================================================
833Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
834 GLint theLocation,
835 const OpenGl_Vec3& theValue)
836{
837 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
838 {
839 return Standard_False;
840 }
841
842 theCtx->core20->glUniform3fv (theLocation, 1, theValue);
843 return Standard_True;
844}
845
846// =======================================================================
847// function : SetUniform
848// purpose : Specifies the value of the floating-point uniform 4D vector
849// =======================================================================
850Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
851 const GLchar* theName,
852 const OpenGl_Vec4& theValue)
853{
854 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue);
855}
856
857// =======================================================================
858// function : SetUniform
859// purpose : Specifies the value of the floating-point uniform 4D vector
860// =======================================================================
861Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
862 GLint theLocation,
863 const OpenGl_Vec4& theValue)
864{
865 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
866 {
867 return Standard_False;
868 }
869
870 theCtx->core20->glUniform4fv (theLocation, 1, theValue);
871 return Standard_True;
872}
873
874// =======================================================================
875// function : SetUniform
876// purpose : Specifies the value of the floating-point uniform 4x4 matrix
877// =======================================================================
878Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
879 const GLchar* theName,
880 const OpenGl_Matrix& theValue,
881 GLboolean theTranspose)
882{
883 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue, theTranspose);
884}
885
886// =======================================================================
887// function : SetUniform
888// purpose : Specifies the value of the floating-point uniform 4x4 matrix
889// =======================================================================
890Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
891 GLint theLocation,
892 const OpenGl_Matrix& theValue,
893 GLboolean theTranspose)
894{
895 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
896 {
897 return Standard_False;
898 }
899
900 theCtx->core20->glUniformMatrix4fv (theLocation, 1, theTranspose, *theValue.mat);
901 return Standard_True;
902}
903
904// =======================================================================
905// function : SetUniform
906// purpose : Specifies the value of the floating-point uniform 4x4 matrix
907// =======================================================================
908Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
909 const GLchar* theName,
910 const Tmatrix3& theValue,
911 GLboolean theTranspose)
912{
913 return SetUniform (theCtx, GetUniformLocation (theCtx, theName), theValue, theTranspose);
914}
915
916// =======================================================================
917// function : SetUniform
918// purpose : Specifies the value of the floating-point uniform 4x4 matrix
919// =======================================================================
920Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
921 GLint theLocation,
922 const Tmatrix3& theValue,
923 GLboolean theTranspose)
924{
925 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
926 {
927 return Standard_False;
928 }
929
930 theCtx->core20->glUniformMatrix4fv (theLocation, 1, theTranspose, *theValue);
931 return Standard_True;
932}
933
934// =======================================================================
935// function : SetUniform
936// purpose : Specifies the value of the float uniform array
937// =======================================================================
938Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
939 GLint theLocation,
940 GLuint theCount,
941 const Standard_ShortReal* theData)
942{
943 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
944 {
945 return Standard_False;
946 }
947
948 theCtx->core20->glUniform1fv (theLocation, theCount, theData);
949 return Standard_True;
950}
951
952// =======================================================================
953// function : SetUniform
954// purpose : Specifies the value of the float2 uniform array
955// =======================================================================
956Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
957 GLint theLocation,
958 GLuint theCount,
959 const OpenGl_Vec2* theData)
960{
961 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
962 {
963 return Standard_False;
964 }
965
966 theCtx->core20->glUniform2fv (theLocation, theCount, theData[0].GetData());
967 return Standard_True;
968}
969
970// =======================================================================
971// function : SetUniform
972// purpose : Specifies the value of the float3 uniform array
973// =======================================================================
974Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
975 GLint theLocation,
976 GLuint theCount,
977 const OpenGl_Vec3* theData)
978{
979 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
980 {
981 return Standard_False;
982 }
983
984 theCtx->core20->glUniform3fv (theLocation, theCount, theData[0].GetData());
985 return Standard_True;
986}
987
988// =======================================================================
989// function : SetUniform
990// purpose : Specifies the value of the float4 uniform array
991// =======================================================================
992Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
993 GLint theLocation,
994 GLuint theCount,
995 const OpenGl_Vec4* theData)
996{
997 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
998 {
999 return Standard_False;
1000 }
1001
1002 theCtx->core20->glUniform4fv (theLocation, theCount, theData[0].GetData());
1003 return Standard_True;
1004}
1005
1006// =======================================================================
1007// function : SetUniform
1008// purpose : Specifies the value of the integer uniform array
1009// =======================================================================
1010Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1011 GLint theLocation,
1012 GLuint theCount,
1013 const Standard_Integer* theData)
1014{
1015 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1016 {
1017 return Standard_False;
1018 }
1019
1020 theCtx->core20->glUniform1iv (theLocation, theCount, theData);
1021 return Standard_True;
1022}
1023
1024// =======================================================================
1025// function : SetUniform
1026// purpose : Specifies the value of the int2 uniform array
1027// =======================================================================
1028Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1029 GLint theLocation,
1030 GLuint theCount,
1031 const OpenGl_Vec2i* theData)
1032{
1033 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1034 {
1035 return Standard_False;
1036 }
1037
1038 theCtx->core20->glUniform2iv (theLocation, theCount, theData[0].GetData());
1039 return Standard_True;
1040}
1041
1042// =======================================================================
1043// function : SetUniform
1044// purpose : Specifies the value of the int3 uniform array
1045// =======================================================================
1046Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1047 GLint theLocation,
1048 GLuint theCount,
1049 const OpenGl_Vec3i* theData)
1050{
1051 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1052 {
1053 return Standard_False;
1054 }
1055
1056 theCtx->core20->glUniform3iv (theLocation, theCount, theData[0].GetData());
1057 return Standard_True;
1058}
1059
1060// =======================================================================
1061// function : SetUniform
1062// purpose : Specifies the value of the int4 uniform array
1063// =======================================================================
1064Standard_Boolean OpenGl_ShaderProgram::SetUniform (const Handle(OpenGl_Context)& theCtx,
1065 GLint theLocation,
1066 GLuint theCount,
1067 const OpenGl_Vec4i* theData)
1068{
1069 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1070 {
1071 return Standard_False;
1072 }
1073
1074 theCtx->core20->glUniform4iv (theLocation, theCount, theData[0].GetData());
1075 return Standard_True;
1076}
1077
1078// =======================================================================
1079// function : SetSampler
1080// purpose : Specifies the value of the sampler uniform variable
1081// =======================================================================
1082Standard_Boolean OpenGl_ShaderProgram::SetSampler (const Handle(OpenGl_Context)& theCtx,
1083 const GLchar* theName,
1084 const GLenum theTextureUnit)
1085{
1086 return SetSampler (theCtx, GetUniformLocation (theCtx, theName), theTextureUnit);
1087}
1088
1089// =======================================================================
1090// function : SetSampler
1091// purpose : Specifies the value of the sampler uniform variable
1092// =======================================================================
1093Standard_Boolean OpenGl_ShaderProgram::SetSampler (const Handle(OpenGl_Context)& theCtx,
1094 GLint theLocation,
1095 const GLenum theTextureUnit)
1096{
1097 if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
1098 {
1099 return Standard_False;
1100 }
1101
1102 theCtx->core20->glUniform1i (theLocation, theTextureUnit);
1103 return Standard_True;
1104}
1105
1106// =======================================================================
1107// function : Create
1108// purpose : Creates new empty shader program of specified type
1109// =======================================================================
1110Standard_Boolean OpenGl_ShaderProgram::Create (const Handle(OpenGl_Context)& theCtx)
1111{
1112 if (myProgramID == NO_PROGRAM
1113 && theCtx->core20 != NULL)
1114 {
1115 myProgramID = theCtx->core20->glCreateProgram();
1116 }
1117
1118 return myProgramID != NO_PROGRAM;
1119}
1120
1121// =======================================================================
1122// function : Release
1123// purpose : Destroys shader program
1124// =======================================================================
1125void OpenGl_ShaderProgram::Release (const OpenGl_Context* theCtx)
1126{
1127 if (myProgramID == NO_PROGRAM)
1128 {
1129 return;
1130 }
1131
1132 Standard_ASSERT_RETURN (theCtx != NULL,
1133 "OpenGl_ShaderProgram destroyed without GL context! Possible GPU memory leakage...",);
1134
1135 for (OpenGl_ShaderList::Iterator anIter (myShaderObjects); anIter.More(); anIter.Next())
1136 {
1137 anIter.ChangeValue()->Release (theCtx);
1138 anIter.ChangeValue().Nullify();
1139 }
1140
1141 if (theCtx->core20 != NULL
1142 && theCtx->IsValid())
1143 {
1144 theCtx->core20->glDeleteProgram (myProgramID);
1145 }
1146
1147 myProgramID = NO_PROGRAM;
1148}