Graphic3d_AspectFillArea3d now stores array of textures.
Graphic3d_TextureParams stores texture unit for mapping texture.
OpenGl_Context::BindTextures() - context now manages the set of active textures.
Related code has been removed from OpenGl_Workspace.
OpenGl_Sampler has been extended to hold texture parameters structure.
OpenGl_Texture now holds OpenGl_Sampler instance as class field.
OpenGl_Texture inherits new class OpenGl_NamedResource and holds
texture identifier used for sharing resource in OpenGl_Context.
OpenGl_RaytraceGeometry now creates bindless textures taking
Sampler object directly from OpenGl_Texture.
OpenGl_Context::BindTextures() automatically recreates immutable
Sampler Object on texture parameters change.
Declared new structure OpenGl_ArbSamplerObject for platform-neutral
usage of related functionality.
Related functions are now loaded within OpenGL ES 3.0+.
Declarations.glsl - occActiveSampler has been renamed to occSampler0
with aliases occSamplerBaseColor (main) and occActiveSampler (for compatibility).
Additional texture samplers should be declared explicitly
within specific GLSL program as occSampler1, occSampler2, etc.
AIS_Shape and AIS_ColoredShape now computes Shaded presentation
with UV coordinates if texture mapping is enabled in Drawer.
vshaderprog now accepts Shader source code as parameter.
Graphic3d_TextureParams.hxx
Graphic3d_TextureRoot.cxx
Graphic3d_TextureRoot.hxx
+Graphic3d_TextureUnit.hxx
+Graphic3d_TextureSet.cxx
+Graphic3d_TextureSet.hxx
Graphic3d_ToneMappingMethod.hxx
Graphic3d_TransformError.hxx
Graphic3d_TransformPers.hxx
throw Aspect_AspectFillAreaDefinitionError("Bad value for EdgeLineWidth");
}
}
+
+// =======================================================================
+// function : Graphic3d_AspectFillArea3d
+// purpose :
+// =======================================================================
+void Graphic3d_AspectFillArea3d::SetTextureMap (const Handle(Graphic3d_TextureMap)& theTexture)
+{
+ if (theTexture.IsNull())
+ {
+ myTextureSet.Nullify();
+ return;
+ }
+
+ myTextureSet = new Graphic3d_TextureSet (theTexture);
+}
#include <Graphic3d_PolygonOffset.hxx>
#include <Graphic3d_ShaderProgram.hxx>
#include <Graphic3d_TextureMap.hxx>
+#include <Graphic3d_TextureSet.hxx>
#include <Standard.hxx>
#include <Standard_Boolean.hxx>
#include <Standard_Integer.hxx>
//! Sets up OpenGL/GLSL shader program.
void SetShaderProgram (const Handle(Graphic3d_ShaderProgram)& theProgram) { myProgram = theProgram; }
+ //! Return texture array to be mapped.
+ const Handle(Graphic3d_TextureSet)& TextureSet() const { return myTextureSet; }
+
+ //! Setup texture array to be mapped.
+ void SetTextureSet (const Handle(Graphic3d_TextureSet)& theTextures) { myTextureSet = theTextures; }
+
//! Return texture to be mapped.
- const Handle(Graphic3d_TextureMap)& TextureMap() const { return myTextureMap; }
+ //Standard_DEPRECATED("Deprecated method, TextureSet() should be used instead")
+ Handle(Graphic3d_TextureMap) TextureMap() const
+ {
+ return !myTextureSet.IsNull() && !myTextureSet->IsEmpty()
+ ? myTextureSet->First()
+ : Handle(Graphic3d_TextureMap)();
+ }
//! Assign texture to be mapped.
- //! See also SetTextureMap() to actually activate texture mapping.
- void SetTextureMap (const Handle(Graphic3d_TextureMap)& theTexture) { myTextureMap = theTexture; }
+ //! See also SetTextureMapOn() to actually activate texture mapping.
+ //Standard_DEPRECATED("Deprecated method, SetTextureSet() should be used instead")
+ Standard_EXPORT void SetTextureMap (const Handle(Graphic3d_TextureMap)& theTexture);
//! Return true if texture mapping is enabled (false by default).
bool ToMapTexture() const { return myToMapTexture; }
//! Return true if texture mapping is enabled (false by default).
bool TextureMapState() const { return myToMapTexture; }
+ //! Enable or disable texture mapping (has no effect if texture is not set).
+ void SetTextureMapOn (bool theToMap) { myToMapTexture = theToMap; }
+
//! Enable texture mapping (has no effect if texture is not set).
void SetTextureMapOn() { myToMapTexture = true; }
protected:
Handle(Graphic3d_ShaderProgram) myProgram;
- Handle(Graphic3d_TextureMap) myTextureMap;
+ Handle(Graphic3d_TextureSet) myTextureSet;
Graphic3d_MaterialAspect myFrontMaterial;
Graphic3d_MaterialAspect myBackMaterial;
// =======================================================================
void Graphic3d_ClipPlane::SetCappingTexture (const Handle(Graphic3d_TextureMap)& theTexture)
{
- myAspect->SetTextureMap (theTexture);
if (!theTexture.IsNull())
{
myAspect->SetTextureMapOn();
+ Handle(Graphic3d_TextureSet) aTextureSet = myAspect->TextureSet();
+ if (aTextureSet.IsNull() || aTextureSet->Size() != 1)
+ {
+ aTextureSet = new Graphic3d_TextureSet (theTexture);
+ }
+ else
+ {
+ aTextureSet->SetFirst (theTexture);
+ }
+ myAspect->SetTextureSet (aTextureSet);
}
else
{
myAspect->SetTextureMapOff();
+ myAspect->SetTextureSet (Handle(Graphic3d_TextureSet)());
}
++myAspectMod;
}
Standard_EXPORT void SetCappingTexture (const Handle(Graphic3d_TextureMap)& theTexture);
//! @return capping texture map.
- const Handle(Graphic3d_TextureMap)& CappingTexture() const { return myAspect->TextureMap(); }
+ Handle(Graphic3d_TextureMap) CappingTexture() const { return !myAspect->TextureSet().IsNull() && !myAspect->TextureSet()->IsEmpty()
+ ? myAspect->TextureSet()->First()
+ : Handle(Graphic3d_TextureMap)(); }
//! Set hatch style (stipple) and turn hatching on.
//! @param theStyle [in] the hatch style.
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
-
#include <Graphic3d_TextureParams.hxx>
-#include <Standard_Type.hxx>
IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_TextureParams,Standard_Transient)
// purpose :
// =======================================================================
Graphic3d_TextureParams::Graphic3d_TextureParams()
-: myToModulate (Standard_False),
- myToRepeat (Standard_False),
- myFilter (Graphic3d_TOTF_NEAREST),
- myAnisoLevel (Graphic3d_LOTA_OFF),
- myRotAngle (0.0f),
+: myGenPlaneS (0.0f, 0.0f, 0.0f, 0.0f),
+ myGenPlaneT (0.0f, 0.0f, 0.0f, 0.0f),
myScale (1.0f, 1.0f),
myTranslation(0.0f, 0.0f),
+ mySamplerRevision (0),
+ myTextureUnit(Graphic3d_TextureUnit_BaseColor),
+ myFilter (Graphic3d_TOTF_NEAREST),
+ myAnisoLevel (Graphic3d_LOTA_OFF),
myGenMode (Graphic3d_TOTM_MANUAL),
- myGenPlaneS (0.0f, 0.0f, 0.0f, 0.0f),
- myGenPlaneT (0.0f, 0.0f, 0.0f, 0.0f)
+ myRotAngle (0.0f),
+ myToModulate (Standard_False),
+ myToRepeat (Standard_False)
{
//
}
// =======================================================================
-// function : Destroy
+// function : ~Graphic3d_TextureParams
// purpose :
// =======================================================================
-void Graphic3d_TextureParams::Destroy() const
+Graphic3d_TextureParams::~Graphic3d_TextureParams()
{
//
}
-// =======================================================================
-// function : IsModulate
-// purpose :
-// =======================================================================
-Standard_Boolean Graphic3d_TextureParams::IsModulate() const
-{
- return myToModulate;
-}
-
// =======================================================================
// function : SetModulate
// purpose :
myToModulate = theToModulate;
}
-// =======================================================================
-// function : IsRepeat
-// purpose :
-// =======================================================================
-Standard_Boolean Graphic3d_TextureParams::IsRepeat() const
-{
- return myToRepeat;
-}
-
// =======================================================================
// function : SetRepeat
// purpose :
// =======================================================================
void Graphic3d_TextureParams::SetRepeat (const Standard_Boolean theToRepeat)
{
- myToRepeat = theToRepeat;
-}
-
-// =======================================================================
-// function : Filter
-// purpose :
-// =======================================================================
-Graphic3d_TypeOfTextureFilter Graphic3d_TextureParams::Filter() const
-{
- return myFilter;
+ if (myToRepeat != theToRepeat)
+ {
+ myToRepeat = theToRepeat;
+ updateSamplerRevision();
+ }
}
// =======================================================================
// =======================================================================
void Graphic3d_TextureParams::SetFilter (const Graphic3d_TypeOfTextureFilter theFilter)
{
- myFilter = theFilter;
-}
-
-// =======================================================================
-// function : AnisoFilter
-// purpose :
-// =======================================================================
-Graphic3d_LevelOfTextureAnisotropy Graphic3d_TextureParams::AnisoFilter() const
-{
- return myAnisoLevel;
+ if (myFilter != theFilter)
+ {
+ myFilter = theFilter;
+ updateSamplerRevision();
+ }
}
// =======================================================================
// =======================================================================
void Graphic3d_TextureParams::SetAnisoFilter (const Graphic3d_LevelOfTextureAnisotropy theLevel)
{
- myAnisoLevel = theLevel;
-}
-
-// =======================================================================
-// function : Rotation
-// purpose :
-// =======================================================================
-Standard_ShortReal Graphic3d_TextureParams::Rotation() const
-{
- return myRotAngle;
+ if (myAnisoLevel != theLevel)
+ {
+ myAnisoLevel = theLevel;
+ updateSamplerRevision();
+ }
}
// =======================================================================
myRotAngle = theAngleDegrees;
}
-// =======================================================================
-// function : Scale
-// purpose :
-// =======================================================================
-const Graphic3d_Vec2& Graphic3d_TextureParams::Scale() const
-{
- return myScale;
-}
-
// =======================================================================
// function : SetScale
// purpose :
myScale = theScale;
}
-// =======================================================================
-// function : Translation
-// purpose :
-// =======================================================================
-const Graphic3d_Vec2& Graphic3d_TextureParams::Translation() const
-{
- return myTranslation;
-}
-
// =======================================================================
// function : SetTranslation
// purpose :
myTranslation = theVec;
}
-// =======================================================================
-// function : GenMode
-// purpose :
-// =======================================================================
-Graphic3d_TypeOfTextureMode Graphic3d_TextureParams::GenMode() const
-{
- return myGenMode;
-}
-
-// =======================================================================
-// function : GenPlaneS
-// purpose :
-// =======================================================================
-const Graphic3d_Vec4& Graphic3d_TextureParams::GenPlaneS() const
-{
- return myGenPlaneS;
-}
-
-// =======================================================================
-// function : GenPlaneT
-// purpose :
-// =======================================================================
-const Graphic3d_Vec4& Graphic3d_TextureParams::GenPlaneT() const
-{
- return myGenPlaneT;
-}
-
// =======================================================================
// function : SetGenMode
// purpose :
#ifndef _Graphic3d_TextureParams_HeaderFile
#define _Graphic3d_TextureParams_HeaderFile
-#include <Standard.hxx>
-#include <Standard_Type.hxx>
-
-#include <Standard_Boolean.hxx>
-#include <Graphic3d_TypeOfTextureFilter.hxx>
#include <Graphic3d_LevelOfTextureAnisotropy.hxx>
-#include <Standard_ShortReal.hxx>
#include <Graphic3d_Vec2.hxx>
-#include <Graphic3d_TypeOfTextureMode.hxx>
#include <Graphic3d_Vec4.hxx>
+#include <Graphic3d_TextureUnit.hxx>
+#include <Graphic3d_TypeOfTextureFilter.hxx>
+#include <Graphic3d_TypeOfTextureMode.hxx>
+#include <Standard.hxx>
+#include <Standard_Boolean.hxx>
+#include <Standard_ShortReal.hxx>
+#include <Standard_Type.hxx>
#include <Standard_Transient.hxx>
-
-class Graphic3d_TextureParams;
-DEFINE_STANDARD_HANDLE(Graphic3d_TextureParams, Standard_Transient)
-
//! This class describes texture parameters.
class Graphic3d_TextureParams : public Standard_Transient
{
-
+ DEFINE_STANDARD_RTTIEXT(Graphic3d_TextureParams, Standard_Transient)
public:
-
//! Default constructor.
Standard_EXPORT Graphic3d_TextureParams();
-
- Standard_EXPORT void Destroy() const;
-~Graphic3d_TextureParams()
-{
- Destroy();
-}
-
+
+ //! Destructor.
+ Standard_EXPORT virtual ~Graphic3d_TextureParams();
+
+ //! Default texture unit to be used, default is Graphic3d_TextureUnit_BaseColor.
+ Graphic3d_TextureUnit TextureUnit() const { return myTextureUnit; }
+
+ //! Setup default texture unit.
+ void SetTextureUnit (Graphic3d_TextureUnit theUnit) { myTextureUnit = theUnit; }
+
//! @return TRUE if the texture is modulate.
//! Default value is FALSE.
- Standard_EXPORT Standard_Boolean IsModulate() const;
+ Standard_Boolean IsModulate() const { return myToModulate; }
//! @param theToModulate turn modulation on/off.
Standard_EXPORT void SetModulate (const Standard_Boolean theToModulate);
//! @return TRUE if the texture repeat is enabled.
//! Default value is FALSE.
- Standard_EXPORT Standard_Boolean IsRepeat() const;
+ Standard_Boolean IsRepeat() const { return myToRepeat; }
//! @param theToRepeat turn texture repeat mode ON or OFF (clamping).
Standard_EXPORT void SetRepeat (const Standard_Boolean theToRepeat);
//! @return texture interpolation filter.
//! Default value is Graphic3d_TOTF_NEAREST.
- Standard_EXPORT Graphic3d_TypeOfTextureFilter Filter() const;
+ Graphic3d_TypeOfTextureFilter Filter() const { return myFilter; }
//! @param theFilter texture interpolation filter.
Standard_EXPORT void SetFilter (const Graphic3d_TypeOfTextureFilter theFilter);
//! @return level of anisontropy texture filter.
//! Default value is Graphic3d_LOTA_OFF.
- Standard_EXPORT Graphic3d_LevelOfTextureAnisotropy AnisoFilter() const;
+ Graphic3d_LevelOfTextureAnisotropy AnisoFilter() const { return myAnisoLevel; }
//! @param theLevel level of anisontropy texture filter.
Standard_EXPORT void SetAnisoFilter (const Graphic3d_LevelOfTextureAnisotropy theLevel);
//! @return rotation angle in degrees
//! Default value is 0.
- Standard_EXPORT Standard_ShortReal Rotation() const;
+ Standard_ShortReal Rotation() const { return myRotAngle; }
//! @param theAngleDegrees rotation angle.
Standard_EXPORT void SetRotation (const Standard_ShortReal theAngleDegrees);
//! @return scale factor
//! Default value is no scaling (1.0; 1.0).
- Standard_EXPORT const Graphic3d_Vec2& Scale() const;
+ const Graphic3d_Vec2& Scale() const { return myScale; }
//! @param theScale scale factor.
Standard_EXPORT void SetScale (const Graphic3d_Vec2 theScale);
//! @return translation vector
//! Default value is no translation (0.0; 0.0).
- Standard_EXPORT const Graphic3d_Vec2& Translation() const;
+ const Graphic3d_Vec2& Translation() const { return myTranslation; }
//! @param theVec translation vector.
Standard_EXPORT void SetTranslation (const Graphic3d_Vec2 theVec);
//! @return texture coordinates generation mode.
//! Default value is Graphic3d_TOTM_MANUAL.
- Standard_EXPORT Graphic3d_TypeOfTextureMode GenMode() const;
+ Graphic3d_TypeOfTextureMode GenMode() const { return myGenMode; }
//! @return texture coordinates generation plane S.
- Standard_EXPORT const Graphic3d_Vec4& GenPlaneS() const;
+ const Graphic3d_Vec4& GenPlaneS() const { return myGenPlaneS; }
//! @return texture coordinates generation plane T.
- Standard_EXPORT const Graphic3d_Vec4& GenPlaneT() const;
+ const Graphic3d_Vec4& GenPlaneT() const { return myGenPlaneT; }
//! Setup texture coordinates generation mode.
Standard_EXPORT void SetGenMode (const Graphic3d_TypeOfTextureMode theMode, const Graphic3d_Vec4 thePlaneS, const Graphic3d_Vec4 thePlaneT);
-
-
- DEFINE_STANDARD_RTTIEXT(Graphic3d_TextureParams,Standard_Transient)
-
-protected:
-
-
-
+ //! Return modification counter of parameters related to sampler state.
+ unsigned int SamplerRevision() const { return mySamplerRevision; }
private:
+ //! Increment revision.
+ void updateSamplerRevision() { ++mySamplerRevision; }
- Standard_Boolean myToModulate;
- Standard_Boolean myToRepeat;
- Graphic3d_TypeOfTextureFilter myFilter;
- Graphic3d_LevelOfTextureAnisotropy myAnisoLevel;
- Standard_ShortReal myRotAngle;
- Graphic3d_Vec2 myScale;
- Graphic3d_Vec2 myTranslation;
- Graphic3d_TypeOfTextureMode myGenMode;
- Graphic3d_Vec4 myGenPlaneS;
- Graphic3d_Vec4 myGenPlaneT;
+private:
+ Graphic3d_Vec4 myGenPlaneS; //!< texture coordinates generation plane S
+ Graphic3d_Vec4 myGenPlaneT; //!< texture coordinates generation plane T
+ Graphic3d_Vec2 myScale; //!< texture coordinates scale factor vector; (1,1) by default
+ Graphic3d_Vec2 myTranslation; //!< texture coordinates translation vector; (0,0) by default
+ unsigned int mySamplerRevision; //!< modification counter of parameters related to sampler state
+ Graphic3d_TextureUnit myTextureUnit; //!< default texture unit to bind texture; Graphic3d_TextureUnit_BaseColor by default
+ Graphic3d_TypeOfTextureFilter myFilter; //!< texture filter, Graphic3d_TOTF_NEAREST by default
+ Graphic3d_LevelOfTextureAnisotropy myAnisoLevel; //!< level of anisotropy filter, Graphic3d_LOTA_OFF by default
+ Graphic3d_TypeOfTextureMode myGenMode; //!< texture coordinates generation mode, Graphic3d_TOTM_MANUAL by default
+ Standard_ShortReal myRotAngle; //!< texture coordinates rotation angle in degrees, 0 by default
+ Standard_Boolean myToModulate; //!< flag to modulate texture with material color, FALSE by default
+ Standard_Boolean myToRepeat; //!< flag to repeat (true) or wrap (false) texture coordinates out of [0,1] range
};
-
-
-
-
-
+DEFINE_STANDARD_HANDLE(Graphic3d_TextureParams, Standard_Transient)
#endif // _Graphic3d_TextureParams_HeaderFile
//! This ID will be used to manage resource in graphic driver.
//!
- //! Default implementation generates unique ID although inheritors may re-initialize it.
+ //! Default implementation generates unique ID within constructor;
+ //! inheritors may re-initialize it within their constructor,
+ //! but should never modify it afterwards.
//!
//! Multiple Graphic3d_TextureRoot instances with same ID
//! will be treated as single texture with different parameters
//! to optimize memory usage though this will be more natural
//! to use same instance of Graphic3d_TextureRoot when possible.
//!
- //! Notice that inheritor may set this ID to empty string.
- //! In this case independent graphical resource will be created
+ //! If this ID is set to empty string by inheritor,
+ //! then independent graphical resource will be created
//! for each instance of Graphic3d_AspectFillArea3d where texture will be used.
//!
//! @return texture identifier.
//! Update image revision.
//! Can be used for signaling changes in the texture source (e.g. file update, pixmap update)
- //! without re-creating texture source itself (e.g. preserving the unique id).
+ //! without re-creating texture source itself (since unique id should be never modified).
void UpdateRevision() { ++myRevision; }
//! This method will be called by graphic driver each time when texture resource should be created.
//! to be in Bottom-Up order (see Image_PixMap::IsTopDown()).
Standard_EXPORT Graphic3d_TextureRoot(const Handle(Image_PixMap)& thePixmap, const Graphic3d_TypeOfTexture theType);
- //! Unconditionally generate new texture id.
+ //! Unconditionally generate new texture id. Should be called only within constructor.
Standard_EXPORT void generateId();
protected:
Handle(Graphic3d_TextureParams) myParams; //!< associated texture parameters
- TCollection_AsciiString myTexId; //!< unique identifier of this resource (for sharing)
+ TCollection_AsciiString myTexId; //!< unique identifier of this resource (for sharing graphic resource); should never be modified outside constructor
Handle(Image_PixMap) myPixMap; //!< image pixmap - as one of the ways for defining the texture source
OSD_Path myPath; //!< image file path - as one of the ways for defining the texture source
Standard_Size myRevision; //!< image revision - for signaling changes in the texture source (e.g. file update, pixmap update)
--- /dev/null
+// Copyright (c) 2017 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <Graphic3d_TextureSet.hxx>
+
+IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_TextureSet, Standard_Transient)
--- /dev/null
+// Copyright (c) 2017 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _Graphic3d_TextureSet_HeaderFile
+#define _Graphic3d_TextureSet_HeaderFile
+
+#include <Graphic3d_TextureMap.hxx>
+#include <NCollection_Array1.hxx>
+
+//! Class holding array of textures to be mapped as a set.
+class Graphic3d_TextureSet : public Standard_Transient
+{
+ DEFINE_STANDARD_RTTIEXT(Graphic3d_TextureSet, Standard_Transient)
+public:
+
+ //! Class for iterating texture set.
+ class Iterator : public NCollection_Array1<Handle(Graphic3d_TextureMap)>::Iterator
+ {
+ public:
+ //! Empty constructor.
+ Iterator() {}
+
+ //! Constructor.
+ Iterator (const Handle(Graphic3d_TextureSet)& theSet)
+ {
+ if (!theSet.IsNull())
+ {
+ NCollection_Array1<Handle(Graphic3d_TextureMap)>::Iterator::Init (theSet->myTextures);
+ }
+ }
+ };
+
+public:
+
+ //! Empty constructor.
+ Graphic3d_TextureSet() {}
+
+ //! Constructor.
+ Graphic3d_TextureSet (Standard_Integer theNbTextures)
+ : myTextures (0, theNbTextures - 1) {}
+
+ //! Constructor for a single texture.
+ Graphic3d_TextureSet (const Handle(Graphic3d_TextureMap)& theTexture)
+ : myTextures (0, 0)
+ {
+ myTextures.ChangeFirst() = theTexture;
+ }
+
+ //! Return TRUE if texture array is empty.
+ Standard_Boolean IsEmpty() const { return myTextures.IsEmpty(); }
+
+ //! Return number of textures.
+ Standard_Integer Size() const { return myTextures.Size(); }
+
+ //! Return the lower index in texture set.
+ Standard_Integer Lower() const { return myTextures.Lower(); }
+
+ //! Return the upper index in texture set.
+ Standard_Integer Upper() const { return myTextures.Upper(); }
+
+ //! Return the first texture.
+ const Handle(Graphic3d_TextureMap)& First() const { return myTextures.First(); }
+
+ //! Return the first texture.
+ void SetFirst (const Handle(Graphic3d_TextureMap)& theTexture) { myTextures.ChangeFirst() = theTexture; }
+
+ //! Return the texture at specified position within [0, Size()) range.
+ const Handle(Graphic3d_TextureMap)& Value (Standard_Integer theIndex) const { return myTextures.Value (theIndex); }
+
+ //! Return the texture at specified position within [0, Size()) range.
+ void SetValue (Standard_Integer theIndex,
+ const Handle(Graphic3d_TextureMap)& theTexture) { myTextures.SetValue (theIndex, theTexture); }
+
+protected:
+
+ NCollection_Array1<Handle(Graphic3d_TextureMap)> myTextures;
+
+};
+
+#endif // _Graphic3d_TextureSet_HeaderFile
--- /dev/null
+// Copyright (c) 2017 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _Graphic3d_TextureUnit_HeaderFile
+#define _Graphic3d_TextureUnit_HeaderFile
+
+//! Texture unit.
+enum Graphic3d_TextureUnit
+{
+ // value as index number
+ Graphic3d_TextureUnit_0,
+ Graphic3d_TextureUnit_1,
+ Graphic3d_TextureUnit_2,
+ Graphic3d_TextureUnit_3,
+ Graphic3d_TextureUnit_4,
+ Graphic3d_TextureUnit_5,
+ Graphic3d_TextureUnit_6,
+ Graphic3d_TextureUnit_7,
+ Graphic3d_TextureUnit_8,
+ Graphic3d_TextureUnit_9,
+ Graphic3d_TextureUnit_10,
+ Graphic3d_TextureUnit_11,
+ Graphic3d_TextureUnit_12,
+ Graphic3d_TextureUnit_13,
+ Graphic3d_TextureUnit_14,
+ Graphic3d_TextureUnit_15,
+
+ Graphic3d_TextureUnit_BaseColor = Graphic3d_TextureUnit_0, //!< base color of the material
+ //Graphic3d_TextureUnit_Normal = Graphic3d_TextureUnit_1, //!< tangent space normal map
+ //Graphic3d_TextureUnit_MetallicRoughness = Graphic3d_TextureUnit_2, //!< metalness+roughness of the material
+ //Graphic3d_TextureUnit_Emissive = Graphic3d_TextureUnit_3, //!< emissive map controls the color and intensity of the light being emitted by the material
+ //Graphic3d_TextureUnit_Occlusion = Graphic3d_TextureUnit_4, //!< occlusion map indicating areas of indirect lighting
+};
+enum
+{
+ Graphic3d_TextureUnit_NB = Graphic3d_TextureUnit_15 + 1
+};
+
+#endif // _Graphic3d_TextureUnit_HeaderFile
Graphic3d_TypeOfLimit_MaxNbClipPlanes, //!< maximum number of active clipping planes
Graphic3d_TypeOfLimit_MaxNbViews, //!< maximum number of views
Graphic3d_TypeOfLimit_MaxTextureSize, //!< maximum size of texture
+ Graphic3d_TypeOfLimit_MaxCombinedTextureUnits, //!< maximum number of combined texture units for multitexturing
Graphic3d_TypeOfLimit_MaxMsaa, //!< maximum number of MSAA samples
Graphic3d_TypeOfLimit_HasRayTracing, //!< indicates whether ray tracing is supported
Graphic3d_TypeOfLimit_HasRayTracingTextures, //!< indicates whether ray tracing textures are supported
OpenGl_ArbDbg.hxx
OpenGl_ArbFBO.hxx
OpenGl_ArbIns.hxx
+OpenGl_ArbSamplerObject.hxx
OpenGl_ArbTBO.hxx
OpenGl_ArbTexBindless.hxx
OpenGl_AspectFace.cxx
OpenGl_FrameBuffer.cxx
OpenGl_Texture.cxx
OpenGl_Texture.hxx
+OpenGl_TextureSet.cxx
+OpenGl_TextureSet.hxx
OpenGl_Resource.hxx
OpenGl_Resource.cxx
+OpenGl_NamedResource.hxx
OpenGl_Font.hxx
OpenGl_Font.cxx
OpenGl_BackgroundArray.cxx
--- /dev/null
+// Copyright (c) 2017 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _OpenGl_ArbSamplerObject_Header
+#define _OpenGl_ArbSamplerObject_Header
+
+#include <OpenGl_GlFunctions.hxx>
+
+//! Provide Sampler Object functionality (texture parameters stored independently from texture itself).
+//! Available since OpenGL 3.3+ (GL_ARB_sampler_objects extension) and OpenGL ES 3.0+.
+struct OpenGl_ArbSamplerObject : protected OpenGl_GlFunctions
+{
+ using OpenGl_GlFunctions::glGenSamplers;
+ using OpenGl_GlFunctions::glDeleteSamplers;
+ using OpenGl_GlFunctions::glIsSampler;
+ using OpenGl_GlFunctions::glBindSampler;
+ using OpenGl_GlFunctions::glSamplerParameteri;
+ using OpenGl_GlFunctions::glSamplerParameteriv;
+ using OpenGl_GlFunctions::glSamplerParameterf;
+ using OpenGl_GlFunctions::glSamplerParameterfv;
+ using OpenGl_GlFunctions::glGetSamplerParameteriv;
+ using OpenGl_GlFunctions::glGetSamplerParameterfv;
+
+#if !defined(GL_ES_VERSION_2_0)
+ using OpenGl_GlFunctions::glSamplerParameterIiv;
+ using OpenGl_GlFunctions::glSamplerParameterIuiv;
+ using OpenGl_GlFunctions::glGetSamplerParameterIiv;
+ using OpenGl_GlFunctions::glGetSamplerParameterIuiv;
+#endif
+
+};
+
+#endif // _OpenGl_ArbSamplerObject_Header
#include <OpenGl_AspectFace.hxx>
#include <OpenGl_Context.hxx>
+#include <OpenGl_Sampler.hxx>
#include <OpenGl_ShaderManager.hxx>
#include <OpenGl_ShaderProgram.hxx>
#include <OpenGl_Texture.hxx>
myAspectEdge.Aspect()->SetWidth (theAspect->EdgeWidth());
// update texture binding
- const TCollection_AsciiString& aTextureKey = myAspect->TextureMap().IsNull() ? THE_EMPTY_KEY : myAspect->TextureMap()->GetId();
- if (aTextureKey.IsEmpty() || myResources.TextureId != aTextureKey)
- {
- myResources.ResetTextureReadiness();
- }
- else if (!myResources.Texture.IsNull()
- && !myAspect->TextureMap().IsNull()
- && myResources.Texture->Revision() != myAspect->TextureMap()->Revision())
- {
- myResources.ResetTextureReadiness();
- }
+ myResources.UpdateTexturesRediness (myAspect->TextureSet());
// update shader program binding
const TCollection_AsciiString& aShaderKey = myAspect->ShaderProgram().IsNull() ? THE_EMPTY_KEY : myAspect->ShaderProgram()->GetId();
// =======================================================================
void OpenGl_AspectFace::Release (OpenGl_Context* theContext)
{
- if (!myResources.Texture.IsNull())
- {
- if (theContext)
- {
- if (myResources.TextureId.IsEmpty())
- {
- theContext->DelayedRelease (myResources.Texture);
- }
- else
- {
- myResources.Texture.Nullify(); // we need nullify all handles before ReleaseResource() call
- theContext->ReleaseResource (myResources.TextureId, Standard_True);
- }
- }
- myResources.Texture.Nullify();
- }
- myResources.TextureId.Clear();
- myResources.ResetTextureReadiness();
-
+ myResources.ReleaseTextures (theContext);
if (!myResources.ShaderProgram.IsNull()
&& theContext)
{
}
// =======================================================================
-// function : BuildTexture
+// function : ReleaseTextures
// purpose :
// =======================================================================
-void OpenGl_AspectFace::Resources::BuildTexture (const Handle(OpenGl_Context)& theCtx,
- const Handle(Graphic3d_TextureMap)& theTexture)
+void OpenGl_AspectFace::Resources::ReleaseTextures (OpenGl_Context* theCtx)
{
- // release old texture resource
- if (!Texture.IsNull())
+ if (myTextures.IsNull())
+ {
+ return;
+ }
+
+ for (OpenGl_TextureSet::Iterator aTextureIter (myTextures); aTextureIter.More(); aTextureIter.Next())
{
- if (!theTexture.IsNull()
- && theTexture->GetId() == TextureId
- && theTexture->Revision() != Texture->Revision())
+ Handle(OpenGl_Texture)& aTextureRes = aTextureIter.ChangeValue();
+ if (aTextureRes.IsNull())
{
- Handle(Image_PixMap) anImage = theTexture->GetImage();
- if (!anImage.IsNull())
+ continue;
+ }
+
+ if (theCtx != NULL)
+ {
+ if (aTextureRes->ResourceId().IsEmpty())
{
- Texture->Init (theCtx, *anImage.operator->(), theTexture->Type());
- Texture->SetRevision (Texture->Revision());
- return;
+ theCtx->DelayedRelease (aTextureRes);
}
+ else
+ {
+ const TCollection_AsciiString aName = aTextureRes->ResourceId();
+ aTextureRes.Nullify(); // we need nullify all handles before ReleaseResource() call
+ theCtx->ReleaseResource (aName, Standard_True);
+ }
+ }
+ aTextureRes.Nullify();
+ }
+ myIsTextureReady = Standard_False;
+}
+
+// =======================================================================
+// function : UpdateTexturesRediness
+// purpose :
+// =======================================================================
+void OpenGl_AspectFace::Resources::UpdateTexturesRediness (const Handle(Graphic3d_TextureSet)& theTextures)
+{
+ const Standard_Integer aNbTexturesOld = !myTextures.IsNull() ? myTextures->Size() : 0;
+ const Standard_Integer aNbTexturesNew = !theTextures.IsNull() ? theTextures->Size() : 0;
+ if (aNbTexturesOld != aNbTexturesNew)
+ {
+ myIsTextureReady = Standard_False;
+ return;
+ }
+ if (aNbTexturesOld == 0)
+ {
+ return;
+ }
+
+ Graphic3d_TextureSet::Iterator aTextureIter (theTextures);
+ OpenGl_TextureSet::Iterator aResIter (myTextures);
+ for (; aResIter.More(); aResIter.Next(), aTextureIter.Next())
+ {
+ const Handle(OpenGl_Texture)& aResource = aResIter.Value();
+ const Handle(Graphic3d_TextureMap)& aTexture = aTextureIter.Value();
+ if (aTexture.IsNull() != aResource.IsNull())
+ {
+ myIsTextureReady = Standard_False;
+ return;
+ }
+ else if (aTexture.IsNull())
+ {
+ continue;
}
- if (TextureId.IsEmpty())
+ const TCollection_AsciiString& aTextureKey = aTexture->GetId();
+ if (aTextureKey.IsEmpty() || aResource->ResourceId() != aTextureKey)
+ {
+ myIsTextureReady = Standard_False;
+ return;
+ }
+ else if (aResource->Revision() != aTexture->Revision())
{
- theCtx->DelayedRelease (Texture);
- Texture.Nullify();
+ myIsTextureReady = Standard_False;
+ return;
}
else
{
- Texture.Nullify(); // we need nullify all handles before ReleaseResource() call
- theCtx->ReleaseResource (TextureId, Standard_True);
+ // just invalidate texture parameters
+ aResource->Sampler()->SetParameters (aTexture->GetParams());
}
}
+}
- TextureId = theTexture.IsNull() ? THE_EMPTY_KEY : theTexture->GetId();
+// =======================================================================
+// function : BuildTextures
+// purpose :
+// =======================================================================
+void OpenGl_AspectFace::Resources::BuildTextures (const Handle(OpenGl_Context)& theCtx,
+ const Handle(Graphic3d_TextureSet)& theTextures)
+{
+ // release old texture resources
+ const Standard_Integer aNbTexturesOld = !myTextures.IsNull() ? myTextures->Size() : 0;
+ const Standard_Integer aNbTexturesNew = !theTextures.IsNull() ? theTextures->Size() : 0;
+ if (aNbTexturesOld != aNbTexturesNew)
+ {
+ ReleaseTextures (theCtx.get());
+ if (aNbTexturesNew > 0)
+ {
+ myTextures = new OpenGl_TextureSet (theTextures->Size());
+ }
+ else
+ {
+ myTextures.Nullify();
+ }
+ }
+ if (myTextures.IsNull())
+ {
+ return;
+ }
- if (!theTexture.IsNull())
+ Graphic3d_TextureSet::Iterator aTextureIter (theTextures);
+ OpenGl_TextureSet::Iterator aResIter (myTextures);
+ for (; aResIter.More(); aResIter.Next(), aTextureIter.Next())
{
- if (TextureId.IsEmpty() || !theCtx->GetResource<Handle(OpenGl_Texture)> (TextureId, Texture))
+ Handle(OpenGl_Texture)& aResource = aResIter.ChangeValue();
+ const Handle(Graphic3d_TextureMap)& aTexture = aTextureIter.Value();
+ if (!aResource.IsNull())
+ {
+ if (!aTexture.IsNull()
+ && aTexture->GetId() == aResource->ResourceId()
+ && aTexture->Revision() != aResource->Revision())
+ {
+ if (Handle(Image_PixMap) anImage = aTexture->GetImage())
+ {
+ aResource->Sampler()->SetParameters (aTexture->GetParams());
+ aResource->Init (theCtx, *anImage.operator->(), aTexture->Type());
+ aResource->SetRevision (aTexture->Revision());
+ continue;
+ }
+ }
+
+ if (aResource->ResourceId().IsEmpty())
+ {
+ theCtx->DelayedRelease (aResource);
+ aResource.Nullify();
+ }
+ else
+ {
+ const TCollection_AsciiString aTextureKey = aResource->ResourceId();
+ aResource.Nullify(); // we need nullify all handles before ReleaseResource() call
+ theCtx->ReleaseResource (aTextureKey, Standard_True);
+ }
+ }
+
+ if (!aTexture.IsNull())
{
- Texture = new OpenGl_Texture (theTexture->GetParams());
- Handle(Image_PixMap) anImage = theTexture->GetImage();
- if (!anImage.IsNull())
+ const TCollection_AsciiString& aTextureKeyNew = aTexture->GetId();
+ if (aTextureKeyNew.IsEmpty()
+ || !theCtx->GetResource<Handle(OpenGl_Texture)> (aTextureKeyNew, aResource))
{
- Texture->Init (theCtx, *anImage.operator->(), theTexture->Type());
- Texture->SetRevision (Texture->Revision());
+ aResource = new OpenGl_Texture (aTextureKeyNew, aTexture->GetParams());
+ if (Handle(Image_PixMap) anImage = aTexture->GetImage())
+ {
+ aResource->Init (theCtx, *anImage.operator->(), aTexture->Type());
+ aResource->SetRevision (aTexture->Revision());
+ }
+ if (!aTextureKeyNew.IsEmpty())
+ {
+ theCtx->ShareResource (aTextureKeyNew, aResource);
+ }
}
- if (!TextureId.IsEmpty())
+ else
{
- theCtx->ShareResource (TextureId, Texture);
+ aResource->Sampler()->SetParameters (aTexture->GetParams());
}
}
}
#define _OpenGl_AspectFace_Header
#include <OpenGl_AspectLine.hxx>
+#include <OpenGl_TextureSet.hxx>
#include <Graphic3d_AspectFillArea3d.hxx>
#include <Graphic3d_ShaderProgram.hxx>
#include <Graphic3d_TextureMap.hxx>
//! Set if lighting should be disabled or not.
void SetNoLighting (bool theValue) { myIsNoLighting = theValue; }
- //! @return texture mapping parameters.
- const Handle(Graphic3d_TextureParams)& TextureParams() const
- {
- return myAspect->TextureMap()->GetParams();
- }
-
- //! @return texture map.
- const Handle(OpenGl_Texture)& TextureRes (const Handle(OpenGl_Context)& theCtx) const
+ //! Returne textures map.
+ const Handle(OpenGl_TextureSet)& TextureSet (const Handle(OpenGl_Context)& theCtx) const
{
if (!myResources.IsTextureReady())
{
- myResources.BuildTexture (theCtx, myAspect->TextureMap());
+ myResources.BuildTextures (theCtx, myAspect->TextureSet());
myResources.SetTextureReady();
}
-
- return myResources.Texture;
+ return myResources.TextureSet();
}
//! Init and return OpenGl shader program resource.
mutable struct Resources
{
public:
+ //! Empty constructor.
Resources()
- : myIsTextureReady (Standard_False),
- myIsShaderReady (Standard_False) {}
+ : myIsTextureReady (Standard_False),
+ myIsShaderReady (Standard_False) {}
+ //! Return TRUE if texture resource is up-to-date.
Standard_Boolean IsTextureReady() const { return myIsTextureReady; }
+
+ //! Return TRUE if shader resource is up-to-date.
Standard_Boolean IsShaderReady () const { return myIsShaderReady; }
+
+ //! Set texture resource up-to-date state.
void SetTextureReady() { myIsTextureReady = Standard_True; }
+
+ //! Set shader resource up-to-date state.
void SetShaderReady () { myIsShaderReady = Standard_True; }
- void ResetTextureReadiness() { myIsTextureReady = Standard_False; }
+
+ //! Reset shader resource up-to-date state.
void ResetShaderReadiness () { myIsShaderReady = Standard_False; }
- Standard_EXPORT void BuildTexture (const Handle(OpenGl_Context)& theCtx,
- const Handle(Graphic3d_TextureMap)& theTexture);
+ //! Return textures array.
+ const Handle(OpenGl_TextureSet)& TextureSet() const { return myTextures; }
+
+ //! Update texture resource up-to-date state.
+ Standard_EXPORT void UpdateTexturesRediness (const Handle(Graphic3d_TextureSet)& theTextures);
+
+ //! Build texture resource.
+ Standard_EXPORT void BuildTextures (const Handle(OpenGl_Context)& theCtx,
+ const Handle(Graphic3d_TextureSet)& theTextures);
+
+ //! Build shader resource.
Standard_EXPORT void BuildShader (const Handle(OpenGl_Context)& theCtx,
const Handle(Graphic3d_ShaderProgram)& theShader);
- Handle(OpenGl_Texture) Texture;
- TCollection_AsciiString TextureId;
+ //! Release texture resource.
+ Standard_EXPORT void ReleaseTextures (OpenGl_Context* theCtx);
+
Handle(OpenGl_ShaderProgram) ShaderProgram;
TCollection_AsciiString ShaderProgramId;
private:
+ Handle(OpenGl_TextureSet) myTextures;
Standard_Boolean myIsTextureReady;
Standard_Boolean myIsShaderReady;
{
myAspect = theAspect;
- // update sprite resource bindings
- TCollection_AsciiString aSpriteKey = THE_EMPTY_KEY;
- TCollection_AsciiString aSpriteAKey = THE_EMPTY_KEY;
- myResources.SpriteKeys (theAspect->GetMarkerImage(), theAspect->Type(), theAspect->Scale(), theAspect->ColorRGBA(), aSpriteKey, aSpriteAKey);
-
- if (aSpriteKey.IsEmpty() || myResources.SpriteKey != aSpriteKey
- || aSpriteAKey.IsEmpty() || myResources.SpriteAKey != aSpriteAKey)
- {
- myResources.ResetSpriteReadiness();
- myMarkerSize = theAspect->Scale();
- }
-
- // update shader program resource bindings
- const TCollection_AsciiString& aShaderKey = myAspect->ShaderProgram().IsNull() ? THE_EMPTY_KEY : myAspect->ShaderProgram()->GetId();
-
- if (aShaderKey.IsEmpty() || myResources.ShaderProgramId != aShaderKey)
- {
- myResources.ResetShaderReadiness();
- }
+ // update resource bindings
+ myResources.UpdateTexturesRediness (theAspect, myMarkerSize);
+ myResources.UpdateShaderRediness (theAspect);
}
// =======================================================================
// =======================================================================
void OpenGl_AspectMarker::Release (OpenGl_Context* theCtx)
{
- if (!myResources.Sprite.IsNull())
+ myResources.ReleaseTextures(theCtx);
+ myResources.ReleaseShaders (theCtx);
+}
+
+// =======================================================================
+// function : ReleaseTextures
+// purpose :
+// =======================================================================
+void OpenGl_AspectMarker::Resources::ReleaseTextures (OpenGl_Context* theCtx)
+{
+ myIsSpriteReady = Standard_False;
+ if (mySprite.IsNull())
+ {
+ return;
+ }
+
+ if (theCtx != NULL)
{
- if (theCtx)
+ if (mySprite->First()->ResourceId().IsEmpty())
+ {
+ theCtx->DelayedRelease (mySprite->ChangeFirst());
+ theCtx->DelayedRelease (mySpriteA->ChangeFirst());
+ }
+ else
{
- if (myResources.SpriteKey.IsEmpty())
{
- theCtx->DelayedRelease (myResources.Sprite);
- theCtx->DelayedRelease (myResources.SpriteA);
+ const TCollection_AsciiString aSpriteKey = mySprite->First()->ResourceId();
+ mySprite.Nullify(); // we need nullify all handles before ReleaseResource() call
+ theCtx->ReleaseResource (aSpriteKey, Standard_True);
}
- else
+ if (!mySpriteA.IsNull())
{
- myResources.Sprite.Nullify(); // we need nullify all handles before ReleaseResource() call
- myResources.SpriteA.Nullify();
- theCtx->ReleaseResource (myResources.SpriteKey, Standard_True);
- theCtx->ReleaseResource (myResources.SpriteAKey, Standard_True);
+ const TCollection_AsciiString aSpriteKeyA = mySpriteA->First()->ResourceId();
+ mySpriteA.Nullify();
+ theCtx->ReleaseResource (aSpriteKeyA, Standard_True);
}
}
- myResources.Sprite.Nullify();
- myResources.SpriteA.Nullify();
}
- myResources.SpriteKey.Clear();
- myResources.SpriteAKey.Clear();
- myResources.ResetSpriteReadiness();
+ mySprite.Nullify();
+ mySpriteA.Nullify();
+}
+
+// =======================================================================
+// function : ReleaseShaders
+// purpose :
+// =======================================================================
+void OpenGl_AspectMarker::Resources::ReleaseShaders (OpenGl_Context* theCtx)
+{
+ if (!myShaderProgram.IsNull() && theCtx != NULL)
+ {
+ theCtx->ShaderManager()->Unregister (myShaderProgramId,
+ myShaderProgram);
+ }
+ myShaderProgramId.Clear();
+ myIsShaderReady = Standard_False;
+}
- if (!myResources.ShaderProgram.IsNull() && theCtx)
+// =======================================================================
+// function : UpdateTexturesRediness
+// purpose :
+// =======================================================================
+void OpenGl_AspectMarker::Resources::UpdateTexturesRediness (const Handle(Graphic3d_AspectMarker3d)& theAspect,
+ Standard_ShortReal& theMarkerSize)
+{
+ // update sprite resource bindings
+ TCollection_AsciiString aSpriteKeyNew, aSpriteAKeyNew;
+ spriteKeys (theAspect->GetMarkerImage(), theAspect->Type(), theAspect->Scale(), theAspect->ColorRGBA(), aSpriteKeyNew, aSpriteAKeyNew);
+ const TCollection_AsciiString& aSpriteKeyOld = !mySprite.IsNull() ? mySprite ->First()->ResourceId() : THE_EMPTY_KEY;
+ const TCollection_AsciiString& aSpriteAKeyOld = !mySpriteA.IsNull() ? mySpriteA->First()->ResourceId() : THE_EMPTY_KEY;
+ if (aSpriteKeyNew.IsEmpty() || aSpriteKeyOld != aSpriteKeyNew
+ || aSpriteAKeyNew.IsEmpty() || aSpriteAKeyOld != aSpriteAKeyNew)
{
- theCtx->ShaderManager()->Unregister (myResources.ShaderProgramId,
- myResources.ShaderProgram);
+ myIsSpriteReady = Standard_False;
+ theMarkerSize = theAspect->Scale();
+ }
+}
+
+// =======================================================================
+// function : UpdateShaderRediness
+// purpose :
+// =======================================================================
+void OpenGl_AspectMarker::Resources::UpdateShaderRediness (const Handle(Graphic3d_AspectMarker3d)& theAspect)
+{
+ // update shader program resource bindings
+ const TCollection_AsciiString& aShaderKey = theAspect->ShaderProgram().IsNull() ? THE_EMPTY_KEY : theAspect->ShaderProgram()->GetId();
+ if (aShaderKey.IsEmpty() || myShaderProgramId != aShaderKey)
+ {
+ myIsShaderReady = Standard_False;
}
- myResources.ShaderProgramId.Clear();
- myResources.ResetShaderReadiness();
}
// =======================================================================
Standard_ShortReal& theMarkerSize)
{
// generate key for shared resource
- TCollection_AsciiString aNewKey = THE_EMPTY_KEY;
- TCollection_AsciiString aNewKeyA = THE_EMPTY_KEY;
- SpriteKeys (theMarkerImage, theType, theScale, theColor, aNewKey, aNewKeyA);
+ TCollection_AsciiString aNewKey, aNewKeyA;
+ spriteKeys (theMarkerImage, theType, theScale, theColor, aNewKey, aNewKeyA);
+
+ const TCollection_AsciiString& aSpriteKeyOld = !mySprite.IsNull() ? mySprite ->First()->ResourceId() : THE_EMPTY_KEY;
+ const TCollection_AsciiString& aSpriteAKeyOld = !mySpriteA.IsNull() ? mySpriteA->First()->ResourceId() : THE_EMPTY_KEY;
// release old shared resources
- const Standard_Boolean aNewResource = aNewKey.IsEmpty() || SpriteKey != aNewKey;
+ const Standard_Boolean aNewResource = aNewKey.IsEmpty()
+ || aSpriteKeyOld != aNewKey;
if (aNewResource)
{
- if (!Sprite.IsNull())
+ if (!mySprite.IsNull())
{
- if (SpriteKey.IsEmpty())
+ if (mySprite->First()->ResourceId().IsEmpty())
{
- theCtx->DelayedRelease (Sprite);
- Sprite.Nullify();
+ theCtx->DelayedRelease (mySprite->ChangeFirst());
+ mySprite.Nullify();
}
else
{
- Sprite.Nullify(); // we need nullify all handles before ReleaseResource() call
- theCtx->ReleaseResource (SpriteKey, Standard_True);
+ const TCollection_AsciiString anOldKey = mySprite->First()->ResourceId();
+ mySprite.Nullify(); // we need nullify all handles before ReleaseResource() call
+ theCtx->ReleaseResource (anOldKey, Standard_True);
}
}
- SpriteKey = aNewKey;
}
- if (aNewKeyA.IsEmpty() || SpriteAKey != aNewKeyA)
+ if (aNewKeyA.IsEmpty() || aSpriteAKeyOld != aNewKeyA)
{
- if (!SpriteA.IsNull())
+ if (!mySpriteA.IsNull())
{
- if (SpriteAKey.IsEmpty())
+ if (mySpriteA->First()->ResourceId().IsEmpty())
{
- theCtx->DelayedRelease (SpriteA);
- SpriteA.Nullify();
+ theCtx->DelayedRelease (mySpriteA->ChangeFirst());
+ mySpriteA.Nullify();
}
else
{
- SpriteA.Nullify(); // we need nullify all handles before ReleaseResource() call
- theCtx->ReleaseResource (SpriteAKey, Standard_True);
+ const TCollection_AsciiString anOldKey = mySprite->First()->ResourceId();
+ mySpriteA.Nullify(); // we need nullify all handles before ReleaseResource() call
+ theCtx->ReleaseResource (anOldKey, Standard_True);
}
}
- SpriteAKey = aNewKeyA;
}
if (!aNewResource)
{
- if (!Sprite->IsDisplayList())
+ const OpenGl_PointSprite* aSprite = dynamic_cast<OpenGl_PointSprite*> (mySprite->First().get());
+ if (!aSprite->IsDisplayList())
{
- theMarkerSize = Standard_ShortReal (Max (Sprite->SizeX(), Sprite->SizeY()));
+ theMarkerSize = Standard_ShortReal (Max (aSprite->SizeX(), aSprite->SizeY()));
}
return;
}
return;
}
+ if (mySprite.IsNull())
+ {
+ mySprite = new OpenGl_TextureSet (1);
+ mySpriteA = new OpenGl_TextureSet (1);
+ }
+
+ Handle(OpenGl_PointSprite) aSprite, aSpriteA;
if (!aNewKey.IsEmpty()
- && theCtx->GetResource<Handle(OpenGl_PointSprite)> (aNewKeyA, SpriteA) // alpha sprite could be shared
- && theCtx->GetResource<Handle(OpenGl_PointSprite)> (aNewKey, Sprite))
+ && theCtx->GetResource<Handle(OpenGl_PointSprite)> (aNewKeyA, aSpriteA) // alpha sprite could be shared
+ && theCtx->GetResource<Handle(OpenGl_PointSprite)> (aNewKey, aSprite))
{
// reuse shared resource
- if (!Sprite->IsDisplayList())
+ if (!aSprite->IsDisplayList())
{
- theMarkerSize = Standard_ShortReal (Max (Sprite->SizeX(), Sprite->SizeY()));
+ theMarkerSize = Standard_ShortReal (Max (aSprite->SizeX(), aSprite->SizeY()));
}
+ mySprite ->ChangeFirst() = aSprite;
+ mySpriteA->ChangeFirst() = aSpriteA;
return;
}
- const bool hadAlreadyAlpha = !SpriteA.IsNull();
+ const bool hadAlreadyAlpha = !aSpriteA.IsNull();
if (!hadAlreadyAlpha)
{
- SpriteA = new OpenGl_PointSprite();
+ aSpriteA = new OpenGl_PointSprite (aNewKeyA);
}
- Sprite = new OpenGl_PointSprite();
+ aSprite = new OpenGl_PointSprite (aNewKey);
+ mySprite ->ChangeFirst() = aSprite;
+ mySpriteA->ChangeFirst() = aSpriteA;
if (!aNewKey.IsEmpty())
{
- theCtx->ShareResource (aNewKey, Sprite);
+ theCtx->ShareResource (aNewKey, aSprite);
if (!hadAlreadyAlpha)
{
- theCtx->ShareResource (aNewKeyA, SpriteA);
+ theCtx->ShareResource (aNewKeyA, aSpriteA);
}
}
theMarkerSize = Max ((Standard_ShortReal )anImage->Width(),(Standard_ShortReal )anImage->Height());
- Sprite->Init (theCtx, *anImage.operator->(), Graphic3d_TOT_2D);
+ aSprite->Init (theCtx, *anImage.operator->(), Graphic3d_TOT_2D);
if (!hadAlreadyAlpha)
{
if (anImageA.IsNull()
- && Sprite->GetFormat() != GL_ALPHA
+ && aSprite->GetFormat() != GL_ALPHA
&& !aNewMarkerImage.IsNull())
{
anImageA = aNewMarkerImage->GetImageAlpha();
}
if (!anImageA.IsNull())
{
- SpriteA->Init (theCtx, *anImageA.operator->(), Graphic3d_TOT_2D);
+ aSpriteA->Init (theCtx, *anImageA.operator->(), Graphic3d_TOT_2D);
}
}
}
#if !defined(GL_ES_VERSION_2_0)
// Creating list with bitmap for using it in compatibility mode
GLuint aBitmapList = glGenLists (1);
- Sprite->SetDisplayList (theCtx, aBitmapList);
+ aSprite->SetDisplayList (theCtx, aBitmapList);
Standard_Integer aWidth, aHeight, anOffset, aNumOfBytes;
if (theType == Aspect_TOM_USERDEFINED && !theMarkerImage.IsNull())
}
// release old shader program resources
- if (!ShaderProgram.IsNull())
+ if (!myShaderProgram.IsNull())
{
- theCtx->ShaderManager()->Unregister (ShaderProgramId, ShaderProgram);
- ShaderProgramId.Clear();
- ShaderProgram.Nullify();
+ theCtx->ShaderManager()->Unregister (myShaderProgramId, myShaderProgram);
+ myShaderProgramId.Clear();
+ myShaderProgram.Nullify();
}
if (theShader.IsNull())
{
return;
}
- theCtx->ShaderManager()->Create (theShader, ShaderProgramId, ShaderProgram);
+ theCtx->ShaderManager()->Create (theShader, myShaderProgramId, myShaderProgram);
}
// =======================================================================
-// function : resourceKeys
+// function : spriteKeys
// purpose :
// =======================================================================
-void OpenGl_AspectMarker::Resources::SpriteKeys (const Handle(Graphic3d_MarkerImage)& theMarkerImage,
+void OpenGl_AspectMarker::Resources::spriteKeys (const Handle(Graphic3d_MarkerImage)& theMarkerImage,
const Aspect_TypeOfMarker theType,
const Standard_ShortReal theScale,
const Graphic3d_Vec4& theColor,
#include <TCollection_AsciiString.hxx>
#include <OpenGl_Element.hxx>
+#include <OpenGl_TextureSet.hxx>
class OpenGl_PointSprite;
class OpenGl_ShaderProgram;
//! Init and return OpenGl point sprite resource.
//! @return point sprite texture.
- const Handle(OpenGl_PointSprite)& SpriteRes (const Handle(OpenGl_Context)& theCtx) const
+ const Handle(OpenGl_TextureSet)& SpriteRes (const Handle(OpenGl_Context)& theCtx) const
{
if (!myResources.IsSpriteReady())
{
myResources.SetSpriteReady();
}
- return myResources.Sprite;
+ return myResources.Sprite();
}
//! Init and return OpenGl highlight point sprite resource.
//! @return point sprite texture for highlight.
- const Handle(OpenGl_PointSprite)& SpriteHighlightRes (const Handle(OpenGl_Context)& theCtx) const
+ const Handle(OpenGl_TextureSet)& SpriteHighlightRes (const Handle(OpenGl_Context)& theCtx) const
{
if (!myResources.IsSpriteReady())
{
myResources.SetSpriteReady();
}
- return myResources.SpriteA;
+ return myResources.SpriteA();
}
//! Init and return OpenGl shader program resource.
myResources.SetShaderReady();
}
- return myResources.ShaderProgram;
+ return myResources.ShaderProgram();
}
Standard_EXPORT virtual void Render (const Handle(OpenGl_Workspace)& theWorkspace) const;
{
public:
- Resources() :
- SpriteKey (""),
- SpriteAKey (""),
- myIsSpriteReady (Standard_False),
- myIsShaderReady (Standard_False) {}
+ //! Empty constructor.
+ Resources()
+ : myIsSpriteReady (Standard_False),
+ myIsShaderReady (Standard_False) {}
+
+ const Handle(OpenGl_TextureSet)& Sprite() const { return mySprite; }
+ const Handle(OpenGl_TextureSet)& SpriteA() const { return mySpriteA; }
+ const Handle(OpenGl_ShaderProgram)& ShaderProgram() const { return myShaderProgram; }
Standard_Boolean IsSpriteReady() const { return myIsSpriteReady; }
Standard_Boolean IsShaderReady() const { return myIsShaderReady; }
void SetSpriteReady() { myIsSpriteReady = Standard_True; }
void SetShaderReady() { myIsShaderReady = Standard_True; }
- void ResetSpriteReadiness() { myIsSpriteReady = Standard_False; }
- void ResetShaderReadiness() { myIsShaderReady = Standard_False; }
+ //! Update texture resource up-to-date state.
+ Standard_EXPORT void UpdateTexturesRediness (const Handle(Graphic3d_AspectMarker3d)& theAspect,
+ Standard_ShortReal& theMarkerSize);
+
+ //! Update shader resource up-to-date state.
+ Standard_EXPORT void UpdateShaderRediness (const Handle(Graphic3d_AspectMarker3d)& theAspect);
+
+ //! Release texture resource.
+ Standard_EXPORT void ReleaseTextures (OpenGl_Context* theCtx);
+
+ //! Release shader resource.
+ Standard_EXPORT void ReleaseShaders (OpenGl_Context* theCtx);
+
+ //! Build texture resources.
Standard_EXPORT void BuildSprites (const Handle(OpenGl_Context)& theCtx,
const Handle(Graphic3d_MarkerImage)& theMarkerImage,
const Aspect_TypeOfMarker theType,
const Graphic3d_Vec4& theColor,
Standard_ShortReal& theMarkerSize);
+ //! Build shader resources.
Standard_EXPORT void BuildShader (const Handle(OpenGl_Context)& theCtx,
const Handle(Graphic3d_ShaderProgram)& theShader);
- Standard_EXPORT void SpriteKeys (const Handle(Graphic3d_MarkerImage)& theMarkerImage,
- const Aspect_TypeOfMarker theType,
- const Standard_ShortReal theScale,
- const Graphic3d_Vec4& theColor,
- TCollection_AsciiString& theKey,
- TCollection_AsciiString& theKeyA);
-
- Handle(OpenGl_PointSprite) Sprite;
- TCollection_AsciiString SpriteKey;
-
- Handle(OpenGl_PointSprite) SpriteA;
- TCollection_AsciiString SpriteAKey;
+ private:
- Handle(OpenGl_ShaderProgram) ShaderProgram;
- TCollection_AsciiString ShaderProgramId;
+ //! Generate resource keys for a sprite.
+ static void spriteKeys (const Handle(Graphic3d_MarkerImage)& theMarkerImage,
+ const Aspect_TypeOfMarker theType,
+ const Standard_ShortReal theScale,
+ const Graphic3d_Vec4& theColor,
+ TCollection_AsciiString& theKey,
+ TCollection_AsciiString& theKeyA);
private:
- Standard_Boolean myIsSpriteReady;
- Standard_Boolean myIsShaderReady;
+ Handle(OpenGl_TextureSet) mySprite;
+ Handle(OpenGl_TextureSet) mySpriteA;
+ Handle(OpenGl_ShaderProgram) myShaderProgram;
+ TCollection_AsciiString myShaderProgramId;
+ Standard_Boolean myIsSpriteReady;
+ Standard_Boolean myIsShaderReady;
} myResources;
// Get texture parameters
const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext();
const OpenGl_AspectFace* anAspectFace = theWorkspace->AspectFace();
- GLfloat aTextureWidth = (GLfloat )anAspectFace->TextureRes (aCtx)->SizeX();
- GLfloat aTextureHeight = (GLfloat )anAspectFace->TextureRes (aCtx)->SizeY();
+ GLfloat aTextureWidth = (GLfloat )anAspectFace->TextureSet (aCtx)->First()->SizeX();
+ GLfloat aTextureHeight = (GLfloat )anAspectFace->TextureSet (aCtx)->First()->SizeY();
if (myFillMethod == Aspect_FM_CENTERED)
{
}
if (myPlaneRoot->ToUseObjectTexture())
{
+ myFillAreaAspect->SetTextureSet (theObjAspect->TextureSet());
if (theObjAspect->ToMapTexture())
{
- myFillAreaAspect->SetTextureMap (theObjAspect->TextureMap());
myFillAreaAspect->SetTextureMapOn();
}
else
#include <OpenGl_ArbDbg.hxx>
#include <OpenGl_ArbFBO.hxx>
#include <OpenGl_ExtGS.hxx>
+#include <OpenGl_ArbSamplerObject.hxx>
#include <OpenGl_ArbTexBindless.hxx>
#include <OpenGl_GlCore44.hxx>
#include <OpenGl_FrameBuffer.hxx>
arbNPTW (Standard_False),
arbTexRG (Standard_False),
arbTexFloat (Standard_False),
+ arbSamplerObject (NULL),
arbTexBindless (NULL),
arbTBO (NULL),
arbTboRGB32 (Standard_False),
myAnisoMax (1),
myTexClamp (GL_CLAMP_TO_EDGE),
myMaxTexDim (1024),
+ myMaxTexCombined (1),
myMaxClipPlanes (6),
myMaxMsaaSamples(0),
myMaxDrawBuffers (1),
mySharedResources.Nullify();
myDelayed.Nullify();
- // release sampler object
- if (!myTexSampler.IsNull())
- {
- myTexSampler->Release (this);
- }
-
if (arbDbg != NULL
&& myIsGlDebugCtx
&& IsValid())
extGS = NULL;
myDefaultVao = 0;
+ //! Make record shorter to retrieve function pointer using variable with same name
+ #define FindProcShort(theFunc) FindProc(#theFunc, myFuncs->theFunc)
+
#if defined(GL_ES_VERSION_2_0)
hasTexRGBA8 = IsGlGreaterEqual (3, 0)
arbFBO = (OpenGl_ArbFBO* )(&(*myFuncs));
}
if (IsGlGreaterEqual (3, 0)
- && FindProc ("glBlitFramebuffer", myFuncs->glBlitFramebuffer))
+ && FindProcShort (glBlitFramebuffer))
{
arbFBOBlit = (OpenGl_ArbFBOBlit* )(&(*myFuncs));
}
+ if (IsGlGreaterEqual (3, 0)
+ && FindProcShort (glGenSamplers)
+ && FindProcShort (glDeleteSamplers)
+ && FindProcShort (glIsSampler)
+ && FindProcShort (glBindSampler)
+ && FindProcShort (glSamplerParameteri)
+ && FindProcShort (glSamplerParameteriv)
+ && FindProcShort (glSamplerParameterf)
+ && FindProcShort (glSamplerParameterfv)
+ && FindProcShort (glGetSamplerParameteriv)
+ && FindProcShort (glGetSamplerParameterfv))
+ //&& FindProcShort (glSamplerParameterIiv) // only on Desktop or with extensions GL_OES_texture_border_clamp/GL_EXT_texture_border_clamp
+ //&& FindProcShort (glSamplerParameterIuiv)
+ //&& FindProcShort (glGetSamplerParameterIiv)
+ //&& FindProcShort (glGetSamplerParameterIuiv))
+ {
+ arbSamplerObject = (OpenGl_ArbSamplerObject* )(&(*myFuncs));
+ }
extFragDepth = !IsGlGreaterEqual(3, 0)
&& CheckExtension ("GL_EXT_frag_depth");
if (IsGlGreaterEqual (3, 1)
}
glGetIntegerv (GL_MAX_TEXTURE_SIZE, &myMaxTexDim);
+ if (IsGlGreaterEqual (1, 5))
+ {
+ glGetIntegerv (GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &myMaxTexCombined);
+ }
if (extAnis)
{
bool has43 = false;
bool has44 = false;
- //! Make record shorter to retrieve function pointer using variable with same name
- #define FindProcShort(theFunc) FindProc(#theFunc, myFuncs->theFunc)
-
// retrieve platform-dependent extensions
#if defined(HAVE_EGL)
//
&& FindProcShort (glGetSamplerParameterIiv)
&& FindProcShort (glGetSamplerParameterfv)
&& FindProcShort (glGetSamplerParameterIuiv);
+ if (hasSamplerObjects)
+ {
+ arbSamplerObject = (OpenGl_ArbSamplerObject* )(&(*myFuncs));
+ }
// load GL_ARB_timer_query (added to OpenGL 3.3 core)
const bool hasTimerQuery = (IsGlGreaterEqual (3, 3) || CheckExtension ("GL_ARB_timer_query"))
core33back = (OpenGl_GlCore33Back* )(&(*myFuncs));
}
- // initialize sampler object
- myTexSampler = new OpenGl_Sampler();
- myTexSampler->Init (*this);
-
if (!has40)
{
checkWrongVersion (4, 0);
if ((theFlags & Graphic3d_DiagnosticInfo_Limits) != 0)
{
addInfo (theDict, "Max texture size", TCollection_AsciiString(myMaxTexDim));
+ addInfo (theDict, "Max combined texture units", TCollection_AsciiString(myMaxTexCombined));
addInfo (theDict, "Max MSAA samples", TCollection_AsciiString(myMaxMsaaSamples));
}
}
}
+// =======================================================================
+// function : BindTextures
+// purpose :
+// =======================================================================
+Handle(OpenGl_TextureSet) OpenGl_Context::BindTextures (const Handle(OpenGl_TextureSet)& theTextures)
+{
+ if (myActiveTextures == theTextures)
+ {
+ return myActiveTextures;
+ }
+
+ Handle(OpenGl_Context) aThisCtx (this);
+ OpenGl_TextureSet::Iterator aTextureIterOld (myActiveTextures), aTextureIterNew (theTextures);
+ for (;;)
+ {
+ if (!aTextureIterNew.More())
+ {
+ for (; aTextureIterOld.More(); aTextureIterOld.Next())
+ {
+ if (const Handle(OpenGl_Texture)& aTextureOld = aTextureIterOld.Value())
+ {
+ #if !defined(GL_ES_VERSION_2_0)
+ if (core11 != NULL)
+ {
+ OpenGl_Sampler::resetGlobalTextureParams (aThisCtx, *aTextureOld, aTextureOld->Sampler()->Parameters());
+ }
+ #endif
+ aTextureOld->Unbind (aThisCtx);
+ }
+ }
+ break;
+ }
+
+ const Handle(OpenGl_Texture)& aTextureNew = aTextureIterNew.Value();
+ if (aTextureIterOld.More())
+ {
+ const Handle(OpenGl_Texture)& aTextureOld = aTextureIterOld.Value();
+ if (aTextureNew == aTextureOld)
+ {
+ aTextureIterNew.Next();
+ aTextureIterOld.Next();
+ continue;
+ }
+ else if (aTextureNew.IsNull()
+ || !aTextureNew->IsValid())
+ {
+ if (!aTextureOld.IsNull())
+ {
+ #if !defined(GL_ES_VERSION_2_0)
+ if (core11 != NULL)
+ {
+ OpenGl_Sampler::resetGlobalTextureParams (aThisCtx, *aTextureOld, aTextureOld->Sampler()->Parameters());
+ }
+ #endif
+ aTextureOld->Unbind (aThisCtx);
+ }
+
+ aTextureIterNew.Next();
+ aTextureIterOld.Next();
+ continue;
+ }
+
+ aTextureIterOld.Next();
+ }
+ if (aTextureNew.IsNull())
+ {
+ aTextureIterNew.Next();
+ continue;
+ }
+
+ const Graphic3d_TextureUnit aTexUnit = aTextureNew->Sampler()->Parameters()->TextureUnit();
+ if (aTexUnit >= myMaxTexCombined)
+ {
+ PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
+ TCollection_AsciiString("Texture unit ") + aTexUnit + " for " + aTextureNew->ResourceId() + " exceeds hardware limit " + myMaxTexCombined);
+ aTextureIterNew.Next();
+ continue;
+ }
+
+ aTextureNew->Bind (aThisCtx);
+ if (aTextureNew->Sampler()->ToUpdateParameters())
+ {
+ if (aTextureNew->Sampler()->IsImmutable())
+ {
+ aTextureNew->Sampler()->Init (aThisCtx, *aTextureNew);
+ }
+ else
+ {
+ OpenGl_Sampler::applySamplerParams (aThisCtx, aTextureNew->Sampler()->Parameters(), aTextureNew->Sampler().get(), aTextureNew->GetTarget(), aTextureNew->HasMipmaps());
+ }
+ }
+ #if !defined(GL_ES_VERSION_2_0)
+ if (core11 != NULL)
+ {
+ OpenGl_Sampler::applyGlobalTextureParams (aThisCtx, *aTextureNew, aTextureNew->Sampler()->Parameters());
+ }
+ #endif
+ aTextureIterNew.Next();
+ }
+
+ Handle(OpenGl_TextureSet) anOldTextures = myActiveTextures;
+ myActiveTextures = theTextures;
+ return anOldTextures;
+}
+
// =======================================================================
// function : BindProgram
// purpose :
#include <Aspect_TypeOfLine.hxx>
#include <NCollection_DataMap.hxx>
#include <Graphic3d_DiagnosticInfo.hxx>
+#include <Graphic3d_TextureUnit.hxx>
#include <NCollection_Map.hxx>
#include <NCollection_Handle.hxx>
#include <NCollection_List.hxx>
#include <OpenGl_MatrixState.hxx>
#include <OpenGl_Vec.hxx>
#include <OpenGl_Resource.hxx>
+#include <OpenGl_TextureSet.hxx>
#include <Standard_Transient.hxx>
#include <TColStd_IndexedDataMapOfStringString.hxx>
#include <TColStd_PackedMapOfInteger.hxx>
#include <OpenGl_Clipping.hxx>
#include <OpenGl_GlCore11.hxx>
-#include <OpenGl_ShaderProgram.hxx>
#include <NCollection_Shared.hxx>
struct OpenGl_ArbDbg;
struct OpenGl_ArbFBO;
struct OpenGl_ArbFBOBlit;
-struct OpenGl_ExtGS;
+struct OpenGl_ArbSamplerObject;
struct OpenGl_ArbTexBindless;
+struct OpenGl_ExtGS;
template<typename theBaseClass_t> struct OpenGl_TmplCore12;
typedef OpenGl_TmplCore12<OpenGl_GlCore11> OpenGl_GlCore12;
typedef OpenGl_TmplCore44<OpenGl_GlCore43Back> OpenGl_GlCore44Back;
typedef OpenGl_TmplCore44<OpenGl_GlCore43> OpenGl_GlCore44;
-class OpenGl_ShaderManager;
-class OpenGl_Sampler;
-class OpenGl_FrameBuffer;
-class OpenGl_AspectFace;
class Graphic3d_PresentationAttributes;
+class OpenGl_AspectFace;
+class OpenGl_FrameBuffer;
+class OpenGl_Sampler;
+class OpenGl_ShaderProgram;
+class OpenGl_ShaderManager;
enum OpenGl_FeatureFlag
{
//! @return value for GL_MAX_TEXTURE_SIZE
Standard_Integer MaxTextureSize() const { return myMaxTexDim; }
+ //! @return value for GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS
+ Standard_Integer MaxCombinedTextureUnits() const { return myMaxTexCombined; }
+
//! @return value for GL_MAX_SAMPLES
Standard_Integer MaxMsaaSamples() const { return myMaxMsaaSamples; }
//! OpenGl state variables has a possibility of being out-of-date.
Standard_EXPORT void FetchState();
+ //! @return active textures
+ const Handle(OpenGl_TextureSet)& ActiveTextures() const { return myActiveTextures; }
+
+ //! Bind specified texture set to current context,
+ //! or unbind previous one when NULL specified.
+ Standard_EXPORT Handle(OpenGl_TextureSet) BindTextures (const Handle(OpenGl_TextureSet)& theTextures);
+
//! @return active GLSL program
const Handle(OpenGl_ShaderProgram)& ActiveProgram() const
{
return myActiveProgram;
}
- //! @return OpenGL sampler object used to override default texture parameters
- const Handle(OpenGl_Sampler)& TextureSampler()
- {
- return myTexSampler;
- }
-
//! Bind specified program to current context,
//! or unbind previous one when NULL specified.
//! @return true if some program is bound to context
Standard_Boolean arbNPTW; //!< GL_ARB_texture_non_power_of_two
Standard_Boolean arbTexRG; //!< GL_ARB_texture_rg
Standard_Boolean arbTexFloat; //!< GL_ARB_texture_float (on desktop OpenGL - since 3.0 or as extension GL_ARB_texture_float; on OpenGL ES - since 3.0)
+ OpenGl_ArbSamplerObject* arbSamplerObject; //!< GL_ARB_sampler_objects (on desktop OpenGL - since 3.3 or as extension GL_ARB_sampler_objects; on OpenGL ES - since 3.0)
OpenGl_ArbTexBindless* arbTexBindless; //!< GL_ARB_bindless_texture
OpenGl_ArbTBO* arbTBO; //!< GL_ARB_texture_buffer_object
Standard_Boolean arbTboRGB32; //!< GL_ARB_texture_buffer_object_rgb32 (3-component TBO), in core since 4.0
Standard_Integer myAnisoMax; //!< maximum level of anisotropy texture filter
Standard_Integer myTexClamp; //!< either GL_CLAMP_TO_EDGE (1.2+) or GL_CLAMP (1.1)
Standard_Integer myMaxTexDim; //!< value for GL_MAX_TEXTURE_SIZE
+ Standard_Integer myMaxTexCombined; //!< value for GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS
Standard_Integer myMaxClipPlanes; //!< value for GL_MAX_CLIP_PLANES
Standard_Integer myMaxMsaaSamples; //!< value for GL_MAX_SAMPLES
Standard_Integer myMaxDrawBuffers; //!< value for GL_MAX_DRAW_BUFFERS
private: //! @name fields tracking current state
Handle(OpenGl_ShaderProgram) myActiveProgram; //!< currently active GLSL program
- Handle(OpenGl_Sampler) myTexSampler; //!< currently active sampler object
+ Handle(OpenGl_TextureSet) myActiveTextures; //!< currently bound textures
+ //!< currently active sampler objects
Handle(OpenGl_FrameBuffer) myDefaultFbo; //!< default Frame Buffer Object
Handle(OpenGl_LineAttributes) myHatchStyles; //!< resource holding predefined hatch styles patterns
Standard_Integer myViewport[4]; //!< current viewport
aParams->SetFilter (Graphic3d_TOTF_BILINEAR);
aParams->SetAnisoFilter (Graphic3d_LOTA_OFF);
- myTextures.Append (new OpenGl_Texture (aParams));
+ myTextures.Append (new OpenGl_Texture (myKey + "_texture" + myTextures.Size(), aParams));
Handle(OpenGl_Texture)& aTexture = myTextures.ChangeLast();
Image_PixMap aBlackImg;
typedef void (*glDrawBuffers_t)(GLsizei n, const GLenum* bufs);
glDrawBuffers_t glDrawBuffers;
+ typedef void (*glGenSamplers_t)(GLsizei count, GLuint* samplers);
+ glGenSamplers_t glGenSamplers;
+
+ typedef void (*glDeleteSamplers_t)(GLsizei count, const GLuint* samplers);
+ glDeleteSamplers_t glDeleteSamplers;
+
+ typedef GLboolean (*glIsSampler_t)(GLuint sampler);
+ glIsSampler_t glIsSampler;
+
+ typedef void (*glBindSampler_t)(GLuint unit, GLuint sampler);
+ glBindSampler_t glBindSampler;
+
+ typedef void (*glSamplerParameteri_t)(GLuint sampler, GLenum pname, GLint param);
+ glSamplerParameteri_t glSamplerParameteri;
+
+ typedef void (*glSamplerParameteriv_t)(GLuint sampler, GLenum pname, const GLint* param);
+ glSamplerParameteriv_t glSamplerParameteriv;
+
+ typedef void (*glSamplerParameterf_t)(GLuint sampler, GLenum pname, GLfloat param);
+ glSamplerParameterf_t glSamplerParameterf;
+
+ typedef void (*glSamplerParameterfv_t)(GLuint sampler, GLenum pname, const GLfloat* param);
+ glSamplerParameterfv_t glSamplerParameterfv;
+
+ typedef void (*glGetSamplerParameteriv_t)(GLuint sampler, GLenum pname, GLint* params);
+ glGetSamplerParameteriv_t glGetSamplerParameteriv;
+
+ typedef void (*glGetSamplerParameterfv_t)(GLuint sampler, GLenum pname, GLfloat* params);
+ glGetSamplerParameterfv_t glGetSamplerParameterfv;
+
public: //! @name OpenGL ES 3.1
typedef void (*glTexStorage2DMultisample_t)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations);
return 10000;
case Graphic3d_TypeOfLimit_MaxTextureSize:
return !aCtx.IsNull() ? aCtx->MaxTextureSize() : 1024;
+ case Graphic3d_TypeOfLimit_MaxCombinedTextureUnits:
+ return !aCtx.IsNull() ? aCtx->MaxCombinedTextureUnits() : 1;
case Graphic3d_TypeOfLimit_MaxMsaa:
return !aCtx.IsNull() ? aCtx->MaxMsaaSamples() : 0;
case Graphic3d_TypeOfLimit_HasRayTracing:
}
// save environment texture
- Handle(OpenGl_Texture) anEnvironmentTexture = theWorkspace->EnvironmentTexture();
+ Handle(OpenGl_TextureSet) anEnvironmentTexture = theWorkspace->EnvironmentTexture();
if (!myLayerSettings.UseEnvironmentTexture())
{
- theWorkspace->SetEnvironmentTexture (Handle(OpenGl_Texture)());
+ theWorkspace->SetEnvironmentTexture (Handle(OpenGl_TextureSet)());
}
// handle depth offset
// Bind full screen quad buffer and framebuffer resources.
aVerts->BindVertexAttrib (aCtx, Graphic3d_TOA_POS);
- const Handle(OpenGl_Texture) aTextureBack = theWorkspace->DisableTexture();
+ const Handle(OpenGl_TextureSet) aTextureBack = aCtx->BindTextures (Handle(OpenGl_TextureSet)());
- theOitAccumFbo->ColorTexture (0)->Bind (aCtx, GL_TEXTURE0 + 0);
- theOitAccumFbo->ColorTexture (1)->Bind (aCtx, GL_TEXTURE0 + 1);
+ theOitAccumFbo->ColorTexture (0)->Bind (aCtx, Graphic3d_TextureUnit_0);
+ theOitAccumFbo->ColorTexture (1)->Bind (aCtx, Graphic3d_TextureUnit_1);
// Draw full screen quad with special shader to compose the buffers.
aCtx->core11fwd->glBlendFunc (GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA);
// Unbind OpenGL texture objects and shader program.
aVerts->UnbindVertexAttrib (aCtx, Graphic3d_TOA_POS);
- theOitAccumFbo->ColorTexture (0)->Unbind (aCtx, GL_TEXTURE0 + 0);
- theOitAccumFbo->ColorTexture (1)->Unbind (aCtx, GL_TEXTURE0 + 1);
+ theOitAccumFbo->ColorTexture (0)->Unbind (aCtx, Graphic3d_TextureUnit_0);
+ theOitAccumFbo->ColorTexture (1)->Unbind (aCtx, Graphic3d_TextureUnit_1);
aCtx->BindProgram (NULL);
if (!aTextureBack.IsNull())
{
- theWorkspace->EnableTexture (aTextureBack);
+ aCtx->BindTextures (aTextureBack);
}
}
else
--- /dev/null
+// Created on: 2011-03-18
+// Created by: Anton POLETAEV
+// Copyright (c) 2011-2014 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _OpenGl_NamedResource_HeaderFile
+#define _OpenGl_NamedResource_HeaderFile
+
+#include <OpenGl_Resource.hxx>
+#include <TCollection_AsciiString.hxx>
+
+//! Named resource object.
+class OpenGl_NamedResource : public OpenGl_Resource
+{
+ DEFINE_STANDARD_RTTIEXT(OpenGl_NamedResource, OpenGl_Resource)
+public:
+
+ //! Empty constructor
+ OpenGl_NamedResource (const TCollection_AsciiString& theId)
+ : myResourceId (theId) {}
+
+ //! Return resource name.
+ const TCollection_AsciiString& ResourceId() const { return myResourceId; }
+
+protected:
+
+ TCollection_AsciiString myResourceId; //!< resource name
+
+};
+
+#endif // _OpenGl_NamedResource_HeaderFile
#include <Graphic3d_TextureParams.hxx>
#include <OpenGl_Context.hxx>
+#include <OpenGl_Sampler.hxx>
#include <Standard_Assert.hxx>
#include <Image_PixMap.hxx>
-
IMPLEMENT_STANDARD_RTTIEXT(OpenGl_PointSprite,OpenGl_Texture)
// =======================================================================
// function : OpenGl_PointSprite
// purpose :
// =======================================================================
-OpenGl_PointSprite::OpenGl_PointSprite()
-: OpenGl_Texture (NULL),
+OpenGl_PointSprite::OpenGl_PointSprite (const TCollection_AsciiString& theResourceId)
+: OpenGl_Texture (theResourceId, Handle(Graphic3d_TextureParams)()),
myBitmapList (0)
{
- //myParams->SetFilter (Graphic3d_TOTF_NEAREST);
- myParams->SetModulate (Standard_False);
- myParams->SetGenMode (Graphic3d_TOTM_SPRITE,
- Graphic3d_Vec4 (0.0f, 0.0f, 0.0f, 0.0f),
- Graphic3d_Vec4 (0.0f, 0.0f, 0.0f, 0.0f));
+ //mySampler->Parameters()->SetFilter (Graphic3d_TOTF_NEAREST);
+ mySampler->Parameters()->SetModulate (Standard_False);
+ mySampler->Parameters()->SetGenMode (Graphic3d_TOTM_SPRITE,
+ Graphic3d_Vec4 (0.0f, 0.0f, 0.0f, 0.0f),
+ Graphic3d_Vec4 (0.0f, 0.0f, 0.0f, 0.0f));
}
// =======================================================================
myBitmapList = theBitmapList;
}
-
// =======================================================================
// function : DrawBitmap
// purpose :
public:
//! Create uninitialized resource.
- Standard_EXPORT OpenGl_PointSprite();
+ Standard_EXPORT OpenGl_PointSprite (const TCollection_AsciiString& theResourceId);
//! Destroy object.
Standard_EXPORT virtual ~OpenGl_PointSprite();
#include <OpenGl_IndexBuffer.hxx>
#include <OpenGl_PointSprite.hxx>
#include <OpenGl_PrimitiveArray.hxx>
+#include <OpenGl_Sampler.hxx>
#include <OpenGl_ShaderManager.hxx>
#include <OpenGl_ShaderProgram.hxx>
#include <OpenGl_Structure.hxx>
{
const OpenGl_AspectMarker* anAspectMarker = theWorkspace->ApplyAspectMarker();
const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext();
- const Handle(OpenGl_PointSprite)& aSpriteNorm = anAspectMarker->SpriteRes (aCtx);
- if (!aSpriteNorm.IsNull()
- && !aSpriteNorm->IsDisplayList())
+ const Handle(OpenGl_TextureSet)& aSpriteNormRes = anAspectMarker->SpriteRes (aCtx);
+ const OpenGl_PointSprite* aSpriteNorm = !aSpriteNormRes.IsNull() ? dynamic_cast<const OpenGl_PointSprite*> (aSpriteNormRes->First().get()) : NULL;
+ if (aSpriteNorm != NULL
+ && !aSpriteNorm->IsDisplayList())
{
// Textured markers will be drawn with the point sprites
aCtx->SetPointSize (anAspectMarker->MarkerSize());
#if !defined(GL_ES_VERSION_2_0)
// Textured markers will be drawn with the glBitmap
else if (anAspectMarker->Aspect()->Type() != Aspect_TOM_POINT
- && !aSpriteNorm.IsNull())
+ && aSpriteNorm != NULL)
{
/**if (!isHilight && (myPArray->vcolours != NULL))
{
if (!myIsVboInit)
{
// compatibility - keep data to draw markers using display lists
- const Standard_Boolean toKeepData = myDrawMode == GL_POINTS
- && !anAspectMarker->SpriteRes (aCtx).IsNull()
- && anAspectMarker->SpriteRes (aCtx)->IsDisplayList();
+ Standard_Boolean toKeepData = Standard_False;
+ if (myDrawMode == GL_POINTS)
+ {
+ const Handle(OpenGl_TextureSet)& aSpriteNormRes = anAspectMarker->SpriteRes (aCtx);
+ const OpenGl_PointSprite* aSpriteNorm = !aSpriteNormRes.IsNull() ? dynamic_cast<const OpenGl_PointSprite*> (aSpriteNormRes->First().get()) : NULL;
+ toKeepData = aSpriteNorm != NULL
+ && aSpriteNorm->IsDisplayList();
+ }
#if defined (GL_ES_VERSION_2_0)
processIndices (aCtx);
#endif
&& myVboAttribs->HasNormalAttribute();
// Temporarily disable environment mapping
- Handle(OpenGl_Texture) aTextureBack;
+ Handle(OpenGl_TextureSet) aTextureBack;
bool toDrawArray = true;
if (myDrawMode > GL_LINE_STRIP)
{
}
else if (myDrawMode <= GL_LINE_STRIP)
{
- aTextureBack = theWorkspace->DisableTexture();
+ aTextureBack = aCtx->BindTextures (Handle(OpenGl_TextureSet)());
if (myDrawMode == GL_POINTS)
{
toDrawArray = anAspectMarker->Aspect()->Type() != Aspect_TOM_EMPTY;
{
case GL_POINTS:
{
- const Handle(OpenGl_PointSprite)& aSpriteNorm = anAspectMarker->SpriteRes (aCtx);
- if (!aSpriteNorm.IsNull()
- && !aSpriteNorm->IsDisplayList())
+ const Handle(OpenGl_TextureSet)& aSpriteNormRes = anAspectMarker->SpriteRes (aCtx);
+ const OpenGl_PointSprite* aSpriteNorm = !aSpriteNormRes.IsNull() ? dynamic_cast<const OpenGl_PointSprite*> (aSpriteNormRes->First().get()) : NULL;
+ if (aSpriteNorm != NULL
+ && !aSpriteNorm->IsDisplayList())
{
- const Handle(OpenGl_PointSprite)& aSprite = (toHilight && anAspectMarker->SpriteHighlightRes (aCtx)->IsValid())
- ? anAspectMarker->SpriteHighlightRes (aCtx)
- : aSpriteNorm;
- theWorkspace->EnableTexture (aSprite);
+ const Handle(OpenGl_TextureSet)& aSprite = toHilight && anAspectMarker->SpriteHighlightRes (aCtx)->First()->IsValid()
+ ? anAspectMarker->SpriteHighlightRes (aCtx)
+ : aSpriteNormRes;
+ aCtx->BindTextures (aSprite);
aCtx->ShaderManager()->BindMarkerProgram (aSprite, isLightOn, hasVertColor, anAspectMarker->ShaderProgramRes (aCtx));
}
else
{
- aCtx->ShaderManager()->BindMarkerProgram (NULL, isLightOn, hasVertColor, anAspectMarker->ShaderProgramRes (aCtx));
+ aCtx->ShaderManager()->BindMarkerProgram (Handle(OpenGl_TextureSet)(), isLightOn, hasVertColor, anAspectMarker->ShaderProgramRes (aCtx));
}
break;
}
}
default:
{
- const Handle(OpenGl_Texture)& aTexture = theWorkspace->ActiveTexture();
+ const Handle(OpenGl_TextureSet)& aTextures = aCtx->ActiveTextures();
const Standard_Boolean isLightOnFace = isLightOn
- && (aTexture.IsNull()
- || aTexture->GetParams()->IsModulate());
- const Standard_Boolean toEnableEnvMap = (!aTexture.IsNull() && (aTexture == theWorkspace->EnvironmentTexture()));
- aCtx->ShaderManager()->BindFaceProgram (aTexture,
+ && (aTextures.IsNull()
+ || aTextures->IsEmpty()
+ || aTextures->First().IsNull()
+ || aTextures->First()->Sampler()->Parameters()->IsModulate());
+ const Standard_Boolean toEnableEnvMap = (!aTextures.IsNull() && (aTextures == theWorkspace->EnvironmentTexture()));
+ aCtx->ShaderManager()->BindFaceProgram (aTextures,
isLightOnFace,
hasVertColor,
toEnableEnvMap,
}
#endif
- if (!theWorkspace->ActiveTexture().IsNull()
+ if (!aCtx->ActiveTextures().IsNull()
+ && !aCtx->ActiveTextures()->IsEmpty()
+ && !aCtx->ActiveTextures()->First().IsNull()
&& myDrawMode != GL_POINTS) // transformation is not supported within point sprites
{
- aCtx->SetTextureMatrix (theWorkspace->ActiveTexture()->GetParams());
+ aCtx->SetTextureMatrix (aCtx->ActiveTextures()->First()->Sampler()->Parameters());
}
if (myDrawMode <= GL_LINE_STRIP)
if (myDrawMode <= GL_LINE_STRIP)
{
- theWorkspace->EnableTexture (aTextureBack);
+ aCtx->BindTextures (aTextureBack);
}
else
{
// commercial license or contractual agreement.
#include <OpenGl_Resource.hxx>
+#include <OpenGl_NamedResource.hxx>
-
-IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Resource,Standard_Transient)
+IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Resource, Standard_Transient)
+IMPLEMENT_STANDARD_RTTIEXT(OpenGl_NamedResource, OpenGl_Resource)
OpenGl_Resource::OpenGl_Resource() {}
OpenGl_Resource::~OpenGl_Resource() {}
// commercial license or contractual agreement.
#include <OpenGl_Sampler.hxx>
-#include <OpenGl_GlCore33.hxx>
-#include <Standard_Assert.hxx>
+#include <OpenGl_ArbSamplerObject.hxx>
+#include <OpenGl_Texture.hxx>
+#include <Standard_Assert.hxx>
IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Sampler,OpenGl_Resource)
// function : OpenGl_Sampler
// purpose :
// =======================================================================
-OpenGl_Sampler::OpenGl_Sampler()
-: mySamplerID (NO_SAMPLER)
+OpenGl_Sampler::OpenGl_Sampler (const Handle(Graphic3d_TextureParams)& theParams)
+: myParams (theParams),
+ mySamplerRevision (0),
+ mySamplerID (NO_SAMPLER),
+ myIsImmutable (false)
{
- //
+ if (myParams.IsNull())
+ {
+ myParams = new Graphic3d_TextureParams();
+ }
}
// =======================================================================
// function : Release
// purpose :
// =======================================================================
-void OpenGl_Sampler::Release (OpenGl_Context* theContext)
+void OpenGl_Sampler::Release (OpenGl_Context* theCtx)
{
- if (isValidSampler())
+ myIsImmutable = false;
+ mySamplerRevision = myParams->SamplerRevision() - 1;
+ if (!isValidSampler())
{
- // application can not handle this case by exception - this is bug in code
- Standard_ASSERT_RETURN (theContext != NULL,
- "OpenGl_Sampler destroyed without GL context! Possible GPU memory leakage...",);
+ return;
+ }
- if (theContext->IsValid())
- {
- #if !defined(GL_ES_VERSION_2_0) || defined(GL_ES_VERSION_3_0)
- theContext->core33->glDeleteSamplers (1, &mySamplerID);
- #endif
- }
+ // application can not handle this case by exception - this is bug in code
+ Standard_ASSERT_RETURN (theCtx != NULL,
+ "OpenGl_Sampler destroyed without GL context! Possible GPU memory leakage...",);
- mySamplerID = NO_SAMPLER;
+ if (theCtx->IsValid())
+ {
+ theCtx->arbSamplerObject->glDeleteSamplers (1, &mySamplerID);
}
+
+ mySamplerID = NO_SAMPLER;
}
// =======================================================================
-// function : Init
-// purpose : Initializes sampler object
+// function : Create
+// purpose :
// =======================================================================
-Standard_Boolean OpenGl_Sampler::Init (OpenGl_Context& theContext)
+Standard_Boolean OpenGl_Sampler::Create (const Handle(OpenGl_Context)& theCtx)
{
- if (theContext.core33 == NULL)
+ if (isValidSampler())
+ {
+ return Standard_True;
+ }
+ else if (theCtx->arbSamplerObject == NULL)
{
return Standard_False;
}
+ theCtx->arbSamplerObject->glGenSamplers (1, &mySamplerID);
+ return Standard_True;
+}
+
+// =======================================================================
+// function : Init
+// purpose :
+// =======================================================================
+Standard_Boolean OpenGl_Sampler::Init (const Handle(OpenGl_Context)& theCtx,
+ const OpenGl_Texture& theTexture)
+{
if (isValidSampler())
{
- Release (&theContext);
+ if (!ToUpdateParameters())
+ {
+ return Standard_True;
+ }
+ else if (!myIsImmutable)
+ {
+ applySamplerParams (theCtx, myParams, this, theTexture.GetTarget(), theTexture.HasMipmaps());
+ return Standard_True;
+ }
+ Release (theCtx.get());
+ }
+
+ if (!Create (theCtx))
+ {
+ return Standard_False;
}
-#if !defined(GL_ES_VERSION_2_0) || defined(GL_ES_VERSION_3_0)
- theContext.core33->glGenSamplers (1, &mySamplerID);
+ applySamplerParams (theCtx, myParams, this, theTexture.GetTarget(), theTexture.HasMipmaps());
return Standard_True;
-#else
- return Standard_False;
-#endif
}
// =======================================================================
// function : Bind
// purpose : Binds sampler object to the given texture unit
// =======================================================================
-void OpenGl_Sampler::Bind (OpenGl_Context& theContext,
- const GLuint theUnit)
+void OpenGl_Sampler::Bind (const Handle(OpenGl_Context)& theCtx,
+ const Graphic3d_TextureUnit theUnit)
{
if (isValidSampler())
{
- #if !defined(GL_ES_VERSION_2_0) || defined(GL_ES_VERSION_3_0)
- theContext.core33->glBindSampler (theUnit, mySamplerID);
- #else
- (void )theContext;
- (void )theUnit;
- #endif
+ theCtx->arbSamplerObject->glBindSampler (theUnit, mySamplerID);
}
}
// function : Unbind
// purpose : Unbinds sampler object from the given texture unit
// =======================================================================
-void OpenGl_Sampler::Unbind (OpenGl_Context& theContext,
- const GLuint theUnit)
+void OpenGl_Sampler::Unbind (const Handle(OpenGl_Context)& theCtx,
+ const Graphic3d_TextureUnit theUnit)
{
if (isValidSampler())
{
- #if !defined(GL_ES_VERSION_2_0) || defined(GL_ES_VERSION_3_0)
- theContext.core33->glBindSampler (theUnit, NO_SAMPLER);
- #else
- (void )theContext;
- (void )theUnit;
- #endif
+ theCtx->arbSamplerObject->glBindSampler (theUnit, NO_SAMPLER);
}
}
// =======================================================================
-// function : SetParameter
-// purpose : Sets sampler parameters
+// function : setParameter
+// purpose :
// =======================================================================
-void OpenGl_Sampler::SetParameter (OpenGl_Context& theContext,
- const GLenum theParam,
- const GLint theValue)
+void OpenGl_Sampler::setParameter (const Handle(OpenGl_Context)& theCtx,
+ OpenGl_Sampler* theSampler,
+ GLenum theTarget,
+ GLenum theParam,
+ GLint theValue)
{
- if (isValidSampler())
+ if (theSampler != NULL && theSampler->isValidSampler())
+ {
+ theCtx->arbSamplerObject->glSamplerParameteri (theSampler->mySamplerID, theParam, theValue);
+ }
+ else
+ {
+ theCtx->core11fwd->glTexParameteri (theTarget, theParam, theValue);
+ }
+}
+
+// =======================================================================
+// function : SetParameters
+// purpose :
+// =======================================================================
+void OpenGl_Sampler::SetParameters (const Handle(Graphic3d_TextureParams)& theParams)
+{
+ if (myParams != theParams)
+ {
+ myParams = theParams;
+ mySamplerRevision = myParams->SamplerRevision() - 1;
+ }
+}
+
+// =======================================================================
+// function : applySamplerParams
+// purpose :
+// =======================================================================
+void OpenGl_Sampler::applySamplerParams (const Handle(OpenGl_Context)& theCtx,
+ const Handle(Graphic3d_TextureParams)& theParams,
+ OpenGl_Sampler* theSampler,
+ const GLenum theTarget,
+ const bool theHasMipMaps)
+{
+ if (theSampler != NULL && theSampler->Parameters() == theParams)
+ {
+ theSampler->mySamplerRevision = theParams->SamplerRevision();
+ }
+
+ // setup texture filtering
+ const GLenum aFilter = (theParams->Filter() == Graphic3d_TOTF_NEAREST) ? GL_NEAREST : GL_LINEAR;
+ GLenum aFilterMin = aFilter;
+ if (theHasMipMaps)
+ {
+ aFilterMin = GL_NEAREST_MIPMAP_NEAREST;
+ if (theParams->Filter() == Graphic3d_TOTF_BILINEAR)
+ {
+ aFilterMin = GL_LINEAR_MIPMAP_NEAREST;
+ }
+ else if (theParams->Filter() == Graphic3d_TOTF_TRILINEAR)
+ {
+ aFilterMin = GL_LINEAR_MIPMAP_LINEAR;
+ }
+ }
+
+ setParameter (theCtx, theSampler, theTarget, GL_TEXTURE_MIN_FILTER, aFilterMin);
+ setParameter (theCtx, theSampler, theTarget, GL_TEXTURE_MAG_FILTER, aFilter);
+
+ // setup texture wrapping
+ const GLenum aWrapMode = theParams->IsRepeat() ? GL_REPEAT : theCtx->TextureWrapClamp();
+ setParameter (theCtx, theSampler, theTarget, GL_TEXTURE_WRAP_S, aWrapMode);
+#if !defined(GL_ES_VERSION_2_0)
+ if (theTarget == GL_TEXTURE_1D)
{
- #if !defined(GL_ES_VERSION_2_0) || defined(GL_ES_VERSION_3_0)
- theContext.core33->glSamplerParameteri (mySamplerID, theParam, theValue);
- #else
- (void )theContext;
- (void )theParam;
- (void )theValue;
- #endif
+ return;
}
+#endif
+ setParameter (theCtx, theSampler, theTarget, GL_TEXTURE_WRAP_T, aWrapMode);
+ if (theTarget == GL_TEXTURE_3D)
+ {
+ setParameter (theCtx, theSampler, theTarget, GL_TEXTURE_WRAP_R, aWrapMode);
+ return;
+ }
+
+ if (theCtx->extAnis)
+ {
+ // setup degree of anisotropy filter
+ const GLint aMaxDegree = theCtx->MaxDegreeOfAnisotropy();
+ GLint aDegree;
+ switch (theParams->AnisoFilter())
+ {
+ case Graphic3d_LOTA_QUALITY:
+ {
+ aDegree = aMaxDegree;
+ break;
+ }
+ case Graphic3d_LOTA_MIDDLE:
+ {
+ aDegree = (aMaxDegree <= 4) ? 2 : (aMaxDegree / 2);
+ break;
+ }
+ case Graphic3d_LOTA_FAST:
+ {
+ aDegree = 2;
+ break;
+ }
+ case Graphic3d_LOTA_OFF:
+ default:
+ {
+ aDegree = 1;
+ break;
+ }
+ }
+
+ setParameter (theCtx, theSampler, theTarget, GL_TEXTURE_MAX_ANISOTROPY_EXT, aDegree);
+ }
+}
+
+// =======================================================================
+// function : applyGlobalTextureParams
+// purpose :
+// =======================================================================
+void OpenGl_Sampler::applyGlobalTextureParams (const Handle(OpenGl_Context)& theCtx,
+ const OpenGl_Texture& theTexture,
+ const Handle(Graphic3d_TextureParams)& theParams)
+{
+#if defined(GL_ES_VERSION_2_0)
+ (void )theCtx;
+ (void )theTexture;
+ (void )theParams;
+#else
+ if (theCtx->core11 == NULL)
+ {
+ return;
+ }
+
+ GLint anEnvMode = GL_MODULATE; // lighting mode
+ if (!theParams->IsModulate())
+ {
+ anEnvMode = GL_DECAL;
+ if (theTexture.GetFormat() == GL_ALPHA
+ || theTexture.GetFormat() == GL_LUMINANCE)
+ {
+ anEnvMode = GL_REPLACE;
+ }
+ }
+
+ // setup generation of texture coordinates
+ switch (theParams->GenMode())
+ {
+ case Graphic3d_TOTM_OBJECT:
+ {
+ theCtx->core11->glTexGeni (GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
+ theCtx->core11->glTexGenfv (GL_S, GL_OBJECT_PLANE, theParams->GenPlaneS().GetData());
+ if (theTexture.GetTarget() != GL_TEXTURE_1D)
+ {
+ theCtx->core11->glTexGeni (GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
+ theCtx->core11->glTexGenfv (GL_T, GL_OBJECT_PLANE, theParams->GenPlaneT().GetData());
+ }
+ break;
+ }
+ case Graphic3d_TOTM_SPHERE:
+ {
+ theCtx->core11->glTexGeni (GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
+ if (theTexture.GetTarget() != GL_TEXTURE_1D)
+ {
+ theCtx->core11->glTexGeni (GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
+ }
+ break;
+ }
+ case Graphic3d_TOTM_EYE:
+ {
+ theCtx->WorldViewState.Push();
+ theCtx->WorldViewState.SetIdentity();
+ theCtx->ApplyWorldViewMatrix();
+
+ theCtx->core11->glTexGeni (GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
+ theCtx->core11->glTexGenfv (GL_S, GL_EYE_PLANE, theParams->GenPlaneS().GetData());
+ if (theTexture.GetTarget() != GL_TEXTURE_1D)
+ {
+ theCtx->core11->glTexGeni (GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
+ theCtx->core11->glTexGenfv (GL_T, GL_EYE_PLANE, theParams->GenPlaneT().GetData());
+ }
+
+ theCtx->WorldViewState.Pop();
+ break;
+ }
+ case Graphic3d_TOTM_SPRITE:
+ {
+ if (theCtx->core20fwd != NULL)
+ {
+ theCtx->core11fwd->glEnable (GL_POINT_SPRITE);
+ glTexEnvi (GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE);
+ anEnvMode = GL_REPLACE;
+ }
+ break;
+ }
+ case Graphic3d_TOTM_MANUAL:
+ default: break;
+ }
+
+ // setup lighting
+ glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, anEnvMode);
+
+ switch (theTexture.GetTarget())
+ {
+ case GL_TEXTURE_1D:
+ {
+ if (theParams->GenMode() != Graphic3d_TOTM_MANUAL)
+ {
+ theCtx->core11fwd->glEnable (GL_TEXTURE_GEN_S);
+ }
+ theCtx->core11fwd->glEnable (GL_TEXTURE_1D);
+ break;
+ }
+ case GL_TEXTURE_2D:
+ {
+ if (theParams->GenMode() != Graphic3d_TOTM_MANUAL)
+ {
+ theCtx->core11fwd->glEnable (GL_TEXTURE_GEN_S);
+ theCtx->core11fwd->glEnable (GL_TEXTURE_GEN_T);
+ }
+ theCtx->core11fwd->glEnable (GL_TEXTURE_2D);
+ break;
+ }
+ default: break;
+ }
+#endif
+}
+
+// =======================================================================
+// function : resetGlobalTextureParams
+// purpose :
+// =======================================================================
+void OpenGl_Sampler::resetGlobalTextureParams (const Handle(OpenGl_Context)& theCtx,
+ const OpenGl_Texture& theTexture,
+ const Handle(Graphic3d_TextureParams)& theParams)
+{
+#if defined(GL_ES_VERSION_2_0)
+ (void )theCtx;
+ (void )theTexture;
+ (void )theParams;
+#else
+ if (theCtx->core11 == NULL)
+ {
+ return;
+ }
+
+ // reset texture matrix because some code may expect it is identity
+ GLint aMatrixMode = GL_TEXTURE;
+ theCtx->core11fwd->glGetIntegerv (GL_MATRIX_MODE, &aMatrixMode);
+ theCtx->core11->glMatrixMode (GL_TEXTURE);
+ theCtx->core11->glLoadIdentity();
+ theCtx->core11->glMatrixMode (aMatrixMode);
+
+ switch (theTexture.GetTarget())
+ {
+ case GL_TEXTURE_1D:
+ {
+ if (theParams->GenMode() != GL_NONE)
+ {
+ theCtx->core11fwd->glDisable (GL_TEXTURE_GEN_S);
+ }
+ theCtx->core11fwd->glDisable (GL_TEXTURE_1D);
+ break;
+ }
+ case GL_TEXTURE_2D:
+ {
+ if (theParams->GenMode() != GL_NONE)
+ {
+ theCtx->core11fwd->glDisable (GL_TEXTURE_GEN_S);
+ theCtx->core11fwd->glDisable (GL_TEXTURE_GEN_T);
+ if (theParams->GenMode() == Graphic3d_TOTM_SPRITE)
+ {
+ theCtx->core11fwd->glDisable (GL_POINT_SPRITE);
+ }
+ }
+ theCtx->core11fwd->glDisable (GL_TEXTURE_2D);
+ break;
+ }
+ default: break;
+ }
+#endif
}
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
-#ifndef OPENGL_SAMPLER_H
-#define OPENGL_SAMPLER_H
+#ifndef _OpenGl_Sampler_Header
+#define _OpenGl_Sampler_Header
#include <OpenGl_Context.hxx>
+#include <OpenGl_Resource.hxx>
-class OpenGl_Sampler;
-DEFINE_STANDARD_HANDLE(OpenGl_Sampler, OpenGl_Resource)
+class OpenGl_Texture;
//! Class implements OpenGL sampler object resource that
//! stores the sampling parameters for a texture access.
class OpenGl_Sampler : public OpenGl_Resource
{
+ friend class OpenGl_Context;
+ friend class OpenGl_Texture;
+ DEFINE_STANDARD_RTTIEXT(OpenGl_Sampler, OpenGl_Resource)
public:
//! Helpful constant defining invalid sampler identifier
public:
//! Creates new sampler object.
- Standard_EXPORT OpenGl_Sampler();
+ Standard_EXPORT OpenGl_Sampler (const Handle(Graphic3d_TextureParams)& theParams);
//! Releases resources of sampler object.
Standard_EXPORT virtual ~OpenGl_Sampler();
//! Destroys object - will release GPU memory if any.
Standard_EXPORT virtual void Release (OpenGl_Context* theContext) Standard_OVERRIDE;
- //! Initializes sampler object.
- Standard_EXPORT Standard_Boolean Init (OpenGl_Context& theContext);
+ //! Creates an uninitialized sampler object.
+ Standard_EXPORT Standard_Boolean Create (const Handle(OpenGl_Context)& theContext);
+
+ //! Creates and initializes sampler object.
+ //! Existing object will be reused if possible, however if existing Sampler Object has Immutable flag
+ //! and texture parameters should be re-initialized, then Sampler Object will be recreated.
+ Standard_EXPORT Standard_Boolean Init (const Handle(OpenGl_Context)& theContext,
+ const OpenGl_Texture& theTexture);
//! Returns true if current object was initialized.
Standard_Boolean IsValid() const
return isValidSampler();
}
+ //! Binds sampler object to texture unit specified in parameters.
+ void Bind (const Handle(OpenGl_Context)& theCtx)
+ {
+ Bind (theCtx, myParams->TextureUnit());
+ }
+
+ //! Unbinds sampler object from texture unit specified in parameters.
+ void Unbind (const Handle(OpenGl_Context)& theCtx)
+ {
+ Unbind (theCtx, myParams->TextureUnit());
+ }
+
//! Binds sampler object to the given texture unit.
- Standard_EXPORT void Bind (OpenGl_Context& theContext, const GLuint theUnit = 0);
+ Standard_EXPORT void Bind (const Handle(OpenGl_Context)& theCtx,
+ const Graphic3d_TextureUnit theUnit);
//! Unbinds sampler object from the given texture unit.
- Standard_EXPORT void Unbind (OpenGl_Context& theContext, const GLuint theUnit = 0);
+ Standard_EXPORT void Unbind (const Handle(OpenGl_Context)& theCtx,
+ const Graphic3d_TextureUnit theUnit);
//! Sets specific sampler parameter.
- Standard_EXPORT void SetParameter (OpenGl_Context& theContext, const GLenum theParam, const GLint theValue);
+ void SetParameter (const Handle(OpenGl_Context)& theCtx,
+ GLenum theTarget,
+ GLenum theParam,
+ GLint theValue)
+ {
+ setParameter (theCtx, this, theTarget, theParam, theValue);
+ }
//! Returns OpenGL sampler ID.
GLuint SamplerID() const
return mySamplerID;
}
+ //! Return immutable flag preventing further modifications of sampler parameters, FALSE by default.
+ //! Immutable flag might be set when Sampler Object is used within Bindless Texture.
+ bool IsImmutable() const { return myIsImmutable; }
+
+ //! Setup immutable flag. It is not possible unsetting this flag without Sampler destruction.
+ void SetImmutable() { myIsImmutable = true; }
+
+ //! Returns texture parameters.
+ const Handle(Graphic3d_TextureParams)& Parameters() { return myParams; }
+
+ //! Sets texture parameters.
+ Standard_EXPORT void SetParameters (const Handle(Graphic3d_TextureParams)& theParams);
+
+ //! Returns texture parameters initialization state.
+ bool ToUpdateParameters() const { return mySamplerRevision != myParams->SamplerRevision(); }
+
protected:
//! Checks if sampler object is valid.
return mySamplerID != NO_SAMPLER;
}
-protected:
-
- GLuint mySamplerID; //!< OpenGL sampler object ID
+ //! Sets specific sampler parameter.
+ Standard_EXPORT static void setParameter (const Handle(OpenGl_Context)& theContext,
+ OpenGl_Sampler* theSampler,
+ GLenum theTarget,
+ GLenum theParam,
+ GLint theValue);
+
+ //! Apply sampler parameters.
+ //! If Sampler Object is not NULL and valid resource, the parameters will be set to it (and it is not required Sampler Object being bound).
+ //! Otherwise, parameters will be applied to currently bound Texture object.
+ Standard_EXPORT static void applySamplerParams (const Handle(OpenGl_Context)& theCtx,
+ const Handle(Graphic3d_TextureParams)& theParams,
+ OpenGl_Sampler* theSampler,
+ const GLenum theTarget,
+ const bool theHasMipMaps);
+
+ //! Apply global texture state for deprecated OpenGL functionality.
+ Standard_EXPORT static void applyGlobalTextureParams (const Handle(OpenGl_Context)& theCtx,
+ const OpenGl_Texture& theTexture,
+ const Handle(Graphic3d_TextureParams)& theParams);
+
+ //! Reset global texture state for deprecated OpenGL functionality.
+ Standard_EXPORT static void resetGlobalTextureParams (const Handle(OpenGl_Context)& theCtx,
+ const OpenGl_Texture& theTexture,
+ const Handle(Graphic3d_TextureParams)& theParams);
-public:
+protected:
- DEFINE_STANDARD_RTTIEXT(OpenGl_Sampler,OpenGl_Resource)
+ Handle(Graphic3d_TextureParams) myParams; //!< texture parameters
+ unsigned int mySamplerRevision; //!< modification counter of parameters related to sampler state
+ GLuint mySamplerID; //!< OpenGL sampler object ID
+ bool myIsImmutable; //!< immutable flag preventing further modifications of sampler parameters, FALSE by default
};
-#endif // OPENGL_SAMPLER_H
+DEFINE_STANDARD_HANDLE(OpenGl_Sampler, OpenGl_Resource)
+
+#endif // _OpenGl_Sampler_Header
// function : AcquireTextures
// purpose : Makes the OpenGL texture handles resident
// =======================================================================
-Standard_Boolean OpenGl_RaytraceGeometry::AcquireTextures (const Handle(OpenGl_Context)& theContext) const
+Standard_Boolean OpenGl_RaytraceGeometry::AcquireTextures (const Handle(OpenGl_Context)& theContext)
{
if (theContext->arbTexBindless == NULL)
{
}
#if !defined(GL_ES_VERSION_2_0)
- for (Standard_Integer anIdx = 0; anIdx < myTextures.Size(); ++anIdx)
+ Standard_Integer aTexIter = 0;
+ for (NCollection_Vector<Handle(OpenGl_Texture)>::Iterator aTexSrcIter (myTextures); aTexSrcIter.More(); aTexSrcIter.Next(), ++aTexIter)
{
- theContext->arbTexBindless->glMakeTextureHandleResidentARB (myTextureHandles[anIdx]);
+ GLuint64& aHandle = myTextureHandles[aTexIter];
+ const Handle(OpenGl_Texture)& aTexture = aTexSrcIter.Value();
+ if (!aTexture->Sampler()->IsValid()
+ || !aTexture->Sampler()->IsImmutable())
+ {
+ // need to recreate texture sampler handle
+ aHandle = GLuint64(-1); // specs do not define value for invalid handle, set -1 to initialize something
+ if (!aTexture->InitSamplerObject (theContext))
+ {
+ continue;
+ }
- if (glGetError() != GL_NO_ERROR)
+ aTexture->Sampler()->SetImmutable();
+ aHandle = theContext->arbTexBindless->glGetTextureSamplerHandleARB (aTexture->TextureId(), aTexture->Sampler()->SamplerID());
+ const GLenum anErr = glGetError();
+ if (anErr != GL_NO_ERROR)
+ {
+ theContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
+ TCollection_AsciiString ("Error: Failed to get 64-bit handle of OpenGL texture #") + int(anErr));
+ myTextureHandles.clear();
+ return Standard_False;
+ }
+ }
+
+ theContext->arbTexBindless->glMakeTextureHandleResidentARB (aHandle);
+ const GLenum anErr = glGetError();
+ if (anErr != GL_NO_ERROR)
{
-#ifdef RAY_TRACE_PRINT_INFO
- std::cout << "Error: Failed to make OpenGL texture resident" << std::endl;
-#endif
+ theContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
+ TCollection_AsciiString ("Error: Failed to make OpenGL texture resident #") + int(anErr));
return Standard_False;
}
}
}
#if !defined(GL_ES_VERSION_2_0)
- for (Standard_Integer anIdx = 0; anIdx < myTextures.Size(); ++anIdx)
+ for (size_t aTexIter = 0; aTexIter < myTextureHandles.size(); ++aTexIter)
{
- theContext->arbTexBindless->glMakeTextureHandleNonResidentARB (myTextureHandles[anIdx]);
-
- if (glGetError() != GL_NO_ERROR)
+ theContext->arbTexBindless->glMakeTextureHandleNonResidentARB (myTextureHandles[aTexIter]);
+ const GLenum anErr = glGetError();
+ if (anErr != GL_NO_ERROR)
{
-#ifdef RAY_TRACE_PRINT_INFO
- std::cout << "Error: Failed to make OpenGL texture non-resident" << std::endl;
-#endif
+ theContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
+ TCollection_AsciiString("Error: Failed to make OpenGL texture non-resident #") + int(anErr));
return Standard_False;
}
}
return Standard_False;
}
- if (myTextureSampler.IsNull())
- {
- myTextureSampler = new OpenGl_Sampler();
- myTextureSampler->Init (*theContext.operator->());
- myTextureSampler->SetParameter (*theContext.operator->(), GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- myTextureSampler->SetParameter (*theContext.operator->(), GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- myTextureSampler->SetParameter (*theContext.operator->(), GL_TEXTURE_WRAP_S, GL_REPEAT);
- myTextureSampler->SetParameter (*theContext.operator->(), GL_TEXTURE_WRAP_T, GL_REPEAT);
- }
-
myTextureHandles.clear();
+ myTextureHandles.resize (myTextures.Size());
#if !defined(GL_ES_VERSION_2_0)
- for (Standard_Integer anIdx = 0; anIdx < myTextures.Size(); ++anIdx)
+ Standard_Integer aTexIter = 0;
+ for (NCollection_Vector<Handle(OpenGl_Texture)>::Iterator aTexSrcIter (myTextures); aTexSrcIter.More(); aTexSrcIter.Next(), ++aTexIter)
{
- const GLuint64 aHandle = theContext->arbTexBindless->glGetTextureSamplerHandleARB (
- myTextures.Value (anIdx)->TextureId(), myTextureSampler->SamplerID());
+ GLuint64& aHandle = myTextureHandles[aTexIter];
+ aHandle = GLuint64(-1); // specs do not define value for invalid handle, set -1 to initialize something
- if (glGetError() != GL_NO_ERROR)
+ const Handle(OpenGl_Texture)& aTexture = aTexSrcIter.Value();
+ if (!aTexture->Sampler()->IsValid()
+ && !aTexture->InitSamplerObject (theContext))
{
-#ifdef RAY_TRACE_PRINT_INFO
- std::cout << "Error: Failed to get 64-bit handle of OpenGL texture" << std::endl;
-#endif
- return Standard_False;
+ continue;
}
- myTextureHandles.push_back (aHandle);
+ aTexture->Sampler()->SetImmutable();
+ aHandle = theContext->arbTexBindless->glGetTextureSamplerHandleARB (aTexture->TextureId(), aTexture->Sampler()->SamplerID());
+ const GLenum anErr = glGetError();
+ if (anErr != GL_NO_ERROR)
+ {
+ theContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
+ TCollection_AsciiString ("Error: Failed to get 64-bit handle of OpenGL texture #") + int(anErr));
+ myTextureHandles.clear();
+ return Standard_False;
+ }
}
#endif
Standard_Boolean UpdateTextureHandles (const Handle(OpenGl_Context)& theContext);
//! Makes the OpenGL texture handles resident (must be called before using).
- Standard_Boolean AcquireTextures (const Handle(OpenGl_Context)& theContext) const;
+ Standard_Boolean AcquireTextures (const Handle(OpenGl_Context)& theContext);
//! Makes the OpenGL texture handles non-resident (must be called after using).
Standard_Boolean ReleaseTextures (const Handle(OpenGl_Context)& theContext) const;
}
//! Releases OpenGL resources.
- void ReleaseResources (const Handle(OpenGl_Context)& theContext)
+ void ReleaseResources (const Handle(OpenGl_Context)& )
{
- if (!myTextureSampler.IsNull())
- {
- myTextureSampler->Release (theContext.operator->());
- myTextureSampler.Nullify();
- }
+ //
}
public: //! @name auxiliary methods
protected:
NCollection_Vector<Handle(OpenGl_Texture)> myTextures; //!< Array of texture maps shared between rendered objects
- Handle(OpenGl_Sampler) myTextureSampler; //!< Sampler object providing fixed sampling params for texures
std::vector<GLuint64> myTextureHandles; //!< Array of unique 64-bit texture handles obtained from OpenGL
Standard_Integer myTopLevelTreeDepth; //!< Depth of high-level scene BVH from last build
Standard_Integer myBotLevelTreeDepth; //!< Maximum depth of bottom-level scene BVHs from last build
EOL"}";
TCollection_AsciiString
- aSrcGetAlpha = EOL"float getAlpha(void) { return occTexture2D(occActiveSampler, TexCoord.st).a; }";
+ aSrcGetAlpha = EOL"float getAlpha(void) { return occTexture2D(occSamplerBaseColor, TexCoord.st).a; }";
#if !defined(GL_ES_VERSION_2_0)
if (myContext->core11 == NULL)
{
- aSrcGetAlpha = EOL"float getAlpha(void) { return occTexture2D(occActiveSampler, TexCoord.st).r; }";
+ aSrcGetAlpha = EOL"float getAlpha(void) { return occTexture2D(occSamplerBaseColor, TexCoord.st).r; }";
}
#endif
}
myContext->BindProgram (myBlitProgram);
- myBlitProgram->SetSampler (myContext, "uColorSampler", 0);
- myBlitProgram->SetSampler (myContext, "uDepthSampler", 1);
+ myBlitProgram->SetSampler (myContext, "uColorSampler", Graphic3d_TextureUnit_0);
+ myBlitProgram->SetSampler (myContext, "uDepthSampler", Graphic3d_TextureUnit_1);
myContext->BindProgram (NULL);
return Standard_True;
}
}
myContext->BindProgram (aProgram);
- aProgram->SetSampler (myContext, "uAccumTexture", 0);
- aProgram->SetSampler (myContext, "uWeightTexture", 1);
+ aProgram->SetSampler (myContext, "uAccumTexture", Graphic3d_TextureUnit_0);
+ aProgram->SetSampler (myContext, "uWeightTexture", Graphic3d_TextureUnit_1);
myContext->BindProgram (Handle(OpenGl_ShaderProgram)());
return Standard_True;
}
// =======================================================================
TCollection_AsciiString OpenGl_ShaderManager::pointSpriteAlphaSrc (const Standard_Integer theBits)
{
- TCollection_AsciiString aSrcGetAlpha = EOL"float getAlpha(void) { return occTexture2D(occActiveSampler, " THE_VEC2_glPointCoord ").a; }";
+ TCollection_AsciiString aSrcGetAlpha = EOL"float getAlpha(void) { return occTexture2D(occSamplerBaseColor, " THE_VEC2_glPointCoord ").a; }";
#if !defined(GL_ES_VERSION_2_0)
if (myContext->core11 == NULL
&& (theBits & OpenGl_PO_TextureA) != 0)
{
- aSrcGetAlpha = EOL"float getAlpha(void) { return occTexture2D(occActiveSampler, " THE_VEC2_glPointCoord ").r; }";
+ aSrcGetAlpha = EOL"float getAlpha(void) { return occTexture2D(occSamplerBaseColor, " THE_VEC2_glPointCoord ").r; }";
}
#else
(void )theBits;
if ((theBits & OpenGl_PO_TextureRGB) != 0)
{
aSrcFragGetColor =
- EOL"vec4 getColor(void) { return occTexture2D(occActiveSampler, " THE_VEC2_glPointCoord "); }";
+ EOL"vec4 getColor(void) { return occTexture2D(occSamplerBaseColor, " THE_VEC2_glPointCoord "); }";
}
if (textureUsed (theBits))
aSrcVertExtraMain += THE_VARY_TexCoord_Trsf;
aSrcFragGetColor =
- EOL"vec4 getColor(void) { return occTexture2D(occActiveSampler, TexCoord.st / TexCoord.w); }";
+ EOL"vec4 getColor(void) { return occTexture2D(occSamplerBaseColor, TexCoord.st / TexCoord.w); }";
}
else if ((theBits & OpenGl_PO_TextureEnv) != 0)
{
EOL" TexCoord = vec4(aReflect.xy * inversesqrt (dot (aReflect, aReflect)) * 0.5 + vec2 (0.5), 0.0, 1.0);";
aSrcFragGetColor =
- EOL"vec4 getColor(void) { return occTexture2D (occActiveSampler, TexCoord.st); }";
+ EOL"vec4 getColor(void) { return occTexture2D (occSamplerBaseColor, TexCoord.st); }";
}
}
if ((theBits & OpenGl_PO_VertColor) != 0)
EOL"vec4 getColor(void)"
EOL"{"
EOL" vec4 aColor = " + theBaseColorSrc + ";"
- EOL" aColor = occTexture2D(occActiveSampler, " THE_VEC2_glPointCoord ") * aColor;"
+ EOL" aColor = occTexture2D(occSamplerBaseColor, " THE_VEC2_glPointCoord ") * aColor;"
EOL" if (aColor.a <= 0.1) discard;"
EOL" return aColor;"
EOL"}";
EOL"vec4 getColor(void)"
EOL"{"
EOL" vec4 aColor = gl_FrontFacing ? FrontColor : BackColor;"
- EOL" return occTexture2D(occActiveSampler, TexCoord.st / TexCoord.w) * aColor;"
+ EOL" return occTexture2D(occSamplerBaseColor, TexCoord.st / TexCoord.w) * aColor;"
EOL"}";
}
}
EOL"vec4 getColor(void)"
EOL"{"
EOL" vec4 aColor = " thePhongCompLight ";"
- EOL" return occTexture2D(occActiveSampler, TexCoord.st / TexCoord.w) * aColor;"
+ EOL" return occTexture2D(occSamplerBaseColor, TexCoord.st / TexCoord.w) * aColor;"
EOL"}";
}
}
}
myContext->BindProgram (theProgram);
- theProgram->SetSampler (myContext, "uLeftSampler", 0);
- theProgram->SetSampler (myContext, "uRightSampler", 1);
+ theProgram->SetSampler (myContext, "uLeftSampler", Graphic3d_TextureUnit_0);
+ theProgram->SetSampler (myContext, "uRightSampler", Graphic3d_TextureUnit_1);
myContext->BindProgram (NULL);
return Standard_True;
}
Standard_EXPORT Standard_Boolean IsEmpty() const;
//! Bind program for filled primitives rendering
- Standard_Boolean BindFaceProgram (const Handle(OpenGl_Texture)& theTexture,
- const Standard_Boolean theToLightOn,
+ Standard_Boolean BindFaceProgram (const Handle(OpenGl_TextureSet)& theTextures,
+ const Standard_Boolean theToLightOn,
const Standard_Boolean theHasVertColor,
const Standard_Boolean theEnableEnvMap,
const Handle(OpenGl_ShaderProgram)& theCustomProgram)
return bindProgramWithState (theCustomProgram);
}
- const Standard_Integer aBits = getProgramBits (theTexture, theHasVertColor, theEnableEnvMap);
+ const Standard_Integer aBits = getProgramBits (theTextures, theHasVertColor, theEnableEnvMap);
Handle(OpenGl_ShaderProgram)& aProgram = getStdProgram (theToLightOn, aBits);
return bindProgramWithState (aProgram);
}
//! Bind program for line rendering
- Standard_Boolean BindLineProgram (const Handle(OpenGl_Texture)& theTexture,
+ Standard_Boolean BindLineProgram (const Handle(OpenGl_TextureSet)& theTextures,
const Standard_Boolean theStipple,
const Standard_Boolean theToLightOn,
const Standard_Boolean theHasVertColor,
return bindProgramWithState (theCustomProgram);
}
- Standard_Integer aBits = getProgramBits (theTexture, theHasVertColor);
+ Standard_Integer aBits = getProgramBits (theTextures, theHasVertColor);
if (theStipple)
{
aBits |= OpenGl_PO_StippleLine;
}
//! Bind program for point rendering
- Standard_Boolean BindMarkerProgram (const Handle(OpenGl_Texture)& theTexture,
+ Standard_Boolean BindMarkerProgram (const Handle(OpenGl_TextureSet)& theTextures,
const Standard_Boolean theToLightOn,
const Standard_Boolean theHasVertColor,
const Handle(OpenGl_ShaderProgram)& theCustomProgram)
return bindProgramWithState (theCustomProgram);
}
- const Standard_Integer aBits = getProgramBits (theTexture, theHasVertColor) | OpenGl_PO_Point;
+ const Standard_Integer aBits = getProgramBits (theTextures, theHasVertColor) | OpenGl_PO_Point;
Handle(OpenGl_ShaderProgram)& aProgram = getStdProgram (theToLightOn, aBits);
return bindProgramWithState (aProgram);
}
protected:
//! Define program bits.
- Standard_Integer getProgramBits (const Handle(OpenGl_Texture)& theTexture,
- const Standard_Boolean theHasVertColor,
- const Standard_Boolean theEnableEnvMap = Standard_False)
+ Standard_Integer getProgramBits (const Handle(OpenGl_TextureSet)& theTextures,
+ const Standard_Boolean theHasVertColor,
+ const Standard_Boolean theEnableEnvMap = Standard_False)
{
Standard_Integer aBits = 0;
// Environment map overwrites material texture
aBits |= OpenGl_PO_TextureEnv;
}
- else if (!theTexture.IsNull())
+ else if (!theTextures.IsNull()
+ && !theTextures->IsEmpty()
+ && !theTextures->First().IsNull())
{
- aBits |= theTexture->IsAlpha() ? OpenGl_PO_TextureA : OpenGl_PO_TextureRGB;
+ aBits |= theTextures->First()->IsAlpha() ? OpenGl_PO_TextureA : OpenGl_PO_TextureRGB;
}
if (theHasVertColor)
{
#include <malloc.h> // for alloca()
#endif
-IMPLEMENT_STANDARD_RTTIEXT(OpenGl_ShaderProgram,OpenGl_Resource)
+IMPLEMENT_STANDARD_RTTIEXT(OpenGl_ShaderProgram, OpenGl_NamedResource)
OpenGl_VariableSetterSelector OpenGl_ShaderProgram::mySetterSelector = OpenGl_VariableSetterSelector();
"occLightSources", // OpenGl_OCC_LIGHT_SOURCE_PARAMS
"occLightAmbient", // OpenGl_OCC_LIGHT_AMBIENT
- "occActiveSampler", // OpenGl_OCCT_ACTIVE_SAMPLER
"occTextureEnable", // OpenGl_OCCT_TEXTURE_ENABLE
"occDistinguishingMode", // OpenGl_OCCT_DISTINGUISH_MODE
"occFrontMaterial", // OpenGl_OCCT_FRONT_MATERIAL
// purpose : Creates uninitialized shader program
// =======================================================================
OpenGl_ShaderProgram::OpenGl_ShaderProgram (const Handle(Graphic3d_ShaderProgram)& theProxy)
-: myProgramID (NO_PROGRAM),
+: OpenGl_NamedResource (!theProxy.IsNull() ? theProxy->GetId() : ""),
+ myProgramID (NO_PROGRAM),
myProxy (theProxy),
myShareCount(1)
{
}
// set uniform defaults
- const GLint aLocSampler = GetStateLocation (OpenGl_OCCT_ACTIVE_SAMPLER);
- const GLint aLocTexEnable = GetStateLocation (OpenGl_OCCT_TEXTURE_ENABLE);
- if (aLocSampler != INVALID_LOCATION
- || aLocTexEnable != INVALID_LOCATION)
+ const Handle(OpenGl_ShaderProgram)& anOldProgram = theCtx->ActiveProgram();
+ theCtx->core20fwd->glUseProgram (myProgramID);
{
- const Handle(OpenGl_ShaderProgram)& anOldProgram = theCtx->ActiveProgram();
- theCtx->core20fwd->glUseProgram (myProgramID);
- SetUniform (theCtx, aLocSampler, 0); // GL_TEXTURE0
- SetUniform (theCtx, aLocTexEnable, 0); // Off
- theCtx->core20fwd->glUseProgram (!anOldProgram.IsNull() ? anOldProgram->ProgramId() : OpenGl_ShaderProgram::NO_PROGRAM);
+ const GLint aLocTexEnable = GetStateLocation (OpenGl_OCCT_TEXTURE_ENABLE);
+ if (aLocTexEnable != INVALID_LOCATION)
+ {
+ SetUniform (theCtx, aLocTexEnable, 0); // Off
+ }
+ }
+ {
+ const GLint aLocSampler = GetUniformLocation (theCtx, "occActiveSampler");
+ if (aLocSampler != INVALID_LOCATION)
+ {
+ SetUniform (theCtx, aLocSampler, GLint(Graphic3d_TextureUnit_0));
+ }
+ }
+
+ const TCollection_AsciiString aSamplerNamePrefix ("occSampler");
+ const Standard_Integer aNbUnitsMax = Max (theCtx->MaxCombinedTextureUnits(), Graphic3d_TextureUnit_NB);
+ for (GLint aUnitIter = 0; aUnitIter < aNbUnitsMax; ++aUnitIter)
+ {
+ const TCollection_AsciiString aName = aSamplerNamePrefix + aUnitIter;
+ const GLint aLocSampler = GetUniformLocation (theCtx, aName.ToCString());
+ if (aLocSampler != INVALID_LOCATION)
+ {
+ SetUniform (theCtx, aLocSampler, aUnitIter);
+ }
}
+ theCtx->core20fwd->glUseProgram (!anOldProgram.IsNull() ? anOldProgram->ProgramId() : OpenGl_ShaderProgram::NO_PROGRAM);
return Standard_True;
}
// =======================================================================
Standard_Boolean OpenGl_ShaderProgram::SetSampler (const Handle(OpenGl_Context)& theCtx,
const GLchar* theName,
- const GLenum theTextureUnit)
+ const Graphic3d_TextureUnit theTextureUnit)
{
return SetSampler (theCtx, GetUniformLocation (theCtx, theName), theTextureUnit);
}
// =======================================================================
Standard_Boolean OpenGl_ShaderProgram::SetSampler (const Handle(OpenGl_Context)& theCtx,
GLint theLocation,
- const GLenum theTextureUnit)
+ const Graphic3d_TextureUnit theTextureUnit)
{
if (myProgramID == NO_PROGRAM || theLocation == INVALID_LOCATION)
{
#include <OpenGl_Vec.hxx>
#include <OpenGl_Matrix.hxx>
+#include <OpenGl_NamedResource.hxx>
#include <OpenGl_ShaderObject.hxx>
class OpenGl_ShaderProgram;
-DEFINE_STANDARD_HANDLE(OpenGl_ShaderProgram, OpenGl_Resource)
+DEFINE_STANDARD_HANDLE(OpenGl_ShaderProgram, OpenGl_NamedResource)
//! The enumeration of OCCT-specific OpenGL/GLSL variables.
enum OpenGl_StateVariable
OpenGl_OCC_LIGHT_AMBIENT,
// Material state
- OpenGl_OCCT_ACTIVE_SAMPLER,
OpenGl_OCCT_TEXTURE_ENABLE,
OpenGl_OCCT_DISTINGUISH_MODE,
OpenGl_OCCT_FRONT_MATERIAL,
OpenGl_OCCT_NUMBER_OF_STATE_VARIABLES
};
-class OpenGl_ShaderProgram;
-
//! Interface for generic setter of user-defined uniform variables.
struct OpenGl_SetterInterface
{
};
//! Wrapper for OpenGL program object.
-class OpenGl_ShaderProgram : public OpenGl_Resource
+class OpenGl_ShaderProgram : public OpenGl_NamedResource
{
friend class OpenGl_View;
-
+ friend class OpenGl_ShaderManager;
+ DEFINE_STANDARD_RTTIEXT(OpenGl_ShaderProgram, OpenGl_NamedResource)
public:
//! Non-valid shader name.
//! Specifies the value of the sampler uniform variable.
Standard_EXPORT Standard_Boolean SetSampler (const Handle(OpenGl_Context)& theCtx,
const GLchar* theName,
- const GLenum theTextureUnit);
+ const Graphic3d_TextureUnit theTextureUnit);
//! Specifies the value of the sampler uniform variable.
Standard_EXPORT Standard_Boolean SetSampler (const Handle(OpenGl_Context)& theCtx,
GLint theLocation,
- const GLenum theTextureUnit);
+ const Graphic3d_TextureUnit theTextureUnit);
protected:
//! Stores locations of OCCT state uniform variables.
GLint myStateLocations[OpenGl_OCCT_NUMBER_OF_STATE_VARIABLES];
-public:
-
- DEFINE_STANDARD_RTTIEXT(OpenGl_ShaderProgram,OpenGl_Resource)
- friend class OpenGl_ShaderManager;
-
};
template<class T>
virtual void Render (const Handle(OpenGl_Workspace)& theWorkspace) const
{
#if !defined(GL_ES_VERSION_2_0)
- // Apply line aspect
- const Handle(OpenGl_Texture) aPrevTexture = theWorkspace->DisableTexture();
+ const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext();
+ if (aCtx->core11 == NULL)
+ {
+ return;
+ }
- theWorkspace->GetGlContext()->BindProgram (Handle(OpenGl_ShaderProgram)());
- theWorkspace->GetGlContext()->ShaderManager()->PushState (Handle(OpenGl_ShaderProgram)());
+ const Handle(OpenGl_TextureSet) aPrevTexture = aCtx->BindTextures (Handle(OpenGl_TextureSet)());
+ aCtx->BindProgram (Handle(OpenGl_ShaderProgram)());
+ aCtx->ShaderManager()->PushState (Handle(OpenGl_ShaderProgram)());
glDisable (GL_LIGHTING);
// Use highlight colors
- theWorkspace->GetGlContext()->core11->glColor3fv (theWorkspace->LineColor().GetData());
+ aCtx->core11->glColor3fv (theWorkspace->LineColor().GetData());
glEnableClientState (GL_VERTEX_ARRAY);
glVertexPointer (3, GL_FLOAT, 0, (GLfloat* )&myVerts);
// restore aspects
if (!aPrevTexture.IsNull())
{
- theWorkspace->EnableTexture (aPrevTexture);
+ aCtx->BindTextures (aPrevTexture);
}
#else
(void )theWorkspace;
void OpenGl_Text::Render (const Handle(OpenGl_Workspace)& theWorkspace) const
{
const OpenGl_AspectText* aTextAspect = theWorkspace->ApplyAspectText();
- const Handle(OpenGl_Texture) aPrevTexture = theWorkspace->DisableTexture();
const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext();
+ const Handle(OpenGl_TextureSet) aPrevTexture = aCtx->BindTextures (Handle(OpenGl_TextureSet)());
#if !defined(GL_ES_VERSION_2_0)
const Standard_Integer aPrevPolygonMode = aCtx->SetPolygonMode (GL_FILL);
const bool aPrevHatchingMode = aCtx->SetPolygonHatchEnabled (false);
// restore aspects
if (!aPrevTexture.IsNull())
{
- theWorkspace->EnableTexture (aPrevTexture);
+ aCtx->BindTextures (aPrevTexture);
}
#if !defined(GL_ES_VERSION_2_0)
aCtx->SetPolygonMode (aPrevPolygonMode);
}
// bind flat program
- theCtx->ShaderManager()->BindFaceProgram (Handle(OpenGl_Texture)(), Standard_False, Standard_False, Standard_False, Handle(OpenGl_ShaderProgram)());
+ theCtx->ShaderManager()->BindFaceProgram (Handle(OpenGl_TextureSet)(), Standard_False, Standard_False, Standard_False, Handle(OpenGl_ShaderProgram)());
#if !defined(GL_ES_VERSION_2_0)
if (theCtx->core11 != NULL
#include <OpenGl_ArbFBO.hxx>
#include <OpenGl_Context.hxx>
#include <OpenGl_GlCore32.hxx>
+#include <OpenGl_Sampler.hxx>
#include <Graphic3d_TextureParams.hxx>
#include <TCollection_ExtendedString.hxx>
#include <Standard_Assert.hxx>
#include <Image_PixMap.hxx>
-
-IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Texture,OpenGl_Resource)
+IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Texture, OpenGl_NamedResource)
//! Simple class to reset unpack alignment settings
struct OpenGl_UnpackAlignmentSentry
// function : OpenGl_Texture
// purpose :
// =======================================================================
-OpenGl_Texture::OpenGl_Texture (const Handle(Graphic3d_TextureParams)& theParams)
-: OpenGl_Resource(),
+OpenGl_Texture::OpenGl_Texture (const TCollection_AsciiString& theResourceId,
+ const Handle(Graphic3d_TextureParams)& theParams)
+: OpenGl_NamedResource (theResourceId),
+ mySampler (new OpenGl_Sampler (theParams)),
myRevision (0),
myTextureId (NO_TEXTURE),
myTarget (GL_TEXTURE_2D),
mySizeZ (0),
myTextFormat (GL_RGBA),
myHasMipmaps (Standard_False),
- myIsAlpha (false),
- myParams (theParams)
+ myIsAlpha (false)
{
- if (myParams.IsNull())
- {
- myParams = new Graphic3d_TextureParams();
- }
+ //
}
// =======================================================================
Release (NULL);
}
-// =======================================================================
-// function : HasMipmaps
-// purpose :
-// =======================================================================
-Standard_Boolean OpenGl_Texture::HasMipmaps() const
-{
- return myHasMipmaps;
-}
-
-// =======================================================================
-// function : GetParams
-// purpose :
-// =======================================================================
-const Handle(Graphic3d_TextureParams)& OpenGl_Texture::GetParams() const
-{
- return myParams;
-}
-
-// =======================================================================
-// function : SetParams
-// purpose :
-// =======================================================================
-void OpenGl_Texture::SetParams (const Handle(Graphic3d_TextureParams)& theParams)
-{
- myParams = theParams;
-}
-
// =======================================================================
// function : Create
// purpose :
// =======================================================================
-bool OpenGl_Texture::Create (const Handle(OpenGl_Context)& )
+bool OpenGl_Texture::Create (const Handle(OpenGl_Context)& theCtx)
{
+ if (myTextureId != NO_TEXTURE)
+ {
+ return true;
+ }
+
+ theCtx->core11fwd->glGenTextures (1, &myTextureId);
if (myTextureId == NO_TEXTURE)
{
- glGenTextures (1, &myTextureId);
+ return false;
}
- return myTextureId != NO_TEXTURE;
+
+ //mySampler->Create (theCtx); // do not create sampler object by default
+ return true;
}
// =======================================================================
// =======================================================================
void OpenGl_Texture::Release (OpenGl_Context* theGlCtx)
{
+ mySampler->Release (theGlCtx);
if (myTextureId == NO_TEXTURE)
{
return;
mySizeX = mySizeY = mySizeZ = 0;
}
+// =======================================================================
+// function : applyDefaultSamplerParams
+// purpose :
+// =======================================================================
+void OpenGl_Texture::applyDefaultSamplerParams (const Handle(OpenGl_Context)& theCtx)
+{
+ OpenGl_Sampler::applySamplerParams (theCtx, mySampler->Parameters(), NULL, myTarget, myHasMipmaps);
+ if (mySampler->IsValid() && !mySampler->IsImmutable())
+ {
+ OpenGl_Sampler::applySamplerParams (theCtx, mySampler->Parameters(), mySampler.get(), myTarget, myHasMipmaps);
+ }
+}
+
// =======================================================================
// function : Bind
// purpose :
// =======================================================================
void OpenGl_Texture::Bind (const Handle(OpenGl_Context)& theCtx,
- const GLenum theTextureUnit) const
+ const Graphic3d_TextureUnit theTextureUnit) const
{
if (theCtx->core15fwd != NULL)
{
- theCtx->core15fwd->glActiveTexture (theTextureUnit);
+ theCtx->core15fwd->glActiveTexture (GL_TEXTURE0 + theTextureUnit);
}
+ mySampler->Bind (theCtx, theTextureUnit);
glBindTexture (myTarget, myTextureId);
}
// purpose :
// =======================================================================
void OpenGl_Texture::Unbind (const Handle(OpenGl_Context)& theCtx,
- const GLenum theTextureUnit) const
+ const Graphic3d_TextureUnit theTextureUnit) const
{
if (theCtx->core15fwd != NULL)
{
- theCtx->core15fwd->glActiveTexture (theTextureUnit);
+ theCtx->core15fwd->glActiveTexture (GL_TEXTURE0 + theTextureUnit);
}
+ mySampler->Unbind (theCtx, theTextureUnit);
glBindTexture (myTarget, NO_TEXTURE);
}
+//=======================================================================
+//function : InitSamplerObject
+//purpose :
+//=======================================================================
+bool OpenGl_Texture::InitSamplerObject (const Handle(OpenGl_Context)& theCtx)
+{
+ return myTextureId != NO_TEXTURE
+ && mySampler->Init (theCtx, *this);
+}
+
//=======================================================================
//function : GetDataFormat
//purpose :
}
#endif
- const GLenum aFilter = (myParams->Filter() == Graphic3d_TOTF_NEAREST) ? GL_NEAREST : GL_LINEAR;
- const GLenum aWrapMode = myParams->IsRepeat() ? GL_REPEAT : theCtx->TextureWrapClamp();
-
#if !defined(GL_ES_VERSION_2_0)
GLint aTestWidth = 0;
GLint aTestHeight = 0;
{
#if !defined(GL_ES_VERSION_2_0)
Bind (theCtx);
- glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, aFilter);
- glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, aFilter);
- glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, aWrapMode);
+ applyDefaultSamplerParams (theCtx);
if (toPatchExisting)
{
glTexSubImage1D (GL_TEXTURE_1D, 0, 0,
case Graphic3d_TOT_2D:
{
Bind (theCtx);
- glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, aFilter);
- glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, aFilter);
- glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, aWrapMode);
- glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, aWrapMode);
+ applyDefaultSamplerParams (theCtx);
if (toPatchExisting)
{
glTexSubImage2D (GL_TEXTURE_2D, 0,
}
case Graphic3d_TOT_2D_MIPMAP:
{
- GLenum aFilterMin = aFilter;
- aFilterMin = GL_NEAREST_MIPMAP_NEAREST;
- if (myParams->Filter() == Graphic3d_TOTF_BILINEAR)
- {
- aFilterMin = GL_LINEAR_MIPMAP_NEAREST;
- }
- else if (myParams->Filter() == Graphic3d_TOTF_TRILINEAR)
- {
- aFilterMin = GL_LINEAR_MIPMAP_LINEAR;
- }
-
Bind (theCtx);
- glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, aFilterMin);
- glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, aFilter);
- glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, aWrapMode);
- glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, aWrapMode);
+ applyDefaultSamplerParams (theCtx);
if (toPatchExisting)
{
glTexSubImage2D (GL_TEXTURE_2D, 0,
const GLsizei aSizeX = Min (theCtx->MaxTextureSize(), theSizeX);
const GLsizei aSizeY = Min (theCtx->MaxTextureSize(), theSizeY);
- const GLenum aFilter = (myParams->Filter() == Graphic3d_TOTF_NEAREST) ? GL_NEAREST : GL_LINEAR;
- const GLenum aWrapMode = myParams->IsRepeat() ? GL_REPEAT : theCtx->TextureWrapClamp();
Bind (theCtx);
- glTexParameteri (myTarget, GL_TEXTURE_MIN_FILTER, aFilter);
- glTexParameteri (myTarget, GL_TEXTURE_MAG_FILTER, aFilter);
- glTexParameteri (myTarget, GL_TEXTURE_WRAP_S, aWrapMode);
- glTexParameteri (myTarget, GL_TEXTURE_WRAP_T, aWrapMode);
+ applyDefaultSamplerParams (theCtx);
const GLint anIntFormat = theFormat.Internal();
myTextFormat = theFormat.Format();
}
#endif
- const GLenum aWrapMode = myParams->IsRepeat() ? GL_REPEAT : theCtx->TextureWrapClamp();
- const GLenum aFilter = (myParams->Filter() == Graphic3d_TOTF_NEAREST) ? GL_NEAREST : GL_LINEAR;
-
- glTexParameteri (myTarget, GL_TEXTURE_WRAP_S, aWrapMode);
- glTexParameteri (myTarget, GL_TEXTURE_WRAP_T, aWrapMode);
- glTexParameteri (myTarget, GL_TEXTURE_WRAP_R, aWrapMode);
-
- glTexParameteri (myTarget, GL_TEXTURE_MIN_FILTER, aFilter);
- glTexParameteri (myTarget, GL_TEXTURE_MAG_FILTER, aFilter);
-
+ applyDefaultSamplerParams (theCtx);
theCtx->Functions()->glTexImage3D (myTarget,
0,
anIntFormat,
#define _OpenGl_Texture_H__
#include <OpenGl_GlCore13.hxx>
-#include <OpenGl_Resource.hxx>
+#include <OpenGl_NamedResource.hxx>
+#include <OpenGl_Sampler.hxx>
#include <Graphic3d_TypeOfTexture.hxx>
+#include <Graphic3d_TextureUnit.hxx>
-class OpenGl_Context;
class Graphic3d_TextureParams;
class Image_PixMap;
};
-class OpenGl_Texture;
-DEFINE_STANDARD_HANDLE(OpenGl_Texture, OpenGl_Resource)
-
//! Texture resource.
-class OpenGl_Texture : public OpenGl_Resource
+class OpenGl_Texture : public OpenGl_NamedResource
{
-
+ DEFINE_STANDARD_RTTIEXT(OpenGl_Texture, OpenGl_NamedResource)
public:
//! Helpful constants
public:
- //! Create uninitialized VBO.
- Standard_EXPORT OpenGl_Texture (const Handle(Graphic3d_TextureParams)& theParams = NULL);
+ //! Create uninitialized texture.
+ Standard_EXPORT OpenGl_Texture (const TCollection_AsciiString& theResourceId = TCollection_AsciiString(),
+ const Handle(Graphic3d_TextureParams)& theParams = Handle(Graphic3d_TextureParams)());
//! Destroy object.
Standard_EXPORT virtual ~OpenGl_Texture();
//! Destroy object - will release GPU memory if any.
Standard_EXPORT virtual void Release (OpenGl_Context* theCtx) Standard_OVERRIDE;
+ //! Return texture sampler.
+ const Handle(OpenGl_Sampler)& Sampler() const { return mySampler; }
+
+ //! Set texture sampler.
+ void SetSampler (const Handle(OpenGl_Sampler)& theSampler) { mySampler = theSampler; }
+
+ //! Initialize the Sampler Object (as OpenGL object).
+ //! @param theCtx currently bound OpenGL context
+ Standard_EXPORT bool InitSamplerObject (const Handle(OpenGl_Context)& theCtx);
+
+ //! Bind this Texture to the unit specified in sampler parameters.
+ //! Also binds Sampler Object if it is allocated.
+ void Bind (const Handle(OpenGl_Context)& theCtx) const
+ {
+ Bind (theCtx, mySampler->Parameters()->TextureUnit());
+ }
+
+ //! Unbind texture from the unit specified in sampler parameters.
+ //! Also unbinds Sampler Object if it is allocated.
+ void Unbind (const Handle(OpenGl_Context)& theCtx) const
+ {
+ Unbind (theCtx, mySampler->Parameters()->TextureUnit());
+ }
+
//! Bind this Texture to specified unit.
+ //! Also binds Sampler Object if it is allocated.
Standard_EXPORT void Bind (const Handle(OpenGl_Context)& theCtx,
- const GLenum theTextureUnit = GL_TEXTURE0) const;
+ const Graphic3d_TextureUnit theTextureUnit) const;
//! Unbind texture from specified unit.
+ //! Also unbinds Sampler Object if it is allocated.
Standard_EXPORT void Unbind (const Handle(OpenGl_Context)& theCtx,
- const GLenum theTextureUnit = GL_TEXTURE0) const;
+ const Graphic3d_TextureUnit theTextureUnit) const;
//! Revision of associated data source.
Standard_Size Revision() const { return myRevision; }
const void* thePixels);
//! @return true if texture was generated within mipmaps
- Standard_EXPORT Standard_Boolean HasMipmaps() const;
-
- //! @return assigned texture parameters (not necessary applied)
- Standard_EXPORT const Handle(Graphic3d_TextureParams)& GetParams() const;
-
- //! @param texture parameters
- Standard_EXPORT void SetParams (const Handle(Graphic3d_TextureParams)& theParams);
+ Standard_Boolean HasMipmaps() const { return myHasMipmaps; }
//! Return texture type and format by Image_PixMap data format.
Standard_EXPORT static bool GetDataFormat (const Handle(OpenGl_Context)& theCtx,
protected:
+ //! Apply default sampler parameters after texture creation.
+ Standard_EXPORT void applyDefaultSamplerParams (const Handle(OpenGl_Context)& theCtx);
+
+protected:
+
+ Handle(OpenGl_Sampler) mySampler; //!< texture sampler
Standard_Size myRevision; //!< revision of associated data source
GLuint myTextureId; //!< GL resource ID
GLenum myTarget; //!< GL_TEXTURE_1D/GL_TEXTURE_2D/GL_TEXTURE_3D
Standard_Boolean myHasMipmaps; //!< flag indicates that texture was uploaded with mipmaps
bool myIsAlpha; //!< indicates alpha format
- Handle(Graphic3d_TextureParams) myParams; //!< texture parameters
-
-public:
-
- DEFINE_STANDARD_RTTIEXT(OpenGl_Texture,OpenGl_Resource) // Type definition
-
};
+DEFINE_STANDARD_HANDLE(OpenGl_Texture, OpenGl_NamedResource)
+
#endif // _OpenGl_Texture_H__
}
Bind (theGlCtx);
- BindTexture (theGlCtx);
+ BindTexture (theGlCtx, Graphic3d_TextureUnit_0);
theGlCtx->arbTBO->glTexBuffer (GetTarget(), myTexFormat, myBufferId);
- UnbindTexture (theGlCtx);
+ UnbindTexture(theGlCtx, Graphic3d_TextureUnit_0);
Unbind (theGlCtx);
return true;
}
}
Bind (theGlCtx);
- BindTexture (theGlCtx);
+ BindTexture (theGlCtx, Graphic3d_TextureUnit_0);
theGlCtx->arbTBO->glTexBuffer (GetTarget(), myTexFormat, myBufferId);
- UnbindTexture (theGlCtx);
+ UnbindTexture(theGlCtx, Graphic3d_TextureUnit_0);
Unbind (theGlCtx);
return true;
}
}
Bind (theGlCtx);
- BindTexture (theGlCtx);
+ BindTexture (theGlCtx, Graphic3d_TextureUnit_0);
theGlCtx->arbTBO->glTexBuffer (GetTarget(), myTexFormat, myBufferId);
- UnbindTexture (theGlCtx);
+ UnbindTexture(theGlCtx, Graphic3d_TextureUnit_0);
Unbind (theGlCtx);
return true;
}
}
Bind (theGlCtx);
- BindTexture (theGlCtx);
+ BindTexture (theGlCtx, Graphic3d_TextureUnit_0);
theGlCtx->arbTBO->glTexBuffer (GetTarget(), myTexFormat, myBufferId);
- UnbindTexture (theGlCtx);
+ UnbindTexture(theGlCtx, Graphic3d_TextureUnit_0);
Unbind (theGlCtx);
return true;
}
// purpose :
// =======================================================================
void OpenGl_TextureBufferArb::BindTexture (const Handle(OpenGl_Context)& theGlCtx,
- const GLenum theTextureUnit) const
+ const Graphic3d_TextureUnit theTextureUnit) const
{
- theGlCtx->core20fwd->glActiveTexture (theTextureUnit);
+ theGlCtx->core20fwd->glActiveTexture (GL_TEXTURE0 + theTextureUnit);
glBindTexture (GetTarget(), myTextureId);
}
// purpose :
// =======================================================================
void OpenGl_TextureBufferArb::UnbindTexture (const Handle(OpenGl_Context)& theGlCtx,
- const GLenum theTextureUnit) const
+ const Graphic3d_TextureUnit theTextureUnit) const
{
- theGlCtx->core20fwd->glActiveTexture (theTextureUnit);
+ theGlCtx->core20fwd->glActiveTexture (GL_TEXTURE0 + theTextureUnit);
glBindTexture (GetTarget(), NO_TEXTURE);
}
//! Bind TBO to specified Texture Unit.
Standard_EXPORT void BindTexture (const Handle(OpenGl_Context)& theGlCtx,
- const GLenum theTextureUnit = GL_TEXTURE0) const;
+ const Graphic3d_TextureUnit theTextureUnit) const;
//! Unbind TBO.
Standard_EXPORT void UnbindTexture (const Handle(OpenGl_Context)& theGlCtx,
- const GLenum theTextureUnit = GL_TEXTURE0) const;
+ const Graphic3d_TextureUnit theTextureUnit) const;
protected:
--- /dev/null
+// Created by: Kirill GAVRILOV
+// Copyright (c) 2013-2014 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <OpenGl_TextureSet.hxx>
+
+IMPLEMENT_STANDARD_RTTIEXT(OpenGl_TextureSet, Standard_Transient)
--- /dev/null
+// Copyright (c) 2017 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _OpenGl_TextureSet_Header
+#define _OpenGl_TextureSet_Header
+
+#include <Graphic3d_TextureSet.hxx>
+
+class OpenGl_Texture;
+
+//! Class holding array of textures to be mapped as a set.
+class OpenGl_TextureSet : public Standard_Transient
+{
+ DEFINE_STANDARD_RTTIEXT(OpenGl_TextureSet, Standard_Transient)
+public:
+
+ //! Class for iterating texture set.
+ class Iterator : public NCollection_Array1<Handle(OpenGl_Texture)>::Iterator
+ {
+ public:
+ //! Empty constructor.
+ Iterator() {}
+
+ //! Constructor.
+ Iterator (const Handle(OpenGl_TextureSet)& theSet)
+ {
+ if (!theSet.IsNull())
+ {
+ NCollection_Array1<Handle(OpenGl_Texture)>::Iterator::Init (theSet->myTextures);
+ }
+ }
+ };
+
+public:
+
+ //! Empty constructor.
+ OpenGl_TextureSet() {}
+
+ //! Constructor.
+ OpenGl_TextureSet (Standard_Integer theNbTextures)
+ : myTextures (0, theNbTextures - 1) {}
+
+ //! Constructor for a single texture.
+ OpenGl_TextureSet (const Handle(OpenGl_Texture)& theTexture)
+ : myTextures (0, 0)
+ {
+ myTextures.ChangeFirst() = theTexture;
+ }
+
+ //! Return TRUE if texture array is empty.
+ Standard_Boolean IsEmpty() const { return myTextures.IsEmpty(); }
+
+ //! Return number of textures.
+ Standard_Integer Size() const { return myTextures.Size(); }
+
+ //! Return the lower index in texture set.
+ Standard_Integer Lower() const { return myTextures.Lower(); }
+
+ //! Return the upper index in texture set.
+ Standard_Integer Upper() const { return myTextures.Upper(); }
+
+ //! Return the first texture.
+ const Handle(OpenGl_Texture)& First() const { return myTextures.First(); }
+
+ //! Return the first texture.
+ Handle(OpenGl_Texture)& ChangeFirst() { return myTextures.ChangeFirst(); }
+
+ //! Return the texture at specified position within [0, Size()) range.
+ const Handle(OpenGl_Texture)& Value (Standard_Integer theIndex) const { return myTextures.Value (theIndex); }
+
+ //! Return the texture at specified position within [0, Size()) range.
+ Handle(OpenGl_Texture)& ChangeValue (Standard_Integer theIndex) { return myTextures.ChangeValue (theIndex); }
+
+protected:
+
+ NCollection_Array1<Handle(OpenGl_Texture)> myTextures;
+
+};
+
+#endif //_OpenGl_TextureSet_Header
if (!myTextureEnv.IsNull())
{
- theCtx->DelayedRelease (myTextureEnv);
+ for (OpenGl_TextureSet::Iterator aTextureIter (myTextureEnv); aTextureIter.More(); aTextureIter.Next())
+ {
+ theCtx->DelayedRelease (aTextureIter.ChangeValue());
+ aTextureIter.ChangeValue().Nullify();
+ }
myTextureEnv.Nullify();
}
Handle(OpenGl_Context) aCtx = myWorkspace->GetGlContext();
if (!aCtx.IsNull() && !myTextureEnv.IsNull())
{
- aCtx->DelayedRelease (myTextureEnv);
+ for (OpenGl_TextureSet::Iterator aTextureIter (myTextureEnv); aTextureIter.More(); aTextureIter.Next())
+ {
+ aCtx->DelayedRelease (aTextureIter.ChangeValue());
+ aTextureIter.ChangeValue().Nullify();
+ }
}
myToUpdateEnvironmentMap = Standard_True;
return;
}
- myTextureEnv = new OpenGl_Texture (myTextureEnvData->GetParams());
+ myTextureEnv = new OpenGl_TextureSet (1);
+ Handle(OpenGl_Texture)& aTextureEnv = myTextureEnv->ChangeFirst();
+ aTextureEnv = new OpenGl_Texture (myTextureEnvData->GetId(), myTextureEnvData->GetParams());
Handle(Image_PixMap) anImage = myTextureEnvData->GetImage();
if (!anImage.IsNull())
{
- myTextureEnv->Init (theContext, *anImage.operator->(), myTextureEnvData->Type());
+ aTextureEnv->Init (theContext, *anImage.operator->(), myTextureEnvData->Type());
}
}
const Handle(OpenGl_Window) GlWindow() const { return myWindow; }
//! Returns OpenGL environment map.
- const Handle(OpenGl_Texture)& GlTextureEnv() const { return myTextureEnv; }
+ const Handle(OpenGl_TextureSet)& GlTextureEnv() const { return myTextureEnv; }
//! Returns selector for BVH tree, providing a possibility to store information
//! about current view volume and to detect which objects are overlapping it.
OpenGl_GraduatedTrihedron myGraduatedTrihedron;
- Handle(OpenGl_Texture) myTextureEnv;
+ Handle(OpenGl_TextureSet) myTextureEnv;
//! Framebuffers for OpenGL output.
Handle(OpenGl_FrameBuffer) myOpenGlFBO;
OpenGl_RT_NbVariables // special field
};
- //! Defines OpenGL texture samplers.
- enum ShaderSamplerNames
- {
- OpenGl_RT_EnvironmentMapTexture = 0,
-
- OpenGl_RT_SceneNodeInfoTexture = 1,
- OpenGl_RT_SceneMinPointTexture = 2,
- OpenGl_RT_SceneMaxPointTexture = 3,
- OpenGl_RT_SceneTransformTexture = 4,
-
- OpenGl_RT_GeometryVertexTexture = 5,
- OpenGl_RT_GeometryNormalTexture = 6,
- OpenGl_RT_GeometryTexCrdTexture = 7,
- OpenGl_RT_GeometryTriangTexture = 8,
-
- OpenGl_RT_RaytraceMaterialTexture = 9,
- OpenGl_RT_RaytraceLightSrcTexture = 10,
-
- OpenGl_RT_FsaaInputTexture = 11,
- OpenGl_RT_PrevAccumTexture = 12,
-
- OpenGl_RT_RaytraceDepthTexture = 13
- };
-
//! Defines OpenGL image samplers.
enum ShaderImageNames
{
};
}
+namespace
+{
+ //! Defines OpenGL texture samplers.
+ static const Graphic3d_TextureUnit OpenGl_RT_EnvironmentMapTexture = Graphic3d_TextureUnit_0;
+
+ static const Graphic3d_TextureUnit OpenGl_RT_SceneNodeInfoTexture = Graphic3d_TextureUnit_1;
+ static const Graphic3d_TextureUnit OpenGl_RT_SceneMinPointTexture = Graphic3d_TextureUnit_2;
+ static const Graphic3d_TextureUnit OpenGl_RT_SceneMaxPointTexture = Graphic3d_TextureUnit_3;
+ static const Graphic3d_TextureUnit OpenGl_RT_SceneTransformTexture = Graphic3d_TextureUnit_4;
+
+ static const Graphic3d_TextureUnit OpenGl_RT_GeometryVertexTexture = Graphic3d_TextureUnit_5;
+ static const Graphic3d_TextureUnit OpenGl_RT_GeometryNormalTexture = Graphic3d_TextureUnit_6;
+ static const Graphic3d_TextureUnit OpenGl_RT_GeometryTexCrdTexture = Graphic3d_TextureUnit_7;
+ static const Graphic3d_TextureUnit OpenGl_RT_GeometryTriangTexture = Graphic3d_TextureUnit_8;
+
+ static const Graphic3d_TextureUnit OpenGl_RT_RaytraceMaterialTexture = Graphic3d_TextureUnit_9;
+ static const Graphic3d_TextureUnit OpenGl_RT_RaytraceLightSrcTexture = Graphic3d_TextureUnit_10;
+
+ static const Graphic3d_TextureUnit OpenGl_RT_FsaaInputTexture = Graphic3d_TextureUnit_11;
+ static const Graphic3d_TextureUnit OpenGl_RT_PrevAccumTexture = Graphic3d_TextureUnit_12;
+
+ static const Graphic3d_TextureUnit OpenGl_RT_RaytraceDepthTexture = Graphic3d_TextureUnit_13;
+}
+
// =======================================================================
// function : updateRaytraceGeometry
// purpose : Updates 3D scene geometry for ray-tracing
void buildTextureTransform (const Handle(Graphic3d_TextureParams)& theParams, BVH_Mat4f& theMatrix)
{
theMatrix.InitIdentity();
+ if (theParams.IsNull())
+ {
+ return;
+ }
// Apply scaling
const Graphic3d_Vec2& aScale = theParams->Scale();
theMaterial.BSDF.FresnelBase = aBSDF.FresnelBase.Serialize ();
// Handle material textures
- if (theAspect->Aspect()->ToMapTexture())
+ if (!theAspect->Aspect()->ToMapTexture())
{
- if (theGlContext->HasRayTracingTextures())
- {
- buildTextureTransform (theAspect->TextureParams(), theMaterial.TextureTransform);
+ return theMaterial;
+ }
- // write texture ID to diffuse w-component
- theMaterial.Diffuse.w() = theMaterial.BSDF.Kd.w() =
- static_cast<Standard_ShortReal> (myRaytraceGeometry.AddTexture (theAspect->TextureRes (theGlContext)));
- }
- else if (!myIsRaytraceWarnTextures)
- {
- const TCollection_ExtendedString aWarnMessage =
- "Warning: texturing in Ray-Trace requires GL_ARB_bindless_texture extension which is missing. "
- "Please try to update graphics card driver. At the moment textures will be ignored.";
+ const Handle(OpenGl_TextureSet)& aTextureSet = theAspect->TextureSet (theGlContext);
+ if (aTextureSet.IsNull()
+ || aTextureSet->IsEmpty()
+ || aTextureSet->First().IsNull())
+ {
+ return theMaterial;
+ }
- theGlContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION,
- GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_HIGH, aWarnMessage);
+ if (theGlContext->HasRayTracingTextures())
+ {
+ const Handle(OpenGl_Texture)& aTexture = aTextureSet->First();
+ buildTextureTransform (aTexture->Sampler()->Parameters(), theMaterial.TextureTransform);
- myIsRaytraceWarnTextures = Standard_True;
- }
+ // write texture ID to diffuse w-component
+ theMaterial.Diffuse.w() = theMaterial.BSDF.Kd.w() = static_cast<Standard_ShortReal> (myRaytraceGeometry.AddTexture (aTexture));
+ }
+ else if (!myIsRaytraceWarnTextures)
+ {
+ const TCollection_ExtendedString aWarnMessage =
+ "Warning: texturing in Ray-Trace requires GL_ARB_bindless_texture extension which is missing. "
+ "Please try to update graphics card driver. At the moment textures will be ignored.";
+
+ theGlContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION,
+ GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_HIGH, aWarnMessage);
+
+ myIsRaytraceWarnTextures = Standard_True;
}
return theMaterial;
}
// Set environment map parameters
- const Standard_Boolean toDisableEnvironmentMap = myTextureEnv.IsNull() || !myTextureEnv->IsValid();
-
+ const Standard_Boolean toDisableEnvironmentMap = myTextureEnv.IsNull()
+ || myTextureEnv->IsEmpty()
+ || !myTextureEnv->First()->IsValid();
+
theProgram->SetUniform (theGlContext,
myUniformLocations[theProgramId][OpenGl_RT_uSphereMapEnabled], toDisableEnvironmentMap ? 0 : 1);
#endif
}
- if (!myTextureEnv.IsNull() && myTextureEnv->IsValid())
+ if (!myTextureEnv.IsNull()
+ && !myTextureEnv->IsEmpty()
+ && myTextureEnv->First()->IsValid())
{
- myTextureEnv->Bind (theGlContext, GL_TEXTURE0 + OpenGl_RT_EnvironmentMapTexture);
+ myTextureEnv->First()->Bind (theGlContext, OpenGl_RT_EnvironmentMapTexture);
}
- mySceneMinPointTexture->BindTexture (theGlContext, GL_TEXTURE0 + OpenGl_RT_SceneMinPointTexture);
- mySceneMaxPointTexture->BindTexture (theGlContext, GL_TEXTURE0 + OpenGl_RT_SceneMaxPointTexture);
- mySceneNodeInfoTexture->BindTexture (theGlContext, GL_TEXTURE0 + OpenGl_RT_SceneNodeInfoTexture);
- myGeometryVertexTexture->BindTexture (theGlContext, GL_TEXTURE0 + OpenGl_RT_GeometryVertexTexture);
- myGeometryNormalTexture->BindTexture (theGlContext, GL_TEXTURE0 + OpenGl_RT_GeometryNormalTexture);
- myGeometryTexCrdTexture->BindTexture (theGlContext, GL_TEXTURE0 + OpenGl_RT_GeometryTexCrdTexture);
- myGeometryTriangTexture->BindTexture (theGlContext, GL_TEXTURE0 + OpenGl_RT_GeometryTriangTexture);
- mySceneTransformTexture->BindTexture (theGlContext, GL_TEXTURE0 + OpenGl_RT_SceneTransformTexture);
- myRaytraceMaterialTexture->BindTexture (theGlContext, GL_TEXTURE0 + OpenGl_RT_RaytraceMaterialTexture);
- myRaytraceLightSrcTexture->BindTexture (theGlContext, GL_TEXTURE0 + OpenGl_RT_RaytraceLightSrcTexture);
+ mySceneMinPointTexture ->BindTexture (theGlContext, OpenGl_RT_SceneMinPointTexture);
+ mySceneMaxPointTexture ->BindTexture (theGlContext, OpenGl_RT_SceneMaxPointTexture);
+ mySceneNodeInfoTexture ->BindTexture (theGlContext, OpenGl_RT_SceneNodeInfoTexture);
+ myGeometryVertexTexture ->BindTexture (theGlContext, OpenGl_RT_GeometryVertexTexture);
+ myGeometryNormalTexture ->BindTexture (theGlContext, OpenGl_RT_GeometryNormalTexture);
+ myGeometryTexCrdTexture ->BindTexture (theGlContext, OpenGl_RT_GeometryTexCrdTexture);
+ myGeometryTriangTexture ->BindTexture (theGlContext, OpenGl_RT_GeometryTriangTexture);
+ mySceneTransformTexture ->BindTexture (theGlContext, OpenGl_RT_SceneTransformTexture);
+ myRaytraceMaterialTexture->BindTexture (theGlContext, OpenGl_RT_RaytraceMaterialTexture);
+ myRaytraceLightSrcTexture->BindTexture (theGlContext, OpenGl_RT_RaytraceLightSrcTexture);
}
// =======================================================================
// =======================================================================
void OpenGl_View::unbindRaytraceTextures (const Handle(OpenGl_Context)& theGlContext)
{
- mySceneMinPointTexture->UnbindTexture (theGlContext, GL_TEXTURE0 + OpenGl_RT_SceneMinPointTexture);
- mySceneMaxPointTexture->UnbindTexture (theGlContext, GL_TEXTURE0 + OpenGl_RT_SceneMaxPointTexture);
- mySceneNodeInfoTexture->UnbindTexture (theGlContext, GL_TEXTURE0 + OpenGl_RT_SceneNodeInfoTexture);
- myGeometryVertexTexture->UnbindTexture (theGlContext, GL_TEXTURE0 + OpenGl_RT_GeometryVertexTexture);
- myGeometryNormalTexture->UnbindTexture (theGlContext, GL_TEXTURE0 + OpenGl_RT_GeometryNormalTexture);
- myGeometryTexCrdTexture->UnbindTexture (theGlContext, GL_TEXTURE0 + OpenGl_RT_GeometryTexCrdTexture);
- myGeometryTriangTexture->UnbindTexture (theGlContext, GL_TEXTURE0 + OpenGl_RT_GeometryTriangTexture);
- mySceneTransformTexture->UnbindTexture (theGlContext, GL_TEXTURE0 + OpenGl_RT_SceneTransformTexture);
- myRaytraceMaterialTexture->UnbindTexture (theGlContext, GL_TEXTURE0 + OpenGl_RT_RaytraceMaterialTexture);
- myRaytraceLightSrcTexture->UnbindTexture (theGlContext, GL_TEXTURE0 + OpenGl_RT_RaytraceLightSrcTexture);
+ mySceneMinPointTexture ->UnbindTexture (theGlContext, OpenGl_RT_SceneMinPointTexture);
+ mySceneMaxPointTexture ->UnbindTexture (theGlContext, OpenGl_RT_SceneMaxPointTexture);
+ mySceneNodeInfoTexture ->UnbindTexture (theGlContext, OpenGl_RT_SceneNodeInfoTexture);
+ myGeometryVertexTexture ->UnbindTexture (theGlContext, OpenGl_RT_GeometryVertexTexture);
+ myGeometryNormalTexture ->UnbindTexture (theGlContext, OpenGl_RT_GeometryNormalTexture);
+ myGeometryTexCrdTexture ->UnbindTexture (theGlContext, OpenGl_RT_GeometryTexCrdTexture);
+ myGeometryTriangTexture ->UnbindTexture (theGlContext, OpenGl_RT_GeometryTriangTexture);
+ mySceneTransformTexture ->UnbindTexture (theGlContext, OpenGl_RT_SceneTransformTexture);
+ myRaytraceMaterialTexture->UnbindTexture (theGlContext, OpenGl_RT_RaytraceMaterialTexture);
+ myRaytraceLightSrcTexture->UnbindTexture (theGlContext, OpenGl_RT_RaytraceLightSrcTexture);
theGlContext->core15fwd->glActiveTexture (GL_TEXTURE0);
}
glDisable (GL_DEPTH_TEST); // improve jagged edges without depth buffer
// bind ray-tracing output image as input
- myRaytraceFBO1[aFBOIdx]->ColorTexture()->Bind (theGlContext, GL_TEXTURE0 + OpenGl_RT_FsaaInputTexture);
+ myRaytraceFBO1[aFBOIdx]->ColorTexture()->Bind (theGlContext, OpenGl_RT_FsaaInputTexture);
aResult &= theGlContext->BindProgram (myPostFSAAProgram);
// perform adaptive FSAA pass
theGlContext->core20fwd->glDrawArrays (GL_TRIANGLES, 0, 6);
- aFramebuffer->ColorTexture()->Bind (theGlContext, GL_TEXTURE0 + OpenGl_RT_FsaaInputTexture);
+ aFramebuffer->ColorTexture()->Bind (theGlContext, OpenGl_RT_FsaaInputTexture);
}
aRenderImageFramebuffer = myRaytraceFBO2[aFBOIdx];
aRenderImageFramebuffer->UnbindBuffer (theGlContext);
}
- aRenderImageFramebuffer->ColorTexture()->Bind (
- theGlContext, GL_TEXTURE0 + OpenGl_RT_PrevAccumTexture);
-
- aDepthSourceFramebuffer->DepthStencilTexture()->Bind (
- theGlContext, GL_TEXTURE0 + OpenGl_RT_RaytraceDepthTexture);
+ aRenderImageFramebuffer->ColorTexture() ->Bind (theGlContext, OpenGl_RT_PrevAccumTexture);
+ aDepthSourceFramebuffer->DepthStencilTexture()->Bind (theGlContext, OpenGl_RT_RaytraceDepthTexture);
// copy the output image with depth values
theGlContext->core20fwd->glDrawArrays (GL_TRIANGLES, 0, 6);
- aDepthSourceFramebuffer->DepthStencilTexture()->Unbind (
- theGlContext, GL_TEXTURE0 + OpenGl_RT_RaytraceDepthTexture);
-
- aRenderImageFramebuffer->ColorTexture()->Unbind (
- theGlContext, GL_TEXTURE0 + OpenGl_RT_PrevAccumTexture);
+ aDepthSourceFramebuffer->DepthStencilTexture()->Unbind (theGlContext, OpenGl_RT_RaytraceDepthTexture);
+ aRenderImageFramebuffer->ColorTexture() ->Unbind (theGlContext, OpenGl_RT_PrevAccumTexture);
}
unbindRaytraceTextures (theGlContext);
aDepthSourceFramebuffer = aRenderImageFramebuffer;
- anAccumImageFramebuffer->ColorTexture()->Bind (
- theGlContext, GL_TEXTURE0 + OpenGl_RT_PrevAccumTexture);
+ anAccumImageFramebuffer->ColorTexture()->Bind (theGlContext, OpenGl_RT_PrevAccumTexture);
aRenderImageFramebuffer->BindBuffer (theGlContext);
aRenderImageFramebuffer->UnbindBuffer (theGlContext);
}
- aRenderImageFramebuffer->ColorTexture()->Bind (
- theGlContext, GL_TEXTURE0 + OpenGl_RT_PrevAccumTexture);
+ aRenderImageFramebuffer->ColorTexture()->Bind (theGlContext, OpenGl_RT_PrevAccumTexture);
glEnable (GL_DEPTH_TEST);
// Copy accumulated image with correct depth values
theGlContext->core20fwd->glDrawArrays (GL_TRIANGLES, 0, 6);
- aRenderImageFramebuffer->ColorTexture()->Unbind (
- theGlContext, GL_TEXTURE0 + OpenGl_RT_PrevAccumTexture);
+ aRenderImageFramebuffer->ColorTexture()->Unbind (theGlContext, OpenGl_RT_PrevAccumTexture);
if (myRaytraceParameters.AdaptiveScreenSampling)
{
renderScene (theProjection, theOutputFBO, theOitAccumFbo, theToDrawImmediate);
- myWorkspace->SetEnvironmentTexture (Handle(OpenGl_Texture)());
+ myWorkspace->SetEnvironmentTexture (Handle(OpenGl_TextureSet)());
// ===============================
// Step 4: Trihedron
}
renderStructs (theProjection, theReadDrawFbo, theOitAccumFbo, theToDrawImmediate);
- myWorkspace->DisableTexture();
+ aContext->BindTextures (Handle(OpenGl_TextureSet)());
// Apply restored view matrix.
aContext->ApplyWorldViewMatrix();
}
#endif
- myWorkspace->DisableTexture();
+ aCtx->BindTextures (Handle(OpenGl_TextureSet)());
const Graphic3d_TypeOfTextureFilter aFilter = (aDrawSizeX == aReadSizeX && aDrawSizeY == aReadSizeY) ? Graphic3d_TOTF_NEAREST : Graphic3d_TOTF_BILINEAR;
const GLint aFilterGl = aFilter == Graphic3d_TOTF_NEAREST ? GL_NEAREST : GL_LINEAR;
if (aVerts->IsValid()
&& aManager->BindFboBlitProgram())
{
- theReadFbo->ColorTexture()->Bind (aCtx, GL_TEXTURE0 + 0);
- if (theReadFbo->ColorTexture()->GetParams()->Filter() != aFilter)
+ theReadFbo->ColorTexture()->Bind (aCtx, Graphic3d_TextureUnit_0);
+ if (theReadFbo->ColorTexture()->Sampler()->Parameters()->Filter() != aFilter)
{
- theReadFbo->ColorTexture()->GetParams()->SetFilter (aFilter);
+ theReadFbo->ColorTexture()->Sampler()->Parameters()->SetFilter (aFilter);
aCtx->core20fwd->glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, aFilterGl);
aCtx->core20fwd->glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, aFilterGl);
}
- theReadFbo->DepthStencilTexture()->Bind (aCtx, GL_TEXTURE0 + 1);
- if (theReadFbo->DepthStencilTexture()->GetParams()->Filter() != aFilter)
+ theReadFbo->DepthStencilTexture()->Bind (aCtx, Graphic3d_TextureUnit_1);
+ if (theReadFbo->DepthStencilTexture()->Sampler()->Parameters()->Filter() != aFilter)
{
- theReadFbo->DepthStencilTexture()->GetParams()->SetFilter (aFilter);
+ theReadFbo->DepthStencilTexture()->Sampler()->Parameters()->SetFilter (aFilter);
aCtx->core20fwd->glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, aFilterGl);
aCtx->core20fwd->glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, aFilterGl);
}
aCtx->core20fwd->glDrawArrays (GL_TRIANGLE_STRIP, 0, 4);
aVerts->UnbindVertexAttrib (aCtx, Graphic3d_TOA_POS);
- theReadFbo->DepthStencilTexture()->Unbind (aCtx, GL_TEXTURE0 + 1);
- theReadFbo->ColorTexture() ->Unbind (aCtx, GL_TEXTURE0 + 0);
+ theReadFbo->DepthStencilTexture()->Unbind (aCtx, Graphic3d_TextureUnit_1);
+ theReadFbo->ColorTexture() ->Unbind (aCtx, Graphic3d_TextureUnit_0);
aCtx->BindProgram (NULL);
}
else
aCtx->core20fwd->glDepthMask (GL_TRUE);
aCtx->core20fwd->glEnable (GL_DEPTH_TEST);
- myWorkspace->DisableTexture();
+ aCtx->BindTextures (Handle(OpenGl_TextureSet)());
OpenGl_VertexBuffer* aVerts = initBlitQuad (myToFlipOutput);
const Handle(OpenGl_ShaderManager)& aManager = aCtx->ShaderManager();
aCtx->ActiveProgram()->SetUniform (aCtx, "uMultR", aFilterR);
}
- aPair[0]->ColorTexture()->Bind (aCtx, GL_TEXTURE0 + 0);
- aPair[1]->ColorTexture()->Bind (aCtx, GL_TEXTURE0 + 1);
+ aPair[0]->ColorTexture()->Bind (aCtx, Graphic3d_TextureUnit_0);
+ aPair[1]->ColorTexture()->Bind (aCtx, Graphic3d_TextureUnit_1);
aVerts->BindVertexAttrib (aCtx, 0);
aCtx->core20fwd->glDrawArrays (GL_TRIANGLE_STRIP, 0, 4);
aVerts->UnbindVertexAttrib (aCtx, 0);
- aPair[1]->ColorTexture()->Unbind (aCtx, GL_TEXTURE0 + 1);
- aPair[0]->ColorTexture()->Unbind (aCtx, GL_TEXTURE0 + 0);
+ aPair[1]->ColorTexture()->Unbind (aCtx, Graphic3d_TextureUnit_1);
+ aPair[0]->ColorTexture()->Unbind (aCtx, Graphic3d_TextureUnit_0);
}
else
{
myGlContext->SetLineWidth (myDefaultAspectLine.Aspect()->Width());
}
-// =======================================================================
-// function : DisableTexture
-// purpose :
-// =======================================================================
-Handle(OpenGl_Texture) OpenGl_Workspace::DisableTexture()
-{
- if (myTextureBound.IsNull())
- {
- return myTextureBound;
- }
-
- const Handle(OpenGl_Sampler)& aSampler = myGlContext->TextureSampler();
- if (!aSampler.IsNull())
- {
- aSampler->Unbind (*myGlContext);
- }
-
-#if !defined(GL_ES_VERSION_2_0)
- // reset texture matrix because some code may expect it is identity
- if (myGlContext->core11 != NULL)
- {
- GLint aMatrixMode = GL_TEXTURE;
- glGetIntegerv (GL_MATRIX_MODE, &aMatrixMode);
- glMatrixMode (GL_TEXTURE);
- glLoadIdentity();
- glMatrixMode (aMatrixMode);
- }
-#endif
-
- myTextureBound->Unbind (myGlContext);
- switch (myTextureBound->GetTarget())
- {
- #if !defined(GL_ES_VERSION_2_0)
- case GL_TEXTURE_1D:
- {
- if (myGlContext->core11 != NULL)
- {
- if (myTextureBound->GetParams()->GenMode() != GL_NONE)
- {
- glDisable (GL_TEXTURE_GEN_S);
- }
- glDisable (GL_TEXTURE_1D);
- }
- break;
- }
- #endif
- case GL_TEXTURE_2D:
- {
- #if !defined(GL_ES_VERSION_2_0)
- if (myGlContext->core11 != NULL)
- {
- if (myTextureBound->GetParams()->GenMode() != GL_NONE)
- {
- glDisable (GL_TEXTURE_GEN_S);
- glDisable (GL_TEXTURE_GEN_T);
- if (myTextureBound->GetParams()->GenMode() == Graphic3d_TOTM_SPRITE)
- {
- glDisable (GL_POINT_SPRITE);
- }
- }
- glDisable (GL_TEXTURE_2D);
- }
- #endif
- break;
- }
- default: break;
- }
-
- Handle(OpenGl_Texture) aPrevTexture = myTextureBound;
- myTextureBound.Nullify();
- return aPrevTexture;
-}
-
-// =======================================================================
-// function : setTextureParams
-// purpose :
-// =======================================================================
-void OpenGl_Workspace::setTextureParams (Handle(OpenGl_Texture)& theTexture,
- const Handle(Graphic3d_TextureParams)& theParams)
-{
- const Handle(Graphic3d_TextureParams)& aParams = theParams.IsNull() ? theTexture->GetParams() : theParams;
- if (aParams.IsNull())
- {
- return;
- }
-
-#if !defined(GL_ES_VERSION_2_0)
- if (myGlContext->core11 != NULL)
- {
- GLint anEnvMode = GL_MODULATE; // lighting mode
- if (!aParams->IsModulate())
- {
- anEnvMode = GL_DECAL;
- if (theTexture->GetFormat() == GL_ALPHA
- || theTexture->GetFormat() == GL_LUMINANCE)
- {
- anEnvMode = GL_REPLACE;
- }
- }
-
- // setup generation of texture coordinates
- switch (aParams->GenMode())
- {
- case Graphic3d_TOTM_OBJECT:
- {
- glTexGeni (GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
- glTexGenfv (GL_S, GL_OBJECT_PLANE, aParams->GenPlaneS().GetData());
- if (theTexture->GetTarget() != GL_TEXTURE_1D)
- {
- glTexGeni (GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
- glTexGenfv (GL_T, GL_OBJECT_PLANE, aParams->GenPlaneT().GetData());
- }
- break;
- }
- case Graphic3d_TOTM_SPHERE:
- {
- glTexGeni (GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
- if (theTexture->GetTarget() != GL_TEXTURE_1D)
- {
- glTexGeni (GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
- }
- break;
- }
- case Graphic3d_TOTM_EYE:
- {
- myGlContext->WorldViewState.Push();
-
- myGlContext->WorldViewState.SetIdentity();
- myGlContext->ApplyWorldViewMatrix();
-
- glTexGeni (GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
- glTexGenfv (GL_S, GL_EYE_PLANE, aParams->GenPlaneS().GetData());
-
- if (theTexture->GetTarget() != GL_TEXTURE_1D)
- {
- glTexGeni (GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
- glTexGenfv (GL_T, GL_EYE_PLANE, aParams->GenPlaneT().GetData());
- }
-
- myGlContext->WorldViewState.Pop();
-
- break;
- }
- case Graphic3d_TOTM_SPRITE:
- {
- if (myGlContext->core20fwd != NULL)
- {
- glEnable (GL_POINT_SPRITE);
- glTexEnvi (GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE);
- anEnvMode = GL_REPLACE;
- }
- break;
- }
- case Graphic3d_TOTM_MANUAL:
- default: break;
- }
-
- // setup lighting
- glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, anEnvMode);
- }
-#endif
-
- // get active sampler object to override default texture parameters
- const Handle(OpenGl_Sampler)& aSampler = myGlContext->TextureSampler();
-
- // setup texture filtering and wrapping
- //if (theTexture->GetParams() != theParams)
- const GLenum aFilter = (aParams->Filter() == Graphic3d_TOTF_NEAREST) ? GL_NEAREST : GL_LINEAR;
- const GLenum aWrapMode = aParams->IsRepeat() ? GL_REPEAT : myGlContext->TextureWrapClamp();
- switch (theTexture->GetTarget())
- {
- #if !defined(GL_ES_VERSION_2_0)
- case GL_TEXTURE_1D:
- {
- if (aSampler.IsNull() || !aSampler->IsValid())
- {
- glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, aFilter);
- glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, aFilter);
- glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, aWrapMode);
- }
- else
- {
- aSampler->SetParameter (*myGlContext, GL_TEXTURE_MAG_FILTER, aFilter);
- aSampler->SetParameter (*myGlContext, GL_TEXTURE_MIN_FILTER, aFilter);
- aSampler->SetParameter (*myGlContext, GL_TEXTURE_WRAP_S, aWrapMode);
- }
-
- break;
- }
- #endif
- case GL_TEXTURE_2D:
- {
- GLenum aFilterMin = aFilter;
- if (theTexture->HasMipmaps())
- {
- aFilterMin = GL_NEAREST_MIPMAP_NEAREST;
- if (aParams->Filter() == Graphic3d_TOTF_BILINEAR)
- {
- aFilterMin = GL_LINEAR_MIPMAP_NEAREST;
- }
- else if (aParams->Filter() == Graphic3d_TOTF_TRILINEAR)
- {
- aFilterMin = GL_LINEAR_MIPMAP_LINEAR;
- }
-
- if (myGlContext->extAnis)
- {
- // setup degree of anisotropy filter
- const GLint aMaxDegree = myGlContext->MaxDegreeOfAnisotropy();
- GLint aDegree;
- switch (aParams->AnisoFilter())
- {
- case Graphic3d_LOTA_QUALITY:
- {
- aDegree = aMaxDegree;
- break;
- }
- case Graphic3d_LOTA_MIDDLE:
- {
- aDegree = (aMaxDegree <= 4) ? 2 : (aMaxDegree / 2);
- break;
- }
- case Graphic3d_LOTA_FAST:
- {
- aDegree = 2;
- break;
- }
- case Graphic3d_LOTA_OFF:
- default:
- {
- aDegree = 1;
- break;
- }
- }
-
- if (aSampler.IsNull() || !aSampler->IsValid())
- {
- glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, aDegree);
- }
- else
- {
- aSampler->SetParameter (*myGlContext, GL_TEXTURE_MAX_ANISOTROPY_EXT, aDegree);
- }
- }
- }
-
- if (aSampler.IsNull() || !aSampler->IsValid())
- {
- glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, aFilterMin);
- glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, aFilter);
- glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, aWrapMode);
- glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, aWrapMode);
- }
- else
- {
- aSampler->SetParameter (*myGlContext, GL_TEXTURE_MIN_FILTER, aFilterMin);
- aSampler->SetParameter (*myGlContext, GL_TEXTURE_MAG_FILTER, aFilter);
- aSampler->SetParameter (*myGlContext, GL_TEXTURE_WRAP_S, aWrapMode);
- aSampler->SetParameter (*myGlContext, GL_TEXTURE_WRAP_T, aWrapMode);
- }
-
- break;
- }
- default: break;
- }
-
- switch (theTexture->GetTarget())
- {
- #if !defined(GL_ES_VERSION_2_0)
- case GL_TEXTURE_1D:
- {
- if (myGlContext->core11 != NULL)
- {
- if (aParams->GenMode() != Graphic3d_TOTM_MANUAL)
- {
- glEnable (GL_TEXTURE_GEN_S);
- }
- glEnable (GL_TEXTURE_1D);
- }
- break;
- }
- #endif
- case GL_TEXTURE_2D:
- {
- #if !defined(GL_ES_VERSION_2_0)
- if (myGlContext->core11 != NULL)
- {
- if (aParams->GenMode() != Graphic3d_TOTM_MANUAL)
- {
- glEnable (GL_TEXTURE_GEN_S);
- glEnable (GL_TEXTURE_GEN_T);
- }
- glEnable (GL_TEXTURE_2D);
- }
- #endif
- break;
- }
- default: break;
- }
-
- theTexture->SetParams (aParams);
-}
-
-// =======================================================================
-// function : EnableTexture
-// purpose :
-// =======================================================================
-Handle(OpenGl_Texture) OpenGl_Workspace::EnableTexture (const Handle(OpenGl_Texture)& theTexture,
- const Handle(Graphic3d_TextureParams)& theParams)
-{
- if (theTexture.IsNull() || !theTexture->IsValid())
- {
- return DisableTexture();
- }
-
- if (myTextureBound == theTexture
- && (theParams.IsNull() || theParams == theTexture->GetParams()))
- {
- // already bound
- return myTextureBound;
- }
-
- Handle(OpenGl_Texture) aPrevTexture = DisableTexture();
- myTextureBound = theTexture;
- myTextureBound->Bind (myGlContext);
- setTextureParams (myTextureBound, theParams);
-
- // If custom sampler object is available it will be
- // used for overriding default texture parameters
- const Handle(OpenGl_Sampler)& aSampler = myGlContext->TextureSampler();
-
- if (!aSampler.IsNull() && aSampler->IsValid())
- {
- aSampler->Bind (*myGlContext);
- }
-
- return aPrevTexture;
-}
-
// =======================================================================
// function : SetAspectLine
// purpose :
if (myAspectFaceSet->Aspect()->ToMapTexture())
{
- EnableTexture (myAspectFaceSet->TextureRes (myGlContext),
- myAspectFaceSet->TextureParams());
+ myGlContext->BindTextures (myAspectFaceSet->TextureSet (myGlContext));
}
else
{
- if (!myEnvironmentTexture.IsNull())
- {
- EnableTexture (myEnvironmentTexture,
- myEnvironmentTexture->GetParams());
- }
- else
- {
- DisableTexture();
- }
+ myGlContext->BindTextures (myEnvironmentTexture);
}
myAspectFaceApplied = myAspectFaceSet->Aspect();
if (!Activate())
return Handle(OpenGl_FrameBuffer)();
- DisableTexture();
-
// create the FBO
const Handle(OpenGl_Context)& aCtx = GetGlContext();
+ aCtx->BindTextures (Handle(OpenGl_TextureSet)());
Handle(OpenGl_FrameBuffer) aFrameBuffer = new OpenGl_FrameBuffer();
if (!aFrameBuffer->Init (aCtx, theWidth, theHeight, GL_RGBA8, GL_DEPTH24_STENCIL8, 0))
{
//! Clear the applied aspect state to default values.
void ResetAppliedAspect();
- Standard_EXPORT Handle(OpenGl_Texture) DisableTexture();
- Standard_EXPORT Handle(OpenGl_Texture) EnableTexture (const Handle(OpenGl_Texture)& theTexture,
- const Handle(Graphic3d_TextureParams)& theParams = NULL);
- const Handle(OpenGl_Texture)& ActiveTexture() const { return myTextureBound; }
-
//! Set filter for restricting rendering of particular elements.
//! Filter can be applied for rendering passes used by recursive
//! rendering algorithms for rendering elements of groups.
}
//! Sets a new environment texture.
- void SetEnvironmentTexture (const Handle(OpenGl_Texture)& theTexture)
- {
- myEnvironmentTexture = theTexture;
- }
+ void SetEnvironmentTexture (const Handle(OpenGl_TextureSet)& theTexture) { myEnvironmentTexture = theTexture; }
//! Returns environment texture.
- const Handle(OpenGl_Texture)& EnvironmentTexture() const
- {
- return myEnvironmentTexture;
- }
-
-protected:
-
- void setTextureParams (Handle(OpenGl_Texture)& theTexture,
- const Handle(Graphic3d_TextureParams)& theParams);
+ const Handle(OpenGl_TextureSet)& EnvironmentTexture() const { return myEnvironmentTexture; }
protected: //! @name protected fields
protected: //! @name fields related to status
Handle(OpenGl_RenderFilter) myRenderFilter;
- Handle(OpenGl_Texture) myTextureBound; //!< currently bound texture (managed by OpenGl_AspectFace and OpenGl_View environment texture)
const OpenGl_AspectLine* myAspectLineSet;
const OpenGl_AspectFace* myAspectFaceSet;
Handle(Graphic3d_AspectFillArea3d) myAspectFaceApplied;
OpenGl_AspectFace myAspectFaceHl; //!< Hiddenline aspect
- Handle(OpenGl_Texture) myEnvironmentTexture;
+ Handle(OpenGl_TextureSet) myEnvironmentTexture;
public: //! @name type definition
float occBackMaterial_Shininess(void); //!< Specular exponent
float occBackMaterial_Transparency(void); //!< Transparency coefficient
+#define occActiveSampler occSampler0 //!< alias for backward compatibility
+#define occSamplerBaseColor occSampler0 //!< alias to a base color texture
+uniform sampler2D occSampler0; //!< current active sampler;
+ //! occSampler1, occSampler2,... should be defined in GLSL program body for multitexturing
uniform vec4 occColor; //!< color value (in case of disabled lighting)
uniform THE_PREC_ENUM int occDistinguishingMode; //!< Are front and back faces distinguished?
uniform THE_PREC_ENUM int occTextureEnable; //!< Is texture enabled?
-uniform sampler2D occActiveSampler; //!< Current active sampler
uniform vec4 occTexTrsf2d[2]; //!< 2D texture transformation parameters
uniform float occPointSize; //!< point size
"float occBackMaterial_Shininess(void); //!< Specular exponent\n"
"float occBackMaterial_Transparency(void); //!< Transparency coefficient\n"
"\n"
+ "#define occActiveSampler occSampler0 //!< alias for backward compatibility\n"
+ "#define occSamplerBaseColor occSampler0 //!< alias to a base color texture\n"
+ "uniform sampler2D occSampler0; //!< current active sampler;\n"
+ " //! occSampler1, occSampler2,... should be defined in GLSL program body for multitexturing\n"
"uniform vec4 occColor; //!< color value (in case of disabled lighting)\n"
"uniform THE_PREC_ENUM int occDistinguishingMode; //!< Are front and back faces distinguished?\n"
"uniform THE_PREC_ENUM int occTextureEnable; //!< Is texture enabled?\n"
- "uniform sampler2D occActiveSampler; //!< Current active sampler\n"
"uniform vec4 occTexTrsf2d[2]; //!< 2D texture transformation parameters\n"
"uniform float occPointSize; //!< point size\n"
"\n"
#include <Graphic3d_AspectLine3d.hxx>
#include <Graphic3d_CStructure.hxx>
#include <Graphic3d_Texture2Dmanual.hxx>
+#include <Graphic3d_GraphicDriver.hxx>
#include <Image_AlienPixMap.hxx>
#include <OSD_File.hxx>
#include <Prs3d_Drawer.hxx>
Graphic3d_LevelOfTextureAnisotropy anAnisoFilter = Graphic3d_LOTA_OFF;
Handle(AIS_Shape) aTexturedIO;
- Handle(Graphic3d_TextureMap) aTextureOld;
- Handle(Graphic3d_Texture2Dmanual) aTextureNew;
+ Handle(Graphic3d_TextureSet) aTextureSetOld;
+ NCollection_Vector<Handle(Graphic3d_Texture2Dmanual)> aTextureVecNew;
bool toSetGenRepeat = false;
bool toSetGenScale = false;
bool toSetGenOrigin = false;
bool toSetImage = false;
- bool toSetNewImage = false;
+ bool toComputeUV = false;
const TCollection_AsciiString aCommandName (theArgVec[0]);
bool toSetDefaults = aCommandName == "vtexdefault";
if (aTexturedIO->Attributes()->HasOwnShadingAspect())
{
- aTextureOld = aTexturedIO->Attributes()->ShadingAspect()->Aspect()->TextureMap();
+ aTextureSetOld = aTexturedIO->Attributes()->ShadingAspect()->Aspect()->TextureSet();
}
}
else if (aNameCase == "-scale"
{
toSetDefaults = true;
}
- else if (aTextureNew.IsNull()
- && aCommandName == "vtexture")
+ else if (aCommandName == "vtexture"
+ && (aTextureVecNew.IsEmpty()
+ || aNameCase.StartsWith ("-tex")))
{
+ Standard_Integer aTexIndex = 0;
+ TCollection_AsciiString aTexName = aName;
+ if (aNameCase.StartsWith ("-tex"))
+ {
+ if (anArgIter + 1 >= theArgsNb
+ || aNameCase.Length() < 5)
+ {
+ std::cout << "Syntax error: invalid argument '" << theArgVec[anArgIter] << "'\n";
+ return 1;
+ }
+
+ TCollection_AsciiString aTexIndexStr = aNameCase.SubString (5, aNameCase.Length());
+ if (!aTexIndexStr.IsIntegerValue())
+ {
+ std::cout << "Syntax error: invalid argument '" << theArgVec[anArgIter] << "'\n";
+ return 1;
+ }
+
+ aTexIndex = aTexIndexStr.IntegerValue();
+ aTexName = theArgVec[anArgIter + 1];
+ ++anArgIter;
+ }
+ if (aTexIndex >= Graphic3d_TextureUnit_NB
+ || aTexIndex >= aCtx->CurrentViewer()->Driver()->InquireLimit (Graphic3d_TypeOfLimit_MaxCombinedTextureUnits))
+ {
+ std::cout << "Error: too many textures specified\n";
+ return 1;
+ }
+
toSetImage = true;
- toSetNewImage = true;
- if (aName.IsIntegerValue())
+ if (aTexName.IsIntegerValue())
{
- const Standard_Integer aValue = aName.IntegerValue();
+ const Standard_Integer aValue = aTexName.IntegerValue();
if (aValue < 0 || aValue >= Graphic3d_Texture2D::NumberOfTextures())
{
std::cout << "Syntax error: texture with ID " << aValue << " is undefined!\n";
return 1;
}
- aTextureNew = new Graphic3d_Texture2Dmanual (Graphic3d_NameOfTexture2D (aValue));
+ aTextureVecNew.SetValue (aTexIndex, new Graphic3d_Texture2Dmanual (Graphic3d_NameOfTexture2D (aValue)));
}
- else if (aNameCase == "?")
+ else if (aTexName == "?")
{
const TCollection_AsciiString aTextureFolder = Graphic3d_TextureRoot::TexturesFolder();
theDi.Eval (aCmnd.ToCString());
return 0;
}
- else if (aNameCase != "off")
+ else if (aTexName != "off")
{
- if (!OSD_File (aName).Exists())
+ if (!OSD_File (aTexName).Exists())
{
- std::cout << "Syntax error: non-existing image file has been specified '" << aName << "'.\n";
+ std::cout << "Syntax error: non-existing image file has been specified '" << aTexName << "'.\n";
return 1;
}
- aTextureNew = new Graphic3d_Texture2Dmanual (aName);
+ aTextureVecNew.SetValue (aTexIndex, new Graphic3d_Texture2Dmanual (aTexName));
+ }
+ else
+ {
+ aTextureVecNew.SetValue (aTexIndex, Handle(Graphic3d_Texture2Dmanual)());
}
+ aTextureVecNew.ChangeValue (aTexIndex)->GetParams()->SetTextureUnit ((Graphic3d_TextureUnit )aTexIndex);
+ }
+ else
+ {
+ std::cout << "Syntax error: invalid argument '" << theArgVec[anArgIter] << "'\n";
+ return 1;
+ }
+ }
- if (!aTextureNew.IsNull())
+ if (toSetImage)
+ {
+ // check if new image set is equal to already set one
+ Standard_Integer aNbChanged = 0;
+ Handle(Graphic3d_TextureSet) aTextureSetNew;
+ if (!aTextureVecNew.IsEmpty())
+ {
+ aNbChanged = aTextureVecNew.Size();
+ aTextureSetNew = new Graphic3d_TextureSet (aTextureVecNew.Size());
+ for (Standard_Integer aTexIter = 0; aTexIter < aTextureSetNew->Size(); ++aTexIter)
{
- if (!aTextureOld.IsNull())
+ Handle(Graphic3d_Texture2Dmanual)& aTextureNew = aTextureVecNew.ChangeValue (aTexIter);
+ Handle(Graphic3d_TextureRoot) aTextureOld;
+ if (!aTextureSetOld.IsNull()
+ && aTexIter < aTextureSetOld->Size())
+ {
+ aTextureOld = aTextureSetOld->Value (aTexIter);
+ }
+
+ if (!aTextureOld.IsNull()
+ && !aTextureNew.IsNull())
{
*aTextureNew->GetParams() = *aTextureOld->GetParams();
if (Handle(Graphic3d_Texture2Dmanual) anOldManualTex = Handle(Graphic3d_Texture2Dmanual)::DownCast (aTextureOld))
&& aFilePathOld == aFilePathNew
&& (!aFilePathNew.IsEmpty() || aTextureNew->Name() != Graphic3d_NOT_2D_UNKNOWN))
{
- toSetNewImage = false;
+ --aNbChanged;
aTextureNew = anOldManualTex;
}
}
}
- else
- {
- aTexturedIO->SetToUpdate (AIS_Shaded);
- }
- }
-
- if (!aTexturedIO->Attributes()->HasOwnShadingAspect())
- {
- aTexturedIO->Attributes()->SetShadingAspect (new Prs3d_ShadingAspect());
- *aTexturedIO->Attributes()->ShadingAspect()->Aspect() = *aCtx->DefaultDrawer()->ShadingAspect()->Aspect();
- }
-
- if (!aTextureNew.IsNull())
- {
- aTexturedIO->Attributes()->ShadingAspect()->Aspect()->SetTextureMapOn();
- }
- else
- {
- aTexturedIO->Attributes()->ShadingAspect()->Aspect()->SetTextureMapOff();
+ aTextureSetNew->SetValue (aTexIter, aTextureNew);
}
- aTexturedIO->Attributes()->ShadingAspect()->Aspect()->SetTextureMap (aTextureNew);
- aTextureOld.Nullify();
}
- else
+ if (aNbChanged == 0
+ && ((aTextureSetOld.IsNull() && aTextureSetNew.IsNull())
+ || (aTextureSetOld->Size() == aTextureSetNew->Size())))
{
- std::cout << "Syntax error: invalid argument '" << theArgVec[anArgIter] << "'\n";
- return 1;
+ aTextureSetNew = aTextureSetOld;
+ }
+
+ if (!aTexturedIO->Attributes()->HasOwnShadingAspect())
+ {
+ aTexturedIO->Attributes()->SetShadingAspect (new Prs3d_ShadingAspect());
+ *aTexturedIO->Attributes()->ShadingAspect()->Aspect() = *aCtx->DefaultDrawer()->ShadingAspect()->Aspect();
}
+
+ toComputeUV = !aTextureSetNew.IsNull() && aTextureSetOld.IsNull();
+ aTexturedIO->Attributes()->ShadingAspect()->Aspect()->SetTextureMapOn (!aTextureSetNew.IsNull());
+ aTexturedIO->Attributes()->ShadingAspect()->Aspect()->SetTextureSet (aTextureSetNew);
+ aTextureSetOld.Nullify();
}
if (toSetDefaults)
if (aCommandName == "vtexture"
&& theArgsNb == 2)
{
- if (!aTextureOld.IsNull())
+ if (!aTextureSetOld.IsNull())
{
- toSetNewImage = true;
+ //toComputeUV = true; // we can keep UV vertex attributes
aTexturedIO->Attributes()->ShadingAspect()->Aspect()->SetTextureMapOff();
- aTexturedIO->Attributes()->ShadingAspect()->Aspect()->SetTextureMap (Handle(Graphic3d_TextureMap)());
- aTextureOld.Nullify();
+ aTexturedIO->Attributes()->ShadingAspect()->Aspect()->SetTextureSet (Handle(Graphic3d_TextureSet)());
+ aTextureSetOld.Nullify();
}
}
toSetGenScale = true;
}
- if (toSetGenRepeat || toSetGenOrigin || toSetGenScale || toSetNewImage)
+ if (toSetGenRepeat || toSetGenOrigin || toSetGenScale || toComputeUV)
{
aTexturedIO->SetToUpdate (AIS_Shaded);
if (toSetImage)
theCommands.Add ("vtexture",
"vtexture [-noupdate|-update] name [ImageFile|IdOfTexture|off]"
+ "\n\t\t: [-tex0 Image0] [-tex1 Image1] [...]"
"\n\t\t: [-origin {u v|off}] [-scale {u v|off}] [-repeat {u v|off}]"
"\n\t\t: [-trsfTrans du dv] [-trsfScale su sv] [-trsfAngle Angle]"
"\n\t\t: [-modulate {on|off}]"
{
if (theArgNb < 3)
{
- std::cerr << theArgVec[0] << " syntax error: lack of arguments\n";
+ std::cout << "Syntax error: lack of arguments\n";
return 1;
}
const TCollection_AsciiString aSrcVert = theArgVec[theArgNb - 2];
const TCollection_AsciiString aSrcFrag = theArgVec[theArgNb - 1];
- if (!aSrcVert.IsEmpty()
- && !OSD_File (aSrcVert).Exists())
+ if (aSrcVert.IsEmpty() || aSrcFrag.IsEmpty())
{
- std::cerr << "Non-existing vertex shader source\n";
+ std::cout << "Syntax error: lack of arguments\n";
return 1;
}
- if (!aSrcFrag.IsEmpty()
- && !OSD_File (aSrcFrag).Exists())
+
+ const bool isVertFile = OSD_File (aSrcVert).Exists();
+ const bool isFragFile = OSD_File (aSrcFrag).Exists();
+ if (!isVertFile
+ && aSrcVert.Search ("gl_Position") == -1)
{
- std::cerr << "Non-existing fragment shader source\n";
+ std::cerr << "Error: non-existing or invalid vertex shader source\n";
+ return 1;
+ }
+ if (!isFragFile
+ && aSrcFrag.Search ("occFragColor") == -1)
+ {
+ std::cerr << "Error: non-existing or invalid fragment shader source\n";
return 1;
}
aProgram = new Graphic3d_ShaderProgram();
- aProgram->AttachShader (Graphic3d_ShaderObject::CreateFromFile (Graphic3d_TOS_VERTEX, aSrcVert));
- aProgram->AttachShader (Graphic3d_ShaderObject::CreateFromFile (Graphic3d_TOS_FRAGMENT, aSrcFrag));
+ aProgram->AttachShader (isVertFile
+ ? Graphic3d_ShaderObject::CreateFromFile (Graphic3d_TOS_VERTEX, aSrcVert)
+ : Graphic3d_ShaderObject::CreateFromSource(Graphic3d_TOS_VERTEX, aSrcVert));
+ aProgram->AttachShader (isFragFile
+ ? Graphic3d_ShaderObject::CreateFromFile (Graphic3d_TOS_FRAGMENT, aSrcFrag)
+ : Graphic3d_ShaderObject::CreateFromSource(Graphic3d_TOS_FRAGMENT, aSrcFrag));
anArgsNb = theArgNb - 2;
}
--- /dev/null
+puts "========"
+puts "0028912: Visualization, TKOpenGl - multi-texture support"
+puts "========"
+
+pload MODELING VISUALIZATION
+
+set aShaderVert "
+THE_SHADER_OUT vec2 TexCoord;
+void main() {
+ TexCoord = occTexCoord.st;
+ gl_Position = occProjectionMatrix * occWorldViewMatrix * occModelWorldMatrix * occVertex;
+}"
+
+set aShaderFrag "
+uniform sampler2D occSampler1;
+uniform sampler2D occSampler2;
+uniform sampler2D occSampler3;
+THE_SHADER_IN vec2 TexCoord;
+void main() {
+ if (TexCoord.s < 0.5 && TexCoord.t < 0.5) { occFragColor = occTexture2D(occSampler0, TexCoord.st); }
+ else if (TexCoord.s < 0.5 && TexCoord.t >= 0.5) { occFragColor = occTexture2D(occSampler1, TexCoord.st); }
+ else if (TexCoord.s >= 0.5 && TexCoord.t < 0.5) { occFragColor = occTexture2D(occSampler2, TexCoord.st); }
+ else { occFragColor = occTexture2D(occSampler3, TexCoord.st); }
+}"
+
+# draw a box
+box b 1 2 3
+vclear
+vinit View1
+vaxo
+vdisplay -dispMode 1 b
+vfit
+vrotate 0.2 0.0 0.0
+
+# take snapshot with built-in shader
+vtexture b -tex0 3 -tex1 4 -tex2 5 -tex3 6
+vdump $::imagedir/${::casename}_normal.png
+
+vshaderprog b $aShaderVert $aShaderFrag
+vdump $::imagedir/${::casename}_multi.png