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