1 // Created on: 2011-07-13
2 // Created by: Sergey ZERCHANINOV
3 // Copyright (c) 2011-2014 OPEN CASCADE SAS
5 // This file is part of Open CASCADE Technology software library.
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
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.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
16 #include <Aspect_PolygonOffsetMode.hxx>
17 #include <NCollection_Vec3.hxx>
19 #include <OpenGl_AspectFace.hxx>
20 #include <OpenGl_Context.hxx>
21 #include <OpenGl_Sampler.hxx>
22 #include <OpenGl_ShaderManager.hxx>
23 #include <OpenGl_ShaderProgram.hxx>
24 #include <OpenGl_Texture.hxx>
25 #include <OpenGl_Workspace.hxx>
27 #include <Graphic3d_ShaderProgram.hxx>
28 #include <Graphic3d_TextureMap.hxx>
29 #include <Graphic3d_TextureParams.hxx>
30 #include <Graphic3d_TypeOfReflection.hxx>
31 #include <Graphic3d_MaterialAspect.hxx>
33 #include <Image_PixMap.hxx>
37 //! Initialize default material in this way for backward compatibility.
38 inline Graphic3d_MaterialAspect initDefaultMaterial()
40 Graphic3d_MaterialAspect aMat;
41 aMat.SetMaterialType (Graphic3d_MATERIAL_ASPECT);
42 aMat.SetAmbient (0.2f);
43 aMat.SetDiffuse (0.8f);
44 aMat.SetSpecular (0.1f);
45 aMat.SetEmissive (0.0f);
46 aMat.SetAmbientColor (Quantity_NOC_WHITE);
47 aMat.SetDiffuseColor (Quantity_NOC_WHITE);
48 aMat.SetEmissiveColor(Quantity_NOC_WHITE);
49 aMat.SetSpecularColor(Quantity_NOC_WHITE);
50 aMat.SetShininess (10.0f / 128.0f);
51 aMat.SetRefractionIndex (1.0f);
55 static const TCollection_AsciiString THE_EMPTY_KEY;
56 static const Graphic3d_MaterialAspect THE_DEFAULT_MATERIAL = initDefaultMaterial();
59 // =======================================================================
60 // function : OpenGl_AspectFace
62 // =======================================================================
63 OpenGl_AspectFace::OpenGl_AspectFace()
64 : myAspect (new Graphic3d_AspectFillArea3d (Aspect_IS_SOLID, Quantity_NOC_WHITE,
65 Quantity_NOC_WHITE, Aspect_TOL_SOLID, 1.0,
66 THE_DEFAULT_MATERIAL, THE_DEFAULT_MATERIAL)),
67 myShadingModel (Graphic3d_TOSM_UNLIT)
69 myAspect->SetShadingModel (myShadingModel);
70 myAspect->SetHatchStyle (Handle(Graphic3d_HatchStyle)());
73 // =======================================================================
74 // function : OpenGl_AspectFace
76 // =======================================================================
77 OpenGl_AspectFace::OpenGl_AspectFace (const Handle(Graphic3d_AspectFillArea3d)& theAspect)
78 : myShadingModel (Graphic3d_TOSM_DEFAULT)
80 SetAspect (theAspect);
83 // =======================================================================
84 // function : SetAspect
86 // =======================================================================
87 void OpenGl_AspectFace::SetAspect (const Handle(Graphic3d_AspectFillArea3d)& theAspect)
91 const Graphic3d_MaterialAspect& aMat = theAspect->FrontMaterial();
92 myShadingModel = theAspect->ShadingModel() != Graphic3d_TOSM_UNLIT
93 && (aMat.ReflectionMode (Graphic3d_TOR_AMBIENT)
94 || aMat.ReflectionMode (Graphic3d_TOR_DIFFUSE)
95 || aMat.ReflectionMode (Graphic3d_TOR_SPECULAR)
96 || aMat.ReflectionMode (Graphic3d_TOR_EMISSION))
97 ? theAspect->ShadingModel()
98 : Graphic3d_TOSM_UNLIT;
100 myAspectEdge.Aspect()->SetColor (theAspect->EdgeColor());
101 myAspectEdge.Aspect()->SetType (theAspect->EdgeLineType());
102 myAspectEdge.Aspect()->SetWidth (theAspect->EdgeWidth());
104 // update texture binding
105 myResources.UpdateTexturesRediness (myAspect->TextureSet());
107 // update shader program binding
108 const TCollection_AsciiString& aShaderKey = myAspect->ShaderProgram().IsNull() ? THE_EMPTY_KEY : myAspect->ShaderProgram()->GetId();
109 if (aShaderKey.IsEmpty() || myResources.ShaderProgramId != aShaderKey)
111 myResources.ResetShaderReadiness();
115 // =======================================================================
118 // =======================================================================
119 void OpenGl_AspectFace::Render (const Handle(OpenGl_Workspace)& theWorkspace) const
121 theWorkspace->SetAspectFace (this);
124 // =======================================================================
125 // function : Release
127 // =======================================================================
128 void OpenGl_AspectFace::Release (OpenGl_Context* theContext)
130 myResources.ReleaseTextures (theContext);
131 if (!myResources.ShaderProgram.IsNull()
134 theContext->ShaderManager()->Unregister (myResources.ShaderProgramId,
135 myResources.ShaderProgram);
137 myResources.ShaderProgramId.Clear();
138 myResources.ResetShaderReadiness();
141 // =======================================================================
142 // function : ReleaseTextures
144 // =======================================================================
145 void OpenGl_AspectFace::Resources::ReleaseTextures (OpenGl_Context* theCtx)
147 if (myTextures.IsNull())
152 for (OpenGl_TextureSet::Iterator aTextureIter (myTextures); aTextureIter.More(); aTextureIter.Next())
154 Handle(OpenGl_Texture)& aTextureRes = aTextureIter.ChangeValue();
155 if (aTextureRes.IsNull())
162 if (aTextureRes->ResourceId().IsEmpty())
164 theCtx->DelayedRelease (aTextureRes);
168 const TCollection_AsciiString aName = aTextureRes->ResourceId();
169 aTextureRes.Nullify(); // we need nullify all handles before ReleaseResource() call
170 theCtx->ReleaseResource (aName, Standard_True);
173 aTextureRes.Nullify();
175 myIsTextureReady = Standard_False;
178 // =======================================================================
179 // function : UpdateTexturesRediness
181 // =======================================================================
182 void OpenGl_AspectFace::Resources::UpdateTexturesRediness (const Handle(Graphic3d_TextureSet)& theTextures)
184 const Standard_Integer aNbTexturesOld = !myTextures.IsNull() ? myTextures->Size() : 0;
185 const Standard_Integer aNbTexturesNew = !theTextures.IsNull() ? theTextures->Size() : 0;
186 if (aNbTexturesOld != aNbTexturesNew)
188 myIsTextureReady = Standard_False;
191 if (aNbTexturesOld == 0)
196 Graphic3d_TextureSet::Iterator aTextureIter (theTextures);
197 OpenGl_TextureSet::Iterator aResIter (myTextures);
198 for (; aResIter.More(); aResIter.Next(), aTextureIter.Next())
200 const Handle(OpenGl_Texture)& aResource = aResIter.Value();
201 const Handle(Graphic3d_TextureMap)& aTexture = aTextureIter.Value();
202 if (aTexture.IsNull() != aResource.IsNull())
204 myIsTextureReady = Standard_False;
207 else if (aTexture.IsNull())
212 const TCollection_AsciiString& aTextureKey = aTexture->GetId();
213 if (aTextureKey.IsEmpty() || aResource->ResourceId() != aTextureKey)
215 myIsTextureReady = Standard_False;
218 else if (aResource->Revision() != aTexture->Revision())
220 myIsTextureReady = Standard_False;
225 // just invalidate texture parameters
226 aResource->Sampler()->SetParameters (aTexture->GetParams());
231 // =======================================================================
232 // function : BuildTextures
234 // =======================================================================
235 void OpenGl_AspectFace::Resources::BuildTextures (const Handle(OpenGl_Context)& theCtx,
236 const Handle(Graphic3d_TextureSet)& theTextures)
238 // release old texture resources
239 const Standard_Integer aNbTexturesOld = !myTextures.IsNull() ? myTextures->Size() : 0;
240 const Standard_Integer aNbTexturesNew = !theTextures.IsNull() ? theTextures->Size() : 0;
241 if (aNbTexturesOld != aNbTexturesNew)
243 ReleaseTextures (theCtx.get());
244 if (aNbTexturesNew > 0)
246 myTextures = new OpenGl_TextureSet (theTextures->Size());
250 myTextures.Nullify();
253 if (myTextures.IsNull())
258 Graphic3d_TextureSet::Iterator aTextureIter (theTextures);
259 OpenGl_TextureSet::Iterator aResIter (myTextures);
260 for (; aResIter.More(); aResIter.Next(), aTextureIter.Next())
262 Handle(OpenGl_Texture)& aResource = aResIter.ChangeValue();
263 const Handle(Graphic3d_TextureMap)& aTexture = aTextureIter.Value();
264 if (!aResource.IsNull())
266 if (!aTexture.IsNull()
267 && aTexture->GetId() == aResource->ResourceId()
268 && aTexture->Revision() != aResource->Revision())
270 if (Handle(Image_PixMap) anImage = aTexture->GetImage())
272 aResource->Sampler()->SetParameters (aTexture->GetParams());
273 aResource->Init (theCtx, *anImage.operator->(), aTexture->Type());
274 aResource->SetRevision (aTexture->Revision());
279 if (aResource->ResourceId().IsEmpty())
281 theCtx->DelayedRelease (aResource);
286 const TCollection_AsciiString aTextureKey = aResource->ResourceId();
287 aResource.Nullify(); // we need nullify all handles before ReleaseResource() call
288 theCtx->ReleaseResource (aTextureKey, Standard_True);
292 if (!aTexture.IsNull())
294 const TCollection_AsciiString& aTextureKeyNew = aTexture->GetId();
295 if (aTextureKeyNew.IsEmpty()
296 || !theCtx->GetResource<Handle(OpenGl_Texture)> (aTextureKeyNew, aResource))
298 aResource = new OpenGl_Texture (aTextureKeyNew, aTexture->GetParams());
299 if (Handle(Image_PixMap) anImage = aTexture->GetImage())
301 aResource->Init (theCtx, *anImage.operator->(), aTexture->Type());
302 aResource->SetRevision (aTexture->Revision());
304 if (!aTextureKeyNew.IsEmpty())
306 theCtx->ShareResource (aTextureKeyNew, aResource);
311 aResource->Sampler()->SetParameters (aTexture->GetParams());
317 // =======================================================================
318 // function : BuildShader
320 // =======================================================================
321 void OpenGl_AspectFace::Resources::BuildShader (const Handle(OpenGl_Context)& theCtx,
322 const Handle(Graphic3d_ShaderProgram)& theShader)
324 if (theCtx->core20fwd == NULL)
329 // release old shader program resources
330 if (!ShaderProgram.IsNull())
332 theCtx->ShaderManager()->Unregister (ShaderProgramId, ShaderProgram);
333 ShaderProgramId.Clear();
334 ShaderProgram.Nullify();
336 if (theShader.IsNull())
341 theCtx->ShaderManager()->Create (theShader, ShaderProgramId, ShaderProgram);