30f0ad28 |
1 | // Created on: 2013-09-26 |
2 | // Created by: Denis BOGOLEPOV |
3 | // Copyright (c) 2013 OPEN CASCADE SAS |
4 | // |
973c2be1 |
5 | // This file is part of Open CASCADE Technology software library. |
30f0ad28 |
6 | // |
973c2be1 |
7 | // This library is free software; you can redistribute it and / or modify it |
8 | // under the terms of the GNU Lesser General Public version 2.1 as published |
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 | |
28 | IMPLEMENT_STANDARD_HANDLE (OpenGl_ShaderManager, Standard_Transient) |
29 | IMPLEMENT_STANDARD_RTTIEXT(OpenGl_ShaderManager, Standard_Transient) |
30 | |
31 | // ======================================================================= |
32 | // function : OpenGl_ShaderManager |
33 | // purpose : Creates new empty shader manager |
34 | // ======================================================================= |
35 | OpenGl_ShaderManager::OpenGl_ShaderManager (OpenGl_Context* theContext) |
36 | : myContext (theContext), |
37 | myIsPP (Standard_False) |
38 | { |
39 | // |
40 | } |
41 | |
42 | // ======================================================================= |
43 | // function : ~OpenGl_ShaderManager |
44 | // purpose : Releases resources of shader manager |
45 | // ======================================================================= |
46 | OpenGl_ShaderManager::~OpenGl_ShaderManager() |
47 | { |
48 | myProgramList.Clear(); |
49 | } |
50 | |
51 | // ======================================================================= |
52 | // function : Create |
53 | // purpose : Creates new shader program |
54 | // ======================================================================= |
392ac980 |
55 | void OpenGl_ShaderManager::Create (const Handle(Graphic3d_ShaderProgram)& theProxy, |
56 | TCollection_AsciiString& theShareKey, |
57 | Handle(OpenGl_ShaderProgram)& theProgram) |
30f0ad28 |
58 | { |
392ac980 |
59 | theProgram.Nullify(); |
60 | if (theProxy.IsNull()) |
30f0ad28 |
61 | { |
392ac980 |
62 | return; |
30f0ad28 |
63 | } |
392ac980 |
64 | |
65 | theShareKey = theProxy->GetId(); |
66 | if (myContext->GetResource<Handle(OpenGl_ShaderProgram)> (theShareKey, theProgram)) |
67 | { |
05dd08ce |
68 | if (theProgram->Share()) |
69 | { |
70 | myProgramList.Append (theProgram); |
71 | } |
392ac980 |
72 | return; |
73 | } |
74 | |
75 | theProgram = new OpenGl_ShaderProgram (theProxy); |
76 | if (!theProgram->Initialize (myContext, theProxy->ShaderObjects())) |
30f0ad28 |
77 | { |
392ac980 |
78 | theProgram->Release (myContext); |
79 | theShareKey.Clear(); |
80 | theProgram.Nullify(); |
81 | return; |
30f0ad28 |
82 | } |
30f0ad28 |
83 | |
392ac980 |
84 | myProgramList.Append (theProgram); |
85 | myContext->ShareResource (theShareKey, theProgram); |
30f0ad28 |
86 | } |
87 | |
88 | // ======================================================================= |
89 | // function : Unregister |
90 | // purpose : Removes specified shader program from the manager |
91 | // ======================================================================= |
392ac980 |
92 | void OpenGl_ShaderManager::Unregister (TCollection_AsciiString& theShareKey, |
93 | Handle(OpenGl_ShaderProgram)& theProgram) |
30f0ad28 |
94 | { |
95 | for (OpenGl_ShaderProgramList::Iterator anIt (myProgramList); anIt.More(); anIt.Next()) |
96 | { |
97 | if (anIt.Value() == theProgram) |
98 | { |
392ac980 |
99 | if (!theProgram->UnShare()) |
100 | { |
101 | theShareKey.Clear(); |
102 | theProgram.Nullify(); |
103 | return; |
104 | } |
105 | |
30f0ad28 |
106 | myProgramList.Remove (anIt); |
392ac980 |
107 | myMaterialStates.UnBind (theProgram); |
30f0ad28 |
108 | break; |
109 | } |
110 | } |
111 | |
112 | const TCollection_AsciiString anID = theProgram->myProxy->GetId(); |
113 | if (anID.IsEmpty()) |
114 | { |
115 | myContext->DelayedRelease (theProgram); |
116 | theProgram.Nullify(); |
117 | } |
118 | else |
119 | { |
120 | theProgram.Nullify(); |
05dd08ce |
121 | myContext->ReleaseResource (anID, Standard_True); |
30f0ad28 |
122 | } |
123 | } |
124 | |
125 | // ======================================================================= |
126 | // function : ShaderPrograms |
127 | // purpose : Returns list of registered shader programs |
128 | // ======================================================================= |
129 | const OpenGl_ShaderProgramList& OpenGl_ShaderManager::ShaderPrograms() const |
130 | { |
131 | return myProgramList; |
132 | } |
133 | |
134 | // ======================================================================= |
135 | // function : Empty |
136 | // purpose : Returns true if no program objects are attached |
137 | // ======================================================================= |
138 | Standard_Boolean OpenGl_ShaderManager::IsEmpty() const |
139 | { |
140 | return myProgramList.IsEmpty(); |
141 | } |
142 | |
143 | // ======================================================================= |
144 | // function : UpdateLightSourceStateTo |
145 | // purpose : Updates state of OCCT light sources |
146 | // ======================================================================= |
147 | void OpenGl_ShaderManager::UpdateLightSourceStateTo (const OpenGl_ListOfLight* theLights) |
148 | { |
149 | myLightSourceState.Set (theLights); |
150 | myLightSourceState.Update(); |
151 | } |
152 | |
153 | // ======================================================================= |
154 | // function : SetProjectionState |
155 | // purpose : Sets new state of OCCT projection transform |
156 | // ======================================================================= |
b5ac8292 |
157 | void OpenGl_ShaderManager::UpdateProjectionStateTo (const Tmatrix3* theProjectionMatrix) |
30f0ad28 |
158 | { |
159 | myProjectionState.Set (theProjectionMatrix); |
160 | myProjectionState.Update(); |
161 | } |
162 | |
163 | // ======================================================================= |
164 | // function : SetModelWorldState |
165 | // purpose : Sets new state of OCCT model-world transform |
166 | // ======================================================================= |
b5ac8292 |
167 | void OpenGl_ShaderManager::UpdateModelWorldStateTo (const Tmatrix3* theModelWorldMatrix) |
30f0ad28 |
168 | { |
169 | myModelWorldState.Set (theModelWorldMatrix); |
170 | myModelWorldState.Update(); |
171 | } |
172 | |
173 | // ======================================================================= |
174 | // function : SetWorldViewState |
175 | // purpose : Sets new state of OCCT world-view transform |
176 | // ======================================================================= |
b5ac8292 |
177 | void OpenGl_ShaderManager::UpdateWorldViewStateTo (const Tmatrix3* theWorldViewMatrix) |
30f0ad28 |
178 | { |
179 | myWorldViewState.Set (theWorldViewMatrix); |
180 | myWorldViewState.Update(); |
181 | } |
182 | |
183 | // ======================================================================= |
184 | // function : RevertProjectionStateTo |
185 | // purpose : Reverts state of OCCT projection transform |
186 | // ======================================================================= |
b5ac8292 |
187 | void OpenGl_ShaderManager::RevertProjectionStateTo (const Tmatrix3* theProjectionMatrix) |
30f0ad28 |
188 | { |
189 | myProjectionState.Set (theProjectionMatrix); |
190 | myProjectionState.Revert(); |
191 | } |
192 | |
193 | // ======================================================================= |
194 | // function : RevertModelWorldStateTo |
195 | // purpose : Reverts state of OCCT model-world transform |
196 | // ======================================================================= |
b5ac8292 |
197 | void OpenGl_ShaderManager::RevertModelWorldStateTo (const Tmatrix3* theModelWorldMatrix) |
30f0ad28 |
198 | { |
199 | myModelWorldState.Set (theModelWorldMatrix); |
200 | myModelWorldState.Revert(); |
201 | } |
202 | |
203 | // ======================================================================= |
204 | // function : RevertWorldViewStateTo |
205 | // purpose : Reverts state of OCCT world-view transform |
206 | // ======================================================================= |
b5ac8292 |
207 | void OpenGl_ShaderManager::RevertWorldViewStateTo (const Tmatrix3* theWorldViewMatrix) |
30f0ad28 |
208 | { |
209 | myWorldViewState.Set (theWorldViewMatrix); |
210 | myWorldViewState.Revert(); |
211 | } |
212 | |
213 | // ======================================================================= |
214 | // function : LightSourceState |
215 | // purpose : Returns current state of OCCT light sources |
216 | // ======================================================================= |
217 | const OpenGl_LightSourceState& OpenGl_ShaderManager::LightSourceState() const |
218 | { |
219 | return myLightSourceState; |
220 | } |
221 | |
222 | // ======================================================================= |
223 | // function : ProjectionState |
224 | // purpose : Returns current state of OCCT projection transform |
225 | // ======================================================================= |
226 | const OpenGl_ProjectionState& OpenGl_ShaderManager::ProjectionState() const |
227 | { |
228 | return myProjectionState; |
229 | } |
230 | |
231 | // ======================================================================= |
232 | // function : ModelWorldState |
233 | // purpose : Returns current state of OCCT model-world transform |
234 | // ======================================================================= |
235 | const OpenGl_ModelWorldState& OpenGl_ShaderManager::ModelWorldState() const |
236 | { |
237 | return myModelWorldState; |
238 | } |
239 | |
240 | // ======================================================================= |
241 | // function : WorldViewState |
242 | // purpose : Returns current state of OCCT world-view transform |
243 | // ======================================================================= |
244 | const OpenGl_WorldViewState& OpenGl_ShaderManager::WorldViewState() const |
245 | { |
246 | return myWorldViewState; |
247 | } |
248 | |
4fe9ad57 |
249 | //! Packed properties of light source |
250 | class OpenGl_ShaderLightParameters |
251 | { |
252 | public: |
253 | |
254 | OpenGl_Vec4 Color; |
255 | OpenGl_Vec4 Position; |
256 | OpenGl_Vec4 Direction; |
257 | OpenGl_Vec4 Parameters; |
258 | |
259 | //! Returns packed (serialized) representation of light source properties |
0adbd30f |
260 | const OpenGl_Vec4* Packed() const { return reinterpret_cast<const OpenGl_Vec4*> (this); } |
01eaf654 |
261 | static Standard_Integer NbOfVec4() { return 4; } |
4fe9ad57 |
262 | |
263 | }; |
264 | |
265 | //! Packed light source type information |
266 | class OpenGl_ShaderLightType |
267 | { |
268 | public: |
269 | |
270 | Standard_Integer Type; |
271 | Standard_Integer IsHeadlight; |
272 | |
273 | //! Returns packed (serialized) representation of light source type |
0adbd30f |
274 | const OpenGl_Vec2i* Packed() const { return reinterpret_cast<const OpenGl_Vec2i*> (this); } |
01eaf654 |
275 | static Standard_Integer NbOfVec2i() { return 1; } |
4fe9ad57 |
276 | |
277 | }; |
278 | |
30f0ad28 |
279 | // ======================================================================= |
280 | // function : PushLightSourceState |
281 | // purpose : Pushes state of OCCT light sources to the program |
282 | // ======================================================================= |
283 | void OpenGl_ShaderManager::PushLightSourceState (const Handle(OpenGl_ShaderProgram)& theProgram) const |
284 | { |
12381341 |
285 | if (myLightSourceState.Index() == theProgram->ActiveState (OpenGl_LIGHT_SOURCES_STATE) |
286 | || !theProgram->IsValid()) |
30f0ad28 |
287 | { |
288 | return; |
289 | } |
30f0ad28 |
290 | |
01eaf654 |
291 | OpenGl_ShaderLightType* aLightTypeArray = new OpenGl_ShaderLightType[OpenGLMaxLights]; |
292 | for (Standard_Integer aLightIt = 0; aLightIt < OpenGLMaxLights; ++aLightIt) |
293 | { |
294 | aLightTypeArray[aLightIt].Type = -1; |
295 | } |
296 | |
12381341 |
297 | const Standard_Integer aLightsDefNb = Min (myLightSourceState.LightSources()->Size(), OpenGLMaxLights); |
298 | if (aLightsDefNb < 1) |
299 | { |
30f0ad28 |
300 | theProgram->SetUniform (myContext, |
12381341 |
301 | theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_COUNT), |
302 | 0); |
30f0ad28 |
303 | theProgram->SetUniform (myContext, |
12381341 |
304 | theProgram->GetStateLocation (OpenGl_OCC_LIGHT_AMBIENT), |
305 | OpenGl_Vec4 (0.0f, 0.0f, 0.0f, 0.0f)); |
01eaf654 |
306 | theProgram->SetUniform (myContext, |
307 | theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_TYPES), |
308 | OpenGLMaxLights * OpenGl_ShaderLightType::NbOfVec2i(), |
309 | aLightTypeArray[0].Packed()); |
12381341 |
310 | theProgram->UpdateState (OpenGl_LIGHT_SOURCES_STATE, myLightSourceState.Index()); |
0c4033b4 |
311 | delete[] aLightTypeArray; |
12381341 |
312 | return; |
313 | } |
30f0ad28 |
314 | |
4fe9ad57 |
315 | OpenGl_ShaderLightParameters* aLightParamsArray = new OpenGl_ShaderLightParameters[aLightsDefNb]; |
30f0ad28 |
316 | |
12381341 |
317 | OpenGl_Vec4 anAmbient (0.0f, 0.0f, 0.0f, 0.0f); |
318 | Standard_Integer aLightsNb = 0; |
319 | for (OpenGl_ListOfLight::Iterator anIter (*myLightSourceState.LightSources()); anIter.More(); anIter.Next()) |
320 | { |
321 | const OpenGl_Light& aLight = anIter.Value(); |
322 | if (aLight.Type == Visual3d_TOLS_AMBIENT) |
30f0ad28 |
323 | { |
12381341 |
324 | anAmbient += aLight.Color; |
325 | continue; |
326 | } |
327 | else if (aLightsNb >= OpenGLMaxLights) |
328 | { |
329 | continue; |
330 | } |
30f0ad28 |
331 | |
4fe9ad57 |
332 | OpenGl_ShaderLightType& aLightType = aLightTypeArray[aLightsNb]; |
333 | aLightType.Type = aLight.Type; |
334 | aLightType.IsHeadlight = aLight.IsHeadlight; |
30f0ad28 |
335 | |
4fe9ad57 |
336 | OpenGl_ShaderLightParameters& aLightParams = aLightParamsArray[aLightsNb]; |
337 | aLightParams.Color = aLight.Color; |
338 | aLightParams.Position = aLight.Type == Visual3d_TOLS_DIRECTIONAL |
339 | ? -aLight.Direction |
340 | : aLight.Position; |
12381341 |
341 | if (aLight.Type == Visual3d_TOLS_SPOT) |
342 | { |
4fe9ad57 |
343 | aLightParams.Direction = aLight.Direction; |
30f0ad28 |
344 | } |
4fe9ad57 |
345 | aLightParams.Parameters = aLight.Params; |
12381341 |
346 | ++aLightsNb; |
347 | } |
30f0ad28 |
348 | |
12381341 |
349 | theProgram->SetUniform (myContext, |
350 | theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_COUNT), |
351 | aLightsNb); |
352 | theProgram->SetUniform (myContext, |
353 | theProgram->GetStateLocation (OpenGl_OCC_LIGHT_AMBIENT), |
354 | anAmbient); |
01eaf654 |
355 | theProgram->SetUniform (myContext, |
356 | theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_TYPES), |
357 | OpenGLMaxLights * OpenGl_ShaderLightType::NbOfVec2i(), |
358 | aLightTypeArray[0].Packed()); |
12381341 |
359 | if (aLightsNb > 0) |
360 | { |
4fe9ad57 |
361 | theProgram->SetUniform (myContext, |
362 | theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_PARAMS), |
363 | aLightsNb * OpenGl_ShaderLightParameters::NbOfVec4(), |
364 | aLightParamsArray[0].Packed()); |
30f0ad28 |
365 | } |
4fe9ad57 |
366 | delete[] aLightParamsArray; |
367 | delete[] aLightTypeArray; |
30f0ad28 |
368 | |
369 | theProgram->UpdateState (OpenGl_LIGHT_SOURCES_STATE, myLightSourceState.Index()); |
370 | } |
371 | |
372 | // ======================================================================= |
373 | // function : PushProjectionState |
374 | // purpose : Pushes state of OCCT projection transform to the program |
375 | // ======================================================================= |
376 | void OpenGl_ShaderManager::PushProjectionState (const Handle(OpenGl_ShaderProgram)& theProgram) const |
377 | { |
378 | if (myProjectionState.Index() == theProgram->ActiveState (OpenGl_PROJECTION_STATE)) |
379 | { |
380 | return; |
381 | } |
382 | |
383 | theProgram->SetUniform (myContext, |
384 | theProgram->GetStateLocation (OpenGl_OCC_PROJECTION_MATRIX), |
385 | myProjectionState.ProjectionMatrix()); |
386 | |
387 | GLint aLocation = theProgram->GetStateLocation (OpenGl_OCC_PROJECTION_MATRIX_INVERSE); |
388 | if (aLocation != OpenGl_ShaderProgram::INVALID_LOCATION) |
389 | { |
390 | theProgram->SetUniform (myContext, aLocation, myProjectionState.ProjectionMatrixInverse()); |
391 | } |
392 | |
393 | theProgram->SetUniform (myContext, |
394 | theProgram->GetStateLocation (OpenGl_OCC_PROJECTION_MATRIX_TRANSPOSE), |
395 | myProjectionState.ProjectionMatrix(), true); |
396 | |
397 | aLocation = theProgram->GetStateLocation (OpenGl_OCC_PROJECTION_MATRIX_INVERSE_TRANSPOSE); |
398 | if (aLocation != OpenGl_ShaderProgram::INVALID_LOCATION) |
399 | { |
400 | theProgram->SetUniform (myContext, aLocation, myProjectionState.ProjectionMatrixInverse(), true); |
401 | } |
402 | |
403 | theProgram->UpdateState (OpenGl_PROJECTION_STATE, myProjectionState.Index()); |
404 | } |
405 | |
406 | // ======================================================================= |
407 | // function : PushModelWorldState |
408 | // purpose : Pushes state of OCCT model-world transform to the program |
409 | // ======================================================================= |
410 | void OpenGl_ShaderManager::PushModelWorldState (const Handle(OpenGl_ShaderProgram)& theProgram) const |
411 | { |
412 | if (myModelWorldState.Index() == theProgram->ActiveState (OpenGl_MODEL_WORLD_STATE)) |
413 | { |
414 | return; |
415 | } |
416 | |
417 | theProgram->SetUniform (myContext, |
418 | theProgram->GetStateLocation (OpenGl_OCC_MODEL_WORLD_MATRIX), |
419 | myModelWorldState.ModelWorldMatrix()); |
420 | |
421 | GLint aLocation = theProgram->GetStateLocation (OpenGl_OCC_MODEL_WORLD_MATRIX_INVERSE); |
422 | if (aLocation != OpenGl_ShaderProgram::INVALID_LOCATION) |
423 | { |
424 | theProgram->SetUniform (myContext, aLocation, myModelWorldState.ModelWorldMatrixInverse()); |
425 | } |
426 | |
427 | theProgram->SetUniform (myContext, |
428 | theProgram->GetStateLocation (OpenGl_OCC_MODEL_WORLD_MATRIX_TRANSPOSE), |
429 | myModelWorldState.ModelWorldMatrix(), true); |
430 | |
431 | aLocation = theProgram->GetStateLocation (OpenGl_OCC_MODEL_WORLD_MATRIX_INVERSE_TRANSPOSE); |
432 | if (aLocation != OpenGl_ShaderProgram::INVALID_LOCATION) |
433 | { |
434 | theProgram->SetUniform (myContext, aLocation, myModelWorldState.ModelWorldMatrixInverse(), true); |
435 | } |
436 | |
437 | theProgram->UpdateState (OpenGl_MODEL_WORLD_STATE, myModelWorldState.Index()); |
438 | } |
439 | |
440 | // ======================================================================= |
441 | // function : PushWorldViewState |
442 | // purpose : Pushes state of OCCT world-view transform to the program |
443 | // ======================================================================= |
444 | void OpenGl_ShaderManager::PushWorldViewState (const Handle(OpenGl_ShaderProgram)& theProgram) const |
445 | { |
446 | if (myWorldViewState.Index() == theProgram->ActiveState (OpenGl_WORLD_VIEW_STATE)) |
447 | { |
448 | return; |
449 | } |
450 | |
451 | theProgram->SetUniform (myContext, |
452 | theProgram->GetStateLocation (OpenGl_OCC_WORLD_VIEW_MATRIX), |
453 | myWorldViewState.WorldViewMatrix()); |
454 | |
455 | GLint aLocation = theProgram->GetStateLocation (OpenGl_OCC_WORLD_VIEW_MATRIX_INVERSE); |
456 | if (aLocation != OpenGl_ShaderProgram::INVALID_LOCATION) |
457 | { |
458 | theProgram->SetUniform (myContext, aLocation, myWorldViewState.WorldViewMatrixInverse()); |
459 | } |
460 | |
461 | theProgram->SetUniform (myContext, |
462 | theProgram->GetStateLocation (OpenGl_OCC_WORLD_VIEW_MATRIX_TRANSPOSE), |
463 | myWorldViewState.WorldViewMatrix(), true); |
464 | |
465 | aLocation = theProgram->GetStateLocation (OpenGl_OCC_WORLD_VIEW_MATRIX_INVERSE_TRANSPOSE); |
466 | if (aLocation != OpenGl_ShaderProgram::INVALID_LOCATION) |
467 | { |
468 | theProgram->SetUniform (myContext, aLocation, myWorldViewState.WorldViewMatrixInverse(), true); |
469 | } |
470 | |
471 | theProgram->UpdateState (OpenGl_WORLD_VIEW_STATE, myWorldViewState.Index()); |
472 | } |
473 | |
474 | // ======================================================================= |
475 | // function : UpdateClippingState |
476 | // purpose : Updates state of OCCT clipping planes |
477 | // ======================================================================= |
478 | void OpenGl_ShaderManager::UpdateClippingState() |
479 | { |
480 | myClippingState.Update(); |
481 | } |
482 | |
483 | // ======================================================================= |
484 | // function : RevertClippingState |
485 | // purpose : Reverts state of OCCT clipping planes |
486 | // ======================================================================= |
487 | void OpenGl_ShaderManager::RevertClippingState() |
488 | { |
489 | myClippingState.Revert(); |
490 | } |
491 | |
492 | // ======================================================================= |
493 | // function : PushClippingState |
494 | // purpose : Pushes state of OCCT clipping planes to the program |
495 | // ======================================================================= |
496 | void OpenGl_ShaderManager::PushClippingState (const Handle(OpenGl_ShaderProgram)& theProgram) const |
497 | { |
498 | if (myClippingState.Index() == theProgram->ActiveState (OpenGl_CLIP_PLANES_STATE)) |
499 | { |
500 | return; |
501 | } |
502 | |
12381341 |
503 | theProgram->UpdateState (OpenGl_CLIP_PLANES_STATE, myClippingState.Index()); |
504 | const GLint aLocEquations = theProgram->GetStateLocation (OpenGl_OCC_CLIP_PLANE_EQUATIONS); |
505 | const GLint aLocSpaces = theProgram->GetStateLocation (OpenGl_OCC_CLIP_PLANE_SPACES); |
506 | if (aLocEquations == OpenGl_ShaderProgram::INVALID_LOCATION |
507 | && aLocSpaces == OpenGl_ShaderProgram::INVALID_LOCATION) |
508 | { |
509 | return; |
510 | } |
511 | |
5495fa7e |
512 | GLint aPlanesNb = 0; |
51b10cd4 |
513 | for (Graphic3d_SequenceOfHClipPlane::Iterator anIter (myContext->Clipping().Planes()); |
12381341 |
514 | anIter.More(); anIter.Next()) |
30f0ad28 |
515 | { |
516 | const Handle(Graphic3d_ClipPlane)& aPlane = anIter.Value(); |
517 | if (!myContext->Clipping().IsEnabled (aPlane)) |
518 | { |
519 | continue; |
520 | } |
521 | |
12381341 |
522 | ++aPlanesNb; |
523 | } |
524 | if (aPlanesNb < 1) |
525 | { |
526 | return; |
527 | } |
528 | |
5495fa7e |
529 | const Standard_Size MAX_CLIP_PLANES = 8; |
530 | OpenGl_Vec4* anEquations = new OpenGl_Vec4[MAX_CLIP_PLANES]; |
531 | GLint* aSpaces = new GLint [MAX_CLIP_PLANES]; |
12381341 |
532 | GLuint aPlaneId = 0; |
51b10cd4 |
533 | for (Graphic3d_SequenceOfHClipPlane::Iterator anIter (myContext->Clipping().Planes()); |
12381341 |
534 | anIter.More(); anIter.Next()) |
535 | { |
536 | const Handle(Graphic3d_ClipPlane)& aPlane = anIter.Value(); |
537 | if (!myContext->Clipping().IsEnabled (aPlane)) |
30f0ad28 |
538 | { |
12381341 |
539 | continue; |
30f0ad28 |
540 | } |
541 | |
12381341 |
542 | const Graphic3d_ClipPlane::Equation& anEquation = aPlane->GetEquation(); |
543 | anEquations[aPlaneId] = OpenGl_Vec4 ((float) anEquation.x(), |
544 | (float) anEquation.y(), |
545 | (float) anEquation.z(), |
546 | (float) anEquation.w()); |
547 | aSpaces[aPlaneId] = myContext->Clipping().GetEquationSpace (aPlane); |
548 | ++aPlaneId; |
30f0ad28 |
549 | } |
5495fa7e |
550 | |
551 | theProgram->SetUniform (myContext, |
552 | theProgram->GetStateLocation (OpenGl_OCC_CLIP_PLANE_COUNT), |
553 | aPlanesNb); |
554 | theProgram->SetUniform (myContext, aLocEquations, MAX_CLIP_PLANES, anEquations); |
555 | theProgram->SetUniform (myContext, aLocSpaces, MAX_CLIP_PLANES, aSpaces); |
4fe9ad57 |
556 | |
12381341 |
557 | delete[] anEquations; |
558 | delete[] aSpaces; |
30f0ad28 |
559 | } |
560 | |
561 | // ======================================================================= |
562 | // function : UpdateMaterialStateTo |
563 | // purpose : Updates state of OCCT material for specified program |
564 | // ======================================================================= |
565 | void OpenGl_ShaderManager::UpdateMaterialStateTo (const Handle(OpenGl_ShaderProgram)& theProgram, |
566 | const OpenGl_Element* theAspect) |
567 | { |
568 | if (myMaterialStates.IsBound (theProgram)) |
569 | { |
570 | myMaterialStates.ChangeFind (theProgram).Set (theAspect); |
571 | } |
572 | else |
573 | { |
574 | myMaterialStates.Bind (theProgram, OpenGl_MaterialState (theAspect)); |
575 | } |
576 | |
577 | myMaterialStates.ChangeFind (theProgram).Update(); |
578 | } |
579 | |
580 | // ======================================================================= |
581 | // function : ResetMaterialStates |
582 | // purpose : Resets state of OCCT material for all programs |
583 | // ======================================================================= |
584 | void OpenGl_ShaderManager::ResetMaterialStates() |
585 | { |
586 | for (OpenGl_ShaderProgramList::Iterator anIt (myProgramList); anIt.More(); anIt.Next()) |
587 | { |
588 | anIt.Value()->UpdateState (OpenGl_MATERIALS_STATE, 0); |
589 | } |
590 | } |
591 | |
592 | // ======================================================================= |
593 | // function : MaterialState |
594 | // purpose : Returns state of OCCT material for specified program |
595 | // ======================================================================= |
596 | const OpenGl_MaterialState* OpenGl_ShaderManager::MaterialState (const Handle(OpenGl_ShaderProgram)& theProgram) const |
597 | { |
598 | if (!myMaterialStates.IsBound (theProgram)) |
599 | return NULL; |
600 | |
601 | return &myMaterialStates.Find (theProgram); |
602 | } |
603 | |
604 | namespace |
605 | { |
606 | |
607 | static const OpenGl_Vec4 THE_COLOR_BLACK_VEC4 (0.0f, 0.0f, 0.0f, 0.0f); |
608 | |
609 | // ======================================================================= |
610 | // function : PushAspectFace |
611 | // purpose : |
612 | // ======================================================================= |
613 | static void PushAspectFace (const Handle(OpenGl_Context)& theCtx, |
614 | const Handle(OpenGl_ShaderProgram)& theProgram, |
615 | const OpenGl_AspectFace* theAspect) |
616 | { |
617 | theProgram->SetUniform (theCtx, |
618 | theProgram->GetStateLocation (OpenGl_OCCT_TEXTURE_ENABLE), |
619 | theAspect->DoTextureMap()); |
30f0ad28 |
620 | theProgram->SetUniform (theCtx, |
621 | theProgram->GetStateLocation (OpenGl_OCCT_ACTIVE_SAMPLER), |
622 | 0 /* GL_TEXTURE0 */); |
30f0ad28 |
623 | theProgram->SetUniform (theCtx, |
624 | theProgram->GetStateLocation (OpenGl_OCCT_DISTINGUISH_MODE), |
625 | theAspect->DistinguishingMode()); |
626 | |
0adbd30f |
627 | OpenGl_Material aParams; |
12381341 |
628 | for (Standard_Integer anIndex = 0; anIndex < 2; ++anIndex) |
30f0ad28 |
629 | { |
12381341 |
630 | const GLint aLoc = theProgram->GetStateLocation (anIndex == 0 |
631 | ? OpenGl_OCCT_FRONT_MATERIAL |
632 | : OpenGl_OCCT_BACK_MATERIAL); |
633 | if (aLoc == OpenGl_ShaderProgram::INVALID_LOCATION) |
30f0ad28 |
634 | { |
12381341 |
635 | continue; |
30f0ad28 |
636 | } |
30f0ad28 |
637 | |
0adbd30f |
638 | aParams.Init (anIndex == 0 ? theAspect->IntFront() : theAspect->IntBack()); |
639 | theProgram->SetUniform (theCtx, aLoc, OpenGl_Material::NbOfVec4(), |
640 | aParams.Packed()); |
30f0ad28 |
641 | } |
642 | } |
643 | |
644 | // ======================================================================= |
645 | // function : PushAspectLine |
646 | // purpose : |
647 | // ======================================================================= |
648 | static void PushAspectLine (const Handle(OpenGl_Context)& theCtx, |
649 | const Handle(OpenGl_ShaderProgram)& theProgram, |
650 | const OpenGl_AspectLine* theAspect) |
651 | { |
652 | theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_TEXTURE_ENABLE), TOff); |
653 | theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_DISTINGUISH_MODE), TOff); |
654 | |
655 | const OpenGl_Vec4 aDiffuse (theAspect->Color().rgb[0], |
656 | theAspect->Color().rgb[1], |
657 | theAspect->Color().rgb[2], |
658 | theAspect->Color().rgb[3]); |
12381341 |
659 | OpenGl_Vec4 aParams[5]; |
660 | aParams[0] = THE_COLOR_BLACK_VEC4; |
661 | aParams[1] = THE_COLOR_BLACK_VEC4; |
662 | aParams[2] = aDiffuse; |
663 | aParams[3] = THE_COLOR_BLACK_VEC4; |
664 | aParams[4].x() = 0.0f; // shininess |
665 | aParams[4].y() = 0.0f; // transparency |
4fe9ad57 |
666 | theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL), |
667 | 5, aParams); |
30f0ad28 |
668 | } |
669 | |
670 | // ======================================================================= |
671 | // function : PushAspectText |
672 | // purpose : |
673 | // ======================================================================= |
674 | static void PushAspectText (const Handle(OpenGl_Context)& theCtx, |
675 | const Handle(OpenGl_ShaderProgram)& theProgram, |
676 | const OpenGl_AspectText* theAspect) |
677 | { |
678 | theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_TEXTURE_ENABLE), TOn); |
679 | theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_DISTINGUISH_MODE), TOff); |
680 | theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_ACTIVE_SAMPLER), 0 /* GL_TEXTURE0 */); |
681 | |
682 | OpenGl_Vec4 aDiffuse (theAspect->Color().rgb[0], |
683 | theAspect->Color().rgb[1], |
684 | theAspect->Color().rgb[2], |
685 | theAspect->Color().rgb[3]); |
686 | if (theAspect->DisplayType() == Aspect_TODT_DEKALE |
687 | || theAspect->DisplayType() == Aspect_TODT_SUBTITLE) |
688 | { |
689 | aDiffuse = OpenGl_Vec4 (theAspect->SubtitleColor().rgb[0], |
690 | theAspect->SubtitleColor().rgb[1], |
691 | theAspect->SubtitleColor().rgb[2], |
692 | theAspect->SubtitleColor().rgb[3]); |
693 | } |
694 | |
12381341 |
695 | OpenGl_Vec4 aParams[5]; |
696 | aParams[0] = THE_COLOR_BLACK_VEC4; |
697 | aParams[1] = THE_COLOR_BLACK_VEC4; |
698 | aParams[2] = aDiffuse; |
699 | aParams[3] = THE_COLOR_BLACK_VEC4; |
700 | aParams[4].x() = 0.0f; // shininess |
701 | aParams[4].y() = 0.0f; // transparency |
4fe9ad57 |
702 | theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL), |
703 | 5, aParams); |
30f0ad28 |
704 | } |
705 | |
706 | // ======================================================================= |
707 | // function : PushAspectMarker |
708 | // purpose : |
709 | // ======================================================================= |
710 | static void PushAspectMarker (const Handle(OpenGl_Context)& theCtx, |
711 | const Handle(OpenGl_ShaderProgram)& theProgram, |
712 | const OpenGl_AspectMarker* theAspect) |
713 | { |
714 | theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_TEXTURE_ENABLE), TOn); |
715 | theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_DISTINGUISH_MODE), TOff); |
716 | theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_ACTIVE_SAMPLER), 0 /* GL_TEXTURE0 */); |
717 | |
718 | const OpenGl_Vec4 aDiffuse (theAspect->Color().rgb[0], |
719 | theAspect->Color().rgb[1], |
720 | theAspect->Color().rgb[2], |
721 | theAspect->Color().rgb[3]); |
12381341 |
722 | OpenGl_Vec4 aParams[5]; |
723 | aParams[0] = THE_COLOR_BLACK_VEC4; |
724 | aParams[1] = THE_COLOR_BLACK_VEC4; |
725 | aParams[2] = aDiffuse; |
726 | aParams[3] = THE_COLOR_BLACK_VEC4; |
727 | aParams[4].x() = 0.0f; // shininess |
728 | aParams[4].y() = 0.0f; // transparency |
4fe9ad57 |
729 | theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL), |
730 | 5, aParams); |
30f0ad28 |
731 | } |
732 | |
733 | }; // nameless namespace |
734 | |
735 | // ======================================================================= |
736 | // function : PushMaterialState |
737 | // purpose : Pushes current state of OCCT material to the program |
738 | // ======================================================================= |
739 | void OpenGl_ShaderManager::PushMaterialState (const Handle(OpenGl_ShaderProgram)& theProgram) const |
740 | { |
741 | if (!myMaterialStates.IsBound (theProgram)) |
742 | { |
743 | return; |
744 | } |
745 | |
746 | const OpenGl_MaterialState& aState = myMaterialStates.Find (theProgram); |
747 | if (aState.Index() == theProgram->ActiveState (OpenGl_MATERIALS_STATE)) |
748 | { |
749 | return; |
750 | } |
751 | |
752 | if (typeid (*aState.Aspect()) == typeid (OpenGl_AspectFace)) |
753 | { |
754 | PushAspectFace (myContext, theProgram, dynamic_cast<const OpenGl_AspectFace*> (aState.Aspect())); |
755 | } |
756 | else if (typeid (*aState.Aspect()) == typeid (OpenGl_AspectLine)) |
757 | { |
758 | PushAspectLine (myContext, theProgram, dynamic_cast<const OpenGl_AspectLine*> (aState.Aspect())); |
759 | } |
760 | else if (typeid (*aState.Aspect()) == typeid (OpenGl_AspectText)) |
761 | { |
762 | PushAspectText (myContext, theProgram, dynamic_cast<const OpenGl_AspectText*> (aState.Aspect())); |
763 | } |
764 | else if (typeid (*aState.Aspect()) == typeid (OpenGl_AspectMarker)) |
765 | { |
766 | PushAspectMarker (myContext, theProgram, dynamic_cast<const OpenGl_AspectMarker*> (aState.Aspect())); |
767 | } |
768 | |
769 | theProgram->UpdateState (OpenGl_MATERIALS_STATE, aState.Index()); |
770 | } |
771 | |
772 | // ======================================================================= |
773 | // function : PushWorldViewState |
774 | // purpose : Pushes state of OCCT graphics parameters to the program |
775 | // ======================================================================= |
776 | void OpenGl_ShaderManager::PushState (const Handle(OpenGl_ShaderProgram)& theProgram) const |
777 | { |
778 | PushClippingState (theProgram); |
779 | PushMaterialState (theProgram); |
780 | PushWorldViewState (theProgram); |
781 | PushModelWorldState (theProgram); |
782 | PushProjectionState (theProgram); |
783 | PushLightSourceState (theProgram); |
12381341 |
784 | } |