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