1 // Created on: 2014-10-08
2 // Created by: Denis BOGOLEPOV
3 // Copyright (c) 2014 OPEN CASCADE SAS
5 // This file is part of Open CASCADE Technology software library.
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.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
16 #include <OpenGl_Sampler.hxx>
18 #include <OpenGl_ArbSamplerObject.hxx>
19 #include <OpenGl_Texture.hxx>
20 #include <Standard_Assert.hxx>
22 IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Sampler,OpenGl_Resource)
24 // =======================================================================
25 // function : OpenGl_Sampler
27 // =======================================================================
28 OpenGl_Sampler::OpenGl_Sampler (const Handle(Graphic3d_TextureParams)& theParams)
29 : myParams (theParams),
30 mySamplerRevision (0),
31 mySamplerID (NO_SAMPLER),
34 if (myParams.IsNull())
36 myParams = new Graphic3d_TextureParams();
40 // =======================================================================
41 // function : ~OpenGl_Sampler
43 // =======================================================================
44 OpenGl_Sampler::~OpenGl_Sampler()
49 // =======================================================================
52 // =======================================================================
53 void OpenGl_Sampler::Release (OpenGl_Context* theCtx)
55 myIsImmutable = false;
56 mySamplerRevision = myParams->SamplerRevision() - 1;
57 if (!isValidSampler())
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...",);
66 if (theCtx->IsValid())
68 theCtx->arbSamplerObject->glDeleteSamplers (1, &mySamplerID);
71 mySamplerID = NO_SAMPLER;
74 // =======================================================================
77 // =======================================================================
78 Standard_Boolean OpenGl_Sampler::Create (const Handle(OpenGl_Context)& theCtx)
84 else if (theCtx->arbSamplerObject == NULL)
86 return Standard_False;
89 theCtx->arbSamplerObject->glGenSamplers (1, &mySamplerID);
93 // =======================================================================
96 // =======================================================================
97 Standard_Boolean OpenGl_Sampler::Init (const Handle(OpenGl_Context)& theCtx,
98 const OpenGl_Texture& theTexture)
100 if (isValidSampler())
102 if (!ToUpdateParameters())
104 return Standard_True;
106 else if (!myIsImmutable)
108 applySamplerParams (theCtx, myParams, this, theTexture.GetTarget(), theTexture.MaxMipmapLevel());
109 return Standard_True;
111 Release (theCtx.get());
114 if (!Create (theCtx))
116 return Standard_False;
119 applySamplerParams (theCtx, myParams, this, theTexture.GetTarget(), theTexture.MaxMipmapLevel());
120 return Standard_True;
123 // =======================================================================
125 // purpose : Binds sampler object to the given texture unit
126 // =======================================================================
127 void OpenGl_Sampler::Bind (const Handle(OpenGl_Context)& theCtx,
128 const Graphic3d_TextureUnit theUnit)
130 if (isValidSampler())
132 theCtx->arbSamplerObject->glBindSampler (theUnit, mySamplerID);
136 // =======================================================================
138 // purpose : Unbinds sampler object from the given texture unit
139 // =======================================================================
140 void OpenGl_Sampler::Unbind (const Handle(OpenGl_Context)& theCtx,
141 const Graphic3d_TextureUnit theUnit)
143 if (isValidSampler())
145 theCtx->arbSamplerObject->glBindSampler (theUnit, NO_SAMPLER);
149 // =======================================================================
150 // function : setParameter
152 // =======================================================================
153 void OpenGl_Sampler::setParameter (const Handle(OpenGl_Context)& theCtx,
154 OpenGl_Sampler* theSampler,
159 if (theSampler != NULL && theSampler->isValidSampler())
161 theCtx->arbSamplerObject->glSamplerParameteri (theSampler->mySamplerID, theParam, theValue);
165 theCtx->core11fwd->glTexParameteri (theTarget, theParam, theValue);
169 // =======================================================================
170 // function : SetParameters
172 // =======================================================================
173 void OpenGl_Sampler::SetParameters (const Handle(Graphic3d_TextureParams)& theParams)
175 if (myParams != theParams)
177 myParams = theParams;
178 mySamplerRevision = myParams->SamplerRevision() - 1;
182 // =======================================================================
183 // function : applySamplerParams
185 // =======================================================================
186 void OpenGl_Sampler::applySamplerParams (const Handle(OpenGl_Context)& theCtx,
187 const Handle(Graphic3d_TextureParams)& theParams,
188 OpenGl_Sampler* theSampler,
189 const GLenum theTarget,
190 const Standard_Integer theMaxMipLevels)
192 if (theSampler != NULL && theSampler->Parameters() == theParams)
194 theSampler->mySamplerRevision = theParams->SamplerRevision();
197 // setup texture filtering
198 const GLenum aFilter = (theParams->Filter() == Graphic3d_TOTF_NEAREST) ? GL_NEAREST : GL_LINEAR;
199 GLenum aFilterMin = aFilter;
200 if (theMaxMipLevels > 0)
202 aFilterMin = GL_NEAREST_MIPMAP_NEAREST;
203 if (theParams->Filter() == Graphic3d_TOTF_BILINEAR)
205 aFilterMin = GL_LINEAR_MIPMAP_NEAREST;
207 else if (theParams->Filter() == Graphic3d_TOTF_TRILINEAR)
209 aFilterMin = GL_LINEAR_MIPMAP_LINEAR;
213 setParameter (theCtx, theSampler, theTarget, GL_TEXTURE_MIN_FILTER, aFilterMin);
214 setParameter (theCtx, theSampler, theTarget, GL_TEXTURE_MAG_FILTER, aFilter);
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)
225 setParameter (theCtx, theSampler, theTarget, GL_TEXTURE_WRAP_T, aWrapMode);
226 if (theTarget == GL_TEXTURE_3D
227 || theTarget == GL_TEXTURE_CUBE_MAP)
229 if (theCtx->HasTextureBaseLevel())
231 setParameter (theCtx, theSampler, theTarget, GL_TEXTURE_WRAP_R, aWrapMode);
238 // setup degree of anisotropy filter
239 const GLint aMaxDegree = theCtx->MaxDegreeOfAnisotropy();
241 switch (theParams->AnisoFilter())
243 case Graphic3d_LOTA_QUALITY:
245 aDegree = aMaxDegree;
248 case Graphic3d_LOTA_MIDDLE:
250 aDegree = (aMaxDegree <= 4) ? 2 : (aMaxDegree / 2);
253 case Graphic3d_LOTA_FAST:
258 case Graphic3d_LOTA_OFF:
266 setParameter (theCtx, theSampler, theTarget, GL_TEXTURE_MAX_ANISOTROPY_EXT, aDegree);
269 if (theCtx->HasTextureBaseLevel()
270 && (theSampler == NULL || !theSampler->isValidSampler()))
272 const Standard_Integer aMaxLevel = Min (theMaxMipLevels, theParams->MaxLevel());
273 setParameter (theCtx, theSampler, theTarget, GL_TEXTURE_BASE_LEVEL, theParams->BaseLevel());
274 setParameter (theCtx, theSampler, theTarget, GL_TEXTURE_MAX_LEVEL, aMaxLevel);
278 // =======================================================================
279 // function : applyGlobalTextureParams
281 // =======================================================================
282 void OpenGl_Sampler::applyGlobalTextureParams (const Handle(OpenGl_Context)& theCtx,
283 const OpenGl_Texture& theTexture,
284 const Handle(Graphic3d_TextureParams)& theParams)
286 #if defined(GL_ES_VERSION_2_0)
291 if (theCtx->core11 == NULL
292 || theParams->TextureUnit() >= theCtx->MaxTextureUnitsFFP())
297 GLint anEnvMode = GL_MODULATE; // lighting mode
298 if (!theParams->IsModulate())
300 anEnvMode = GL_DECAL;
301 if (theTexture.GetFormat() == GL_ALPHA
302 || theTexture.GetFormat() == GL_LUMINANCE)
304 anEnvMode = GL_REPLACE;
308 // setup generation of texture coordinates
309 switch (theParams->GenMode())
311 case Graphic3d_TOTM_OBJECT:
313 theCtx->core11->glTexGeni (GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
314 theCtx->core11->glTexGenfv (GL_S, GL_OBJECT_PLANE, theParams->GenPlaneS().GetData());
315 if (theTexture.GetTarget() != GL_TEXTURE_1D)
317 theCtx->core11->glTexGeni (GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
318 theCtx->core11->glTexGenfv (GL_T, GL_OBJECT_PLANE, theParams->GenPlaneT().GetData());
322 case Graphic3d_TOTM_SPHERE:
324 theCtx->core11->glTexGeni (GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
325 if (theTexture.GetTarget() != GL_TEXTURE_1D)
327 theCtx->core11->glTexGeni (GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
331 case Graphic3d_TOTM_EYE:
333 theCtx->WorldViewState.Push();
334 theCtx->WorldViewState.SetIdentity();
335 theCtx->ApplyWorldViewMatrix();
337 theCtx->core11->glTexGeni (GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
338 theCtx->core11->glTexGenfv (GL_S, GL_EYE_PLANE, theParams->GenPlaneS().GetData());
339 if (theTexture.GetTarget() != GL_TEXTURE_1D)
341 theCtx->core11->glTexGeni (GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
342 theCtx->core11->glTexGenfv (GL_T, GL_EYE_PLANE, theParams->GenPlaneT().GetData());
345 theCtx->WorldViewState.Pop();
348 case Graphic3d_TOTM_SPRITE:
350 if (theCtx->core20fwd != NULL)
352 theCtx->core11fwd->glEnable (GL_POINT_SPRITE);
353 glTexEnvi (GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE);
354 anEnvMode = GL_REPLACE;
358 case Graphic3d_TOTM_MANUAL:
363 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, anEnvMode);
365 switch (theTexture.GetTarget())
369 if (theParams->GenMode() != Graphic3d_TOTM_MANUAL)
371 theCtx->core11fwd->glEnable (GL_TEXTURE_GEN_S);
373 theCtx->core11fwd->glEnable (GL_TEXTURE_1D);
378 if (theParams->GenMode() != Graphic3d_TOTM_MANUAL)
380 theCtx->core11fwd->glEnable (GL_TEXTURE_GEN_S);
381 theCtx->core11fwd->glEnable (GL_TEXTURE_GEN_T);
383 theCtx->core11fwd->glEnable (GL_TEXTURE_2D);
391 // =======================================================================
392 // function : resetGlobalTextureParams
394 // =======================================================================
395 void OpenGl_Sampler::resetGlobalTextureParams (const Handle(OpenGl_Context)& theCtx,
396 const OpenGl_Texture& theTexture,
397 const Handle(Graphic3d_TextureParams)& theParams)
399 #if defined(GL_ES_VERSION_2_0)
404 if (theCtx->core11 == NULL)
409 // reset texture matrix because some code may expect it is identity
410 GLint aMatrixMode = GL_TEXTURE;
411 theCtx->core11fwd->glGetIntegerv (GL_MATRIX_MODE, &aMatrixMode);
412 theCtx->core11->glMatrixMode (GL_TEXTURE);
413 theCtx->core11->glLoadIdentity();
414 theCtx->core11->glMatrixMode (aMatrixMode);
416 switch (theTexture.GetTarget())
420 if (theParams->GenMode() != GL_NONE)
422 theCtx->core11fwd->glDisable (GL_TEXTURE_GEN_S);
424 theCtx->core11fwd->glDisable (GL_TEXTURE_1D);
429 if (theParams->GenMode() != GL_NONE)
431 theCtx->core11fwd->glDisable (GL_TEXTURE_GEN_S);
432 theCtx->core11fwd->glDisable (GL_TEXTURE_GEN_T);
433 if (theParams->GenMode() == Graphic3d_TOTM_SPRITE
434 && theCtx->core20fwd != NULL)
436 theCtx->core11fwd->glDisable (GL_POINT_SPRITE);
439 theCtx->core11fwd->glDisable (GL_TEXTURE_2D);