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