1 // Created on: 2011-07-13
2 // Created by: Sergey ZERCHANINOV
3 // Copyright (c) 2011-2012 OPEN CASCADE SAS
5 // The content of this file is subject to the Open CASCADE Technology Public
6 // License Version 6.5 (the "License"). You may not use the content of this file
7 // except in compliance with the License. Please obtain a copy of the License
8 // at http://www.opencascade.org and read it completely before using this file.
10 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
11 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13 // The Original Code and all software distributed under the License is
14 // distributed on an "AS IS" basis, without warranty of any kind, and the
15 // Initial Developer hereby disclaims all such warranties, including without
16 // limitation, any warranties of merchantability, fitness for a particular
17 // purpose or non-infringement. Please see the License for the specific terms
18 // and conditions governing the rights and limitations under the License.
20 #include <OpenGl_AspectFace.hxx>
21 #include <OpenGl_Texture.hxx>
22 #include <OpenGl_Workspace.hxx>
23 #include <OpenGl_Context.hxx>
25 #include <Aspect_PolygonOffsetMode.hxx>
26 #include <Graphic3d_CGroup.hxx>
27 #include <Graphic3d_TextureMap.hxx>
28 #include <Graphic3d_TypeOfReflection.hxx>
29 #include <Graphic3d_MaterialAspect.hxx>
31 #include <NCollection_Vec3.hxx>
36 static OPENGL_SURF_PROP THE_DEFAULT_MATERIAL =
38 0.2F, 0.8F, 0.1F, 0.0F, // amb, diff, spec, emsv
39 1.0F, 10.0F, 0.0F, // trans, shine, env_reflexion
41 (OPENGL_AMBIENT_MASK | OPENGL_DIFFUSE_MASK | OPENGL_SPECULAR_MASK), // color_mask
42 {{ 1.0F, 1.0F, 1.0F, 1.0F }}, // ambient color
43 {{ 1.0F, 1.0F, 1.0F, 1.0F }}, // diffuse color
44 {{ 1.0F, 1.0F, 1.0F, 1.0F }}, // specular color
45 {{ 1.0F, 1.0F, 1.0F, 1.0F }}, // emissive color
46 {{ 1.0F, 1.0F, 1.0F, 1.0F }} // material color
49 static TEL_POFFSET_PARAM THE_DEFAULT_POFFSET = { Aspect_POM_Fill, 1.0F, 0.0F };
53 // =======================================================================
54 // function : convertMaterial
56 // =======================================================================
57 void OpenGl_AspectFace::convertMaterial (const CALL_DEF_MATERIAL& theMat,
58 OPENGL_SURF_PROP& theSurf)
60 theSurf.amb = theMat.IsAmbient ? theMat.Ambient : 0.0f;
61 theSurf.diff = theMat.IsDiffuse ? theMat.Diffuse : 0.0f;
62 theSurf.spec = theMat.IsSpecular ? theMat.Specular : 0.0f;
63 theSurf.emsv = theMat.IsEmission ? theMat.Emission : 0.0f;
65 theSurf.isphysic = theMat.IsPhysic ? 1 : 0; // type of material
68 theSurf.color_mask = 0;
71 theSurf.color_mask |= OPENGL_AMBIENT_MASK;
75 theSurf.color_mask |= OPENGL_DIFFUSE_MASK;
77 if (theMat.IsSpecular)
79 theSurf.color_mask |= OPENGL_SPECULAR_MASK;
81 if (theMat.IsEmission)
83 theSurf.color_mask |= OPENGL_EMISSIVE_MASK;
87 theSurf.ambcol.rgb[0] = theMat.ColorAmb.r;
88 theSurf.ambcol.rgb[1] = theMat.ColorAmb.g;
89 theSurf.ambcol.rgb[2] = theMat.ColorAmb.b;
90 theSurf.ambcol.rgb[3] = 1.0f;
93 theSurf.difcol.rgb[0] = theMat.ColorDif.r;
94 theSurf.difcol.rgb[1] = theMat.ColorDif.g;
95 theSurf.difcol.rgb[2] = theMat.ColorDif.b;
96 theSurf.difcol.rgb[3] = 1.0f;
99 theSurf.speccol.rgb[0] = theMat.ColorSpec.r;
100 theSurf.speccol.rgb[1] = theMat.ColorSpec.g;
101 theSurf.speccol.rgb[2] = theMat.ColorSpec.b;
102 theSurf.speccol.rgb[3] = 1.0f;
105 theSurf.emscol.rgb[0] = theMat.ColorEms.r;
106 theSurf.emscol.rgb[1] = theMat.ColorEms.g;
107 theSurf.emscol.rgb[2] = theMat.ColorEms.b;
108 theSurf.emscol.rgb[3] = 1.0f;
110 theSurf.shine = 128.0f * float(theMat.Shininess);
111 theSurf.env_reflexion = theMat.EnvReflexion;
113 // trans = 0. => opaque
114 // trans = 1. => transparent
115 // in OpenGl it is opposite.
116 theSurf.trans = 1.0f - theMat.Transparency;
119 // =======================================================================
120 // function : OpenGl_AspectFace
122 // =======================================================================
123 OpenGl_AspectFace::OpenGl_AspectFace()
124 : InteriorStyle (Aspect_IS_SOLID),
125 Edge (Aspect_IS_SOLID),
127 DistinguishingMode (TEL_HS_SOLID),
128 CullingMode (TelCullNone),
131 IntFront = THE_DEFAULT_MATERIAL;
132 IntBack = THE_DEFAULT_MATERIAL;
133 PolygonOffset = THE_DEFAULT_POFFSET;
136 // =======================================================================
139 // =======================================================================
140 void OpenGl_AspectFace::Init (const Handle(OpenGl_Context)& theContext,
141 const CALL_DEF_CONTEXTFILLAREA& theAspect)
143 InteriorStyle = (Aspect_InteriorStyle )theAspect.Style;
144 Edge = theAspect.Edge ? TOn : TOff;
146 //TelInteriorStyleIndex
147 switch (theAspect.Hatch)
149 case 0: /* Aspect_HS_HORIZONTAL */
150 Hatch = TEL_HS_HORIZONTAL;
152 case 1: /* Aspect_HS_HORIZONTAL_WIDE */
153 Hatch = TEL_HS_HORIZONTAL_SPARSE;
155 case 2: /* Aspect_HS_VERTICAL */
156 Hatch = TEL_HS_VERTICAL;
158 case 3: /* Aspect_HS_VERTICAL_WIDE */
159 Hatch = TEL_HS_VERTICAL_SPARSE;
161 case 4: /* Aspect_HS_DIAGONAL_45 */
162 Hatch = TEL_HS_DIAG_45;
164 case 5: /* Aspect_HS_DIAGONAL_45_WIDE */
165 Hatch = TEL_HS_DIAG_45_SPARSE;
167 case 6: /* Aspect_HS_DIAGONAL_135 */
168 Hatch = TEL_HS_DIAG_135;
170 case 7: /* Aspect_HS_DIAGONAL_135_WIDE */
171 Hatch = TEL_HS_DIAG_135_SPARSE;
173 case 8: /* Aspect_HS_GRID */
176 case 9: /* Aspect_HS_GRID_WIDE */
177 Hatch = TEL_HS_GRID_SPARSE;
179 case 10: /* Aspect_HS_GRID_DIAGONAL */
180 Hatch = TEL_HS_CROSS;
182 case 11: /* Aspect_HS_GRID_DIAGONAL_WIDE */
183 Hatch = TEL_HS_CROSS_SPARSE;
190 DistinguishingMode = theAspect.Distinguish ? TOn : TOff;
191 CullingMode = theAspect.BackFace ? TelCullBack : TelCullNone;
193 convertMaterial (theAspect.Front, IntFront);
194 convertMaterial (theAspect.Back, IntBack);
197 IntFront.matcol.rgb[0] = (float )theAspect.IntColor.r;
198 IntFront.matcol.rgb[1] = (float )theAspect.IntColor.g;
199 IntFront.matcol.rgb[2] = (float )theAspect.IntColor.b;
200 IntFront.matcol.rgb[3] = 1.0f;
202 //TelBackInteriorColour
203 IntBack.matcol.rgb[0] = (float )theAspect.BackIntColor.r;
204 IntBack.matcol.rgb[1] = (float )theAspect.BackIntColor.g;
205 IntBack.matcol.rgb[2] = (float )theAspect.BackIntColor.b;
206 IntBack.matcol.rgb[3] = 1.0f;
209 doTextureMap = theAspect.Texture.doTextureMap;
210 const Handle(Graphic3d_TextureMap)& aNewTexture = theAspect.Texture.TextureMap;
211 TCollection_AsciiString aNewKey = aNewTexture.IsNull() ? TCollection_AsciiString() : aNewTexture->GetId();
212 TextureParams = aNewTexture.IsNull() ? NULL : aNewTexture->GetParams();
213 if (aNewKey.IsEmpty()
214 || myTextureId != aNewKey)
216 if (!TextureRes.IsNull())
218 if (myTextureId.IsEmpty())
220 theContext->DelayedRelease (TextureRes);
221 TextureRes.Nullify();
225 TextureRes.Nullify(); // we need nullify all handles before ReleaseResource() call
226 theContext->ReleaseResource (myTextureId);
229 myTextureId = aNewKey;
231 if (!aNewTexture.IsNull())
233 if (aNewKey.IsEmpty() || !theContext->GetResource<Handle(OpenGl_Texture)> (aNewKey, TextureRes))
235 TextureRes = new OpenGl_Texture (TextureParams);
236 Handle(Image_PixMap) anImage = aNewTexture->GetImage();
237 if (!anImage.IsNull())
239 TextureRes->Init (theContext, *anImage.operator->(), aNewTexture->Type());
241 if (!aNewKey.IsEmpty())
243 theContext->ShareResource (aNewKey, TextureRes);
250 PolygonOffset.mode = (Aspect_PolygonOffsetMode )theAspect.PolygonOffsetMode;
251 PolygonOffset.factor = theAspect.PolygonOffsetFactor;
252 PolygonOffset.units = theAspect.PolygonOffsetUnits;
254 CALL_DEF_CONTEXTLINE anEdgeContext;
255 anEdgeContext.Color.r = (float )theAspect.EdgeColor.r;
256 anEdgeContext.Color.g = (float )theAspect.EdgeColor.g;
257 anEdgeContext.Color.b = (float )theAspect.EdgeColor.b;
258 anEdgeContext.LineType = (Aspect_TypeOfLine )theAspect.LineType;
259 anEdgeContext.Width = (float )theAspect.Width;
260 myAspectEdge.SetContext (anEdgeContext);
263 // =======================================================================
266 // =======================================================================
267 void OpenGl_AspectFace::Init (const Handle(OpenGl_Context)& theContext,
268 const Handle(Graphic3d_AspectFillArea3d)& theAspect)
270 CALL_DEF_CONTEXTFILLAREA aCAspect;
271 Standard_Real aWidth;
272 Quantity_Color aBackIntColor;
273 Quantity_Color aEdgeColor;
274 Aspect_TypeOfLine aLType;
275 Quantity_Color aIntColor;
276 Aspect_InteriorStyle aIntStyle;
277 NCollection_Vec3<Standard_Real> aColor;
279 theAspect->Values (aIntStyle, aIntColor, aBackIntColor, aEdgeColor, aLType, aWidth);
280 aIntColor.Values (aColor.r(), aColor.g(), aColor.b(), Quantity_TOC_RGB);
282 aCAspect.Style = int (aIntStyle);
283 aCAspect.IntColor.r = float (aColor.r());
284 aCAspect.IntColor.g = float (aColor.g());
285 aCAspect.IntColor.b = float (aColor.b());
287 if (theAspect->Distinguish())
289 aBackIntColor.Values (aColor.r(), aColor.g(), aColor.b(), Quantity_TOC_RGB);
292 aCAspect.BackIntColor.r = float (aColor.r());
293 aCAspect.BackIntColor.g = float (aColor.g());
294 aCAspect.BackIntColor.b = float (aColor.b());
296 aCAspect.Edge = theAspect->Edge () ? 1:0;
297 aEdgeColor.Values (aColor.r(), aColor.g(), aColor.b(), Quantity_TOC_RGB);
299 aCAspect.EdgeColor.r = float (aColor.r());
300 aCAspect.EdgeColor.g = float (aColor.g());
301 aCAspect.EdgeColor.b = float (aColor.b());
302 aCAspect.LineType = int (aLType);
303 aCAspect.Width = float (aWidth);
304 aCAspect.Hatch = int (theAspect->HatchStyle ());
306 aCAspect.Distinguish = theAspect->Distinguish () ? 1:0;
307 aCAspect.BackFace = theAspect->BackFace () ? 1:0;
309 aCAspect.Back.Shininess = float ((theAspect->BackMaterial ()).Shininess ());
310 aCAspect.Back.Ambient = float ((theAspect->BackMaterial ()).Ambient ());
311 aCAspect.Back.Diffuse = float ((theAspect->BackMaterial ()).Diffuse ());
312 aCAspect.Back.Specular = float ((theAspect->BackMaterial ()).Specular ());
313 aCAspect.Back.Transparency = float ((theAspect->BackMaterial ()).Transparency ());
314 aCAspect.Back.Emission = float ((theAspect->BackMaterial ()).Emissive ());
317 aCAspect.Back.IsAmbient = ((theAspect->BackMaterial ()).ReflectionMode (Graphic3d_TOR_AMBIENT) ? 1 : 0 );
318 aCAspect.Back.IsDiffuse = ((theAspect->BackMaterial ()).ReflectionMode (Graphic3d_TOR_DIFFUSE) ? 1 : 0 );
319 aCAspect.Back.IsSpecular = ((theAspect->BackMaterial ()).ReflectionMode (Graphic3d_TOR_SPECULAR) ? 1 : 0 );
320 aCAspect.Back.IsEmission = ((theAspect->BackMaterial ()).ReflectionMode (Graphic3d_TOR_EMISSION) ? 1 : 0 );
323 const Graphic3d_MaterialAspect aBackMat = theAspect->BackMaterial ();
324 Standard_Boolean isBackPhys = aBackMat.MaterialType (Graphic3d_MATERIAL_PHYSIC);
325 aCAspect.Back.IsPhysic = (isBackPhys ? 1 : 0 );
328 aCAspect.Back.ColorSpec.r = float (((theAspect->BackMaterial ()).SpecularColor ()).Red ());
329 aCAspect.Back.ColorSpec.g = float (((theAspect->BackMaterial ()).SpecularColor ()).Green ());
330 aCAspect.Back.ColorSpec.b = float (((theAspect->BackMaterial ()).SpecularColor ()).Blue ());
333 aCAspect.Back.ColorAmb.r = float (((theAspect->BackMaterial ()).AmbientColor ()).Red ());
334 aCAspect.Back.ColorAmb.g = float (((theAspect->BackMaterial ()).AmbientColor ()).Green ());
335 aCAspect.Back.ColorAmb.b = float (((theAspect->BackMaterial ()).AmbientColor ()).Blue ());
338 aCAspect.Back.ColorDif.r = float (((theAspect->BackMaterial ()).DiffuseColor ()).Red ());
339 aCAspect.Back.ColorDif.g = float (((theAspect->BackMaterial ()).DiffuseColor ()).Green ());
340 aCAspect.Back.ColorDif.b = float (((theAspect->BackMaterial ()).DiffuseColor ()).Blue ());
343 aCAspect.Back.ColorEms.r = float (((theAspect->BackMaterial ()).EmissiveColor ()).Red ());
344 aCAspect.Back.ColorEms.g = float (((theAspect->BackMaterial ()).EmissiveColor ()).Green ());
345 aCAspect.Back.ColorEms.b = float (((theAspect->BackMaterial ()).EmissiveColor ()).Blue ());
347 aCAspect.Back.EnvReflexion = float ((theAspect->BackMaterial ()).EnvReflexion());
349 aCAspect.Front.Shininess = float ((theAspect->FrontMaterial ()).Shininess ());
350 aCAspect.Front.Ambient = float ((theAspect->FrontMaterial ()).Ambient ());
351 aCAspect.Front.Diffuse = float ((theAspect->FrontMaterial ()).Diffuse ());
352 aCAspect.Front.Specular = float ((theAspect->FrontMaterial ()).Specular ());
353 aCAspect.Front.Transparency = float ((theAspect->FrontMaterial ()).Transparency ());
354 aCAspect.Front.Emission = float ((theAspect->FrontMaterial ()).Emissive ());
357 aCAspect.Front.IsAmbient = ((theAspect->FrontMaterial ()).ReflectionMode (Graphic3d_TOR_AMBIENT) ? 1 : 0);
358 aCAspect.Front.IsDiffuse = ((theAspect->FrontMaterial ()).ReflectionMode (Graphic3d_TOR_DIFFUSE) ? 1 : 0);
359 aCAspect.Front.IsSpecular = ((theAspect->FrontMaterial ()).ReflectionMode (Graphic3d_TOR_SPECULAR) ? 1 : 0);
360 aCAspect.Front.IsEmission = ((theAspect->FrontMaterial ()).ReflectionMode (Graphic3d_TOR_EMISSION) ? 1 : 0);
363 const Graphic3d_MaterialAspect aFrontMat = theAspect->FrontMaterial ();
364 Standard_Boolean isFrontPhys = aFrontMat.MaterialType (Graphic3d_MATERIAL_PHYSIC);
365 aCAspect.Front.IsPhysic = (isFrontPhys ? 1 : 0 );
368 aCAspect.Front.ColorSpec.r = float (((theAspect->FrontMaterial ()).SpecularColor ()).Red ());
369 aCAspect.Front.ColorSpec.g = float (((theAspect->FrontMaterial ()).SpecularColor ()).Green ());
370 aCAspect.Front.ColorSpec.b = float (((theAspect->FrontMaterial ()).SpecularColor ()).Blue ());
373 aCAspect.Front.ColorAmb.r = float (((theAspect->FrontMaterial ()).AmbientColor ()).Red ());
374 aCAspect.Front.ColorAmb.g = float (((theAspect->FrontMaterial ()).AmbientColor ()).Green ());
375 aCAspect.Front.ColorAmb.b = float (((theAspect->FrontMaterial ()).AmbientColor ()).Blue ());
378 aCAspect.Front.ColorDif.r = float (((theAspect->FrontMaterial ()).DiffuseColor ()).Red ());
379 aCAspect.Front.ColorDif.g = float (((theAspect->FrontMaterial ()).DiffuseColor ()).Green ());
380 aCAspect.Front.ColorDif.b = float (((theAspect->FrontMaterial ()).DiffuseColor ()).Blue ());
383 aCAspect.Front.ColorEms.r = float (((theAspect->FrontMaterial ()).EmissiveColor ()).Red ());
384 aCAspect.Front.ColorEms.g = float (((theAspect->FrontMaterial ()).EmissiveColor ()).Green ());
385 aCAspect.Front.ColorEms.b = float (((theAspect->FrontMaterial ()).EmissiveColor ()).Blue ());
387 aCAspect.Front.EnvReflexion = float ((theAspect->FrontMaterial ()).EnvReflexion());
389 aCAspect.Texture.TextureMap = theAspect->TextureMap();
390 aCAspect.Texture.doTextureMap = theAspect->TextureMapState() ? 1 : 0;
392 Standard_Integer aPolyMode;
393 Standard_ShortReal aPolyFactor, aPolyUnits;
394 theAspect->PolygonOffsets (aPolyMode, aPolyFactor, aPolyUnits);
395 aCAspect.PolygonOffsetMode = aPolyMode;
396 aCAspect.PolygonOffsetFactor = (Standard_ShortReal)aPolyFactor;
397 aCAspect.PolygonOffsetUnits = (Standard_ShortReal)aPolyUnits;
399 Init (theContext, aCAspect);
402 // =======================================================================
405 // =======================================================================
406 void OpenGl_AspectFace::Render (const Handle(OpenGl_Workspace)& theWorkspace) const
408 theWorkspace->SetAspectFace (this);
411 // =======================================================================
412 // function : Release
414 // =======================================================================
415 void OpenGl_AspectFace::Release (const Handle(OpenGl_Context)& theContext)
417 if (!TextureRes.IsNull())
419 if (!theContext.IsNull())
421 if (myTextureId.IsEmpty())
423 theContext->DelayedRelease (TextureRes);
427 TextureRes.Nullify(); // we need nullify all handles before ReleaseResource() call
428 theContext->ReleaseResource (myTextureId);
431 TextureRes.Nullify();