0026080: Wrong result obtained by General Fuse operator.
[occt.git] / src / OpenGl / OpenGl_ShaderManager.cxx
CommitLineData
30f0ad28 1// Created on: 2013-09-26
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 <typeinfo>
17
e135a155 18#include <Graphic3d_TextureParams.hxx>
30f0ad28 19#include <OpenGl_AspectFace.hxx>
20#include <OpenGl_AspectLine.hxx>
21#include <OpenGl_AspectMarker.hxx>
22#include <OpenGl_AspectText.hxx>
23#include <OpenGl_Clipping.hxx>
24#include <OpenGl_Context.hxx>
25#include <OpenGl_ShaderManager.hxx>
26#include <OpenGl_ShaderProgram.hxx>
0adbd30f 27#include <OpenGl_Workspace.hxx>
30f0ad28 28
256f9ac0 29IMPLEMENT_STANDARD_HANDLE (OpenGl_SetOfShaderPrograms, Standard_Transient)
30IMPLEMENT_STANDARD_RTTIEXT(OpenGl_SetOfShaderPrograms, Standard_Transient)
31
30f0ad28 32IMPLEMENT_STANDARD_HANDLE (OpenGl_ShaderManager, Standard_Transient)
33IMPLEMENT_STANDARD_RTTIEXT(OpenGl_ShaderManager, Standard_Transient)
34
8625ef7e 35namespace
36{
37
38#define EOL "\n"
39
6c6aadb1 40//! Definition of VertColor varying.
4e1523ef 41const char THE_VARY_TexCoord_OUT[] =
42 EOL"THE_SHADER_OUT vec2 TexCoord;";
43const char THE_VARY_TexCoord_IN[] =
44 EOL"THE_SHADER_IN vec2 TexCoord;";
6c6aadb1 45
8625ef7e 46//! Auxiliary function to transform normal
47const char THE_FUNC_transformNormal[] =
48 EOL"vec3 transformNormal (in vec3 theNormal)"
49 EOL"{"
50 EOL" vec4 aResult = occWorldViewMatrixInverseTranspose"
51 EOL" * occModelWorldMatrixInverseTranspose"
52 EOL" * vec4 (theNormal, 0.0);"
53 EOL" return normalize (aResult.xyz);"
54 EOL"}";
55
56//! Global shader variable for color definition with lighting enabled.
57const char THE_FUNC_lightDef[] =
58 EOL"vec3 Ambient;" //!< Ambient contribution of light sources
59 EOL"vec3 Diffuse;" //!< Diffuse contribution of light sources
60 EOL"vec3 Specular;"; //!< Specular contribution of light sources
61
8625ef7e 62//! Function computes contribution of isotropic point light source
63const char THE_FUNC_pointLight[] =
64 EOL"void pointLight (in int theId,"
65 EOL" in vec3 theNormal,"
66 EOL" in vec3 theView,"
67 EOL" in vec3 thePoint,"
68 EOL" in bool theIsFront)"
69 EOL"{"
70 EOL" vec3 aLight = occLight_Position (theId).xyz;"
71 EOL" if (occLight_IsHeadlight (theId) == 0)"
72 EOL" {"
73 EOL" aLight = vec3 (occWorldViewMatrix * occModelWorldMatrix * vec4 (aLight, 1.0));"
74 EOL" }"
75 EOL" aLight -= thePoint;"
76 EOL
77 EOL" float aDist = length (aLight);"
78 EOL" aLight = aLight * (1.0 / aDist);"
79 EOL
80 EOL" float anAtten = 1.0 / (occLight_ConstAttenuation (theId)"
81 EOL" + occLight_LinearAttenuation (theId) * aDist);"
82 EOL
83 EOL" vec3 aHalf = normalize (aLight + theView);"
84 EOL
85 EOL" vec3 aFaceSideNormal = theIsFront ? theNormal : -theNormal;"
86 EOL" float aNdotL = max (0.0, dot (aFaceSideNormal, aLight));"
87 EOL" float aNdotH = max (0.0, dot (aFaceSideNormal, aHalf ));"
88 EOL
89 EOL" float aSpecl = 0.0;"
90 EOL" if (aNdotL > 0.0)"
91 EOL" {"
92 EOL" aSpecl = pow (aNdotH, theIsFront ? occFrontMaterial_Shininess() : occBackMaterial_Shininess());"
93 EOL" }"
94 EOL
95 EOL"Diffuse += occLight_Diffuse (theId).rgb * aNdotL * anAtten;"
96 EOL"Specular += occLight_Specular (theId).rgb * aSpecl * anAtten;"
97 EOL"}";
98
99//! Function computes contribution of spotlight source
100const char THE_FUNC_spotLight[] =
101 EOL"void spotLight (in int theId,"
102 EOL" in vec3 theNormal,"
103 EOL" in vec3 theView,"
104 EOL" in vec3 thePoint,"
105 EOL" in bool theIsFront)"
106 EOL"{"
107 EOL" vec3 aLight = occLight_Position (theId).xyz;"
108 EOL" vec3 aSpotDir = occLight_SpotDirection (theId).xyz;"
109 EOL" if (occLight_IsHeadlight (theId) == 0)"
110 EOL" {"
111 EOL" aLight = vec3 (occWorldViewMatrix * occModelWorldMatrix * vec4 (aLight, 1.0));"
112 EOL" aSpotDir = vec3 (occWorldViewMatrix * occModelWorldMatrix * vec4 (aSpotDir, 0.0));"
113 EOL" }"
114 EOL" aLight -= thePoint;"
115 EOL
116 EOL" float aDist = length (aLight);"
117 EOL" aLight = aLight * (1.0 / aDist);"
118 EOL
119 EOL" aSpotDir = normalize (aSpotDir);"
120 // light cone
121 EOL" float aCosA = dot (aSpotDir, -aLight);"
122 EOL" if (aCosA >= 1.0 || aCosA < cos (occLight_SpotCutOff (theId)))"
123 EOL" {"
124 EOL" return;"
125 EOL" }"
126 EOL
127 EOL" float anExponent = occLight_SpotExponent (theId);"
128 EOL" float anAtten = 1.0 / (occLight_ConstAttenuation (theId)"
129 EOL" + occLight_LinearAttenuation (theId) * aDist);"
130 EOL" if (anExponent > 0.0)"
131 EOL" {"
132 EOL" anAtten *= pow (aCosA, anExponent * 128.0);"
133 EOL" }"
134 EOL
135 EOL" vec3 aHalf = normalize (aLight + theView);"
136 EOL
137 EOL" vec3 aFaceSideNormal = theIsFront ? theNormal : -theNormal;"
138 EOL" float aNdotL = max (0.0, dot (aFaceSideNormal, aLight));"
139 EOL" float aNdotH = max (0.0, dot (aFaceSideNormal, aHalf ));"
140 EOL
141 EOL" float aSpecl = 0.0;"
142 EOL" if (aNdotL > 0.0)"
143 EOL" {"
144 EOL" aSpecl = pow (aNdotH, theIsFront ? occFrontMaterial_Shininess() : occBackMaterial_Shininess());"
145 EOL" }"
146 EOL
147 EOL" Diffuse += occLight_Diffuse (theId).rgb * aNdotL * anAtten;"
148 EOL" Specular += occLight_Specular (theId).rgb * aSpecl * anAtten;"
149 EOL"}";
150
151//! Function computes contribution of directional light source
152const char THE_FUNC_directionalLight[] =
153 EOL"void directionalLight (in int theId,"
154 EOL" in vec3 theNormal,"
155 EOL" in vec3 theView,"
156 EOL" in bool theIsFront)"
157 EOL"{"
158 EOL" vec3 aLight = normalize (occLight_Position (theId).xyz);"
159 EOL" if (occLight_IsHeadlight (theId) == 0)"
160 EOL" {"
161 EOL" aLight = vec3 (occWorldViewMatrix * occModelWorldMatrix * vec4 (aLight, 0.0));"
162 EOL" }"
163 EOL
164 EOL" vec3 aHalf = normalize (aLight + theView);"
165 EOL
166 EOL" vec3 aFaceSideNormal = theIsFront ? theNormal : -theNormal;"
167 EOL" float aNdotL = max (0.0, dot (aFaceSideNormal, aLight));"
168 EOL" float aNdotH = max (0.0, dot (aFaceSideNormal, aHalf ));"
169 EOL
170 EOL" float aSpecl = 0.0;"
171 EOL" if (aNdotL > 0.0)"
172 EOL" {"
173 EOL" aSpecl = pow (aNdotH, theIsFront ? occFrontMaterial_Shininess() : occBackMaterial_Shininess());"
174 EOL" }"
175 EOL
176 EOL" Diffuse += occLight_Diffuse (theId).rgb * aNdotL;"
177 EOL" Specular += occLight_Specular (theId).rgb * aSpecl;"
178 EOL"}";
179
180//! Process clipping planes in Fragment Shader.
181//! Should be added at the beginning of the main() function.
182const char THE_FRAG_CLIP_PLANES[] =
183 EOL" for (int aPlaneIter = 0; aPlaneIter < occClipPlaneCount; ++aPlaneIter)"
184 EOL" {"
185 EOL" vec4 aClipEquation = occClipPlaneEquations[aPlaneIter];"
186 EOL" int aClipSpace = occClipPlaneSpaces[aPlaneIter];"
187 EOL" if (aClipSpace == OccEquationCoords_World)"
188 EOL" {"
189 EOL" if (dot (aClipEquation.xyz, PositionWorld.xyz) + aClipEquation.w < 0.0)"
190 EOL" {"
191 EOL" discard;"
192 EOL" }"
193 EOL" }"
194 EOL" else if (aClipSpace == OccEquationCoords_View)"
195 EOL" {"
196 EOL" if (dot (aClipEquation.xyz, Position.xyz) + aClipEquation.w < 0.0)"
197 EOL" {"
198 EOL" discard;"
199 EOL" }"
200 EOL" }"
201 EOL" }";
202
203}
204
30f0ad28 205// =======================================================================
206// function : OpenGl_ShaderManager
207// purpose : Creates new empty shader manager
208// =======================================================================
209OpenGl_ShaderManager::OpenGl_ShaderManager (OpenGl_Context* theContext)
8625ef7e 210: myShadingModel (Visual3d_TOM_VERTEX),
211 myContext (theContext),
e6804ff7 212 myLastView (NULL)
30f0ad28 213{
256f9ac0 214 //
30f0ad28 215}
216
217// =======================================================================
218// function : ~OpenGl_ShaderManager
219// purpose : Releases resources of shader manager
220// =======================================================================
221OpenGl_ShaderManager::~OpenGl_ShaderManager()
222{
223 myProgramList.Clear();
224}
225
05e2200b 226// =======================================================================
227// function : clear
228// purpose :
229// =======================================================================
230void OpenGl_ShaderManager::clear()
231{
232 myProgramList.Clear();
233 myLightPrograms.Nullify();
234 myFlatPrograms = OpenGl_SetOfShaderPrograms();
235 myMapOfLightPrograms.Clear();
236 myFontProgram.Nullify();
b86bb3df 237 myBlitProgram.Nullify();
05e2200b 238 switchLightPrograms();
239}
240
30f0ad28 241// =======================================================================
242// function : Create
243// purpose : Creates new shader program
244// =======================================================================
8625ef7e 245Standard_Boolean OpenGl_ShaderManager::Create (const Handle(Graphic3d_ShaderProgram)& theProxy,
246 TCollection_AsciiString& theShareKey,
247 Handle(OpenGl_ShaderProgram)& theProgram)
30f0ad28 248{
392ac980 249 theProgram.Nullify();
250 if (theProxy.IsNull())
30f0ad28 251 {
8625ef7e 252 return Standard_False;
30f0ad28 253 }
392ac980 254
255 theShareKey = theProxy->GetId();
256 if (myContext->GetResource<Handle(OpenGl_ShaderProgram)> (theShareKey, theProgram))
257 {
05dd08ce 258 if (theProgram->Share())
259 {
260 myProgramList.Append (theProgram);
261 }
8625ef7e 262 return Standard_True;
392ac980 263 }
264
265 theProgram = new OpenGl_ShaderProgram (theProxy);
266 if (!theProgram->Initialize (myContext, theProxy->ShaderObjects()))
30f0ad28 267 {
392ac980 268 theProgram->Release (myContext);
269 theShareKey.Clear();
270 theProgram.Nullify();
8625ef7e 271 return Standard_False;
30f0ad28 272 }
30f0ad28 273
392ac980 274 myProgramList.Append (theProgram);
275 myContext->ShareResource (theShareKey, theProgram);
8625ef7e 276 return Standard_True;
30f0ad28 277}
278
279// =======================================================================
280// function : Unregister
281// purpose : Removes specified shader program from the manager
282// =======================================================================
392ac980 283void OpenGl_ShaderManager::Unregister (TCollection_AsciiString& theShareKey,
284 Handle(OpenGl_ShaderProgram)& theProgram)
30f0ad28 285{
286 for (OpenGl_ShaderProgramList::Iterator anIt (myProgramList); anIt.More(); anIt.Next())
287 {
288 if (anIt.Value() == theProgram)
289 {
392ac980 290 if (!theProgram->UnShare())
291 {
292 theShareKey.Clear();
293 theProgram.Nullify();
294 return;
295 }
296
30f0ad28 297 myProgramList.Remove (anIt);
392ac980 298 myMaterialStates.UnBind (theProgram);
30f0ad28 299 break;
300 }
301 }
302
303 const TCollection_AsciiString anID = theProgram->myProxy->GetId();
304 if (anID.IsEmpty())
305 {
306 myContext->DelayedRelease (theProgram);
307 theProgram.Nullify();
308 }
309 else
310 {
311 theProgram.Nullify();
05dd08ce 312 myContext->ReleaseResource (anID, Standard_True);
30f0ad28 313 }
314}
315
316// =======================================================================
317// function : ShaderPrograms
318// purpose : Returns list of registered shader programs
319// =======================================================================
320const OpenGl_ShaderProgramList& OpenGl_ShaderManager::ShaderPrograms() const
321{
322 return myProgramList;
323}
324
325// =======================================================================
326// function : Empty
327// purpose : Returns true if no program objects are attached
328// =======================================================================
329Standard_Boolean OpenGl_ShaderManager::IsEmpty() const
330{
331 return myProgramList.IsEmpty();
332}
333
256f9ac0 334// =======================================================================
335// function : switchLightPrograms
336// purpose :
337// =======================================================================
338void OpenGl_ShaderManager::switchLightPrograms()
339{
340 TCollection_AsciiString aKey (myShadingModel == Visual3d_TOM_FRAGMENT ? "p_" : "g_");
341 const OpenGl_ListOfLight* aLights = myLightSourceState.LightSources();
342 if (aLights != NULL)
343 {
344 for (OpenGl_ListOfLight::Iterator aLightIter (*aLights); aLightIter.More(); aLightIter.Next())
345 {
346 switch (aLightIter.Value().Type)
347 {
348 case Visual3d_TOLS_AMBIENT:
349 break; // skip ambient
350 case Visual3d_TOLS_DIRECTIONAL:
351 aKey += "d";
352 break;
353 case Visual3d_TOLS_POSITIONAL:
354 aKey += "p";
355 break;
356 case Visual3d_TOLS_SPOT:
357 aKey += "s";
358 break;
359 }
360 }
361 }
362
363 if (!myMapOfLightPrograms.Find (aKey, myLightPrograms))
364 {
365 myLightPrograms = new OpenGl_SetOfShaderPrograms();
366 myMapOfLightPrograms.Bind (aKey, myLightPrograms);
367 }
368}
369
30f0ad28 370// =======================================================================
371// function : UpdateLightSourceStateTo
372// purpose : Updates state of OCCT light sources
373// =======================================================================
374void OpenGl_ShaderManager::UpdateLightSourceStateTo (const OpenGl_ListOfLight* theLights)
375{
376 myLightSourceState.Set (theLights);
377 myLightSourceState.Update();
256f9ac0 378 switchLightPrograms();
379}
380
381// =======================================================================
382// function : SetShadingModel
383// purpose :
384// =======================================================================
385void OpenGl_ShaderManager::SetShadingModel (const Visual3d_TypeOfModel theModel)
386{
387 myShadingModel = theModel;
388 switchLightPrograms();
30f0ad28 389}
390
391// =======================================================================
392// function : SetProjectionState
393// purpose : Sets new state of OCCT projection transform
394// =======================================================================
c827ea3a 395void OpenGl_ShaderManager::UpdateProjectionStateTo (const OpenGl_Mat4& theProjectionMatrix)
30f0ad28 396{
397 myProjectionState.Set (theProjectionMatrix);
398 myProjectionState.Update();
399}
400
401// =======================================================================
402// function : SetModelWorldState
403// purpose : Sets new state of OCCT model-world transform
404// =======================================================================
c827ea3a 405void OpenGl_ShaderManager::UpdateModelWorldStateTo (const OpenGl_Mat4& theModelWorldMatrix)
30f0ad28 406{
407 myModelWorldState.Set (theModelWorldMatrix);
408 myModelWorldState.Update();
409}
410
411// =======================================================================
412// function : SetWorldViewState
413// purpose : Sets new state of OCCT world-view transform
414// =======================================================================
c827ea3a 415void OpenGl_ShaderManager::UpdateWorldViewStateTo (const OpenGl_Mat4& theWorldViewMatrix)
30f0ad28 416{
417 myWorldViewState.Set (theWorldViewMatrix);
418 myWorldViewState.Update();
419}
420
30f0ad28 421// =======================================================================
422// function : LightSourceState
423// purpose : Returns current state of OCCT light sources
424// =======================================================================
425const OpenGl_LightSourceState& OpenGl_ShaderManager::LightSourceState() const
426{
427 return myLightSourceState;
428}
429
430// =======================================================================
431// function : ProjectionState
432// purpose : Returns current state of OCCT projection transform
433// =======================================================================
434const OpenGl_ProjectionState& OpenGl_ShaderManager::ProjectionState() const
435{
436 return myProjectionState;
437}
438
439// =======================================================================
440// function : ModelWorldState
441// purpose : Returns current state of OCCT model-world transform
442// =======================================================================
443const OpenGl_ModelWorldState& OpenGl_ShaderManager::ModelWorldState() const
444{
445 return myModelWorldState;
446}
447
448// =======================================================================
449// function : WorldViewState
450// purpose : Returns current state of OCCT world-view transform
451// =======================================================================
452const OpenGl_WorldViewState& OpenGl_ShaderManager::WorldViewState() const
453{
454 return myWorldViewState;
455}
456
4fe9ad57 457//! Packed properties of light source
458class OpenGl_ShaderLightParameters
459{
460public:
461
462 OpenGl_Vec4 Color;
463 OpenGl_Vec4 Position;
464 OpenGl_Vec4 Direction;
465 OpenGl_Vec4 Parameters;
466
467 //! Returns packed (serialized) representation of light source properties
0adbd30f 468 const OpenGl_Vec4* Packed() const { return reinterpret_cast<const OpenGl_Vec4*> (this); }
01eaf654 469 static Standard_Integer NbOfVec4() { return 4; }
4fe9ad57 470
471};
472
473//! Packed light source type information
474class OpenGl_ShaderLightType
475{
476public:
477
478 Standard_Integer Type;
479 Standard_Integer IsHeadlight;
480
481 //! Returns packed (serialized) representation of light source type
0adbd30f 482 const OpenGl_Vec2i* Packed() const { return reinterpret_cast<const OpenGl_Vec2i*> (this); }
01eaf654 483 static Standard_Integer NbOfVec2i() { return 1; }
4fe9ad57 484
485};
486
30f0ad28 487// =======================================================================
488// function : PushLightSourceState
489// purpose : Pushes state of OCCT light sources to the program
490// =======================================================================
491void OpenGl_ShaderManager::PushLightSourceState (const Handle(OpenGl_ShaderProgram)& theProgram) const
492{
12381341 493 if (myLightSourceState.Index() == theProgram->ActiveState (OpenGl_LIGHT_SOURCES_STATE)
494 || !theProgram->IsValid())
30f0ad28 495 {
496 return;
497 }
30f0ad28 498
01eaf654 499 OpenGl_ShaderLightType* aLightTypeArray = new OpenGl_ShaderLightType[OpenGLMaxLights];
500 for (Standard_Integer aLightIt = 0; aLightIt < OpenGLMaxLights; ++aLightIt)
501 {
502 aLightTypeArray[aLightIt].Type = -1;
503 }
504
12381341 505 const Standard_Integer aLightsDefNb = Min (myLightSourceState.LightSources()->Size(), OpenGLMaxLights);
506 if (aLightsDefNb < 1)
507 {
30f0ad28 508 theProgram->SetUniform (myContext,
12381341 509 theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_COUNT),
510 0);
30f0ad28 511 theProgram->SetUniform (myContext,
12381341 512 theProgram->GetStateLocation (OpenGl_OCC_LIGHT_AMBIENT),
513 OpenGl_Vec4 (0.0f, 0.0f, 0.0f, 0.0f));
01eaf654 514 theProgram->SetUniform (myContext,
515 theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_TYPES),
516 OpenGLMaxLights * OpenGl_ShaderLightType::NbOfVec2i(),
517 aLightTypeArray[0].Packed());
12381341 518 theProgram->UpdateState (OpenGl_LIGHT_SOURCES_STATE, myLightSourceState.Index());
0c4033b4 519 delete[] aLightTypeArray;
12381341 520 return;
521 }
30f0ad28 522
4fe9ad57 523 OpenGl_ShaderLightParameters* aLightParamsArray = new OpenGl_ShaderLightParameters[aLightsDefNb];
30f0ad28 524
12381341 525 OpenGl_Vec4 anAmbient (0.0f, 0.0f, 0.0f, 0.0f);
526 Standard_Integer aLightsNb = 0;
527 for (OpenGl_ListOfLight::Iterator anIter (*myLightSourceState.LightSources()); anIter.More(); anIter.Next())
528 {
529 const OpenGl_Light& aLight = anIter.Value();
530 if (aLight.Type == Visual3d_TOLS_AMBIENT)
30f0ad28 531 {
12381341 532 anAmbient += aLight.Color;
533 continue;
534 }
535 else if (aLightsNb >= OpenGLMaxLights)
536 {
537 continue;
538 }
30f0ad28 539
4fe9ad57 540 OpenGl_ShaderLightType& aLightType = aLightTypeArray[aLightsNb];
541 aLightType.Type = aLight.Type;
542 aLightType.IsHeadlight = aLight.IsHeadlight;
30f0ad28 543
4fe9ad57 544 OpenGl_ShaderLightParameters& aLightParams = aLightParamsArray[aLightsNb];
545 aLightParams.Color = aLight.Color;
546 aLightParams.Position = aLight.Type == Visual3d_TOLS_DIRECTIONAL
547 ? -aLight.Direction
548 : aLight.Position;
12381341 549 if (aLight.Type == Visual3d_TOLS_SPOT)
550 {
4fe9ad57 551 aLightParams.Direction = aLight.Direction;
30f0ad28 552 }
4fe9ad57 553 aLightParams.Parameters = aLight.Params;
12381341 554 ++aLightsNb;
555 }
30f0ad28 556
12381341 557 theProgram->SetUniform (myContext,
558 theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_COUNT),
559 aLightsNb);
560 theProgram->SetUniform (myContext,
561 theProgram->GetStateLocation (OpenGl_OCC_LIGHT_AMBIENT),
562 anAmbient);
01eaf654 563 theProgram->SetUniform (myContext,
564 theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_TYPES),
565 OpenGLMaxLights * OpenGl_ShaderLightType::NbOfVec2i(),
566 aLightTypeArray[0].Packed());
12381341 567 if (aLightsNb > 0)
568 {
4fe9ad57 569 theProgram->SetUniform (myContext,
570 theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_PARAMS),
571 aLightsNb * OpenGl_ShaderLightParameters::NbOfVec4(),
572 aLightParamsArray[0].Packed());
30f0ad28 573 }
4fe9ad57 574 delete[] aLightParamsArray;
575 delete[] aLightTypeArray;
30f0ad28 576
577 theProgram->UpdateState (OpenGl_LIGHT_SOURCES_STATE, myLightSourceState.Index());
578}
579
580// =======================================================================
581// function : PushProjectionState
582// purpose : Pushes state of OCCT projection transform to the program
583// =======================================================================
584void OpenGl_ShaderManager::PushProjectionState (const Handle(OpenGl_ShaderProgram)& theProgram) const
585{
586 if (myProjectionState.Index() == theProgram->ActiveState (OpenGl_PROJECTION_STATE))
587 {
588 return;
589 }
590
591 theProgram->SetUniform (myContext,
592 theProgram->GetStateLocation (OpenGl_OCC_PROJECTION_MATRIX),
593 myProjectionState.ProjectionMatrix());
594
595 GLint aLocation = theProgram->GetStateLocation (OpenGl_OCC_PROJECTION_MATRIX_INVERSE);
596 if (aLocation != OpenGl_ShaderProgram::INVALID_LOCATION)
597 {
598 theProgram->SetUniform (myContext, aLocation, myProjectionState.ProjectionMatrixInverse());
599 }
600
601 theProgram->SetUniform (myContext,
602 theProgram->GetStateLocation (OpenGl_OCC_PROJECTION_MATRIX_TRANSPOSE),
603 myProjectionState.ProjectionMatrix(), true);
604
605 aLocation = theProgram->GetStateLocation (OpenGl_OCC_PROJECTION_MATRIX_INVERSE_TRANSPOSE);
606 if (aLocation != OpenGl_ShaderProgram::INVALID_LOCATION)
607 {
608 theProgram->SetUniform (myContext, aLocation, myProjectionState.ProjectionMatrixInverse(), true);
609 }
610
611 theProgram->UpdateState (OpenGl_PROJECTION_STATE, myProjectionState.Index());
612}
613
614// =======================================================================
615// function : PushModelWorldState
616// purpose : Pushes state of OCCT model-world transform to the program
617// =======================================================================
618void OpenGl_ShaderManager::PushModelWorldState (const Handle(OpenGl_ShaderProgram)& theProgram) const
619{
620 if (myModelWorldState.Index() == theProgram->ActiveState (OpenGl_MODEL_WORLD_STATE))
621 {
622 return;
623 }
624
625 theProgram->SetUniform (myContext,
626 theProgram->GetStateLocation (OpenGl_OCC_MODEL_WORLD_MATRIX),
627 myModelWorldState.ModelWorldMatrix());
628
629 GLint aLocation = theProgram->GetStateLocation (OpenGl_OCC_MODEL_WORLD_MATRIX_INVERSE);
630 if (aLocation != OpenGl_ShaderProgram::INVALID_LOCATION)
631 {
632 theProgram->SetUniform (myContext, aLocation, myModelWorldState.ModelWorldMatrixInverse());
633 }
634
635 theProgram->SetUniform (myContext,
636 theProgram->GetStateLocation (OpenGl_OCC_MODEL_WORLD_MATRIX_TRANSPOSE),
637 myModelWorldState.ModelWorldMatrix(), true);
638
639 aLocation = theProgram->GetStateLocation (OpenGl_OCC_MODEL_WORLD_MATRIX_INVERSE_TRANSPOSE);
640 if (aLocation != OpenGl_ShaderProgram::INVALID_LOCATION)
641 {
642 theProgram->SetUniform (myContext, aLocation, myModelWorldState.ModelWorldMatrixInverse(), true);
643 }
644
645 theProgram->UpdateState (OpenGl_MODEL_WORLD_STATE, myModelWorldState.Index());
646}
647
648// =======================================================================
649// function : PushWorldViewState
650// purpose : Pushes state of OCCT world-view transform to the program
651// =======================================================================
652void OpenGl_ShaderManager::PushWorldViewState (const Handle(OpenGl_ShaderProgram)& theProgram) const
653{
654 if (myWorldViewState.Index() == theProgram->ActiveState (OpenGl_WORLD_VIEW_STATE))
655 {
656 return;
657 }
658
659 theProgram->SetUniform (myContext,
660 theProgram->GetStateLocation (OpenGl_OCC_WORLD_VIEW_MATRIX),
661 myWorldViewState.WorldViewMatrix());
662
663 GLint aLocation = theProgram->GetStateLocation (OpenGl_OCC_WORLD_VIEW_MATRIX_INVERSE);
664 if (aLocation != OpenGl_ShaderProgram::INVALID_LOCATION)
665 {
666 theProgram->SetUniform (myContext, aLocation, myWorldViewState.WorldViewMatrixInverse());
667 }
668
669 theProgram->SetUniform (myContext,
670 theProgram->GetStateLocation (OpenGl_OCC_WORLD_VIEW_MATRIX_TRANSPOSE),
671 myWorldViewState.WorldViewMatrix(), true);
672
673 aLocation = theProgram->GetStateLocation (OpenGl_OCC_WORLD_VIEW_MATRIX_INVERSE_TRANSPOSE);
674 if (aLocation != OpenGl_ShaderProgram::INVALID_LOCATION)
675 {
676 theProgram->SetUniform (myContext, aLocation, myWorldViewState.WorldViewMatrixInverse(), true);
677 }
678
679 theProgram->UpdateState (OpenGl_WORLD_VIEW_STATE, myWorldViewState.Index());
680}
681
682// =======================================================================
683// function : UpdateClippingState
684// purpose : Updates state of OCCT clipping planes
685// =======================================================================
686void OpenGl_ShaderManager::UpdateClippingState()
687{
688 myClippingState.Update();
689}
690
691// =======================================================================
692// function : RevertClippingState
693// purpose : Reverts state of OCCT clipping planes
694// =======================================================================
695void OpenGl_ShaderManager::RevertClippingState()
696{
697 myClippingState.Revert();
698}
699
700// =======================================================================
701// function : PushClippingState
702// purpose : Pushes state of OCCT clipping planes to the program
703// =======================================================================
704void OpenGl_ShaderManager::PushClippingState (const Handle(OpenGl_ShaderProgram)& theProgram) const
705{
706 if (myClippingState.Index() == theProgram->ActiveState (OpenGl_CLIP_PLANES_STATE))
707 {
708 return;
709 }
710
12381341 711 theProgram->UpdateState (OpenGl_CLIP_PLANES_STATE, myClippingState.Index());
712 const GLint aLocEquations = theProgram->GetStateLocation (OpenGl_OCC_CLIP_PLANE_EQUATIONS);
713 const GLint aLocSpaces = theProgram->GetStateLocation (OpenGl_OCC_CLIP_PLANE_SPACES);
714 if (aLocEquations == OpenGl_ShaderProgram::INVALID_LOCATION
715 && aLocSpaces == OpenGl_ShaderProgram::INVALID_LOCATION)
716 {
717 return;
718 }
719
5495fa7e 720 GLint aPlanesNb = 0;
51b10cd4 721 for (Graphic3d_SequenceOfHClipPlane::Iterator anIter (myContext->Clipping().Planes());
12381341 722 anIter.More(); anIter.Next())
30f0ad28 723 {
724 const Handle(Graphic3d_ClipPlane)& aPlane = anIter.Value();
725 if (!myContext->Clipping().IsEnabled (aPlane))
726 {
727 continue;
728 }
729
12381341 730 ++aPlanesNb;
731 }
732 if (aPlanesNb < 1)
733 {
734 return;
735 }
736
5495fa7e 737 const Standard_Size MAX_CLIP_PLANES = 8;
738 OpenGl_Vec4* anEquations = new OpenGl_Vec4[MAX_CLIP_PLANES];
739 GLint* aSpaces = new GLint [MAX_CLIP_PLANES];
12381341 740 GLuint aPlaneId = 0;
51b10cd4 741 for (Graphic3d_SequenceOfHClipPlane::Iterator anIter (myContext->Clipping().Planes());
12381341 742 anIter.More(); anIter.Next())
743 {
744 const Handle(Graphic3d_ClipPlane)& aPlane = anIter.Value();
745 if (!myContext->Clipping().IsEnabled (aPlane))
30f0ad28 746 {
12381341 747 continue;
30f0ad28 748 }
749
12381341 750 const Graphic3d_ClipPlane::Equation& anEquation = aPlane->GetEquation();
751 anEquations[aPlaneId] = OpenGl_Vec4 ((float) anEquation.x(),
752 (float) anEquation.y(),
753 (float) anEquation.z(),
754 (float) anEquation.w());
755 aSpaces[aPlaneId] = myContext->Clipping().GetEquationSpace (aPlane);
756 ++aPlaneId;
30f0ad28 757 }
5495fa7e 758
759 theProgram->SetUniform (myContext,
760 theProgram->GetStateLocation (OpenGl_OCC_CLIP_PLANE_COUNT),
761 aPlanesNb);
762 theProgram->SetUniform (myContext, aLocEquations, MAX_CLIP_PLANES, anEquations);
763 theProgram->SetUniform (myContext, aLocSpaces, MAX_CLIP_PLANES, aSpaces);
4fe9ad57 764
12381341 765 delete[] anEquations;
766 delete[] aSpaces;
30f0ad28 767}
768
769// =======================================================================
770// function : UpdateMaterialStateTo
771// purpose : Updates state of OCCT material for specified program
772// =======================================================================
773void OpenGl_ShaderManager::UpdateMaterialStateTo (const Handle(OpenGl_ShaderProgram)& theProgram,
774 const OpenGl_Element* theAspect)
775{
776 if (myMaterialStates.IsBound (theProgram))
777 {
595a42a4 778 OpenGl_MaterialState& aState = myMaterialStates.ChangeFind (theProgram);
779 aState.Set (theAspect);
780 aState.Update();
30f0ad28 781 }
782 else
783 {
595a42a4 784 myMaterialStates.Bind (theProgram, OpenGl_MaterialState (theAspect));
785 myMaterialStates.ChangeFind (theProgram).Update();
30f0ad28 786 }
30f0ad28 787}
788
789// =======================================================================
790// function : ResetMaterialStates
791// purpose : Resets state of OCCT material for all programs
792// =======================================================================
793void OpenGl_ShaderManager::ResetMaterialStates()
794{
795 for (OpenGl_ShaderProgramList::Iterator anIt (myProgramList); anIt.More(); anIt.Next())
796 {
797 anIt.Value()->UpdateState (OpenGl_MATERIALS_STATE, 0);
798 }
799}
800
801// =======================================================================
802// function : MaterialState
803// purpose : Returns state of OCCT material for specified program
804// =======================================================================
805const OpenGl_MaterialState* OpenGl_ShaderManager::MaterialState (const Handle(OpenGl_ShaderProgram)& theProgram) const
806{
807 if (!myMaterialStates.IsBound (theProgram))
808 return NULL;
809
810 return &myMaterialStates.Find (theProgram);
811}
812
e135a155 813// =======================================================================
814// function : SurfaceDetailState
815// purpose : Returns current state of OCCT surface detail
816// =======================================================================
817const OpenGl_SurfaceDetailState& OpenGl_ShaderManager::SurfaceDetailState() const
818{
819 return mySurfaceDetailState;
820}
821
822// =======================================================================
823// function : UpdateSurfaceDetailStateTo
824// purpose : Updates state of OCCT surface detail
825// =======================================================================
826void OpenGl_ShaderManager::UpdateSurfaceDetailStateTo (const Visual3d_TypeOfSurfaceDetail theDetail)
827{
828 mySurfaceDetailState.Set (theDetail);
829 mySurfaceDetailState.Update();
830}
831
30f0ad28 832namespace
833{
834
835static const OpenGl_Vec4 THE_COLOR_BLACK_VEC4 (0.0f, 0.0f, 0.0f, 0.0f);
836
837// =======================================================================
838// function : PushAspectFace
839// purpose :
840// =======================================================================
841static void PushAspectFace (const Handle(OpenGl_Context)& theCtx,
842 const Handle(OpenGl_ShaderProgram)& theProgram,
843 const OpenGl_AspectFace* theAspect)
844{
845 theProgram->SetUniform (theCtx,
846 theProgram->GetStateLocation (OpenGl_OCCT_TEXTURE_ENABLE),
847 theAspect->DoTextureMap());
30f0ad28 848 theProgram->SetUniform (theCtx,
849 theProgram->GetStateLocation (OpenGl_OCCT_ACTIVE_SAMPLER),
850 0 /* GL_TEXTURE0 */);
30f0ad28 851 theProgram->SetUniform (theCtx,
852 theProgram->GetStateLocation (OpenGl_OCCT_DISTINGUISH_MODE),
853 theAspect->DistinguishingMode());
854
0adbd30f 855 OpenGl_Material aParams;
12381341 856 for (Standard_Integer anIndex = 0; anIndex < 2; ++anIndex)
30f0ad28 857 {
12381341 858 const GLint aLoc = theProgram->GetStateLocation (anIndex == 0
859 ? OpenGl_OCCT_FRONT_MATERIAL
860 : OpenGl_OCCT_BACK_MATERIAL);
861 if (aLoc == OpenGl_ShaderProgram::INVALID_LOCATION)
30f0ad28 862 {
12381341 863 continue;
30f0ad28 864 }
30f0ad28 865
95b2678c 866 aParams.Init (anIndex == 0 || theAspect->DistinguishingMode() != TOn
867 ? theAspect->IntFront()
868 : theAspect->IntBack());
0adbd30f 869 theProgram->SetUniform (theCtx, aLoc, OpenGl_Material::NbOfVec4(),
870 aParams.Packed());
30f0ad28 871 }
872}
873
874// =======================================================================
875// function : PushAspectLine
876// purpose :
877// =======================================================================
878static void PushAspectLine (const Handle(OpenGl_Context)& theCtx,
879 const Handle(OpenGl_ShaderProgram)& theProgram,
880 const OpenGl_AspectLine* theAspect)
881{
882 theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_TEXTURE_ENABLE), TOff);
883 theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_DISTINGUISH_MODE), TOff);
884
885 const OpenGl_Vec4 aDiffuse (theAspect->Color().rgb[0],
886 theAspect->Color().rgb[1],
887 theAspect->Color().rgb[2],
888 theAspect->Color().rgb[3]);
12381341 889 OpenGl_Vec4 aParams[5];
890 aParams[0] = THE_COLOR_BLACK_VEC4;
891 aParams[1] = THE_COLOR_BLACK_VEC4;
892 aParams[2] = aDiffuse;
893 aParams[3] = THE_COLOR_BLACK_VEC4;
894 aParams[4].x() = 0.0f; // shininess
895 aParams[4].y() = 0.0f; // transparency
4fe9ad57 896 theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL),
897 5, aParams);
30f0ad28 898}
899
900// =======================================================================
901// function : PushAspectText
902// purpose :
903// =======================================================================
904static void PushAspectText (const Handle(OpenGl_Context)& theCtx,
905 const Handle(OpenGl_ShaderProgram)& theProgram,
906 const OpenGl_AspectText* theAspect)
907{
908 theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_TEXTURE_ENABLE), TOn);
909 theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_DISTINGUISH_MODE), TOff);
910 theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_ACTIVE_SAMPLER), 0 /* GL_TEXTURE0 */);
911
912 OpenGl_Vec4 aDiffuse (theAspect->Color().rgb[0],
913 theAspect->Color().rgb[1],
914 theAspect->Color().rgb[2],
915 theAspect->Color().rgb[3]);
916 if (theAspect->DisplayType() == Aspect_TODT_DEKALE
917 || theAspect->DisplayType() == Aspect_TODT_SUBTITLE)
918 {
919 aDiffuse = OpenGl_Vec4 (theAspect->SubtitleColor().rgb[0],
920 theAspect->SubtitleColor().rgb[1],
921 theAspect->SubtitleColor().rgb[2],
922 theAspect->SubtitleColor().rgb[3]);
923 }
924
12381341 925 OpenGl_Vec4 aParams[5];
926 aParams[0] = THE_COLOR_BLACK_VEC4;
927 aParams[1] = THE_COLOR_BLACK_VEC4;
928 aParams[2] = aDiffuse;
929 aParams[3] = THE_COLOR_BLACK_VEC4;
930 aParams[4].x() = 0.0f; // shininess
931 aParams[4].y() = 0.0f; // transparency
4fe9ad57 932 theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL),
933 5, aParams);
30f0ad28 934}
935
936// =======================================================================
937// function : PushAspectMarker
938// purpose :
939// =======================================================================
940static void PushAspectMarker (const Handle(OpenGl_Context)& theCtx,
941 const Handle(OpenGl_ShaderProgram)& theProgram,
942 const OpenGl_AspectMarker* theAspect)
943{
944 theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_TEXTURE_ENABLE), TOn);
945 theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_DISTINGUISH_MODE), TOff);
946 theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_ACTIVE_SAMPLER), 0 /* GL_TEXTURE0 */);
947
948 const OpenGl_Vec4 aDiffuse (theAspect->Color().rgb[0],
949 theAspect->Color().rgb[1],
950 theAspect->Color().rgb[2],
951 theAspect->Color().rgb[3]);
12381341 952 OpenGl_Vec4 aParams[5];
953 aParams[0] = THE_COLOR_BLACK_VEC4;
954 aParams[1] = THE_COLOR_BLACK_VEC4;
955 aParams[2] = aDiffuse;
956 aParams[3] = THE_COLOR_BLACK_VEC4;
957 aParams[4].x() = 0.0f; // shininess
958 aParams[4].y() = 0.0f; // transparency
4fe9ad57 959 theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL),
960 5, aParams);
30f0ad28 961}
962
963}; // nameless namespace
964
965// =======================================================================
966// function : PushMaterialState
967// purpose : Pushes current state of OCCT material to the program
968// =======================================================================
969void OpenGl_ShaderManager::PushMaterialState (const Handle(OpenGl_ShaderProgram)& theProgram) const
970{
971 if (!myMaterialStates.IsBound (theProgram))
972 {
973 return;
974 }
975
976 const OpenGl_MaterialState& aState = myMaterialStates.Find (theProgram);
977 if (aState.Index() == theProgram->ActiveState (OpenGl_MATERIALS_STATE))
978 {
979 return;
980 }
981
982 if (typeid (*aState.Aspect()) == typeid (OpenGl_AspectFace))
983 {
984 PushAspectFace (myContext, theProgram, dynamic_cast<const OpenGl_AspectFace*> (aState.Aspect()));
985 }
986 else if (typeid (*aState.Aspect()) == typeid (OpenGl_AspectLine))
987 {
988 PushAspectLine (myContext, theProgram, dynamic_cast<const OpenGl_AspectLine*> (aState.Aspect()));
989 }
990 else if (typeid (*aState.Aspect()) == typeid (OpenGl_AspectText))
991 {
992 PushAspectText (myContext, theProgram, dynamic_cast<const OpenGl_AspectText*> (aState.Aspect()));
993 }
994 else if (typeid (*aState.Aspect()) == typeid (OpenGl_AspectMarker))
995 {
996 PushAspectMarker (myContext, theProgram, dynamic_cast<const OpenGl_AspectMarker*> (aState.Aspect()));
997 }
998
999 theProgram->UpdateState (OpenGl_MATERIALS_STATE, aState.Index());
1000}
1001
1002// =======================================================================
e135a155 1003// function : PushState
30f0ad28 1004// purpose : Pushes state of OCCT graphics parameters to the program
1005// =======================================================================
1006void OpenGl_ShaderManager::PushState (const Handle(OpenGl_ShaderProgram)& theProgram) const
1007{
1008 PushClippingState (theProgram);
1009 PushMaterialState (theProgram);
1010 PushWorldViewState (theProgram);
1011 PushModelWorldState (theProgram);
05e2200b 1012 PushProjectionState (theProgram);
30f0ad28 1013 PushLightSourceState (theProgram);
12381341 1014}
8625ef7e 1015
1016// =======================================================================
1017// function : prepareStdProgramFont
1018// purpose :
1019// =======================================================================
1020Standard_Boolean OpenGl_ShaderManager::prepareStdProgramFont()
1021{
1022 Handle(Graphic3d_ShaderProgram) aProgramSrc = new Graphic3d_ShaderProgram();
b990e557 1023 TCollection_AsciiString aSrcVert = TCollection_AsciiString()
4e1523ef 1024 + THE_VARY_TexCoord_OUT
b990e557 1025 + EOL"void main()"
1026 EOL"{"
1027 EOL" TexCoord = occTexCoord.st;"
1028 EOL" gl_Position = occProjectionMatrix * occWorldViewMatrix * occModelWorldMatrix * occVertex;"
1029 EOL"}";
1030
4e1523ef 1031 TCollection_AsciiString
1032 aSrcGetAlpha = EOL"float getAlpha(void) { return occTexture2D(occActiveSampler, TexCoord.st).a; }";
1033#if !defined(GL_ES_VERSION_2_0)
1034 if (myContext->core11 == NULL)
1035 {
1036 aSrcGetAlpha = EOL"float getAlpha(void) { return occTexture2D(occActiveSampler, TexCoord.st).r; }";
1037 }
1038#endif
1039
b990e557 1040 TCollection_AsciiString aSrcFrag = TCollection_AsciiString() +
4e1523ef 1041 + THE_VARY_TexCoord_IN
1042 + aSrcGetAlpha
1043 + EOL"void main()"
b990e557 1044 EOL"{"
1045 EOL" vec4 aColor = occColor;"
1046 EOL" aColor.a *= getAlpha();"
1047 EOL" if (aColor.a <= 0.285) discard;"
4e1523ef 1048 EOL" occFragColor = aColor;"
b990e557 1049 EOL"}";
8625ef7e 1050
4e1523ef 1051#if !defined(GL_ES_VERSION_2_0)
1052 if (myContext->core32 != NULL)
1053 {
1054 aProgramSrc->SetHeader ("#version 150");
1055 }
1056#endif
8625ef7e 1057 aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_VERTEX, aSrcVert));
1058 aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_FRAGMENT, aSrcFrag));
1059 TCollection_AsciiString aKey;
1060 if (!Create (aProgramSrc, aKey, myFontProgram))
1061 {
1062 myFontProgram = new OpenGl_ShaderProgram(); // just mark as invalid
1063 return Standard_False;
1064 }
1065 return Standard_True;
1066}
1067
1068// =======================================================================
b86bb3df 1069// function : prepareStdProgramFboBlit
1070// purpose :
1071// =======================================================================
1072Standard_Boolean OpenGl_ShaderManager::prepareStdProgramFboBlit()
1073{
1074 Handle(Graphic3d_ShaderProgram) aProgramSrc = new Graphic3d_ShaderProgram();
1075 TCollection_AsciiString aSrcVert =
1076 EOL"THE_SHADER_OUT vec2 TexCoord;"
1077 EOL"void main()"
1078 EOL"{"
1079 EOL" TexCoord = occVertex.zw;"
1080 EOL" gl_Position = vec4(occVertex.x, occVertex.y, 0.0, 1.0);"
1081 EOL"}";
1082
1083 TCollection_AsciiString aSrcFrag =
1084 EOL"uniform sampler2D uColorSampler;"
1085 EOL"uniform sampler2D uDepthSampler;"
1086 EOL
1087 EOL"THE_SHADER_IN vec2 TexCoord;"
1088 EOL
1089 EOL"void main()"
1090 EOL"{"
1091 EOL" gl_FragDepth = occTexture2D (uDepthSampler, TexCoord).r;"
1092 EOL" occFragColor = occTexture2D (uColorSampler, TexCoord);"
1093 EOL"}";
1094
1095#if defined(GL_ES_VERSION_2_0)
1096 if (myContext->IsGlGreaterEqual (3, 0))
1097 {
1098 aProgramSrc->SetHeader ("#version 300 es");
1099 }
1100 else
1101 {
1102 // there is no way to draw into depth buffer
1103 aSrcFrag =
1104 EOL"uniform sampler2D uColorSampler;"
1105 EOL
1106 EOL"THE_SHADER_IN vec2 TexCoord;"
1107 EOL
1108 EOL"void main()"
1109 EOL"{"
1110 EOL" occFragColor = occTexture2D (uColorSampler, TexCoord);"
1111 EOL"}";
1112 }
4e1523ef 1113#else
1114 if (myContext->core32 != NULL)
1115 {
1116 aProgramSrc->SetHeader ("#version 150");
1117 }
b86bb3df 1118#endif
b86bb3df 1119 aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_VERTEX, aSrcVert));
1120 aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_FRAGMENT, aSrcFrag));
1121 TCollection_AsciiString aKey;
1122 if (!Create (aProgramSrc, aKey, myBlitProgram))
1123 {
1124 myBlitProgram = new OpenGl_ShaderProgram(); // just mark as invalid
1125 return Standard_False;
1126 }
1127
1128 myContext->BindProgram (myBlitProgram);
1129 myBlitProgram->SetSampler (myContext, "uColorSampler", 0);
1130 myBlitProgram->SetSampler (myContext, "uDepthSampler", 1);
1131 myContext->BindProgram (NULL);
1132 return Standard_True;
1133}
1134
1135// =======================================================================
8625ef7e 1136// function : prepareStdProgramFlat
1137// purpose :
1138// =======================================================================
1139Standard_Boolean OpenGl_ShaderManager::prepareStdProgramFlat (Handle(OpenGl_ShaderProgram)& theProgram,
1140 const Standard_Integer theBits)
1141{
1142 Handle(Graphic3d_ShaderProgram) aProgramSrc = new Graphic3d_ShaderProgram();
e135a155 1143 TCollection_AsciiString aSrcVert, aSrcVertExtraOut, aSrcVertExtraMain, aSrcVertExtraFunc, aSrcFrag, aSrcFragExtraOut, aSrcFragExtraMain;
8625ef7e 1144 TCollection_AsciiString aSrcFragGetColor = EOL"vec4 getColor(void) { return occColor; }";
4e1523ef 1145 TCollection_AsciiString aSrcFragMainGetColor = EOL" occFragColor = getColor();";
8625ef7e 1146 if ((theBits & OpenGl_PO_Point) != 0)
1147 {
1148 #if defined(GL_ES_VERSION_2_0)
1149 aSrcVertExtraMain += EOL" gl_PointSize = occPointSize;";
1150 #endif
1151 if ((theBits & OpenGl_PO_TextureA) != 0)
1152 {
4e1523ef 1153 TCollection_AsciiString
1154 aSrcGetAlpha = EOL"float getAlpha(void) { return occTexture2D(occActiveSampler, gl_PointCoord).a; }";
1155 #if !defined(GL_ES_VERSION_2_0)
1156 if (myContext->core11 == NULL)
1157 {
1158 aSrcGetAlpha = EOL"float getAlpha(void) { return occTexture2D(occActiveSampler, gl_PointCoord).r; }";
1159 }
1160 #endif
1161
1162 aSrcFragGetColor = aSrcGetAlpha
1163 + EOL"vec4 getColor(void)"
8625ef7e 1164 EOL"{"
1165 EOL" vec4 aColor = occColor;"
1166 EOL" aColor.a *= getAlpha();"
1167 EOL" return aColor;"
1168 EOL"}";
1169
1170 aSrcFragMainGetColor =
1171 EOL" vec4 aColor = getColor();"
1172 EOL" if (aColor.a <= 0.1) discard;"
4e1523ef 1173 EOL" occFragColor = aColor;";
8625ef7e 1174 }
1175 else if ((theBits & OpenGl_PO_TextureRGB) != 0)
1176 {
1177 aSrcFragGetColor =
4e1523ef 1178 EOL"vec4 getColor(void) { return occTexture2D(occActiveSampler, gl_PointCoord); }";
8625ef7e 1179 aSrcFragMainGetColor =
1180 EOL" vec4 aColor = getColor();"
1181 EOL" if (aColor.a <= 0.1) discard;"
4e1523ef 1182 EOL" occFragColor = aColor;";
8625ef7e 1183 }
1184 }
6c6aadb1 1185 else
1186 {
1187 if ((theBits & OpenGl_PO_TextureRGB) != 0)
1188 {
4e1523ef 1189 aSrcVertExtraOut += THE_VARY_TexCoord_OUT;
1190 aSrcFragExtraOut += THE_VARY_TexCoord_IN;
6c6aadb1 1191 aSrcVertExtraMain +=
1192 EOL" TexCoord = occTexCoord.st;";
1193
1194 aSrcFragGetColor =
4e1523ef 1195 EOL"vec4 getColor(void) { return occTexture2D(occActiveSampler, TexCoord.st); }";
6c6aadb1 1196 }
e135a155 1197 else if ((theBits & OpenGl_PO_TextureEnv) != 0)
1198 {
1199 aSrcVertExtraOut += THE_VARY_TexCoord_OUT;
1200 aSrcFragExtraOut += THE_VARY_TexCoord_IN;
1201
1202 aSrcVertExtraFunc = THE_FUNC_transformNormal;
1203
1204 aSrcVertExtraMain +=
1205 EOL" vec4 aPosition = occWorldViewMatrix * occModelWorldMatrix * occVertex;"
1206 EOL" vec3 aNormal = transformNormal (occNormal);"
1207 EOL" vec3 aReflect = reflect (normalize (aPosition.xyz), aNormal);"
1208 EOL" aReflect.z += 1.0;"
1209 EOL" TexCoord = aReflect.xy * inversesqrt (dot (aReflect, aReflect)) * 0.5 + vec2 (0.5);";
1210
1211 aSrcFragGetColor =
1212 EOL"vec4 getColor(void) { return occTexture2D (occActiveSampler, TexCoord.st); }";
1213 }
6c6aadb1 1214 }
8625ef7e 1215 if ((theBits & OpenGl_PO_VertColor) != 0)
1216 {
4e1523ef 1217 aSrcVertExtraOut += EOL"THE_SHADER_OUT vec4 VertColor;";
8625ef7e 1218 aSrcVertExtraMain += EOL" VertColor = occVertColor;";
4e1523ef 1219 aSrcFragExtraOut += EOL"THE_SHADER_IN vec4 VertColor;";
8625ef7e 1220 aSrcFragGetColor = EOL"vec4 getColor(void) { return VertColor; }";
1221 }
1222 if ((theBits & OpenGl_PO_ClipPlanes) != 0)
1223 {
4e1523ef 1224 aSrcVertExtraOut +=
1225 EOL"THE_SHADER_OUT vec4 PositionWorld;"
1226 EOL"THE_SHADER_OUT vec4 Position;";
1227 aSrcFragExtraOut +=
1228 EOL"THE_SHADER_IN vec4 PositionWorld;"
1229 EOL"THE_SHADER_IN vec4 Position;";
8625ef7e 1230 aSrcVertExtraMain +=
1231 EOL" PositionWorld = occModelWorldMatrix * occVertex;"
1232 EOL" Position = occWorldViewMatrix * PositionWorld;";
1233 aSrcFragExtraMain += THE_FRAG_CLIP_PLANES;
1234 }
1235
1236 aSrcVert =
e135a155 1237 aSrcVertExtraFunc
1238 + aSrcVertExtraOut
8625ef7e 1239 + EOL"void main()"
1240 EOL"{"
1241 + aSrcVertExtraMain
1242 + EOL" gl_Position = occProjectionMatrix * occWorldViewMatrix * occModelWorldMatrix * occVertex;"
1243 EOL"}";
1244
1245 aSrcFrag =
1246 aSrcFragExtraOut
1247 + aSrcFragGetColor
1248 + EOL"void main()"
1249 EOL"{"
1250 + aSrcFragExtraMain
1251 + aSrcFragMainGetColor
1252 + EOL"}";
1253
4e1523ef 1254#if !defined(GL_ES_VERSION_2_0)
1255 if (myContext->core32 != NULL)
1256 {
1257 aProgramSrc->SetHeader ("#version 150");
1258 }
1259#endif
8625ef7e 1260 aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_VERTEX, aSrcVert));
1261 aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_FRAGMENT, aSrcFrag));
1262
1263 TCollection_AsciiString aKey;
1264 if (!Create (aProgramSrc, aKey, theProgram))
1265 {
1266 theProgram = new OpenGl_ShaderProgram(); // just mark as invalid
1267 return Standard_False;
1268 }
1269 return Standard_True;
1270}
1271
256f9ac0 1272// =======================================================================
1273// function : stdComputeLighting
1274// purpose :
1275// =======================================================================
abdf0b10 1276TCollection_AsciiString OpenGl_ShaderManager::stdComputeLighting (const Standard_Boolean theHasVertColor)
256f9ac0 1277{
1278 bool aLightsMap[Visual3d_TOLS_SPOT + 1] = { false, false, false, false };
1279 TCollection_AsciiString aLightsFunc, aLightsLoop;
1280 const OpenGl_ListOfLight* aLights = myLightSourceState.LightSources();
1281 if (aLights != NULL)
1282 {
1283 Standard_Integer anIndex = 0;
1284 for (OpenGl_ListOfLight::Iterator aLightIter (*aLights); aLightIter.More(); aLightIter.Next(), ++anIndex)
1285 {
1286 switch (aLightIter.Value().Type)
1287 {
1288 case Visual3d_TOLS_AMBIENT:
1289 --anIndex;
1290 break; // skip ambient
1291 case Visual3d_TOLS_DIRECTIONAL:
1292 aLightsLoop = aLightsLoop + EOL" directionalLight (" + anIndex + ", theNormal, theView, theIsFront);";
1293 break;
1294 case Visual3d_TOLS_POSITIONAL:
1295 aLightsLoop = aLightsLoop + EOL" pointLight (" + anIndex + ", theNormal, theView, aPoint, theIsFront);";
1296 break;
1297 case Visual3d_TOLS_SPOT:
1298 aLightsLoop = aLightsLoop + EOL" spotLight (" + anIndex + ", theNormal, theView, aPoint, theIsFront);";
1299 break;
1300 }
1301
1302 bool& aTypeBit = aLightsMap[aLightIter.Value().Type];
1303 if (aTypeBit)
1304 {
1305 continue;
1306 }
1307
1308 aTypeBit = true;
1309 switch (aLightIter.Value().Type)
1310 {
1311 case Visual3d_TOLS_AMBIENT: break;
1312 case Visual3d_TOLS_DIRECTIONAL: aLightsFunc += THE_FUNC_directionalLight; break;
1313 case Visual3d_TOLS_POSITIONAL: aLightsFunc += THE_FUNC_pointLight; break;
1314 case Visual3d_TOLS_SPOT: aLightsFunc += THE_FUNC_spotLight; break;
1315 }
1316 }
1317 }
1318
abdf0b10 1319 TCollection_AsciiString aGetMatAmbient = "theIsFront ? occFrontMaterial_Ambient() : occBackMaterial_Ambient();";
1320 TCollection_AsciiString aGetMatDiffuse = "theIsFront ? occFrontMaterial_Diffuse() : occBackMaterial_Diffuse();";
1321 if (theHasVertColor)
1322 {
1323 aGetMatAmbient = "getVertColor();";
1324 aGetMatDiffuse = "getVertColor();";
1325 }
1326
256f9ac0 1327 return TCollection_AsciiString()
1328 + THE_FUNC_lightDef
1329 + aLightsFunc
1330 + EOL
1331 EOL"vec4 computeLighting (in vec3 theNormal,"
1332 EOL" in vec3 theView,"
1333 EOL" in vec4 thePoint,"
1334 EOL" in bool theIsFront)"
1335 EOL"{"
1336 EOL" Ambient = occLightAmbient.rgb;"
1337 EOL" Diffuse = vec3 (0.0);"
1338 EOL" Specular = vec3 (0.0);"
1339 EOL" vec3 aPoint = thePoint.xyz / thePoint.w;"
1340 + aLightsLoop
abdf0b10 1341 + EOL" vec4 aMaterialAmbient = " + aGetMatAmbient
1342 + EOL" vec4 aMaterialDiffuse = " + aGetMatDiffuse
1343 + EOL" vec4 aMaterialSpecular = theIsFront ? occFrontMaterial_Specular() : occBackMaterial_Specular();"
256f9ac0 1344 EOL" vec4 aMaterialEmission = theIsFront ? occFrontMaterial_Emission() : occBackMaterial_Emission();"
1345 EOL" return vec4 (Ambient, 1.0) * aMaterialAmbient"
1346 EOL" + vec4 (Diffuse, 1.0) * aMaterialDiffuse"
1347 EOL" + vec4 (Specular, 1.0) * aMaterialSpecular"
1348 EOL" + aMaterialEmission;"
1349 EOL"}";
1350}
1351
8625ef7e 1352// =======================================================================
1353// function : prepareStdProgramGouraud
1354// purpose :
1355// =======================================================================
1356Standard_Boolean OpenGl_ShaderManager::prepareStdProgramGouraud (Handle(OpenGl_ShaderProgram)& theProgram,
1357 const Standard_Integer theBits)
1358{
1359 Handle(Graphic3d_ShaderProgram) aProgramSrc = new Graphic3d_ShaderProgram();
abdf0b10 1360 TCollection_AsciiString aSrcVert, aSrcVertColor, aSrcVertExtraOut, aSrcVertExtraMain, aSrcFrag, aSrcFragExtraOut, aSrcFragExtraMain;
6c6aadb1 1361 TCollection_AsciiString aSrcFragGetColor = EOL"vec4 getColor(void) { return gl_FrontFacing ? FrontColor : BackColor; }";
8625ef7e 1362 if ((theBits & OpenGl_PO_Point) != 0)
1363 {
1364 #if defined(GL_ES_VERSION_2_0)
1365 aSrcVertExtraMain += EOL" gl_PointSize = occPointSize;";
1366 #endif
1367 }
abdf0b10 1368 if ((theBits & OpenGl_PO_VertColor) != 0)
1369 {
1370 aSrcVertColor = EOL"vec4 getVertColor(void) { return occVertColor; }";
1371 }
6c6aadb1 1372 if ((theBits & OpenGl_PO_Point) != 0)
1373 {
1374 if ((theBits & OpenGl_PO_TextureRGB) != 0)
1375 {
1376 aSrcFragGetColor =
1377 EOL"vec4 getColor(void)"
1378 EOL"{"
1379 EOL" vec4 aColor = gl_FrontFacing ? FrontColor : BackColor;"
4e1523ef 1380 EOL" return occTexture2D(occActiveSampler, gl_PointCoord) * aColor;"
6c6aadb1 1381 EOL"}";
1382 }
1383 }
1384 else
1385 {
1386 if ((theBits & OpenGl_PO_TextureRGB) != 0)
1387 {
4e1523ef 1388 aSrcVertExtraOut += THE_VARY_TexCoord_OUT;
1389 aSrcFragExtraOut += THE_VARY_TexCoord_IN;
6c6aadb1 1390 aSrcVertExtraMain +=
1391 EOL" TexCoord = occTexCoord.st;";
1392
1393 aSrcFragGetColor =
1394 EOL"vec4 getColor(void)"
1395 EOL"{"
1396 EOL" vec4 aColor = gl_FrontFacing ? FrontColor : BackColor;"
4e1523ef 1397 EOL" return occTexture2D(occActiveSampler, TexCoord.st) * aColor;"
6c6aadb1 1398 EOL"}";
1399 }
1400 }
8625ef7e 1401 if ((theBits & OpenGl_PO_ClipPlanes) != 0)
1402 {
4e1523ef 1403 aSrcVertExtraOut +=
1404 EOL"THE_SHADER_OUT vec4 PositionWorld;"
1405 EOL"THE_SHADER_OUT vec4 Position;";
1406 aSrcFragExtraOut +=
1407 EOL"THE_SHADER_IN vec4 PositionWorld;"
1408 EOL"THE_SHADER_IN vec4 Position;";
8625ef7e 1409 aSrcVertExtraMain +=
1410 EOL" PositionWorld = aPositionWorld;"
1411 EOL" Position = aPosition;";
1412 aSrcFragExtraMain += THE_FRAG_CLIP_PLANES;
1413 }
1414
abdf0b10 1415 const TCollection_AsciiString aLights = stdComputeLighting ((theBits & OpenGl_PO_VertColor) != 0);
8625ef7e 1416 aSrcVert = TCollection_AsciiString()
1417 + THE_FUNC_transformNormal
1418 + EOL
abdf0b10 1419 + aSrcVertColor
256f9ac0 1420 + aLights
8625ef7e 1421 + EOL
4e1523ef 1422 EOL"THE_SHADER_OUT vec4 FrontColor;"
1423 EOL"THE_SHADER_OUT vec4 BackColor;"
8625ef7e 1424 EOL
1425 + aSrcVertExtraOut
1426 + EOL"void main()"
1427 EOL"{"
1428 EOL" vec4 aPositionWorld = occModelWorldMatrix * occVertex;"
1429 EOL" vec4 aPosition = occWorldViewMatrix * aPositionWorld;"
1430 EOL" vec3 aNormal = transformNormal (occNormal);"
1431 EOL" vec3 aView = vec3 (0.0, 0.0, 1.0);"
1432 EOL" FrontColor = computeLighting (normalize (aNormal), normalize (aView), aPosition, true);"
1433 EOL" BackColor = computeLighting (normalize (aNormal), normalize (aView), aPosition, false);"
1434 + aSrcVertExtraMain
1435 + EOL" gl_Position = occProjectionMatrix * occWorldViewMatrix * occModelWorldMatrix * occVertex;"
1436 EOL"}";
1437
1438 aSrcFrag = TCollection_AsciiString()
4e1523ef 1439 + EOL"THE_SHADER_IN vec4 FrontColor;"
1440 EOL"THE_SHADER_IN vec4 BackColor;"
8625ef7e 1441 + aSrcFragExtraOut
6c6aadb1 1442 + aSrcFragGetColor
8625ef7e 1443 + EOL"void main()"
1444 EOL"{"
1445 + aSrcFragExtraMain
4e1523ef 1446 + EOL" occFragColor = getColor();"
8625ef7e 1447 EOL"}";
1448
4e1523ef 1449#if !defined(GL_ES_VERSION_2_0)
1450 if (myContext->core32 != NULL)
1451 {
1452 aProgramSrc->SetHeader ("#version 150");
1453 }
1454#endif
8625ef7e 1455 aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_VERTEX, aSrcVert));
1456 aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_FRAGMENT, aSrcFrag));
1457 TCollection_AsciiString aKey;
1458 if (!Create (aProgramSrc, aKey, theProgram))
1459 {
1460 theProgram = new OpenGl_ShaderProgram(); // just mark as invalid
1461 return Standard_False;
1462 }
1463 return Standard_True;
1464}
1465
1466// =======================================================================
1467// function : prepareStdProgramPhong
1468// purpose :
1469// =======================================================================
1470Standard_Boolean OpenGl_ShaderManager::prepareStdProgramPhong (Handle(OpenGl_ShaderProgram)& theProgram,
1471 const Standard_Integer theBits)
1472{
6c6aadb1 1473 #define thePhongCompLight "computeLighting (normalize (Normal), normalize (View), Position, gl_FrontFacing)"
1474
8625ef7e 1475 Handle(Graphic3d_ShaderProgram) aProgramSrc = new Graphic3d_ShaderProgram();
6c6aadb1 1476 TCollection_AsciiString aSrcVert, aSrcVertExtraOut, aSrcVertExtraMain, aSrcFrag, aSrcFragExtraOut, aSrcFragGetVertColor, aSrcFragExtraMain;
1477 TCollection_AsciiString aSrcFragGetColor = EOL"vec4 getColor(void) { return " thePhongCompLight "; }";
8625ef7e 1478 if ((theBits & OpenGl_PO_Point) != 0)
1479 {
1480 #if defined(GL_ES_VERSION_2_0)
1481 aSrcVertExtraMain += EOL" gl_PointSize = occPointSize;";
1482 #endif
1483 }
abdf0b10 1484 if ((theBits & OpenGl_PO_VertColor) != 0)
1485 {
7e859dff 1486 aSrcVertExtraOut += EOL"THE_SHADER_OUT vec4 VertColor;";
1487 aSrcVertExtraMain += EOL" VertColor = occVertColor;";
1488 aSrcFragGetVertColor = EOL"THE_SHADER_IN vec4 VertColor;"
1489 EOL"vec4 getVertColor(void) { return VertColor; }";
abdf0b10 1490 }
6c6aadb1 1491
1492 if ((theBits & OpenGl_PO_Point) != 0)
1493 {
1494 if ((theBits & OpenGl_PO_TextureRGB) != 0)
1495 {
1496 aSrcFragGetColor =
1497 EOL"vec4 getColor(void)"
1498 EOL"{"
1499 EOL" vec4 aColor = " thePhongCompLight ";"
4e1523ef 1500 EOL" return occTexture2D(occActiveSampler, gl_PointCoord) * aColor;"
6c6aadb1 1501 EOL"}";
1502 }
1503 }
1504 else
1505 {
1506 if ((theBits & OpenGl_PO_TextureRGB) != 0)
1507 {
4e1523ef 1508 aSrcVertExtraOut += THE_VARY_TexCoord_OUT;
1509 aSrcFragExtraOut += THE_VARY_TexCoord_IN;
6c6aadb1 1510 aSrcVertExtraMain +=
1511 EOL" TexCoord = occTexCoord.st;";
1512
1513 aSrcFragGetColor =
1514 EOL"vec4 getColor(void)"
1515 EOL"{"
1516 EOL" vec4 aColor = " thePhongCompLight ";"
4e1523ef 1517 EOL" return occTexture2D(occActiveSampler, TexCoord.st) * aColor;"
6c6aadb1 1518 EOL"}";
1519 }
1520 }
1521
8625ef7e 1522 if ((theBits & OpenGl_PO_ClipPlanes) != 0)
1523 {
1524 aSrcFragExtraMain += THE_FRAG_CLIP_PLANES;
1525 }
1526
1527 aSrcVert = TCollection_AsciiString()
1528 + THE_FUNC_transformNormal
1529 + EOL
4e1523ef 1530 EOL"THE_SHADER_OUT vec4 PositionWorld;"
1531 EOL"THE_SHADER_OUT vec4 Position;"
1532 EOL"THE_SHADER_OUT vec3 Normal;"
1533 EOL"THE_SHADER_OUT vec3 View;"
8625ef7e 1534 EOL
1535 + aSrcVertExtraOut
1536 + EOL"void main()"
1537 EOL"{"
1538 EOL" PositionWorld = occModelWorldMatrix * occVertex;"
1539 EOL" Position = occWorldViewMatrix * PositionWorld;"
1540 EOL" Normal = transformNormal (occNormal);"
1541 EOL" View = vec3 (0.0, 0.0, 1.0);"
1542 + aSrcVertExtraMain
1543 + EOL" gl_Position = occProjectionMatrix * occWorldViewMatrix * occModelWorldMatrix * occVertex;"
1544 EOL"}";
1545
abdf0b10 1546 const TCollection_AsciiString aLights = stdComputeLighting ((theBits & OpenGl_PO_VertColor) != 0);
8625ef7e 1547 aSrcFrag = TCollection_AsciiString()
4e1523ef 1548 + EOL"THE_SHADER_IN vec4 PositionWorld;"
1549 EOL"THE_SHADER_IN vec4 Position;"
1550 EOL"THE_SHADER_IN vec3 Normal;"
1551 EOL"THE_SHADER_IN vec3 View;"
8625ef7e 1552 + EOL
6c6aadb1 1553 + aSrcFragExtraOut
1554 + aSrcFragGetVertColor
256f9ac0 1555 + aLights
6c6aadb1 1556 + aSrcFragGetColor
8625ef7e 1557 + EOL
1558 EOL"void main()"
1559 EOL"{"
1560 + aSrcFragExtraMain
4e1523ef 1561 + EOL" occFragColor = getColor();"
8625ef7e 1562 EOL"}";
1563
4e1523ef 1564#if !defined(GL_ES_VERSION_2_0)
1565 if (myContext->core32 != NULL)
1566 {
1567 aProgramSrc->SetHeader ("#version 150");
1568 }
1569#endif
8625ef7e 1570 aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_VERTEX, aSrcVert));
1571 aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_FRAGMENT, aSrcFrag));
1572 TCollection_AsciiString aKey;
1573 if (!Create (aProgramSrc, aKey, theProgram))
1574 {
1575 theProgram = new OpenGl_ShaderProgram(); // just mark as invalid
1576 return Standard_False;
1577 }
1578 return Standard_True;
1579}
1580
1581// =======================================================================
1582// function : bindProgramWithState
1583// purpose :
1584// =======================================================================
1585Standard_Boolean OpenGl_ShaderManager::bindProgramWithState (const Handle(OpenGl_ShaderProgram)& theProgram,
1586 const OpenGl_Element* theAspect)
1587{
1588 if (!myContext->BindProgram (theProgram))
1589 {
1590 return Standard_False;
1591 }
1592 theProgram->ApplyVariables (myContext);
1593
1594 const OpenGl_MaterialState* aMaterialState = MaterialState (theProgram);
1595 if (aMaterialState == NULL || aMaterialState->Aspect() != theAspect)
1596 {
1597 UpdateMaterialStateTo (theProgram, theAspect);
1598 }
1599
1600 PushState (theProgram);
1601 return Standard_True;
1602}