0023544: Texture management in TKOpenGl should be redesigned
[occt.git] / src / OpenGl / OpenGl_Workspace.cxx
CommitLineData
b311480e 1// Created on: 2011-09-20
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
bf75be98 20#include <OpenGl_GlCore12.hxx>
5f8b738e 21
2166f0fa
SK
22#include <InterfaceGraphic.hxx>
23
24#include <OpenGl_Workspace.hxx>
25
26#include <OpenGl_AspectLine.hxx>
27#include <OpenGl_AspectFace.hxx>
28#include <OpenGl_AspectMarker.hxx>
29#include <OpenGl_AspectText.hxx>
bf75be98 30#include <OpenGl_Context.hxx>
31
32#include <OpenGl_Texture.hxx>
2166f0fa 33
bf75be98 34#include <Graphic3d_TextureParams.hxx>
2166f0fa
SK
35
36IMPLEMENT_STANDARD_HANDLE(OpenGl_Workspace,OpenGl_Window)
37IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Workspace,OpenGl_Window)
38
39namespace
40{
41 static const TEL_COLOUR myDefaultHighlightColor = { { 1.F, 1.F, 1.F, 1.F } };
42
43 static const OpenGl_AspectLine myDefaultAspectLine;
44 static const OpenGl_AspectFace myDefaultAspectFace;
45 static const OpenGl_AspectMarker myDefaultAspectMarker;
46 static const OpenGl_AspectText myDefaultAspectText;
47
48 static const OpenGl_TextParam myDefaultTextParam =
49 {
50 16, Graphic3d_HTA_LEFT, Graphic3d_VTA_BOTTOM
51 };
52
53 static const OpenGl_Matrix myDefaultMatrix =
54 {
55 {{ 1.0F, 0.0F, 0.0F, 0.0F },
56 { 0.0F, 1.0F, 0.0F, 0.0F },
57 { 0.0F, 0.0F, 1.0F, 0.0F },
58 { 0.0F, 0.0F, 0.0F, 1.0F }}
59 };
bf75be98 60
2166f0fa
SK
61};
62
63// =======================================================================
64// function : OpenGl_Workspace
65// purpose :
66// =======================================================================
67OpenGl_Workspace::OpenGl_Workspace (const Handle(OpenGl_Display)& theDisplay,
68 const CALL_DEF_WINDOW& theCWindow,
5e27df78 69 Aspect_RenderingContext theGContext,
70 const Handle(OpenGl_Context)& theShareCtx)
71: OpenGl_Window (theDisplay, theCWindow, theGContext, theShareCtx),
2166f0fa
SK
72 myTransientList (0),
73 myIsTransientOpen (Standard_False),
74 myRetainMode (Standard_False),
75 myUseTransparency (Standard_False),
76 myUseZBuffer (Standard_False),
77 myUseDepthTest (Standard_True),
78 myUseGLLight (Standard_True),
79 myBackBufferRestored (Standard_False),
80 //
81 NamedStatus (0),
82 DegenerateModel (0),
83 SkipRatio (0.F),
84 HighlightColor (&myDefaultHighlightColor),
85 AspectLine_set (&myDefaultAspectLine),
86 AspectLine_applied (NULL),
87 AspectFace_set (&myDefaultAspectFace),
88 AspectFace_applied (NULL),
89 AspectMarker_set (&myDefaultAspectMarker),
90 AspectMarker_applied (NULL),
91 AspectText_set (&myDefaultAspectText),
92 AspectText_applied (NULL),
93 TextParam_set (&myDefaultTextParam),
94 TextParam_applied (NULL),
95 ViewMatrix_applied (&myDefaultMatrix),
96 StructureMatrix_applied (&myDefaultMatrix),
97 PolygonOffset_applied (NULL)
98{
99 theDisplay->InitAttributes();
100
101 // General initialization of the context
102
103 // Eviter d'avoir les faces mal orientees en noir.
104 // Pourrait etre utiliser pour detecter les problemes d'orientation
bf75be98 105 glLightModeli ((GLenum )GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
2166f0fa
SK
106
107 // Optimisation pour le Fog et l'antialiasing
108 glHint (GL_FOG_HINT, GL_FASTEST);
109 glHint (GL_POINT_SMOOTH_HINT, GL_FASTEST);
110 glHint (GL_LINE_SMOOTH_HINT, GL_FASTEST);
111 glHint (GL_POLYGON_SMOOTH_HINT, GL_FASTEST);
112
113 // Polygon Offset
114 EnablePolygonOffset();
115}
116
117// =======================================================================
118// function : ~OpenGl_Workspace
119// purpose :
120// =======================================================================
121OpenGl_Workspace::~OpenGl_Workspace()
122{
123}
124
125// =======================================================================
126// function : Activate
127// purpose :
128// =======================================================================
129Standard_Boolean OpenGl_Workspace::Activate()
130{
131 if (!OpenGl_Window::Activate())
132 return Standard_False;
133
2166f0fa
SK
134 DegenerateModel = 0;
135 SkipRatio = 0.0f;
2166f0fa
SK
136 ViewMatrix_applied = &myDefaultMatrix;
137 StructureMatrix_applied = &myDefaultMatrix;
26395493 138
139 ResetAppliedAspect();
140
141 return Standard_True;
2166f0fa
SK
142}
143
144// =======================================================================
145// function : UseTransparency
146// purpose : call_togl_transparency
147// =======================================================================
148void OpenGl_Workspace::UseTransparency (const Standard_Boolean theFlag)
149{
150 if ((myUseTransparency ? 1 : 0) != (theFlag ? 1 : 0))
151 {
152 myUseTransparency = theFlag;
153 EraseAnimation();
2166f0fa
SK
154 }
155}
26395493 156
157//=======================================================================
158//function : ResetAppliedAspect
159//purpose : Sets default values of GL parameters in accordance with default aspects
160//=======================================================================
161void OpenGl_Workspace::ResetAppliedAspect()
162{
bf75be98 163 NamedStatus = !myTextureBound.IsNull() ? OPENGL_NS_TEXTURE : 0;
26395493 164 HighlightColor = &myDefaultHighlightColor;
165 AspectLine_set = &myDefaultAspectLine;
166 AspectLine_applied = NULL;
167 AspectFace_set = &myDefaultAspectFace;
168 AspectFace_applied = NULL;
169 AspectMarker_set = &myDefaultAspectMarker;
170 AspectMarker_applied = NULL;
171 AspectText_set = &myDefaultAspectText;
172 AspectText_applied = NULL;
173 TextParam_set = &myDefaultTextParam;
174 TextParam_applied = NULL;
175 PolygonOffset_applied = NULL;
176
177 AspectLine(Standard_True);
178 AspectFace(Standard_True);
179 AspectMarker(Standard_True);
180 AspectText(Standard_True);
181}
bf75be98 182
183// =======================================================================
184// function : DisableTexture
185// purpose :
186// =======================================================================
187Handle(OpenGl_Texture) OpenGl_Workspace::DisableTexture()
188{
189 if (myTextureBound.IsNull())
190 {
191 return myTextureBound;
192 }
193
194 // reset texture matrix because some code may expect it is identity
195 GLint aMatrixMode = GL_TEXTURE;
196 glGetIntegerv (GL_MATRIX_MODE, &aMatrixMode);
197 glMatrixMode (GL_TEXTURE);
198 glLoadIdentity();
199 glMatrixMode (aMatrixMode);
200
201 myTextureBound->Unbind (myGlContext);
202 switch (myTextureBound->GetTarget())
203 {
204 case GL_TEXTURE_1D:
205 {
206 if (myTextureBound->GetParams()->GenMode() != GL_NONE)
207 {
208 glDisable (GL_TEXTURE_GEN_S);
209 }
210 glDisable (GL_TEXTURE_1D);
211 break;
212 }
213 case GL_TEXTURE_2D:
214 {
215 if (myTextureBound->GetParams()->GenMode() != GL_NONE)
216 {
217 glDisable (GL_TEXTURE_GEN_S);
218 glDisable (GL_TEXTURE_GEN_T);
219 }
220 glDisable (GL_TEXTURE_2D);
221 break;
222 }
223 default: break;
224 }
225
226 Handle(OpenGl_Texture) aPrevTexture = myTextureBound;
227 myTextureBound.Nullify();
228 return aPrevTexture;
229}
230
231// =======================================================================
232// function : setTextureParams
233// purpose :
234// =======================================================================
235void OpenGl_Workspace::setTextureParams (Handle(OpenGl_Texture)& theTexture,
236 const Handle(Graphic3d_TextureParams)& theParams)
237{
238 const Handle(Graphic3d_TextureParams)& aParams = theParams.IsNull() ? theTexture->GetParams() : theParams;
239 if (aParams.IsNull())
240 {
241 return;
242 }
243
244 GLint aMatrixMode = GL_TEXTURE;
245 glGetIntegerv (GL_MATRIX_MODE, &aMatrixMode);
246
247 // setup texture matrix
248 glMatrixMode (GL_TEXTURE);
249 glLoadIdentity();
250 const Graphic3d_Vec2& aScale = aParams->Scale();
251 const Graphic3d_Vec2& aTrans = aParams->Translation();
252 glScalef ( aScale.x(), aScale.y(), 1.0f);
253 glTranslatef (-aTrans.x(), -aTrans.y(), 0.0f);
254 glRotatef (-aParams->Rotation(), 0.0f, 0.0f, 1.0f);
255
256 // setup generation of texture coordinates
257 switch (aParams->GenMode())
258 {
259 case Graphic3d_TOTM_OBJECT:
260 {
261 glTexGeni (GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
262 glTexGenfv (GL_S, GL_OBJECT_PLANE, aParams->GenPlaneS().GetData());
263 if (theTexture->GetTarget() != GL_TEXTURE_1D)
264 {
265 glTexGeni (GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
266 glTexGenfv (GL_T, GL_OBJECT_PLANE, aParams->GenPlaneT().GetData());
267 }
268 break;
269 }
270 case Graphic3d_TOTM_SPHERE:
271 {
272 glTexGeni (GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
273 if (theTexture->GetTarget() != GL_TEXTURE_1D)
274 {
275 glTexGeni (GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
276 }
277 break;
278 }
279 case Graphic3d_TOTM_EYE:
280 {
281 glMatrixMode (GL_MODELVIEW);
282 glPushMatrix();
283 glLoadIdentity();
284
285 glTexGeni (GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
286 glTexGenfv (GL_S, GL_EYE_PLANE, aParams->GenPlaneS().GetData());
287
288 if (theTexture->GetTarget() != GL_TEXTURE_1D)
289 {
290 glTexGeni (GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
291 glTexGenfv (GL_T, GL_EYE_PLANE, aParams->GenPlaneT().GetData());
292 }
293 glPopMatrix();
294 break;
295 }
296 case Graphic3d_TOTM_MANUAL:
297 default: break;
298 }
299
300 // setup lighting
301 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, aParams->IsModulate() ? GL_MODULATE : GL_DECAL);
302
303 // setup texture filtering and wrapping
304 //if (theTexture->GetParams() != theParams)
305 const GLenum aFilter = (aParams->Filter() == Graphic3d_TOTF_NEAREST) ? GL_NEAREST : GL_LINEAR;
306 const GLenum aWrapMode = aParams->IsRepeat() ? GL_REPEAT : GL_CLAMP;
307 switch (theTexture->GetTarget())
308 {
309 case GL_TEXTURE_1D:
310 {
311 glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, aFilter);
312 glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, aFilter);
313 glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, aWrapMode);
314 break;
315 }
316 case GL_TEXTURE_2D:
317 {
318 GLenum aFilterMin = aFilter;
319 if (theTexture->HasMipmaps())
320 {
321 aFilterMin = GL_NEAREST_MIPMAP_NEAREST;
322 if (aParams->Filter() == Graphic3d_TOTF_BILINEAR)
323 {
324 aFilterMin = GL_LINEAR_MIPMAP_NEAREST;
325 }
326 else if (aParams->Filter() == Graphic3d_TOTF_TRILINEAR)
327 {
328 aFilterMin = GL_LINEAR_MIPMAP_LINEAR;
329 }
330
331 if (myGlContext->extAnis)
332 {
333 // setup degree of anisotropy filter
334 const GLint aMaxDegree = myGlContext->MaxDegreeOfAnisotropy();
335 switch (aParams->AnisoFilter())
336 {
337 case Graphic3d_LOTA_QUALITY:
338 {
339 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, aMaxDegree);
340 break;
341 }
342 case Graphic3d_LOTA_MIDDLE:
343 {
344
345 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, (aMaxDegree <= 4) ? 2 : (aMaxDegree / 2));
346 break;
347 }
348 case Graphic3d_LOTA_FAST:
349 {
350 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 2);
351 break;
352 }
353 case Graphic3d_LOTA_OFF:
354 default:
355 {
356 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1);
357 break;
358 }
359 }
360 }
361 }
362 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, aFilterMin);
363 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, aFilter);
364 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, aWrapMode);
365 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, aWrapMode);
366 break;
367 }
368 default: break;
369 }
370
371 switch (theTexture->GetTarget())
372 {
373 case GL_TEXTURE_1D:
374 {
375 if (aParams->GenMode() != Graphic3d_TOTM_MANUAL)
376 {
377 glEnable (GL_TEXTURE_GEN_S);
378 }
379 glEnable (GL_TEXTURE_1D);
380 break;
381 }
382 case GL_TEXTURE_2D:
383 {
384 if (aParams->GenMode() != Graphic3d_TOTM_MANUAL)
385 {
386 glEnable (GL_TEXTURE_GEN_S);
387 glEnable (GL_TEXTURE_GEN_T);
388 }
389 glEnable (GL_TEXTURE_2D);
390 break;
391 }
392 default: break;
393 }
394
395 glMatrixMode (aMatrixMode); // turn back active matrix
396 theTexture->SetParams (aParams);
397}
398
399// =======================================================================
400// function : EnableTexture
401// purpose :
402// =======================================================================
403Handle(OpenGl_Texture) OpenGl_Workspace::EnableTexture (const Handle(OpenGl_Texture)& theTexture,
404 const Handle(Graphic3d_TextureParams)& theParams)
405{
406 if (theTexture.IsNull() || !theTexture->IsValid())
407 {
408 return DisableTexture();
409 }
410
411 if (myTextureBound.IsNull() && myTextureBound == theTexture)
412 {
413 Handle(OpenGl_Texture) aPrevTexture = myTextureBound;
414 myTextureBound = theTexture;
415 return aPrevTexture;
416 }
417
418 Handle(OpenGl_Texture) aPrevTexture = DisableTexture();
419 myTextureBound = theTexture;
420 myTextureBound->Bind (myGlContext);
421 setTextureParams (myTextureBound, theParams);
422
423 return aPrevTexture;
424}