41f72e217ebad0e36e56d3e41585f51440542d35
[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   static const TCollection_AsciiString THE_EMPTY_KEY;
51
52 };
53
54 // =======================================================================
55 // function : convertMaterial
56 // purpose  :
57 // =======================================================================
58 void OpenGl_AspectFace::convertMaterial (const CALL_DEF_MATERIAL& theMat,
59                                          OPENGL_SURF_PROP&        theSurf)
60 {
61   theSurf.amb  = theMat.IsAmbient  ? theMat.Ambient  : 0.0f;
62   theSurf.diff = theMat.IsDiffuse  ? theMat.Diffuse  : 0.0f;
63   theSurf.spec = theMat.IsSpecular ? theMat.Specular : 0.0f;
64   theSurf.emsv = theMat.IsEmission ? theMat.Emission : 0.0f;
65
66   theSurf.isphysic = theMat.IsPhysic ? 1 : 0; // type of material
67
68   // color of material
69   theSurf.color_mask = 0;
70   if (theMat.IsAmbient)
71   {
72     theSurf.color_mask |= OPENGL_AMBIENT_MASK;
73   }
74   if (theMat.IsDiffuse)
75   {
76     theSurf.color_mask |= OPENGL_DIFFUSE_MASK;
77   }
78   if (theMat.IsSpecular)
79   {
80     theSurf.color_mask |= OPENGL_SPECULAR_MASK;
81   }
82   if (theMat.IsEmission)
83   {
84     theSurf.color_mask |= OPENGL_EMISSIVE_MASK;
85   }
86
87   // ambient color
88   theSurf.ambcol.rgb[0] = theMat.ColorAmb.r;
89   theSurf.ambcol.rgb[1] = theMat.ColorAmb.g;
90   theSurf.ambcol.rgb[2] = theMat.ColorAmb.b;
91   theSurf.ambcol.rgb[3] = 1.0f;
92
93   // diffuse color
94   theSurf.difcol.rgb[0] = theMat.ColorDif.r;
95   theSurf.difcol.rgb[1] = theMat.ColorDif.g;
96   theSurf.difcol.rgb[2] = theMat.ColorDif.b;
97   theSurf.difcol.rgb[3] = 1.0f;
98
99   // specular color
100   theSurf.speccol.rgb[0] = theMat.ColorSpec.r;
101   theSurf.speccol.rgb[1] = theMat.ColorSpec.g;
102   theSurf.speccol.rgb[2] = theMat.ColorSpec.b;
103   theSurf.speccol.rgb[3] = 1.0f;
104
105   // emission color
106   theSurf.emscol.rgb[0] = theMat.ColorEms.r;
107   theSurf.emscol.rgb[1] = theMat.ColorEms.g;
108   theSurf.emscol.rgb[2] = theMat.ColorEms.b;
109   theSurf.emscol.rgb[3] = 1.0f;
110
111   theSurf.shine = 128.0f * float(theMat.Shininess);
112   theSurf.env_reflexion = theMat.EnvReflexion;
113
114   // trans = 0. => opaque
115   // trans = 1. => transparent
116   // in OpenGl it is opposite.
117   theSurf.trans = 1.0f - theMat.Transparency;
118 }
119
120 // =======================================================================
121 // function : OpenGl_AspectFace
122 // purpose  :
123 // =======================================================================
124 OpenGl_AspectFace::OpenGl_AspectFace()
125 : myInteriorStyle (Aspect_IS_SOLID),
126   myEdge (TOff),
127   myHatch (TEL_HS_SOLID),
128   myDistinguishingMode (TOff),
129   myCullingMode (TelCullNone),
130   myIntFront (THE_DEFAULT_MATERIAL),
131   myIntBack (THE_DEFAULT_MATERIAL),
132   myPolygonOffset (THE_DEFAULT_POFFSET),
133   myDoTextureMap (false),
134   myTextureMap(),
135   myIsTextureInit (Standard_False),
136   myTextureRes(),
137   myTextureId()
138 {}
139
140 // =======================================================================
141 // function : SetAspect
142 // purpose  :
143 // =======================================================================
144 void OpenGl_AspectFace::SetAspect (const CALL_DEF_CONTEXTFILLAREA& theAspect)
145 {
146   myInteriorStyle = (Aspect_InteriorStyle )theAspect.Style;
147   myEdge = theAspect.Edge ? TOn : TOff;
148
149   //TelInteriorStyleIndex
150   switch (theAspect.Hatch)
151   {
152     case 0: /* Aspect_HS_HORIZONTAL */
153       myHatch = TEL_HS_HORIZONTAL;
154       break;
155     case 1: /* Aspect_HS_HORIZONTAL_WIDE */
156       myHatch = TEL_HS_HORIZONTAL_SPARSE;
157       break;
158     case 2: /* Aspect_HS_VERTICAL */
159       myHatch = TEL_HS_VERTICAL;
160       break;
161     case 3: /* Aspect_HS_VERTICAL_WIDE */
162       myHatch = TEL_HS_VERTICAL_SPARSE;
163       break;
164     case 4: /* Aspect_HS_DIAGONAL_45 */
165       myHatch = TEL_HS_DIAG_45;
166       break;
167     case 5: /* Aspect_HS_DIAGONAL_45_WIDE */
168       myHatch = TEL_HS_DIAG_45_SPARSE;
169       break;
170     case 6: /* Aspect_HS_DIAGONAL_135 */
171       myHatch = TEL_HS_DIAG_135;
172       break;
173     case 7: /* Aspect_HS_DIAGONAL_135_WIDE */
174       myHatch = TEL_HS_DIAG_135_SPARSE;
175       break;
176     case 8: /* Aspect_HS_GRID */
177       myHatch = TEL_HS_GRID;
178       break;
179     case 9: /* Aspect_HS_GRID_WIDE */
180       myHatch = TEL_HS_GRID_SPARSE;
181       break;
182     case 10: /* Aspect_HS_GRID_DIAGONAL */
183       myHatch = TEL_HS_CROSS;
184       break;
185     case 11: /* Aspect_HS_GRID_DIAGONAL_WIDE */
186       myHatch = TEL_HS_CROSS_SPARSE;
187       break;
188     default:
189       myHatch = 0;
190       break;
191   }
192
193   myDistinguishingMode = theAspect.Distinguish ? TOn : TOff;
194   myCullingMode = theAspect.BackFace ? TelCullBack : TelCullNone;
195
196   convertMaterial (theAspect.Front, myIntFront);
197   convertMaterial (theAspect.Back,  myIntBack);
198
199   //TelInteriorColour
200   myIntFront.matcol.rgb[0] = (float )theAspect.IntColor.r;
201   myIntFront.matcol.rgb[1] = (float )theAspect.IntColor.g;
202   myIntFront.matcol.rgb[2] = (float )theAspect.IntColor.b;
203   myIntFront.matcol.rgb[3] = 1.0f;
204
205   //TelBackInteriorColour
206   myIntBack.matcol.rgb[0] = (float )theAspect.BackIntColor.r;
207   myIntBack.matcol.rgb[1] = (float )theAspect.BackIntColor.g;
208   myIntBack.matcol.rgb[2] = (float )theAspect.BackIntColor.b;
209   myIntBack.matcol.rgb[3] = 1.0f;
210
211   myDoTextureMap  = (theAspect.Texture.doTextureMap != 0);
212   myTextureMap    = theAspect.Texture.TextureMap;
213
214   const TCollection_AsciiString& aNewKey = myTextureMap.IsNull() ? THE_EMPTY_KEY : myTextureMap->GetId();
215   myIsTextureInit = (!aNewKey.IsEmpty() && myTextureId == aNewKey);
216
217   //TelPolygonOffset
218   myPolygonOffset.mode   = (Aspect_PolygonOffsetMode )theAspect.PolygonOffsetMode;
219   myPolygonOffset.factor = theAspect.PolygonOffsetFactor;
220   myPolygonOffset.units  = theAspect.PolygonOffsetUnits;
221
222   CALL_DEF_CONTEXTLINE anEdgeAspect;
223   anEdgeAspect.Color.r  = (float )theAspect.EdgeColor.r;
224   anEdgeAspect.Color.g  = (float )theAspect.EdgeColor.g;
225   anEdgeAspect.Color.b  = (float )theAspect.EdgeColor.b;
226   anEdgeAspect.LineType = (Aspect_TypeOfLine )theAspect.LineType;
227   anEdgeAspect.Width    = (float )theAspect.Width;
228   myAspectEdge.SetAspect (anEdgeAspect);
229 }
230
231 // =======================================================================
232 // function : SetAspect
233 // purpose  :
234 // =======================================================================
235 void OpenGl_AspectFace::SetAspect (const Handle(Graphic3d_AspectFillArea3d)& theAspect)
236 {
237   CALL_DEF_CONTEXTFILLAREA aFaceContext;
238   Standard_Real           aWidth;
239   Quantity_Color          aBackIntColor;
240   Quantity_Color          aEdgeColor;
241   Aspect_TypeOfLine       aLType;
242   Quantity_Color          aIntColor;
243   Aspect_InteriorStyle    aIntStyle;
244   NCollection_Vec3<Standard_Real> aColor;
245
246   theAspect->Values (aIntStyle, aIntColor, aBackIntColor, aEdgeColor, aLType, aWidth);
247   aIntColor.Values (aColor.r(), aColor.g(), aColor.b(), Quantity_TOC_RGB);
248
249   aFaceContext.Style      = int (aIntStyle);
250   aFaceContext.IntColor.r = float (aColor.r());
251   aFaceContext.IntColor.g = float (aColor.g());
252   aFaceContext.IntColor.b = float (aColor.b());
253
254   if (theAspect->Distinguish())
255   {
256     aBackIntColor.Values (aColor.r(), aColor.g(), aColor.b(), Quantity_TOC_RGB);
257   }
258
259   aFaceContext.BackIntColor.r = float (aColor.r());
260   aFaceContext.BackIntColor.g = float (aColor.g());
261   aFaceContext.BackIntColor.b = float (aColor.b());
262
263   aFaceContext.Edge = theAspect->Edge () ? 1:0;
264   aEdgeColor.Values (aColor.r(), aColor.g(), aColor.b(), Quantity_TOC_RGB);
265
266   aFaceContext.EdgeColor.r = float (aColor.r());
267   aFaceContext.EdgeColor.g = float (aColor.g());
268   aFaceContext.EdgeColor.b = float (aColor.b());
269   aFaceContext.LineType    = int (aLType);
270   aFaceContext.Width       = float (aWidth);
271   aFaceContext.Hatch       = int (theAspect->HatchStyle ());
272
273   aFaceContext.Distinguish = theAspect->Distinguish () ? 1:0;
274   aFaceContext.BackFace    = theAspect->BackFace ()    ? 1:0;
275
276   aFaceContext.Back.Shininess = float ((theAspect->BackMaterial ()).Shininess ());
277   aFaceContext.Back.Ambient   = float ((theAspect->BackMaterial ()).Ambient ());
278   aFaceContext.Back.Diffuse   = float ((theAspect->BackMaterial ()).Diffuse ());
279   aFaceContext.Back.Specular  = float ((theAspect->BackMaterial ()).Specular ());
280   aFaceContext.Back.Transparency  = float ((theAspect->BackMaterial ()).Transparency ());
281   aFaceContext.Back.Emission      = float ((theAspect->BackMaterial ()).Emissive ());
282
283   // Reflection mode
284   aFaceContext.Back.IsAmbient = ((theAspect->BackMaterial ()).ReflectionMode (Graphic3d_TOR_AMBIENT) ? 1 : 0 );
285   aFaceContext.Back.IsDiffuse = ((theAspect->BackMaterial ()).ReflectionMode (Graphic3d_TOR_DIFFUSE) ? 1 : 0 );
286   aFaceContext.Back.IsSpecular = ((theAspect->BackMaterial ()).ReflectionMode (Graphic3d_TOR_SPECULAR) ? 1 : 0 );
287   aFaceContext.Back.IsEmission = ((theAspect->BackMaterial ()).ReflectionMode (Graphic3d_TOR_EMISSION) ? 1 : 0 );
288
289   // Material type
290   const Graphic3d_MaterialAspect aBackMat = theAspect->BackMaterial ();
291   Standard_Boolean isBackPhys = aBackMat.MaterialType (Graphic3d_MATERIAL_PHYSIC);
292   aFaceContext.Back.IsPhysic = (isBackPhys ? 1 : 0 );
293
294   // Specular Color
295   aFaceContext.Back.ColorSpec.r = float (((theAspect->BackMaterial ()).SpecularColor ()).Red ());
296   aFaceContext.Back.ColorSpec.g = float (((theAspect->BackMaterial ()).SpecularColor ()).Green ());
297   aFaceContext.Back.ColorSpec.b = float (((theAspect->BackMaterial ()).SpecularColor ()).Blue ());
298
299   // Ambient color
300   aFaceContext.Back.ColorAmb.r = float (((theAspect->BackMaterial ()).AmbientColor ()).Red ());
301   aFaceContext.Back.ColorAmb.g = float (((theAspect->BackMaterial ()).AmbientColor ()).Green ());
302   aFaceContext.Back.ColorAmb.b = float (((theAspect->BackMaterial ()).AmbientColor ()).Blue ());
303
304   // Diffuse color
305   aFaceContext.Back.ColorDif.r = float (((theAspect->BackMaterial ()).DiffuseColor ()).Red ());
306   aFaceContext.Back.ColorDif.g = float (((theAspect->BackMaterial ()).DiffuseColor ()).Green ());
307   aFaceContext.Back.ColorDif.b = float (((theAspect->BackMaterial ()).DiffuseColor ()).Blue ());
308
309   // Emissive color
310   aFaceContext.Back.ColorEms.r = float (((theAspect->BackMaterial ()).EmissiveColor ()).Red ());
311   aFaceContext.Back.ColorEms.g = float (((theAspect->BackMaterial ()).EmissiveColor ()).Green ());
312   aFaceContext.Back.ColorEms.b = float (((theAspect->BackMaterial ()).EmissiveColor ()).Blue ());
313
314   aFaceContext.Back.EnvReflexion = float ((theAspect->BackMaterial ()).EnvReflexion());
315
316   aFaceContext.Front.Shininess    = float ((theAspect->FrontMaterial ()).Shininess ());
317   aFaceContext.Front.Ambient      = float ((theAspect->FrontMaterial ()).Ambient ());
318   aFaceContext.Front.Diffuse      = float ((theAspect->FrontMaterial ()).Diffuse ());
319   aFaceContext.Front.Specular     = float ((theAspect->FrontMaterial ()).Specular ());
320   aFaceContext.Front.Transparency = float ((theAspect->FrontMaterial ()).Transparency ());
321   aFaceContext.Front.Emission     = float ((theAspect->FrontMaterial ()).Emissive ());
322
323   // Reflection mode
324   aFaceContext.Front.IsAmbient    = ((theAspect->FrontMaterial ()).ReflectionMode (Graphic3d_TOR_AMBIENT) ? 1 : 0);
325   aFaceContext.Front.IsDiffuse    = ((theAspect->FrontMaterial ()).ReflectionMode (Graphic3d_TOR_DIFFUSE) ? 1 : 0);
326   aFaceContext.Front.IsSpecular   = ((theAspect->FrontMaterial ()).ReflectionMode (Graphic3d_TOR_SPECULAR) ? 1 : 0);
327   aFaceContext.Front.IsEmission   = ((theAspect->FrontMaterial ()).ReflectionMode (Graphic3d_TOR_EMISSION) ? 1 : 0);
328
329   // Material type
330   const Graphic3d_MaterialAspect aFrontMat = theAspect->FrontMaterial ();
331   Standard_Boolean isFrontPhys = aFrontMat.MaterialType (Graphic3d_MATERIAL_PHYSIC);
332   aFaceContext.Front.IsPhysic = (isFrontPhys ? 1 : 0 );
333
334   // Specular Color
335   aFaceContext.Front.ColorSpec.r = float (((theAspect->FrontMaterial ()).SpecularColor ()).Red ());
336   aFaceContext.Front.ColorSpec.g = float (((theAspect->FrontMaterial ()).SpecularColor ()).Green ());
337   aFaceContext.Front.ColorSpec.b = float (((theAspect->FrontMaterial ()).SpecularColor ()).Blue ());
338
339   // Ambient color
340   aFaceContext.Front.ColorAmb.r = float (((theAspect->FrontMaterial ()).AmbientColor ()).Red ());
341   aFaceContext.Front.ColorAmb.g = float (((theAspect->FrontMaterial ()).AmbientColor ()).Green ());
342   aFaceContext.Front.ColorAmb.b = float (((theAspect->FrontMaterial ()).AmbientColor ()).Blue ());
343
344   // Diffuse color
345   aFaceContext.Front.ColorDif.r = float (((theAspect->FrontMaterial ()).DiffuseColor ()).Red ());
346   aFaceContext.Front.ColorDif.g = float (((theAspect->FrontMaterial ()).DiffuseColor ()).Green ());
347   aFaceContext.Front.ColorDif.b = float (((theAspect->FrontMaterial ()).DiffuseColor ()).Blue ());
348
349   // Emissive color
350   aFaceContext.Front.ColorEms.r = float (((theAspect->FrontMaterial ()).EmissiveColor ()).Red ());
351   aFaceContext.Front.ColorEms.g = float (((theAspect->FrontMaterial ()).EmissiveColor ()).Green ());
352   aFaceContext.Front.ColorEms.b = float (((theAspect->FrontMaterial ()).EmissiveColor ()).Blue ());
353
354   aFaceContext.Front.EnvReflexion = float ((theAspect->FrontMaterial ()).EnvReflexion());
355   aFaceContext.IsDef = 1;
356   aFaceContext.Texture.TextureMap   = theAspect->TextureMap();
357   aFaceContext.Texture.doTextureMap = theAspect->TextureMapState() ? 1 : 0;
358
359   Standard_Integer aPolyMode;
360   Standard_ShortReal aPolyFactor, aPolyUnits;
361   theAspect->PolygonOffsets (aPolyMode, aPolyFactor, aPolyUnits);
362   aFaceContext.PolygonOffsetMode   = aPolyMode;
363   aFaceContext.PolygonOffsetFactor = (Standard_ShortReal)aPolyFactor;
364   aFaceContext.PolygonOffsetUnits  = (Standard_ShortReal)aPolyUnits;
365
366   SetAspect (aFaceContext);
367 }
368
369 // =======================================================================
370 // function : Render
371 // purpose  :
372 // =======================================================================
373 void OpenGl_AspectFace::Render (const Handle(OpenGl_Workspace)& theWorkspace) const
374 {
375   theWorkspace->SetAspectFace (this);
376 }
377
378 // =======================================================================
379 // function : Release
380 // purpose  :
381 // =======================================================================
382 void OpenGl_AspectFace::Release (const Handle(OpenGl_Context)& theContext)
383 {
384   if (!myTextureRes.IsNull())
385   {
386     if (!theContext.IsNull())
387     {
388       if (myTextureId.IsEmpty())
389       {
390         theContext->DelayedRelease (myTextureRes);
391       }
392       else
393       {
394         myTextureRes.Nullify(); // we need nullify all handles before ReleaseResource() call
395         theContext->ReleaseResource (myTextureId);
396       }
397     }
398     myTextureRes.Nullify();
399   }
400   myTextureId.Clear();
401 }
402
403 // =======================================================================
404 // function : buildTexure
405 // purpose  :
406 // =======================================================================
407 void OpenGl_AspectFace::buildTexture (const Handle(OpenGl_Workspace)& theWorkspace) const
408 {
409   const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext();
410
411   const TCollection_AsciiString& aNewKey = myTextureMap.IsNull() ? THE_EMPTY_KEY : myTextureMap->GetId();
412   if (aNewKey.IsEmpty() || myTextureId != aNewKey)
413   {
414     if (!myTextureRes.IsNull())
415     {
416       if (myTextureId.IsEmpty())
417       {
418         aContext->DelayedRelease (myTextureRes);
419         myTextureRes.Nullify();
420       }
421       else
422       {
423         myTextureRes.Nullify(); // we need nullify all handles before ReleaseResource() call
424         aContext->ReleaseResource (myTextureId);
425       }
426     }
427     myTextureId = aNewKey;
428
429     if (!myTextureMap.IsNull())
430     {
431       if (aNewKey.IsEmpty() || !aContext->GetResource<Handle(OpenGl_Texture)> (aNewKey, myTextureRes))
432       {
433         myTextureRes = new OpenGl_Texture (myTextureMap->GetParams());
434         Handle(Image_PixMap) anImage = myTextureMap->GetImage();
435         if (!anImage.IsNull())
436         {
437           myTextureRes->Init (aContext, *anImage.operator->(), myTextureMap->Type());
438         }
439         if (!aNewKey.IsEmpty())
440         {
441           aContext->ShareResource (aNewKey, myTextureRes);
442         }
443       }
444     }
445   }
446 }