0023544: Texture management in TKOpenGl should be redesigned
[occt.git] / src / OpenGl / OpenGl_AspectFace.cxx
CommitLineData
b311480e 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
2166f0fa 20#include <OpenGl_AspectFace.hxx>
bf75be98 21#include <OpenGl_Texture.hxx>
22#include <OpenGl_Workspace.hxx>
23#include <OpenGl_Context.hxx>
2166f0fa 24
2166f0fa 25#include <Aspect_PolygonOffsetMode.hxx>
bf75be98 26#include <Graphic3d_CGroup.hxx>
27#include <Graphic3d_TextureMap.hxx>
2166f0fa 28
bf75be98 29namespace
2166f0fa 30{
2166f0fa 31
bf75be98 32 static OPENGL_SURF_PROP THE_DEFAULT_MATERIAL =
33 {
34 0.2F, 0.8F, 0.1F, 0.0F, // amb, diff, spec, emsv
35 1.0F, 10.0F, 0.0F, // trans, shine, env_reflexion
36 0, // isphysic
37 (OPENGL_AMBIENT_MASK | OPENGL_DIFFUSE_MASK | OPENGL_SPECULAR_MASK), // color_mask
38 {{ 1.0F, 1.0F, 1.0F, 1.0F }}, // ambient color
39 {{ 1.0F, 1.0F, 1.0F, 1.0F }}, // diffuse color
40 {{ 1.0F, 1.0F, 1.0F, 1.0F }}, // specular color
41 {{ 1.0F, 1.0F, 1.0F, 1.0F }}, // emissive color
42 {{ 1.0F, 1.0F, 1.0F, 1.0F }} // material color
43 };
44
45 static TEL_POFFSET_PARAM THE_DEFAULT_POFFSET = { Aspect_POM_Fill, 1.0F, 0.0F };
46
47};
2166f0fa 48
bf75be98 49// =======================================================================
50// function : convertMaterial
51// purpose :
52// =======================================================================
53void OpenGl_AspectFace::convertMaterial (const CALL_DEF_MATERIAL& theMat,
54 OPENGL_SURF_PROP& theSurf)
2166f0fa 55{
bf75be98 56 theSurf.amb = theMat.IsAmbient ? theMat.Ambient : 0.0f;
57 theSurf.diff = theMat.IsDiffuse ? theMat.Diffuse : 0.0f;
58 theSurf.spec = theMat.IsSpecular ? theMat.Specular : 0.0f;
59 theSurf.emsv = theMat.IsEmission ? theMat.Emission : 0.0f;
2166f0fa 60
bf75be98 61 theSurf.isphysic = theMat.IsPhysic ? 1 : 0; // type of material
2166f0fa 62
bf75be98 63 // color of material
64 theSurf.color_mask = 0;
65 if (theMat.IsAmbient)
66 {
67 theSurf.color_mask |= OPENGL_AMBIENT_MASK;
68 }
69 if (theMat.IsDiffuse)
70 {
71 theSurf.color_mask |= OPENGL_DIFFUSE_MASK;
72 }
73 if (theMat.IsSpecular)
74 {
75 theSurf.color_mask |= OPENGL_SPECULAR_MASK;
76 }
77 if (theMat.IsEmission)
78 {
79 theSurf.color_mask |= OPENGL_EMISSIVE_MASK;
80 }
2166f0fa 81
bf75be98 82 // ambient color
83 theSurf.ambcol.rgb[0] = theMat.ColorAmb.r;
84 theSurf.ambcol.rgb[1] = theMat.ColorAmb.g;
85 theSurf.ambcol.rgb[2] = theMat.ColorAmb.b;
86 theSurf.ambcol.rgb[3] = 1.0f;
87
88 // diffuse color
89 theSurf.difcol.rgb[0] = theMat.ColorDif.r;
90 theSurf.difcol.rgb[1] = theMat.ColorDif.g;
91 theSurf.difcol.rgb[2] = theMat.ColorDif.b;
92 theSurf.difcol.rgb[3] = 1.0f;
93
94 // specular color
95 theSurf.speccol.rgb[0] = theMat.ColorSpec.r;
96 theSurf.speccol.rgb[1] = theMat.ColorSpec.g;
97 theSurf.speccol.rgb[2] = theMat.ColorSpec.b;
98 theSurf.speccol.rgb[3] = 1.0f;
99
100 // emission color
101 theSurf.emscol.rgb[0] = theMat.ColorEms.r;
102 theSurf.emscol.rgb[1] = theMat.ColorEms.g;
103 theSurf.emscol.rgb[2] = theMat.ColorEms.b;
104 theSurf.emscol.rgb[3] = 1.0f;
105
106 theSurf.shine = 128.0f * float(theMat.Shininess);
107 theSurf.env_reflexion = theMat.EnvReflexion;
108
109 // trans = 0. => opaque
110 // trans = 1. => transparent
111 // in OpenGl it is opposite.
112 theSurf.trans = 1.0f - theMat.Transparency;
113}
2166f0fa 114
bf75be98 115// =======================================================================
116// function : OpenGl_AspectFace
117// purpose :
118// =======================================================================
119OpenGl_AspectFace::OpenGl_AspectFace()
120: InteriorStyle (Aspect_IS_SOLID),
121 Edge (Aspect_IS_SOLID),
122 Hatch (TOn),
123 DistinguishingMode (TEL_HS_SOLID),
124 CullingMode (TelCullNone),
125 doTextureMap (0)
2166f0fa 126{
bf75be98 127 IntFront = THE_DEFAULT_MATERIAL;
128 IntBack = THE_DEFAULT_MATERIAL;
129 PolygonOffset = THE_DEFAULT_POFFSET;
130}
2166f0fa 131
bf75be98 132// =======================================================================
133// function : Init
134// purpose :
135// =======================================================================
136void OpenGl_AspectFace::Init (const Handle(OpenGl_Context)& theContext,
137 const CALL_DEF_CONTEXTFILLAREA& theAspect)
138{
139 InteriorStyle = (Aspect_InteriorStyle )theAspect.Style;
140 Edge = theAspect.Edge ? TOn : TOff;
2166f0fa
SK
141
142 //TelInteriorStyleIndex
bf75be98 143 switch (theAspect.Hatch)
2166f0fa 144 {
bf75be98 145 case 0: /* Aspect_HS_HORIZONTAL */
146 Hatch = TEL_HS_HORIZONTAL;
2166f0fa 147 break;
bf75be98 148 case 1: /* Aspect_HS_HORIZONTAL_WIDE */
149 Hatch = TEL_HS_HORIZONTAL_SPARSE;
2166f0fa 150 break;
bf75be98 151 case 2: /* Aspect_HS_VERTICAL */
152 Hatch = TEL_HS_VERTICAL;
2166f0fa 153 break;
bf75be98 154 case 3: /* Aspect_HS_VERTICAL_WIDE */
155 Hatch = TEL_HS_VERTICAL_SPARSE;
2166f0fa 156 break;
bf75be98 157 case 4: /* Aspect_HS_DIAGONAL_45 */
158 Hatch = TEL_HS_DIAG_45;
2166f0fa 159 break;
bf75be98 160 case 5: /* Aspect_HS_DIAGONAL_45_WIDE */
161 Hatch = TEL_HS_DIAG_45_SPARSE;
2166f0fa 162 break;
bf75be98 163 case 6: /* Aspect_HS_DIAGONAL_135 */
164 Hatch = TEL_HS_DIAG_135;
2166f0fa 165 break;
bf75be98 166 case 7: /* Aspect_HS_DIAGONAL_135_WIDE */
167 Hatch = TEL_HS_DIAG_135_SPARSE;
2166f0fa 168 break;
bf75be98 169 case 8: /* Aspect_HS_GRID */
170 Hatch = TEL_HS_GRID;
2166f0fa 171 break;
bf75be98 172 case 9: /* Aspect_HS_GRID_WIDE */
173 Hatch = TEL_HS_GRID_SPARSE;
2166f0fa 174 break;
bf75be98 175 case 10: /* Aspect_HS_GRID_DIAGONAL */
176 Hatch = TEL_HS_CROSS;
2166f0fa 177 break;
bf75be98 178 case 11: /* Aspect_HS_GRID_DIAGONAL_WIDE */
179 Hatch = TEL_HS_CROSS_SPARSE;
2166f0fa 180 break;
bf75be98 181 default:
182 Hatch = 0;
2166f0fa
SK
183 break;
184 }
185
bf75be98 186 DistinguishingMode = theAspect.Distinguish ? TOn : TOff;
187 CullingMode = theAspect.BackFace ? TelCullBack : TelCullNone;
2166f0fa 188
bf75be98 189 convertMaterial (theAspect.Front, IntFront);
190 convertMaterial (theAspect.Back, IntBack);
2166f0fa
SK
191
192 //TelInteriorColour
bf75be98 193 IntFront.matcol.rgb[0] = (float )theAspect.IntColor.r;
194 IntFront.matcol.rgb[1] = (float )theAspect.IntColor.g;
195 IntFront.matcol.rgb[2] = (float )theAspect.IntColor.b;
196 IntFront.matcol.rgb[3] = 1.0f;
2166f0fa
SK
197
198 //TelBackInteriorColour
bf75be98 199 IntBack.matcol.rgb[0] = (float )theAspect.BackIntColor.r;
200 IntBack.matcol.rgb[1] = (float )theAspect.BackIntColor.g;
201 IntBack.matcol.rgb[2] = (float )theAspect.BackIntColor.b;
202 IntBack.matcol.rgb[3] = 1.0f;
203
204 // setup texture
205 doTextureMap = theAspect.Texture.doTextureMap;
206 const Handle(Graphic3d_TextureMap)& aNewTexture = theAspect.Texture.TextureMap;
207 TCollection_AsciiString aNewKey = aNewTexture.IsNull() ? TCollection_AsciiString() : aNewTexture->GetId();
208 TextureParams = aNewTexture.IsNull() ? NULL : aNewTexture->GetParams();
209 if (aNewKey.IsEmpty()
210 || myTextureId != aNewKey)
211 {
212 if (!TextureRes.IsNull())
213 {
214 if (myTextureId.IsEmpty())
215 {
216 theContext->DelayedRelease (TextureRes);
217 TextureRes.Nullify();
218 }
219 else
220 {
221 TextureRes.Nullify(); // we need nullify all handles before ReleaseResource() call
222 theContext->ReleaseResource (myTextureId);
223 }
224 }
225 myTextureId = aNewKey;
226
227 if (!aNewTexture.IsNull())
228 {
229 if (aNewKey.IsEmpty() || !theContext->GetResource<Handle(OpenGl_Texture)> (aNewKey, TextureRes))
230 {
231 TextureRes = new OpenGl_Texture (TextureParams);
232 Handle(Image_PixMap) anImage = aNewTexture->GetImage();
233 if (!anImage.IsNull())
234 {
235 TextureRes->Init (theContext, *anImage.operator->(), aNewTexture->Type());
236 }
237 if (!aNewKey.IsEmpty())
238 {
239 theContext->ShareResource (aNewKey, TextureRes);
240 }
241 }
242 }
243 }
2166f0fa
SK
244
245 //TelPolygonOffset
bf75be98 246 PolygonOffset.mode = (Aspect_PolygonOffsetMode )theAspect.PolygonOffsetMode;
247 PolygonOffset.factor = theAspect.PolygonOffsetFactor;
248 PolygonOffset.units = theAspect.PolygonOffsetUnits;
2166f0fa
SK
249
250 CALL_DEF_CONTEXTLINE anEdgeContext;
bf75be98 251 anEdgeContext.Color.r = (float )theAspect.EdgeColor.r;
252 anEdgeContext.Color.g = (float )theAspect.EdgeColor.g;
253 anEdgeContext.Color.b = (float )theAspect.EdgeColor.b;
254 anEdgeContext.LineType = (Aspect_TypeOfLine )theAspect.LineType;
255 anEdgeContext.Width = (float )theAspect.Width;
256 myAspectEdge.SetContext (anEdgeContext);
2166f0fa
SK
257}
258
bf75be98 259// =======================================================================
260// function : Render
261// purpose :
262// =======================================================================
5e27df78 263void OpenGl_AspectFace::Render (const Handle(OpenGl_Workspace)& theWorkspace) const
2166f0fa 264{
5e27df78 265 theWorkspace->SetAspectFace (this);
2166f0fa
SK
266}
267
bf75be98 268// =======================================================================
269// function : Release
270// purpose :
271// =======================================================================
5e27df78 272void OpenGl_AspectFace::Release (const Handle(OpenGl_Context)& theContext)
273{
bf75be98 274 if (!TextureRes.IsNull())
275 {
276 if (!theContext.IsNull())
277 {
278 if (myTextureId.IsEmpty())
279 {
280 theContext->DelayedRelease (TextureRes);
281 }
282 else
283 {
284 TextureRes.Nullify(); // we need nullify all handles before ReleaseResource() call
285 theContext->ReleaseResource (myTextureId);
286 }
287 }
288 TextureRes.Nullify();
289 }
290 myTextureId.Clear();
5e27df78 291}