0030609: Coding - eliminate warnings issued by gcc 8.1.0
[occt.git] / src / OpenGl / OpenGl_Sampler.cxx
CommitLineData
25ef750e 1// Created on: 2014-10-08
2// Created by: Denis BOGOLEPOV
3// Copyright (c) 2014 OPEN CASCADE SAS
4//
5// This file is part of Open CASCADE Technology software library.
6//
7// This library is free software; you can redistribute it and/or modify it under
8// the terms of the GNU Lesser General Public License version 2.1 as published
9// by the Free Software Foundation, with special exception defined in the file
10// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11// distribution for complete text of the license and disclaimer of any warranty.
12//
13// Alternatively, this file may be used under the terms of Open CASCADE
14// commercial license or contractual agreement.
15
16#include <OpenGl_Sampler.hxx>
25ef750e 17
cc8cbabe 18#include <OpenGl_ArbSamplerObject.hxx>
19#include <OpenGl_Texture.hxx>
20#include <Standard_Assert.hxx>
25ef750e 21
92efcf78 22IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Sampler,OpenGl_Resource)
23
25ef750e 24// =======================================================================
25// function : OpenGl_Sampler
26// purpose :
27// =======================================================================
cc8cbabe 28OpenGl_Sampler::OpenGl_Sampler (const Handle(Graphic3d_TextureParams)& theParams)
29: myParams (theParams),
30 mySamplerRevision (0),
31 mySamplerID (NO_SAMPLER),
32 myIsImmutable (false)
25ef750e 33{
cc8cbabe 34 if (myParams.IsNull())
35 {
36 myParams = new Graphic3d_TextureParams();
37 }
25ef750e 38}
39
40// =======================================================================
41// function : ~OpenGl_Sampler
42// purpose :
43// =======================================================================
44OpenGl_Sampler::~OpenGl_Sampler()
45{
46 Release (NULL);
47}
48
49// =======================================================================
50// function : Release
51// purpose :
52// =======================================================================
cc8cbabe 53void OpenGl_Sampler::Release (OpenGl_Context* theCtx)
25ef750e 54{
cc8cbabe 55 myIsImmutable = false;
56 mySamplerRevision = myParams->SamplerRevision() - 1;
57 if (!isValidSampler())
25ef750e 58 {
cc8cbabe 59 return;
60 }
25ef750e 61
cc8cbabe 62 // application can not handle this case by exception - this is bug in code
63 Standard_ASSERT_RETURN (theCtx != NULL,
64 "OpenGl_Sampler destroyed without GL context! Possible GPU memory leakage...",);
25ef750e 65
cc8cbabe 66 if (theCtx->IsValid())
67 {
68 theCtx->arbSamplerObject->glDeleteSamplers (1, &mySamplerID);
25ef750e 69 }
cc8cbabe 70
71 mySamplerID = NO_SAMPLER;
25ef750e 72}
73
74// =======================================================================
cc8cbabe 75// function : Create
76// purpose :
25ef750e 77// =======================================================================
cc8cbabe 78Standard_Boolean OpenGl_Sampler::Create (const Handle(OpenGl_Context)& theCtx)
25ef750e 79{
cc8cbabe 80 if (isValidSampler())
81 {
82 return Standard_True;
83 }
84 else if (theCtx->arbSamplerObject == NULL)
25ef750e 85 {
86 return Standard_False;
87 }
88
cc8cbabe 89 theCtx->arbSamplerObject->glGenSamplers (1, &mySamplerID);
90 return Standard_True;
91}
92
93// =======================================================================
94// function : Init
95// purpose :
96// =======================================================================
97Standard_Boolean OpenGl_Sampler::Init (const Handle(OpenGl_Context)& theCtx,
98 const OpenGl_Texture& theTexture)
99{
25ef750e 100 if (isValidSampler())
101 {
cc8cbabe 102 if (!ToUpdateParameters())
103 {
104 return Standard_True;
105 }
106 else if (!myIsImmutable)
107 {
108 applySamplerParams (theCtx, myParams, this, theTexture.GetTarget(), theTexture.HasMipmaps());
109 return Standard_True;
110 }
111 Release (theCtx.get());
112 }
113
114 if (!Create (theCtx))
115 {
116 return Standard_False;
25ef750e 117 }
118
cc8cbabe 119 applySamplerParams (theCtx, myParams, this, theTexture.GetTarget(), theTexture.HasMipmaps());
25ef750e 120 return Standard_True;
25ef750e 121}
122
123// =======================================================================
124// function : Bind
125// purpose : Binds sampler object to the given texture unit
126// =======================================================================
cc8cbabe 127void OpenGl_Sampler::Bind (const Handle(OpenGl_Context)& theCtx,
128 const Graphic3d_TextureUnit theUnit)
25ef750e 129{
130 if (isValidSampler())
131 {
cc8cbabe 132 theCtx->arbSamplerObject->glBindSampler (theUnit, mySamplerID);
25ef750e 133 }
134}
135
136// =======================================================================
137// function : Unbind
138// purpose : Unbinds sampler object from the given texture unit
139// =======================================================================
cc8cbabe 140void OpenGl_Sampler::Unbind (const Handle(OpenGl_Context)& theCtx,
141 const Graphic3d_TextureUnit theUnit)
25ef750e 142{
143 if (isValidSampler())
144 {
cc8cbabe 145 theCtx->arbSamplerObject->glBindSampler (theUnit, NO_SAMPLER);
25ef750e 146 }
147}
148
149// =======================================================================
cc8cbabe 150// function : setParameter
151// purpose :
25ef750e 152// =======================================================================
cc8cbabe 153void OpenGl_Sampler::setParameter (const Handle(OpenGl_Context)& theCtx,
154 OpenGl_Sampler* theSampler,
155 GLenum theTarget,
156 GLenum theParam,
157 GLint theValue)
25ef750e 158{
cc8cbabe 159 if (theSampler != NULL && theSampler->isValidSampler())
160 {
161 theCtx->arbSamplerObject->glSamplerParameteri (theSampler->mySamplerID, theParam, theValue);
162 }
163 else
164 {
165 theCtx->core11fwd->glTexParameteri (theTarget, theParam, theValue);
166 }
167}
168
169// =======================================================================
170// function : SetParameters
171// purpose :
172// =======================================================================
173void OpenGl_Sampler::SetParameters (const Handle(Graphic3d_TextureParams)& theParams)
174{
175 if (myParams != theParams)
176 {
177 myParams = theParams;
178 mySamplerRevision = myParams->SamplerRevision() - 1;
179 }
180}
181
182// =======================================================================
183// function : applySamplerParams
184// purpose :
185// =======================================================================
186void OpenGl_Sampler::applySamplerParams (const Handle(OpenGl_Context)& theCtx,
187 const Handle(Graphic3d_TextureParams)& theParams,
188 OpenGl_Sampler* theSampler,
189 const GLenum theTarget,
190 const bool theHasMipMaps)
191{
192 if (theSampler != NULL && theSampler->Parameters() == theParams)
193 {
194 theSampler->mySamplerRevision = theParams->SamplerRevision();
195 }
196
197 // setup texture filtering
198 const GLenum aFilter = (theParams->Filter() == Graphic3d_TOTF_NEAREST) ? GL_NEAREST : GL_LINEAR;
199 GLenum aFilterMin = aFilter;
200 if (theHasMipMaps)
201 {
202 aFilterMin = GL_NEAREST_MIPMAP_NEAREST;
203 if (theParams->Filter() == Graphic3d_TOTF_BILINEAR)
204 {
205 aFilterMin = GL_LINEAR_MIPMAP_NEAREST;
206 }
207 else if (theParams->Filter() == Graphic3d_TOTF_TRILINEAR)
208 {
209 aFilterMin = GL_LINEAR_MIPMAP_LINEAR;
210 }
211 }
212
213 setParameter (theCtx, theSampler, theTarget, GL_TEXTURE_MIN_FILTER, aFilterMin);
214 setParameter (theCtx, theSampler, theTarget, GL_TEXTURE_MAG_FILTER, aFilter);
215
216 // setup texture wrapping
217 const GLenum aWrapMode = theParams->IsRepeat() ? GL_REPEAT : theCtx->TextureWrapClamp();
218 setParameter (theCtx, theSampler, theTarget, GL_TEXTURE_WRAP_S, aWrapMode);
219#if !defined(GL_ES_VERSION_2_0)
220 if (theTarget == GL_TEXTURE_1D)
25ef750e 221 {
cc8cbabe 222 return;
25ef750e 223 }
cc8cbabe 224#endif
225 setParameter (theCtx, theSampler, theTarget, GL_TEXTURE_WRAP_T, aWrapMode);
226 if (theTarget == GL_TEXTURE_3D)
227 {
228 setParameter (theCtx, theSampler, theTarget, GL_TEXTURE_WRAP_R, aWrapMode);
229 return;
230 }
231
232 if (theCtx->extAnis)
233 {
234 // setup degree of anisotropy filter
235 const GLint aMaxDegree = theCtx->MaxDegreeOfAnisotropy();
236 GLint aDegree;
237 switch (theParams->AnisoFilter())
238 {
239 case Graphic3d_LOTA_QUALITY:
240 {
241 aDegree = aMaxDegree;
242 break;
243 }
244 case Graphic3d_LOTA_MIDDLE:
245 {
246 aDegree = (aMaxDegree <= 4) ? 2 : (aMaxDegree / 2);
247 break;
248 }
249 case Graphic3d_LOTA_FAST:
250 {
251 aDegree = 2;
252 break;
253 }
254 case Graphic3d_LOTA_OFF:
255 default:
256 {
257 aDegree = 1;
258 break;
259 }
260 }
261
262 setParameter (theCtx, theSampler, theTarget, GL_TEXTURE_MAX_ANISOTROPY_EXT, aDegree);
263 }
264}
265
266// =======================================================================
267// function : applyGlobalTextureParams
268// purpose :
269// =======================================================================
270void OpenGl_Sampler::applyGlobalTextureParams (const Handle(OpenGl_Context)& theCtx,
271 const OpenGl_Texture& theTexture,
272 const Handle(Graphic3d_TextureParams)& theParams)
273{
274#if defined(GL_ES_VERSION_2_0)
275 (void )theCtx;
276 (void )theTexture;
277 (void )theParams;
278#else
5c225e8e 279 if (theCtx->core11 == NULL
280 || theParams->TextureUnit() >= theCtx->MaxTextureUnitsFFP())
cc8cbabe 281 {
282 return;
283 }
284
285 GLint anEnvMode = GL_MODULATE; // lighting mode
286 if (!theParams->IsModulate())
287 {
288 anEnvMode = GL_DECAL;
289 if (theTexture.GetFormat() == GL_ALPHA
290 || theTexture.GetFormat() == GL_LUMINANCE)
291 {
292 anEnvMode = GL_REPLACE;
293 }
294 }
295
296 // setup generation of texture coordinates
297 switch (theParams->GenMode())
298 {
299 case Graphic3d_TOTM_OBJECT:
300 {
301 theCtx->core11->glTexGeni (GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
302 theCtx->core11->glTexGenfv (GL_S, GL_OBJECT_PLANE, theParams->GenPlaneS().GetData());
303 if (theTexture.GetTarget() != GL_TEXTURE_1D)
304 {
305 theCtx->core11->glTexGeni (GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
306 theCtx->core11->glTexGenfv (GL_T, GL_OBJECT_PLANE, theParams->GenPlaneT().GetData());
307 }
308 break;
309 }
310 case Graphic3d_TOTM_SPHERE:
311 {
312 theCtx->core11->glTexGeni (GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
313 if (theTexture.GetTarget() != GL_TEXTURE_1D)
314 {
315 theCtx->core11->glTexGeni (GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
316 }
317 break;
318 }
319 case Graphic3d_TOTM_EYE:
320 {
321 theCtx->WorldViewState.Push();
322 theCtx->WorldViewState.SetIdentity();
323 theCtx->ApplyWorldViewMatrix();
324
325 theCtx->core11->glTexGeni (GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
326 theCtx->core11->glTexGenfv (GL_S, GL_EYE_PLANE, theParams->GenPlaneS().GetData());
327 if (theTexture.GetTarget() != GL_TEXTURE_1D)
328 {
329 theCtx->core11->glTexGeni (GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
330 theCtx->core11->glTexGenfv (GL_T, GL_EYE_PLANE, theParams->GenPlaneT().GetData());
331 }
332
333 theCtx->WorldViewState.Pop();
334 break;
335 }
336 case Graphic3d_TOTM_SPRITE:
337 {
338 if (theCtx->core20fwd != NULL)
339 {
340 theCtx->core11fwd->glEnable (GL_POINT_SPRITE);
341 glTexEnvi (GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE);
342 anEnvMode = GL_REPLACE;
343 }
344 break;
345 }
346 case Graphic3d_TOTM_MANUAL:
347 default: break;
348 }
349
350 // setup lighting
351 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, anEnvMode);
352
353 switch (theTexture.GetTarget())
354 {
355 case GL_TEXTURE_1D:
356 {
357 if (theParams->GenMode() != Graphic3d_TOTM_MANUAL)
358 {
359 theCtx->core11fwd->glEnable (GL_TEXTURE_GEN_S);
360 }
361 theCtx->core11fwd->glEnable (GL_TEXTURE_1D);
362 break;
363 }
364 case GL_TEXTURE_2D:
365 {
366 if (theParams->GenMode() != Graphic3d_TOTM_MANUAL)
367 {
368 theCtx->core11fwd->glEnable (GL_TEXTURE_GEN_S);
369 theCtx->core11fwd->glEnable (GL_TEXTURE_GEN_T);
370 }
371 theCtx->core11fwd->glEnable (GL_TEXTURE_2D);
372 break;
373 }
374 default: break;
375 }
376#endif
377}
378
379// =======================================================================
380// function : resetGlobalTextureParams
381// purpose :
382// =======================================================================
383void OpenGl_Sampler::resetGlobalTextureParams (const Handle(OpenGl_Context)& theCtx,
384 const OpenGl_Texture& theTexture,
385 const Handle(Graphic3d_TextureParams)& theParams)
386{
387#if defined(GL_ES_VERSION_2_0)
388 (void )theCtx;
389 (void )theTexture;
390 (void )theParams;
391#else
392 if (theCtx->core11 == NULL)
393 {
394 return;
395 }
396
397 // reset texture matrix because some code may expect it is identity
398 GLint aMatrixMode = GL_TEXTURE;
399 theCtx->core11fwd->glGetIntegerv (GL_MATRIX_MODE, &aMatrixMode);
400 theCtx->core11->glMatrixMode (GL_TEXTURE);
401 theCtx->core11->glLoadIdentity();
402 theCtx->core11->glMatrixMode (aMatrixMode);
403
404 switch (theTexture.GetTarget())
405 {
406 case GL_TEXTURE_1D:
407 {
408 if (theParams->GenMode() != GL_NONE)
409 {
410 theCtx->core11fwd->glDisable (GL_TEXTURE_GEN_S);
411 }
412 theCtx->core11fwd->glDisable (GL_TEXTURE_1D);
413 break;
414 }
415 case GL_TEXTURE_2D:
416 {
417 if (theParams->GenMode() != GL_NONE)
418 {
419 theCtx->core11fwd->glDisable (GL_TEXTURE_GEN_S);
420 theCtx->core11fwd->glDisable (GL_TEXTURE_GEN_T);
97e0059b 421 if (theParams->GenMode() == Graphic3d_TOTM_SPRITE
422 && theCtx->core20fwd != NULL)
cc8cbabe 423 {
424 theCtx->core11fwd->glDisable (GL_POINT_SPRITE);
425 }
426 }
427 theCtx->core11fwd->glDisable (GL_TEXTURE_2D);
428 break;
429 }
430 default: break;
431 }
432#endif
25ef750e 433}