428620d1825ad0a8d5aad884537bd8693dec5489
[occt.git] / src / OpenGl / OpenGl_AspectFace.cxx
1 // Created on: 2011-07-13
2 // Created by: Sergey ZERCHANINOV
3 // Copyright (c) 2011-2012 OPEN CASCADE SAS
4 //
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.
9 //
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.
12 //
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.
19
20 #include <OpenGl_AspectFace.hxx>
21 #include <OpenGl_Texture.hxx>
22 #include <OpenGl_Workspace.hxx>
23 #include <OpenGl_Context.hxx>
24
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>
30
31 #include <NCollection_Vec3.hxx>
32
33 namespace
34 {
35
36   static OPENGL_SURF_PROP THE_DEFAULT_MATERIAL =
37   {
38     0.2F,  0.8F, 0.1F, 0.0F, // amb, diff, spec, emsv
39     1.0F, 10.0F, 0.0F,       // trans, shine, env_reflexion
40     0, // isphysic
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
47   };
48
49   static TEL_POFFSET_PARAM THE_DEFAULT_POFFSET = { Aspect_POM_Fill, 1.0F, 0.0F };
50
51 };
52
53 // =======================================================================
54 // function : convertMaterial
55 // purpose  :
56 // =======================================================================
57 void OpenGl_AspectFace::convertMaterial (const CALL_DEF_MATERIAL& theMat,
58                                          OPENGL_SURF_PROP&        theSurf)
59 {
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;
64
65   theSurf.isphysic = theMat.IsPhysic ? 1 : 0; // type of material
66
67   // color of material
68   theSurf.color_mask = 0;
69   if (theMat.IsAmbient)
70   {
71     theSurf.color_mask |= OPENGL_AMBIENT_MASK;
72   }
73   if (theMat.IsDiffuse)
74   {
75     theSurf.color_mask |= OPENGL_DIFFUSE_MASK;
76   }
77   if (theMat.IsSpecular)
78   {
79     theSurf.color_mask |= OPENGL_SPECULAR_MASK;
80   }
81   if (theMat.IsEmission)
82   {
83     theSurf.color_mask |= OPENGL_EMISSIVE_MASK;
84   }
85
86   // ambient color
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;
91
92   // diffuse color
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;
97
98   // specular color
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;
103
104   // emission color
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;
109
110   theSurf.shine = 128.0f * float(theMat.Shininess);
111   theSurf.env_reflexion = theMat.EnvReflexion;
112
113   // trans = 0. => opaque
114   // trans = 1. => transparent
115   // in OpenGl it is opposite.
116   theSurf.trans = 1.0f - theMat.Transparency;
117 }
118
119 // =======================================================================
120 // function : OpenGl_AspectFace
121 // purpose  :
122 // =======================================================================
123 OpenGl_AspectFace::OpenGl_AspectFace()
124 : InteriorStyle (Aspect_IS_SOLID),
125   Edge (Aspect_IS_SOLID),
126   Hatch (TOn),
127   DistinguishingMode (TEL_HS_SOLID),
128   CullingMode (TelCullNone),
129   doTextureMap (0)
130 {
131   IntFront      = THE_DEFAULT_MATERIAL;
132   IntBack       = THE_DEFAULT_MATERIAL;
133   PolygonOffset = THE_DEFAULT_POFFSET;
134 }
135
136 // =======================================================================
137 // function : Init
138 // purpose  :
139 // =======================================================================
140 void OpenGl_AspectFace::Init (const Handle(OpenGl_Context)&   theContext,
141                               const CALL_DEF_CONTEXTFILLAREA& theAspect)
142 {
143   InteriorStyle = (Aspect_InteriorStyle )theAspect.Style;
144   Edge = theAspect.Edge ? TOn : TOff;
145
146   //TelInteriorStyleIndex
147   switch (theAspect.Hatch)
148   {
149     case 0: /* Aspect_HS_HORIZONTAL */
150       Hatch = TEL_HS_HORIZONTAL;
151       break;
152     case 1: /* Aspect_HS_HORIZONTAL_WIDE */
153       Hatch = TEL_HS_HORIZONTAL_SPARSE;
154       break;
155     case 2: /* Aspect_HS_VERTICAL */
156       Hatch = TEL_HS_VERTICAL;
157       break;
158     case 3: /* Aspect_HS_VERTICAL_WIDE */
159       Hatch = TEL_HS_VERTICAL_SPARSE;
160       break;
161     case 4: /* Aspect_HS_DIAGONAL_45 */
162       Hatch = TEL_HS_DIAG_45;
163       break;
164     case 5: /* Aspect_HS_DIAGONAL_45_WIDE */
165       Hatch = TEL_HS_DIAG_45_SPARSE;
166       break;
167     case 6: /* Aspect_HS_DIAGONAL_135 */
168       Hatch = TEL_HS_DIAG_135;
169       break;
170     case 7: /* Aspect_HS_DIAGONAL_135_WIDE */
171       Hatch = TEL_HS_DIAG_135_SPARSE;
172       break;
173     case 8: /* Aspect_HS_GRID */
174       Hatch = TEL_HS_GRID;
175       break;
176     case 9: /* Aspect_HS_GRID_WIDE */
177       Hatch = TEL_HS_GRID_SPARSE;
178       break;
179     case 10: /* Aspect_HS_GRID_DIAGONAL */
180       Hatch = TEL_HS_CROSS;
181       break;
182     case 11: /* Aspect_HS_GRID_DIAGONAL_WIDE */
183       Hatch = TEL_HS_CROSS_SPARSE;
184       break;
185     default:
186       Hatch = 0;
187       break;
188   }
189
190   DistinguishingMode = theAspect.Distinguish ? TOn : TOff;
191   CullingMode = theAspect.BackFace ? TelCullBack : TelCullNone;
192
193   convertMaterial (theAspect.Front, IntFront);
194   convertMaterial (theAspect.Back,  IntBack);
195
196   //TelInteriorColour
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;
201
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;
207
208   // setup texture
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)
215   {
216     if (!TextureRes.IsNull())
217     {
218       if (myTextureId.IsEmpty())
219       {
220         theContext->DelayedRelease (TextureRes);
221         TextureRes.Nullify();
222       }
223       else
224       {
225         TextureRes.Nullify(); // we need nullify all handles before ReleaseResource() call
226         theContext->ReleaseResource (myTextureId);
227       }
228     }
229     myTextureId = aNewKey;
230
231     if (!aNewTexture.IsNull())
232     {
233       if (aNewKey.IsEmpty() || !theContext->GetResource<Handle(OpenGl_Texture)> (aNewKey, TextureRes))
234       {
235         TextureRes = new OpenGl_Texture (TextureParams);
236         Handle(Image_PixMap) anImage = aNewTexture->GetImage();
237         if (!anImage.IsNull())
238         {
239           TextureRes->Init (theContext, *anImage.operator->(), aNewTexture->Type());
240         }
241         if (!aNewKey.IsEmpty())
242         {
243           theContext->ShareResource (aNewKey, TextureRes);
244         }
245       }
246     }
247   }
248
249   //TelPolygonOffset
250   PolygonOffset.mode   = (Aspect_PolygonOffsetMode )theAspect.PolygonOffsetMode;
251   PolygonOffset.factor = theAspect.PolygonOffsetFactor;
252   PolygonOffset.units  = theAspect.PolygonOffsetUnits;
253
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);
261 }
262
263 // =======================================================================
264 // function : Init
265 // purpose  :
266 // =======================================================================
267 void OpenGl_AspectFace::Init (const Handle(OpenGl_Context)&   theContext,
268                               const Handle(Graphic3d_AspectFillArea3d)& theAspect)
269 {
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;
278
279   theAspect->Values (aIntStyle, aIntColor, aBackIntColor, aEdgeColor, aLType, aWidth);
280   aIntColor.Values (aColor.r(), aColor.g(), aColor.b(), Quantity_TOC_RGB);
281
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());
286
287   if (theAspect->Distinguish())
288   {
289     aBackIntColor.Values (aColor.r(), aColor.g(), aColor.b(), Quantity_TOC_RGB);
290   }
291
292   aCAspect.BackIntColor.r = float (aColor.r());
293   aCAspect.BackIntColor.g = float (aColor.g());
294   aCAspect.BackIntColor.b = float (aColor.b());
295
296   aCAspect.Edge = theAspect->Edge () ? 1:0;
297   aEdgeColor.Values (aColor.r(), aColor.g(), aColor.b(), Quantity_TOC_RGB);
298
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 ());
305
306   aCAspect.Distinguish = theAspect->Distinguish () ? 1:0;
307   aCAspect.BackFace    = theAspect->BackFace ()    ? 1:0;
308
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 ());
315
316   // Reflection mode
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 );
321
322   // Material type
323   const Graphic3d_MaterialAspect aBackMat = theAspect->BackMaterial ();
324   Standard_Boolean isBackPhys = aBackMat.MaterialType (Graphic3d_MATERIAL_PHYSIC);
325   aCAspect.Back.IsPhysic = (isBackPhys ? 1 : 0 );
326
327   // Specular Color
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 ());
331
332   // Ambient color
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 ());
336
337   // Diffuse color
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 ());
341
342   // Emissive color
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 ());
346
347   aCAspect.Back.EnvReflexion = float ((theAspect->BackMaterial ()).EnvReflexion());
348
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 ());
355
356   // Reflection mode
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);
361
362   // Materail type
363   const Graphic3d_MaterialAspect aFrontMat = theAspect->FrontMaterial ();
364   Standard_Boolean isFrontPhys = aFrontMat.MaterialType (Graphic3d_MATERIAL_PHYSIC);
365   aCAspect.Front.IsPhysic = (isFrontPhys ? 1 : 0 );
366
367   // Specular Color
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 ());
371
372   // Ambient color
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 ());
376
377   // Diffuse color
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 ());
381
382   // Emissive color
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 ());
386
387   aCAspect.Front.EnvReflexion = float ((theAspect->FrontMaterial ()).EnvReflexion());
388   aCAspect.IsDef = 1;
389   aCAspect.Texture.TextureMap   = theAspect->TextureMap();
390   aCAspect.Texture.doTextureMap = theAspect->TextureMapState() ? 1 : 0;
391
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;
398
399   Init (theContext, aCAspect);
400 }
401
402 // =======================================================================
403 // function : Render
404 // purpose  :
405 // =======================================================================
406 void OpenGl_AspectFace::Render (const Handle(OpenGl_Workspace)& theWorkspace) const
407 {
408   theWorkspace->SetAspectFace (this);
409 }
410
411 // =======================================================================
412 // function : Release
413 // purpose  :
414 // =======================================================================
415 void OpenGl_AspectFace::Release (const Handle(OpenGl_Context)& theContext)
416 {
417   if (!TextureRes.IsNull())
418   {
419     if (!theContext.IsNull())
420     {
421       if (myTextureId.IsEmpty())
422       {
423         theContext->DelayedRelease (TextureRes);
424       }
425       else
426       {
427         TextureRes.Nullify(); // we need nullify all handles before ReleaseResource() call
428         theContext->ReleaseResource (myTextureId);
429       }
430     }
431     TextureRes.Nullify();
432   }
433   myTextureId.Clear();
434 }