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