0030807: Visualization, TKOpenGl - supporting cubemaps
authoriko <iko@opencascade.com>
Tue, 9 Jul 2019 13:55:49 +0000 (16:55 +0300)
committerapn <apn@opencascade.com>
Fri, 23 Aug 2019 13:56:40 +0000 (16:56 +0300)
A cubemap texture initialization has been implemented.
Setting environment cubemap as interactive background is posssible now.

29 files changed:
src/Graphic3d/FILES
src/Graphic3d/Graphic3d_CView.hxx
src/Graphic3d/Graphic3d_CubeMap.cxx [new file with mode: 0644]
src/Graphic3d/Graphic3d_CubeMap.hxx [new file with mode: 0644]
src/Graphic3d/Graphic3d_CubeMapOrder.cxx [new file with mode: 0644]
src/Graphic3d/Graphic3d_CubeMapOrder.hxx [new file with mode: 0644]
src/Graphic3d/Graphic3d_CubeMapPacked.cxx [new file with mode: 0644]
src/Graphic3d/Graphic3d_CubeMapPacked.hxx [new file with mode: 0644]
src/Graphic3d/Graphic3d_CubeMapSeparate.cxx [new file with mode: 0644]
src/Graphic3d/Graphic3d_CubeMapSeparate.hxx [new file with mode: 0644]
src/Graphic3d/Graphic3d_CubeMapSide.hxx [new file with mode: 0644]
src/Graphic3d/Graphic3d_TextureUnit.hxx
src/Graphic3d/Graphic3d_TypeOfBackground.hxx
src/Graphic3d/Graphic3d_TypeOfTexture.hxx
src/OpenGl/OpenGl_AspectsTextureSet.cxx
src/OpenGl/OpenGl_BackgroundArray.cxx
src/OpenGl/OpenGl_BackgroundArray.hxx
src/OpenGl/OpenGl_ShaderManager.cxx
src/OpenGl/OpenGl_ShaderManager.hxx
src/OpenGl/OpenGl_Texture.cxx
src/OpenGl/OpenGl_Texture.hxx
src/OpenGl/OpenGl_View.cxx
src/OpenGl/OpenGl_View.hxx
src/OpenGl/OpenGl_View_Raytrace.cxx
src/OpenGl/OpenGl_View_Redraw.cxx
src/V3d/V3d_View.cxx
src/V3d/V3d_View.hxx
src/ViewerTest/ViewerTest_ViewerCommands.cxx
tests/v3d/glsl/cubemap [new file with mode: 0644]

index f3e0acb..c19fc1b 100755 (executable)
@@ -48,6 +48,15 @@ Graphic3d_ClipPlane.hxx
 Graphic3d_CStructure.cxx
 Graphic3d_CStructure.hxx
 Graphic3d_CTexture.hxx
+Graphic3d_CubeMap.cxx
+Graphic3d_CubeMap.hxx
+Graphic3d_CubeMapOrder.cxx
+Graphic3d_CubeMapOrder.hxx
+Graphic3d_CubeMapPacked.cxx
+Graphic3d_CubeMapPacked.hxx
+Graphic3d_CubeMapSeparate.cxx
+Graphic3d_CubeMapSeparate.hxx
+Graphic3d_CubeMapSide.hxx
 Graphic3d_CullingTool.cxx
 Graphic3d_CullingTool.hxx
 Graphic3d_CView.cxx
index e79d24f..ac0df39 100644 (file)
@@ -19,6 +19,7 @@
 #include <Aspect_Window.hxx>
 #include <Graphic3d_BufferType.hxx>
 #include <Graphic3d_Camera.hxx>
+#include <Graphic3d_CubeMap.hxx>
 #include <Graphic3d_CLight.hxx>
 #include <Graphic3d_CStructure.hxx>
 #include <Graphic3d_DataStructureManager.hxx>
@@ -373,6 +374,12 @@ public:
   //! Sets background image fill style.
   virtual void SetBackgroundImageStyle (const Aspect_FillMethod theFillStyle) = 0;
 
+  //! Returns cubemap being setted last time on background.
+  virtual Handle(Graphic3d_CubeMap) BackgroundCubeMap() const = 0;
+
+  //! Sets environment cubemap as background.
+  virtual void SetBackgroundCubeMap (const Handle(Graphic3d_CubeMap)& theCubeMap) = 0;
+
   //! Returns environment texture set for the view.
   virtual Handle(Graphic3d_TextureEnv) TextureEnv() const = 0; 
 
diff --git a/src/Graphic3d/Graphic3d_CubeMap.cxx b/src/Graphic3d/Graphic3d_CubeMap.cxx
new file mode 100644 (file)
index 0000000..f4c95aa
--- /dev/null
@@ -0,0 +1,17 @@
+// Author: Ilya Khramov
+// Copyright (c) 2019 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_CubeMap.hxx>
+
+IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_CubeMap, Graphic3d_TextureMap)
diff --git a/src/Graphic3d/Graphic3d_CubeMap.hxx b/src/Graphic3d/Graphic3d_CubeMap.hxx
new file mode 100644 (file)
index 0000000..c9e859a
--- /dev/null
@@ -0,0 +1,110 @@
+// Author: Ilya Khramov
+// Copyright (c) 2019 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_CubeMap_HeaderFile
+#define _Graphic3d_CubeMap_HeaderFile
+
+#include <Graphic3d_CubeMapOrder.hxx>
+#include <Graphic3d_TextureMap.hxx>
+
+//! Base class for cubemaps.
+//! It is iterator over cubemap sides.
+class Graphic3d_CubeMap : public Graphic3d_TextureMap
+{
+  DEFINE_STANDARD_RTTIEXT(Graphic3d_CubeMap, Graphic3d_TextureMap)
+public:
+
+  //! Constructor defining loading cubemap from file.
+  Graphic3d_CubeMap (const TCollection_AsciiString& theFileName) :
+    Graphic3d_TextureMap (theFileName, Graphic3d_TOT_CUBEMAP),
+    myCurrentSide  (Graphic3d_CMS_POS_X),
+    myEndIsReached (false),
+    myIsTopDown    (true),
+    myZIsInverted  (false)
+  {}
+
+  //! Constructor defining direct cubemap initialization from PixMap.
+  Graphic3d_CubeMap (const Handle(Image_PixMap)& thePixmap = Handle(Image_PixMap)()) :
+    Graphic3d_TextureMap (thePixmap, Graphic3d_TOT_CUBEMAP),
+    myCurrentSide  (Graphic3d_CMS_POS_X),
+    myEndIsReached (false),
+    myIsTopDown    (true),
+    myZIsInverted  (false)
+  {}
+
+  //! Returns whether the iterator has reached the end (true if it hasn't). 
+  Standard_Boolean More() const { return !myEndIsReached; }
+
+  //! Returns current cubemap side (iterator state).
+  Graphic3d_CubeMapSide CurrentSide() const { return myCurrentSide; }
+
+  //! Moves iterator to the next cubemap side.
+  //! Uses OpenGL cubemap sides order +X -> -X -> +Y -> -Y -> +Z -> -Z.
+  void Next()
+  {
+    if (!myEndIsReached && myCurrentSide == Graphic3d_CMS_NEG_Z)
+    {
+      myEndIsReached = true;
+    }
+    else
+    {
+      myCurrentSide = Graphic3d_CubeMapSide (myCurrentSide + 1);
+    }
+  }
+
+  //! Returns whether row's memory layout is top-down.
+  Standard_Boolean IsTopDown() const
+  {
+    return myIsTopDown;
+  }
+
+  //! Sets Z axis inversion (vertical flipping).
+  void SetZInversion (Standard_Boolean theZIsInverted)
+  {
+    myZIsInverted = theZIsInverted;
+  }
+
+  //! Returns whether Z axis is inverted.
+  Standard_Boolean ZIsInverted() const
+  {
+    return myZIsInverted;
+  }
+
+  //! Returns PixMap containing current side of cubemap.
+  //! Returns null handle if current side is invalid.
+  virtual Handle(Image_PixMap) Value() = 0;
+
+  //! Sets iterator state to +X cubemap side.
+  Graphic3d_CubeMap& Reset()
+  { 
+    myCurrentSide = Graphic3d_CMS_POS_X;
+    myEndIsReached = false;
+    return *this;
+  }
+
+  //! Empty destructor.
+  ~Graphic3d_CubeMap() {}
+
+protected:
+
+  Graphic3d_CubeMapSide myCurrentSide;  //!< Iterator state
+  Standard_Boolean      myEndIsReached; //!< Indicates whether end of iteration has been reached or hasn't
+  Standard_Boolean      myIsTopDown;    //!< Stores rows's memory layout
+  Standard_Boolean      myZIsInverted;  //!< Indicates whether Z axis is inverted that allows to synchronize vertical flip of cubemap
+
+};
+
+DEFINE_STANDARD_HANDLE(Graphic3d_CubeMap, Graphic3d_TextureMap)
+
+#endif // _Graphic3d_CubeMap_HeaderFile
diff --git a/src/Graphic3d/Graphic3d_CubeMapOrder.cxx b/src/Graphic3d/Graphic3d_CubeMapOrder.cxx
new file mode 100644 (file)
index 0000000..52c1c30
--- /dev/null
@@ -0,0 +1,278 @@
+// Author: Ilya Khramov
+// Copyright (c) 2019 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_CubeMapOrder.hxx>
+
+#include <Standard_Failure.hxx>
+
+#include <bitset>
+
+// =======================================================================
+// function : Graphic3d_CubeMapOrder
+// purpose  :
+// =======================================================================
+Graphic3d_CubeMapOrder::Graphic3d_CubeMapOrder()
+  :
+  myConvolution  (0),
+  myHasOverflows (false)
+{}
+
+// =======================================================================
+// function : Graphic3d_CubeMapOrder
+// purpose  :
+// =======================================================================
+Graphic3d_CubeMapOrder::Graphic3d_CubeMapOrder (unsigned char thePosXLocation,
+                                                unsigned char theNegXLocation,
+                                                unsigned char thePosYLocation,
+                                                unsigned char theNegYLocation,
+                                                unsigned char thePosZLocation,
+                                                unsigned char theNegZLocation)
+  :
+  myConvolution  (0),
+  myHasOverflows (false)
+{
+  Set (Graphic3d_CMS_POS_X, thePosXLocation);
+  Set (Graphic3d_CMS_NEG_X, theNegXLocation);
+  Set (Graphic3d_CMS_POS_Y, thePosYLocation);
+  Set (Graphic3d_CMS_NEG_Y, theNegYLocation);
+  Set (Graphic3d_CMS_POS_Z, thePosZLocation);
+  Set (Graphic3d_CMS_NEG_Z, theNegZLocation);
+}
+
+// =======================================================================
+// function : Graphic3d_CubeMapOrder
+// purpose  :
+// =======================================================================
+Graphic3d_CubeMapOrder::Graphic3d_CubeMapOrder (const Graphic3d_ValidatedCubeMapOrder theOrder)
+  :
+  myConvolution  (theOrder.Order.myConvolution),
+  myHasOverflows (theOrder.Order.myHasOverflows)
+{}
+
+// =======================================================================
+// function : Set
+// purpose  :
+// =======================================================================
+Graphic3d_CubeMapOrder& Graphic3d_CubeMapOrder::Set (const Graphic3d_CubeMapOrder& theOrder)
+{
+  myConvolution = theOrder.myConvolution;
+  myHasOverflows = theOrder.myHasOverflows;
+  return *this;
+}
+
+// =======================================================================
+// function : operator=
+// purpose  :
+// =======================================================================
+Graphic3d_ValidatedCubeMapOrder Graphic3d_CubeMapOrder::Validated() const
+{
+  if (!IsValid())
+  {
+    throw Standard_Failure("Try of Graphic3d_ValidatedCubeMapOrder creation using invalid Graphic3d_CubeMapOrder");
+  }
+
+  return *this;
+}
+
+// =======================================================================
+// function : Set
+// purpose  :
+// =======================================================================
+Graphic3d_CubeMapOrder& Graphic3d_CubeMapOrder::Set (Graphic3d_CubeMapSide theCubeMapSide, unsigned char theValue)
+{
+  if (theValue > 5)
+  {
+    myHasOverflows = true;
+    return *this;
+  }
+  set (theCubeMapSide, theValue);
+  return *this;
+}
+
+// =======================================================================
+// function : Get
+// purpose  :
+// =======================================================================
+unsigned char Graphic3d_CubeMapOrder::Get (Graphic3d_CubeMapSide theCubeMapSide) const
+{
+  return get (static_cast<unsigned char> (theCubeMapSide));
+}
+
+// =======================================================================
+// function : operator[]
+// purpose  :
+// =======================================================================
+unsigned char Graphic3d_CubeMapOrder::operator[] (Graphic3d_CubeMapSide theCubeMapSide) const
+{
+  return Get (theCubeMapSide);
+}
+
+// =======================================================================
+// function : SetDefault
+// purpose  :
+// =======================================================================
+Graphic3d_CubeMapOrder& Graphic3d_CubeMapOrder::SetDefault()
+{
+  for (unsigned char i = 0; i < 6; ++i)
+  {
+    set (Graphic3d_CubeMapSide (i), i);
+  }
+  return *this;
+}
+
+// =======================================================================
+// function : Permute
+// purpose  :
+// =======================================================================
+Graphic3d_CubeMapOrder& Graphic3d_CubeMapOrder::Permute (Graphic3d_ValidatedCubeMapOrder thePermutation)
+{
+  for (unsigned char i = 0; i < 6; ++i)
+  {
+    set (i, thePermutation->get (get (i)));
+  }
+
+  return *this;
+}
+
+// =======================================================================
+// function : Permuted
+// purpose  :
+// =======================================================================
+Graphic3d_CubeMapOrder Graphic3d_CubeMapOrder::Permuted (Graphic3d_ValidatedCubeMapOrder thePermutation) const
+{
+  Graphic3d_CubeMapOrder anOrder = *this;
+  anOrder.Permute (thePermutation);
+  return anOrder;
+}
+
+// =======================================================================
+// function : Swap
+// purpose  :
+// =======================================================================
+Graphic3d_CubeMapOrder& Graphic3d_CubeMapOrder::Swap (Graphic3d_CubeMapSide theFirstSide,
+                                                      Graphic3d_CubeMapSide theSecondSide)
+{
+  unsigned char aTmp = Get (theFirstSide);
+  set (theFirstSide, Get(theSecondSide));
+  set (theSecondSide, aTmp);
+  return *this;
+}
+
+// =======================================================================
+// function : Swapped
+// purpose  :
+// =======================================================================
+Graphic3d_CubeMapOrder Graphic3d_CubeMapOrder::Swapped (Graphic3d_CubeMapSide theFirstSide,
+                                                        Graphic3d_CubeMapSide theSecondSide) const
+{
+  Graphic3d_CubeMapOrder anOrder = *this;
+  anOrder.Swap (theFirstSide, theSecondSide);
+  return anOrder;
+}
+
+// =======================================================================
+// function : Clear
+// purpose  :
+// =======================================================================
+Graphic3d_CubeMapOrder& Graphic3d_CubeMapOrder::Clear()
+{
+  myConvolution = 0;
+  myHasOverflows = false;
+  return *this;
+}
+
+// =======================================================================
+// function : IsEmpty
+// purpose  :
+// =======================================================================
+bool Graphic3d_CubeMapOrder::IsEmpty() const
+{
+  return myConvolution == 0;
+}
+
+// =======================================================================
+// function : HasRepetitions
+// purpose  :
+// =======================================================================
+bool Graphic3d_CubeMapOrder::HasRepetitions() const
+{
+  std::bitset<6> aBitSet;
+  for (unsigned char i = 0; i < 6; ++i)
+  {
+    std::bitset<6>::reference aFlag = aBitSet[get (i)];
+    if (aFlag)
+    {
+      return true;
+    }
+    aFlag = true;
+  }
+  return false;
+}
+
+// =======================================================================
+// function : HasOverflows
+// purpose  :
+// =======================================================================
+bool Graphic3d_CubeMapOrder::HasOverflows() const
+{
+  return myHasOverflows;
+}
+
+// =======================================================================
+// function : IsValid
+// purpose  :
+// =======================================================================
+bool Graphic3d_CubeMapOrder::IsValid() const
+{
+  return !HasRepetitions() && !HasOverflows();
+}
+
+// =======================================================================
+// function : get
+// purpose  :
+// =======================================================================
+unsigned char Graphic3d_CubeMapOrder::get (unsigned char theCubeMapSide) const
+{
+  return (myConvolution / (1 << (theCubeMapSide * 3))) % (1 << 3);
+}
+
+// =======================================================================
+// function : set
+// purpose  :
+// =======================================================================
+void Graphic3d_CubeMapOrder::set (unsigned char theCubeMapSide, unsigned char theValue)
+{
+  unsigned int aValuePlace = 1 << (theCubeMapSide * 3);
+  myConvolution -= aValuePlace * get (theCubeMapSide);
+  myConvolution += aValuePlace * theValue;
+}
+
+// =======================================================================
+// function : set
+// purpose  :
+// =======================================================================
+void Graphic3d_CubeMapOrder::set (Graphic3d_CubeMapSide theCubeMapSide, unsigned char theValue)
+{
+  set (static_cast<unsigned char> (theCubeMapSide), theValue);
+}
+
+// =======================================================================
+// function : Default
+// purpose  :
+// =======================================================================
+const Graphic3d_ValidatedCubeMapOrder& Graphic3d_CubeMapOrder::Default()
+{
+  static const Graphic3d_ValidatedCubeMapOrder aCubeMapOrder = Graphic3d_CubeMapOrder().SetDefault().Validated();
+  return aCubeMapOrder;
+}
\ No newline at end of file
diff --git a/src/Graphic3d/Graphic3d_CubeMapOrder.hxx b/src/Graphic3d/Graphic3d_CubeMapOrder.hxx
new file mode 100644 (file)
index 0000000..ed0eeb1
--- /dev/null
@@ -0,0 +1,158 @@
+// Author: Ilya Khramov
+// Copyright (c) 2019 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_CubeMapOrder_HeaderFile
+#define _Graphic3d_CubeMapOrder_HeaderFile
+
+#include <Graphic3d_CubeMapSide.hxx>
+#include <Standard_Macro.hxx>
+
+class Graphic3d_ValidatedCubeMapOrder;
+
+//! Graphic3d_CubeMapOrder maps sides of cubemap on tiles in packed cubemap image
+//! to support different tiles order in such images.
+//! Also it can be considered as permutation of numbers from 0 to 5.
+//! It stores permutation in one integer as convolution.
+class Graphic3d_CubeMapOrder
+{
+
+public:
+
+  //! Default constructor.
+  //! Creates empty order with zero convolution.
+  Standard_EXPORT Graphic3d_CubeMapOrder();
+
+  //! Initializes order with values.
+  Standard_EXPORT Graphic3d_CubeMapOrder (unsigned char thePosXLocation,
+                                          unsigned char theNegXLocation,
+                                          unsigned char thePosYLocation,
+                                          unsigned char theNegYLocation,
+                                          unsigned char thePosZLocation,
+                                          unsigned char theNegZLocation);
+
+  //! Creates Graphic3d_CubeMapOrder using Graphic3d_ValidatedCubeMapOrder.
+  Standard_EXPORT Graphic3d_CubeMapOrder (const Graphic3d_ValidatedCubeMapOrder theOrder);
+
+  //! Alias of 'operator='.
+  Standard_EXPORT Graphic3d_CubeMapOrder& Set (const Graphic3d_CubeMapOrder& theOrder);
+
+  //! Checks whether order is valid and returns object containing it.
+  //! If order is invalid then exception will be thrown.
+  //! This method is only way to create Graphic3d_ValidatedCubeMapOrder except copy constructor.
+  Standard_EXPORT Graphic3d_ValidatedCubeMapOrder Validated() const;
+
+public:
+
+  //! Sets number of tile in packed cubemap image according passed cubemap side.
+  Standard_EXPORT Graphic3d_CubeMapOrder& Set (Graphic3d_CubeMapSide theCubeMapSide, unsigned char theValue);
+
+  //! Sets default order (just from 0 to 5)
+  Standard_EXPORT Graphic3d_CubeMapOrder& SetDefault();
+
+  //! Applies another cubemap order as permutation for the current one.
+  Standard_EXPORT Graphic3d_CubeMapOrder& Permute (Graphic3d_ValidatedCubeMapOrder anOrder);
+
+  //! Returns permuted by other cubemap order copy of current one. 
+  Standard_EXPORT Graphic3d_CubeMapOrder Permuted (Graphic3d_ValidatedCubeMapOrder anOrder) const;
+
+  //! Swaps values of two cubemap sides.
+  Standard_EXPORT Graphic3d_CubeMapOrder& Swap (Graphic3d_CubeMapSide theFirstSide,
+                                                Graphic3d_CubeMapSide theSecondSide);
+
+  //! Returns copy of current order with swapped values of two cubemap sides. 
+  Standard_EXPORT Graphic3d_CubeMapOrder Swapped (Graphic3d_CubeMapSide theFirstSide,
+                                                  Graphic3d_CubeMapSide theSecondSide) const;
+
+  //! Returns value of passed cubemap side.
+  Standard_EXPORT unsigned char Get (Graphic3d_CubeMapSide theCubeMapSide) const;
+
+  //! Alias of 'Get'.
+  Standard_EXPORT unsigned char operator[] (Graphic3d_CubeMapSide theCubeMapSide) const;
+
+  //! Makes order empty.
+  Standard_EXPORT Graphic3d_CubeMapOrder& Clear();
+
+  //! Checks whether order is empty.
+  Standard_EXPORT bool IsEmpty() const;
+
+  //! Checks whether order has repetitions.
+  Standard_EXPORT bool HasRepetitions() const;
+
+  //! Checks whether attempts to assign index greater than 5 to any side happed.
+  Standard_EXPORT bool HasOverflows() const;
+
+  //! Checks whether order is valid.
+  //! Order is valid when it doesn't have repetitions
+  //! and there were not attempts to assign indexes greater than 5.
+  Standard_EXPORT bool IsValid() const;
+
+public:
+
+  //! Returns default order in protector container class.
+  //! It is guaranteed to be valid.
+  Standard_EXPORT static const Graphic3d_ValidatedCubeMapOrder& Default();
+
+private:
+
+  //! Alias of 'Get' with other parameter's type for more handful iteration.
+  unsigned char get (unsigned char theCubeMapSide) const;
+
+  //! Alias of 'set' with other parameter's type for more handful iteration and applying permutations.
+  void set (unsigned char theCubeMapSide, unsigned char theValue);
+
+  //! 'Set' without overflow's checking.
+  void set (Graphic3d_CubeMapSide theCubeMapSide, unsigned char theValue);
+
+private:
+
+  unsigned int myConvolution;  //!< Contains all values of permutation as power convolution
+  bool         myHasOverflows; //!< Indicates if there are attempts to assign index greater than 5
+};
+
+//! Graphic3d_ValidatedCubeMapOrder contains completely valid order object.
+//! The only way to create this class except copy constructor is 'Validated' method of Graphic3d_CubeMapOrder.
+//! This class can initialize Graphic3d_CubeMapOrder.
+//! It is supposed to be used in case of necessity of completely valid order (in function argument as example).
+//! It helps to automate order's valid checks.
+class Graphic3d_ValidatedCubeMapOrder
+{
+
+public:
+
+  friend class Graphic3d_CubeMapOrder;
+
+  //! Allows skip access to 'Order' field and work directly.
+  const Graphic3d_CubeMapOrder* operator->() const
+  {
+    return &Order;
+  }
+
+public:
+
+  const Graphic3d_CubeMapOrder Order; //!< Completely valid order
+
+private:
+
+  //! Only Graphic3d_CubeMapOrder can generate Graphic3d_ValidatedCubeMapOrder in 'Validated' method.
+  Graphic3d_ValidatedCubeMapOrder(const Graphic3d_CubeMapOrder theOrder)
+    :
+    Order(theOrder)
+  {}
+
+  //! Deleted 'operator='
+  Graphic3d_ValidatedCubeMapOrder& operator= (const Graphic3d_ValidatedCubeMapOrder&);
+
+};
+
+#endif // _Graphic3d_CubeMapOrder_HeaderFile
\ No newline at end of file
diff --git a/src/Graphic3d/Graphic3d_CubeMapPacked.cxx b/src/Graphic3d/Graphic3d_CubeMapPacked.cxx
new file mode 100644 (file)
index 0000000..ac57c48
--- /dev/null
@@ -0,0 +1,196 @@
+// Author: Ilya Khramov
+// Copyright (c) 2019 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_CubeMapPacked.hxx>
+#include <Image_AlienPixMap.hxx>
+
+IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_CubeMapPacked, Graphic3d_CubeMap)
+
+// =======================================================================
+// function : Graphic3d_CubeMapPacked
+// purpose  :
+// =======================================================================
+Graphic3d_CubeMapPacked::Graphic3d_CubeMapPacked (const TCollection_AsciiString&        theFilePath,
+                                                  const Graphic3d_ValidatedCubeMapOrder theOrder)
+  :
+  Graphic3d_CubeMap (theFilePath),
+  myOrder           (theOrder),
+  myTileNumberX     (1)
+{}
+
+// =======================================================================
+// function : Graphic3d_CubeMapPacked
+// purpose  :
+// =======================================================================
+Graphic3d_CubeMapPacked::Graphic3d_CubeMapPacked (const Handle(Image_PixMap)&           theImage,
+                                                  const Graphic3d_ValidatedCubeMapOrder theOrder)
+  :
+  Graphic3d_CubeMap (Handle(Image_PixMap)()),
+  myOrder           (theOrder),
+  myTileNumberX     (1)
+{
+    if (checkImage (theImage, myTileNumberX))
+    {
+      myPixMap = theImage;
+    }
+}
+
+// =======================================================================
+// function : Value
+// purpose  :
+// =======================================================================
+Handle(Image_PixMap) Graphic3d_CubeMapPacked::Value()
+{
+  if (myTileNumberX != 0)
+  {
+    if (myPixMap.IsNull())
+    {
+      TCollection_AsciiString aFilePath;
+      myPath.SystemName (aFilePath);
+      if (!aFilePath.IsEmpty())
+      {
+        tryLoadImage (aFilePath);
+      }
+    }
+
+    if (!myPixMap.IsNull())
+    {
+      Handle(Image_PixMap) aWrapper = new Image_PixMap();
+
+      Standard_Size aTileSize = myPixMap->SizeX() / myTileNumberX;
+
+      myIsTopDown = myPixMap->IsTopDown();
+
+      Graphic3d_CubeMapOrder anOrder = myOrder;
+
+      if (!myIsTopDown)
+      {
+        myPixMap->SetTopDown (true);
+        anOrder.Swap (Graphic3d_CMS_POS_Y, Graphic3d_CMS_NEG_Y);
+      }
+
+      unsigned int aTileIndexX = anOrder[myCurrentSide] % myTileNumberX;
+      unsigned int aTileIndexY = anOrder[myCurrentSide] / myTileNumberX;
+
+      aTileIndexY = myIsTopDown ? aTileIndexY : (6 / myTileNumberX - 1 - aTileIndexY);
+
+      if (aWrapper->InitWrapper (myPixMap->Format(),
+                                 myPixMap->ChangeRawValue(aTileIndexY * aTileSize, aTileIndexX * aTileSize),
+                                 aTileSize,
+                                 aTileSize,
+                                 myPixMap->SizeRowBytes()))
+      {
+        myPixMap->SetTopDown (myIsTopDown);
+        return aWrapper;
+      }
+      else
+      {
+        myPixMap->SetTopDown(myIsTopDown);
+      }
+    }
+  }
+
+  return Handle(Image_PixMap)();
+}
+
+// =======================================================================
+// function : checkOrder
+// purpose  :
+// =======================================================================
+Standard_Boolean Graphic3d_CubeMapPacked::checkOrder (const NCollection_Array1<unsigned int>& theOrder)
+{
+  Standard_Boolean anOrderIsValid = Standard_True;
+
+  if (theOrder.Size() != 6)
+  {
+    anOrderIsValid = Standard_False;
+  }
+  else
+  {
+    for (unsigned int i = 0; i < 6 && anOrderIsValid; ++i)
+    {
+      if (theOrder[i] > 5)
+      {
+        anOrderIsValid = Standard_False;
+        break;
+      }
+
+      for (unsigned int j = i + 1; j < 6; ++j)
+      {
+        if (theOrder[i] == theOrder[j])
+        {
+          anOrderIsValid =  Standard_False;
+          break;
+        }
+      }
+    }
+  }
+
+  if (!anOrderIsValid)
+  {
+    throw Standard_Failure ("Ivalid order format in tiles of Graphic3d_CubeMapPacked");
+  }
+
+  return anOrderIsValid;
+}
+
+// =======================================================================
+// function : checkImage
+// purpose  :
+// =======================================================================
+Standard_Boolean Graphic3d_CubeMapPacked::checkImage (const Handle(Image_PixMap)& theImage,
+                                                      unsigned int&               theTileNumberX)
+{
+  Standard_Size aSizeX = theImage->SizeX();
+  Standard_Size aSizeY = theImage->SizeY();
+
+  if ((aSizeY % aSizeX == 0) && (aSizeY / aSizeX == 6))
+  {
+    theTileNumberX = 1;
+  }
+  else if ((aSizeX % aSizeY == 0) && (aSizeX / aSizeY == 6))
+  {
+    theTileNumberX = 6;
+  }
+  else if ((aSizeX % 2 == 0) && (aSizeY % 3 == 0) && (aSizeX / 2 == aSizeY / 3))
+  {
+    theTileNumberX = 2;
+  }
+  else if ((aSizeX % 3 == 0) && (aSizeY % 2 == 0) && (aSizeX / 3 == aSizeY / 2))
+  {
+    theTileNumberX = 3;
+  }
+  else
+  {
+    return Standard_False;
+  }
+
+  return Standard_True;
+}
+
+// =======================================================================
+// function : tryLoadImage
+// purpose  :
+// =======================================================================
+void Graphic3d_CubeMapPacked::tryLoadImage (const TCollection_AsciiString& theFilePath)
+{
+  Handle(Image_AlienPixMap) anImage = new Image_AlienPixMap;
+  if (anImage->Load (theFilePath))
+  {
+    if (checkImage (anImage, myTileNumberX))
+    {
+      myPixMap = anImage;
+    }
+  }
+}
diff --git a/src/Graphic3d/Graphic3d_CubeMapPacked.hxx b/src/Graphic3d/Graphic3d_CubeMapPacked.hxx
new file mode 100644 (file)
index 0000000..4a6da46
--- /dev/null
@@ -0,0 +1,71 @@
+// Author: Ilya Khramov
+// Copyright (c) 2019 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_CubeMapPacked_HeaderFile
+#define _Graphic3d_CubeMapPacked_HeaderFile
+
+#include <Graphic3d_CubeMap.hxx>
+#include <NCollection_Array1.hxx>
+#include <OSD_Path.hxx>
+
+//! Class is intended to process cubemap packed into single image plane.
+class Graphic3d_CubeMapPacked : public Graphic3d_CubeMap
+{
+  DEFINE_STANDARD_RTTIEXT(Graphic3d_CubeMapPacked, Graphic3d_CubeMap)
+public:
+
+  //! Initialization to load cubemef from file.
+  //! @theFileName - path to the cubemap image
+  //! @theOrder - array conaining six different indexes of cubemap sides which maps tile grid to cubemap sides
+  Standard_EXPORT Graphic3d_CubeMapPacked (const TCollection_AsciiString&        theFileName,
+                                           const Graphic3d_ValidatedCubeMapOrder theOrder = Graphic3d_CubeMapOrder::Default());
+
+  //! Initialization to set cubemap directly by PixMap.
+  //! @thePixMap - origin PixMap
+  //! @theOrder - array conaining six different indexes of cubemap sides which maps tile grid to cubemap sides
+  Standard_EXPORT Graphic3d_CubeMapPacked (const Handle(Image_PixMap)&           theImage,
+                                           const Graphic3d_ValidatedCubeMapOrder theOrder = Graphic3d_CubeMapOrder::Default());
+
+  //! Returns current cubemap side as PixMap.
+  //! Resulting PixMap is memory wrapper over original image.
+  //! Returns null handle if current side or whole cubemap is invalid.
+  //! Origin image has to contain six quad tiles having one sizes without any gaps to be valid.  
+  Standard_EXPORT Handle(Image_PixMap) Value() Standard_OVERRIDE;
+
+  //! Empty destructor.
+  ~Graphic3d_CubeMapPacked() {}
+
+private:
+
+  //! Checks whether given tiles order is valid.
+  static Standard_Boolean checkOrder (const NCollection_Array1<unsigned int>& theOrder);
+
+  //! Checks whether given pixmap is valid to contain six tiles.
+  static Standard_Boolean checkImage (const Handle(Image_PixMap)& theImage,
+                                      unsigned int&               theTileNumberX);
+
+  //! Tries to load image from file and checks it after that.
+  //! Does nothing in case of fail.
+  void tryLoadImage (const TCollection_AsciiString &theFilePath);
+
+protected:
+
+  Graphic3d_CubeMapOrder myOrder;       //!< order mapping tile grit to cubemap sides
+  unsigned int           myTileNumberX; //!< width of tile grid
+
+};
+
+DEFINE_STANDARD_HANDLE(Graphic3d_CubeMapPacked, Graphic3d_CubeMap)
+
+#endif // _Graphic3d_CubeMapPacked_HeaderFile
diff --git a/src/Graphic3d/Graphic3d_CubeMapSeparate.cxx b/src/Graphic3d/Graphic3d_CubeMapSeparate.cxx
new file mode 100644 (file)
index 0000000..6c9c2bf
--- /dev/null
@@ -0,0 +1,185 @@
+// Author: Ilya Khramov
+// Copyright (c) 2019 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_CubeMapSeparate.hxx>
+#include <Image_AlienPixMap.hxx>
+#include <Message.hxx>
+#include <Message_Messenger.hxx>
+#include <OSD_File.hxx>
+
+IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_CubeMapSeparate, Graphic3d_CubeMap)
+
+// =======================================================================
+// function : Graphic3d_CubeMapSeparate
+// purpose  :
+// =======================================================================
+Graphic3d_CubeMapSeparate::Graphic3d_CubeMapSeparate (const NCollection_Array1<TCollection_AsciiString>& thePaths)
+{
+  if (thePaths.Size() == 6)
+  {
+    for (unsigned int i = 0; i < 6; ++i)
+    {
+      myPaths[i] = thePaths[i];
+    }
+  }
+  else
+  {
+    throw Standard_Failure("Invalid number of paths to load Graphic3d_CubeMapSeparate");
+  }
+}
+
+// =======================================================================
+// function : Graphic3d_CubeMapSeparate
+// purpose  :
+// =======================================================================
+Graphic3d_CubeMapSeparate::Graphic3d_CubeMapSeparate (const NCollection_Array1<Handle(Image_PixMap)>& theImages)
+{
+  if (theImages.Size() == 6)
+  {
+    if (theImages[0].IsNull())
+    {
+      return;
+    }
+
+    if (theImages[0]->SizeX() != theImages[0]->SizeY())
+    {
+      return;
+    }
+
+    myImages[0] = theImages[0];
+    myIsTopDown = myImages[0]->IsTopDown();
+
+    for (unsigned int i = 1; i < 6; ++i)
+    {
+      if (!theImages[i].IsNull())
+      {
+        if (theImages[i]->SizeX() == myImages[0]->SizeX()
+         && theImages[i]->SizeY() == myImages[0]->SizeY()
+         && theImages[i]->Format() == myImages[0]->Format()
+         && theImages[i]->IsTopDown() == myImages[0]->IsTopDown())
+        {
+          myImages[i] = theImages[i];
+          continue;
+        }
+      }
+      resetImages();
+      return;
+    }
+  }
+  else
+  {
+    throw Standard_Failure("Invalid number of images in Graphic3d_CubeMapSeparate initialization");
+  }
+}
+
+// =======================================================================
+// function : Value
+// purpose  :
+// =======================================================================
+Handle(Image_PixMap) Graphic3d_CubeMapSeparate::Value()
+{
+  Graphic3d_CubeMapOrder anOrder = Graphic3d_CubeMapOrder::Default();
+  if (!myIsTopDown)
+  {
+    anOrder.Swap(Graphic3d_CMS_POS_Y, Graphic3d_CMS_NEG_Y);
+  }
+
+  if (!myImages[anOrder[myCurrentSide]].IsNull())
+  {
+    return myImages[anOrder[myCurrentSide]];
+  }
+  else
+  {
+    TCollection_AsciiString aFilePath;
+    myPaths[anOrder[myCurrentSide]].SystemName(aFilePath);
+    if (!aFilePath.IsEmpty())
+    {
+      Handle(Image_AlienPixMap) anImage = new Image_AlienPixMap;
+      if (anImage->Load(aFilePath))
+      {
+        if (anImage->SizeX() == anImage->SizeY())
+        {
+          if (myCurrentSide == 0)
+          {
+            mySize =   anImage->SizeX();
+            myFormat = anImage->Format();
+            myIsTopDown = anImage->IsTopDown();
+            return anImage;
+          }
+          else
+          {
+            if (anImage->Format() == myFormat
+             && anImage->SizeX() == mySize
+             && anImage->IsTopDown() == myIsTopDown)
+            {
+              return anImage;
+            }
+            else
+            {
+              Message::DefaultMessenger()->Send(TCollection_AsciiString() +
+                "'" + aFilePath + "' inconsistent image format or dimension in Graphic3d_CubeMapSeparate");
+            }
+          }
+        }
+      }
+      else
+      {
+        Message::DefaultMessenger()->Send(TCollection_AsciiString() +
+          "Unable to load '" + aFilePath + "' image of Graphic3d_CubeMapSeparate");
+      }
+    }
+    else
+    {
+      Message::DefaultMessenger()->Send(TCollection_AsciiString() +
+        "[" + myCurrentSide + "] path of Graphic3d_CubeMapSeparate is invalid");
+    }
+  }
+
+  return Handle(Image_PixMap)();
+}
+
+// =======================================================================
+// function : IsDone
+// purpose  :
+// =======================================================================
+Standard_Boolean Graphic3d_CubeMapSeparate::IsDone() const
+{
+  if (!myImages[0].IsNull())
+  {
+    return Standard_True;
+  }
+
+  for (unsigned int i = 0; i < 6; ++i)
+  {
+    OSD_File aCubeMapFile(myPaths[i]);
+    if (!aCubeMapFile.Exists())
+    {
+      return Standard_False;
+    }
+  }
+
+  return Standard_True;
+}
+
+// =======================================================================
+// function : resetImages
+// purpose  :
+// =======================================================================
+void Graphic3d_CubeMapSeparate::resetImages()
+{
+  for (unsigned int i = 0; i < 6; ++i)
+  { 
+    myImages[i].Nullify();
+  }
+}
diff --git a/src/Graphic3d/Graphic3d_CubeMapSeparate.hxx b/src/Graphic3d/Graphic3d_CubeMapSeparate.hxx
new file mode 100644 (file)
index 0000000..6f0012d
--- /dev/null
@@ -0,0 +1,71 @@
+// Author: Ilya Khramov
+// Copyright (c) 2019 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_CubeMapSeparate_HeaderFile
+#define _Graphic3d_CubeMapSeparate_HeaderFile
+
+#include <Graphic3d_CubeMap.hxx>
+#include <NCollection_Array1.hxx>
+#include <OSD_Path.hxx>
+
+//! Class to manage cubemap located in six different images.
+class Graphic3d_CubeMapSeparate : public Graphic3d_CubeMap
+{
+  DEFINE_STANDARD_RTTIEXT(Graphic3d_CubeMapSeparate, Graphic3d_CubeMap)
+public:
+
+  //! Initializes cubemap to be loaded from file.
+  //! @thePaths - array of paths to separate image files (has to have size equal 6).
+  Standard_EXPORT Graphic3d_CubeMapSeparate (const NCollection_Array1<TCollection_AsciiString>& thePaths);
+
+  //! Initializes cubemap to be setted directly from PixMaps.
+  //! @theImages - array if PixMaps (has to have size equal 6).
+  Standard_EXPORT Graphic3d_CubeMapSeparate(const NCollection_Array1<Handle(Image_PixMap)>& theImages);
+
+  //! Returns current side of cubemap as PixMap.
+  //! Returns null handle if current side or whole cubemap is invalid.
+  //! All origin images have to have the same sizes, format and quad shapes to form valid cubemap.
+  Standard_EXPORT Handle(Image_PixMap) Value() Standard_OVERRIDE;
+
+  //! Returns NULL.
+  virtual Handle(Image_PixMap) GetImage() const Standard_OVERRIDE
+  {
+    return Handle(Image_PixMap)();
+  }
+
+  //! Checks if a texture class is valid or not.
+  //! Returns true if the construction of the class is correct.
+  Standard_EXPORT Standard_Boolean IsDone() const Standard_OVERRIDE;
+
+  //! Empty destructor.
+  ~Graphic3d_CubeMapSeparate() {}
+
+protected:
+
+  OSD_Path             myPaths[6];  //!< array of paths to cubemap images
+  Handle(Image_PixMap) myImages[6]; //!< array of cubemap images
+
+  Standard_Size        mySize;      //!< size of each side of cubemap
+  Image_Format         myFormat;    //!< format each side of cubemap
+
+private:
+
+  //! Nulifies whole images array.
+  void resetImages();
+
+};
+
+DEFINE_STANDARD_HANDLE(Graphic3d_CubeMapSeparate, Graphic3d_CubeMap)
+
+#endif // _Graphic3d_CubeMapSeparate_HeaderFile
diff --git a/src/Graphic3d/Graphic3d_CubeMapSide.hxx b/src/Graphic3d/Graphic3d_CubeMapSide.hxx
new file mode 100644 (file)
index 0000000..8495f64
--- /dev/null
@@ -0,0 +1,29 @@
+// Author: Ilya Khramov
+// Copyright (c) 2019 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_CubeMapSide_HeaderFile
+#define _Graphic3d_CubeMapSide_HeaderFile
+
+//! Sides of cubemap in order of OpenGL rules
+enum Graphic3d_CubeMapSide
+{
+  Graphic3d_CMS_POS_X, //!< X axis positive direction side
+  Graphic3d_CMS_NEG_X, //!< X axis negative direction side
+  Graphic3d_CMS_POS_Y, //!< Y axis positive direction side
+  Graphic3d_CMS_NEG_Y, //!< Y axis negative direction side
+  Graphic3d_CMS_POS_Z, //!< Z axis positive direction side
+  Graphic3d_CMS_NEG_Z, //!< Z axis negative direction side
+};
+
+#endif // _Graphic3d_CubeMapSide_HeaderFile
index c587f68..477147b 100644 (file)
@@ -40,6 +40,8 @@ enum Graphic3d_TextureUnit
   //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
+
+  Graphic3d_TextureUnit_EnvMap = Graphic3d_TextureUnit_0  //!< environment cubemap for background
 };
 enum
 {
index 52db76b..d537cdd 100644 (file)
 //! Describes type of view background.
 enum Graphic3d_TypeOfBackground
 {
-Graphic3d_TOB_NONE,
+Graphic3d_TOB_NONE = -1,
 Graphic3d_TOB_GRADIENT,
-Graphic3d_TOB_TEXTURE
+Graphic3d_TOB_TEXTURE,
+Graphic3d_TOB_CUBEMAP
+};
+
+enum
+{
+  Graphic3d_TypeOfBackground_NB = Graphic3d_TOB_CUBEMAP + 1
 };
 
 #endif // _Graphic3d_TypeOfBackground_HeaderFile
index d482830..c457e94 100644 (file)
@@ -22,7 +22,8 @@ enum Graphic3d_TypeOfTexture
 {
 Graphic3d_TOT_1D,
 Graphic3d_TOT_2D,
-Graphic3d_TOT_2D_MIPMAP
+Graphic3d_TOT_2D_MIPMAP,
+Graphic3d_TOT_CUBEMAP
 };
 
 #endif // _Graphic3d_TypeOfTexture_HeaderFile
index ac3906f..2ad9729 100644 (file)
@@ -206,12 +206,10 @@ void OpenGl_AspectsTextureSet::build (const Handle(OpenGl_Context)& theCtx,
          &&  aTexture->GetId()    == aResource->ResourceId()
          &&  aTexture->Revision() != aResource->Revision())
         {
-          if (Handle(Image_PixMap) anImage = aTexture->GetImage())
+          if (aResource->Init(theCtx, aTexture))
           {
-            aResource->Sampler()->SetParameters (aTexture->GetParams());
-            aResource->Init (theCtx, *anImage.operator->(), aTexture->Type());
+            aResource->Sampler()->SetParameters(aTexture->GetParams());
             aResource->SetRevision (aTexture->Revision());
-            continue;
           }
         }
 
@@ -235,9 +233,9 @@ void OpenGl_AspectsTextureSet::build (const Handle(OpenGl_Context)& theCtx,
         || !theCtx->GetResource<Handle(OpenGl_Texture)> (aTextureKeyNew, aResource))
         {
           aResource = new OpenGl_Texture (aTextureKeyNew, aTexture->GetParams());
-          if (Handle(Image_PixMap) anImage = aTexture->GetImage())
+
+          if (aResource->Init(theCtx, aTexture))
           {
-            aResource->Init (theCtx, *anImage.operator->(), aTexture->Type());
             aResource->SetRevision (aTexture->Revision());
           }
           if (!aTextureKeyNew.IsEmpty())
@@ -249,9 +247,8 @@ void OpenGl_AspectsTextureSet::build (const Handle(OpenGl_Context)& theCtx,
         {
           if (aTexture->Revision() != aResource->Revision())
           {
-            if (Handle(Image_PixMap) anImage = aTexture->GetImage())
+            if (aResource->Init(theCtx, aTexture))
             {
-              aResource->Init (theCtx, *anImage.operator->(), aTexture->Type());
               aResource->SetRevision (aTexture->Revision());
             }
           }
index fb6f660..cf49fe1 100644 (file)
@@ -119,6 +119,7 @@ bool OpenGl_BackgroundArray::IsDefined() const
   {
     case Graphic3d_TOB_GRADIENT: return myGradientParams.type != Aspect_GFM_NONE;
     case Graphic3d_TOB_TEXTURE:  return myFillMethod          != Aspect_FM_NONE;
+    case Graphic3d_TOB_CUBEMAP:  return Standard_True;
     case Graphic3d_TOB_NONE:     return Standard_False;
   }
   return Standard_False;
@@ -157,6 +158,14 @@ Standard_Boolean OpenGl_BackgroundArray::init (const Handle(OpenGl_Workspace)& t
       }
       break;
     }
+    case Graphic3d_TOB_CUBEMAP:
+    {
+      if (!createCubeMapArray())
+      {
+        return Standard_False;
+      }
+      break;
+    }
     case Graphic3d_TOB_NONE:
     default:
     {
@@ -378,7 +387,33 @@ Standard_Boolean OpenGl_BackgroundArray::createTextureArray (const Handle(OpenGl
 }
 
 // =======================================================================
-// method  : createTextureArray
+// method  : createCubeMapArray
+// purpose :
+// =======================================================================
+Standard_Boolean OpenGl_BackgroundArray::createCubeMapArray() const
+{
+  Graphic3d_Attribute aCubeMapAttribInfo[] =
+  {
+    { Graphic3d_TOA_POS, Graphic3d_TOD_VEC2}
+  };
+
+  if (!myAttribs->Init(4, aCubeMapAttribInfo, 1))
+  {
+    return Standard_False;
+  }
+
+  OpenGl_Vec2* aData = reinterpret_cast<OpenGl_Vec2*>(myAttribs->changeValue(0));
+
+  for (unsigned int i = 0; i < 4; ++i)
+  {
+    aData[i] = (OpenGl_Vec2(Standard_ShortReal(i / 2), Standard_ShortReal(i % 2)) - OpenGl_Vec2(0.5f)) * 2.f;
+  }
+
+  return Standard_True;
+}
+
+// =======================================================================
+// method  : Render
 // purpose :
 // =======================================================================
 void OpenGl_BackgroundArray::Render (const Handle(OpenGl_Workspace)& theWorkspace) const
@@ -402,8 +437,12 @@ void OpenGl_BackgroundArray::Render (const Handle(OpenGl_Workspace)& theWorkspac
 
   OpenGl_Mat4 aProjection = aCtx->ProjectionState.Current();
   OpenGl_Mat4 aWorldView  = aCtx->WorldViewState.Current();
-  myTrsfPers.Apply (theWorkspace->View()->Camera(), aProjection, aWorldView,
-                    aCtx->Viewport()[2], aCtx->Viewport()[3]);
+
+  if (myType != Graphic3d_TOB_CUBEMAP)
+  {
+    myTrsfPers.Apply(theWorkspace->View()->Camera(), aProjection, aWorldView,
+      aCtx->Viewport()[2], aCtx->Viewport()[3]);
+  }
 
   aCtx->ProjectionState.Push();
   aCtx->WorldViewState.Push();
index 0078aa7..65e2b4a 100644 (file)
@@ -85,6 +85,9 @@ protected:
   //! @param theWorkspace OpenGl workspace that stores texture in the current enabled face aspect.
   Standard_EXPORT Standard_Boolean createTextureArray (const Handle(OpenGl_Workspace)& theWorkspace) const;
 
+  //! Initializes cubemap arrays.
+  Standard_EXPORT Standard_Boolean createCubeMapArray() const;
+
   //! Marks array parameters as changed,
   //! on next rendering stage array data is to be updated.
   Standard_EXPORT void invalidateData();
index 2ee0420..4bc3ab1 100644 (file)
@@ -2677,6 +2677,53 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramBoundBox()
 }
 
 // =======================================================================
+// function : GetBgCubeMapProgram
+// purpose  :
+// =======================================================================
+const Handle(Graphic3d_ShaderProgram)& OpenGl_ShaderManager::GetBgCubeMapProgram ()
+{
+  if (myBgCubeMapProgram.IsNull())
+  {
+    myBgCubeMapProgram = new Graphic3d_ShaderProgram;
+
+    OpenGl_ShaderObject::ShaderVariableList aUniforms, aStageInOuts;
+    aStageInOuts.Append (OpenGl_ShaderObject::ShaderVariable("vec3 ViewDirection", Graphic3d_TOS_VERTEX | Graphic3d_TOS_FRAGMENT));
+    aUniforms.Append (OpenGl_ShaderObject::ShaderVariable ("int uZCoeff", Graphic3d_TOS_VERTEX)); // defines orientation of Z axis to make horizontal flip
+    aUniforms.Append (OpenGl_ShaderObject::ShaderVariable ("int uYCoeff", Graphic3d_TOS_VERTEX)); // defines orientation of Y axis to make vertical flip
+    aUniforms.Append (OpenGl_ShaderObject::ShaderVariable ("samplerCube occSampler0", Graphic3d_TOS_FRAGMENT));
+
+    TCollection_AsciiString aSrcVert =
+      EOL"void main()"
+      EOL"{"
+      EOL"  vec4 aViewDirection = occProjectionMatrixInverse * vec4(occVertex.xy, 0.0, 1.0);"
+      EOL"  aViewDirection /= aViewDirection.w;"
+      EOL"  aViewDirection.w = 0.0;"
+      EOL"  ViewDirection = normalize((occWorldViewMatrixInverse * aViewDirection).xyz);"
+      EOL"  ViewDirection = ViewDirection.yzx;" // is needed to sync horizon and frontal camera position
+      EOL"  ViewDirection.y *= uYCoeff;"
+      EOL"  ViewDirection.z *= uZCoeff;"
+      EOL"  gl_Position = vec4(occVertex.xy, 0.0, 1.0);"
+      EOL"}";
+
+    TCollection_AsciiString aSrcFrag =
+      EOL"#define occEnvCubemap occSampler0"
+      EOL"void main()"
+      EOL"{"
+      EOL"  occSetFragColor (vec4(texture(occEnvCubemap, ViewDirection).rgb, 1.0));"
+      EOL"}";
+
+    defaultGlslVersion(myBgCubeMapProgram, "background_cubemap", 0);
+    myBgCubeMapProgram->SetDefaultSampler(false);
+    myBgCubeMapProgram->SetNbLightsMax(0);
+    myBgCubeMapProgram->SetNbClipPlanesMax(0);
+    myBgCubeMapProgram->AttachShader(OpenGl_ShaderObject::CreateFromSource(aSrcVert, Graphic3d_TOS_VERTEX, aUniforms, aStageInOuts));
+    myBgCubeMapProgram->AttachShader(OpenGl_ShaderObject::CreateFromSource(aSrcFrag, Graphic3d_TOS_FRAGMENT, aUniforms, aStageInOuts));
+  }
+
+  return myBgCubeMapProgram;
+}
+
+// =======================================================================
 // function : bindProgramWithState
 // purpose  :
 // =======================================================================
index ec3661f..be560c0 100644 (file)
@@ -251,6 +251,9 @@ public:
   //! Returns bounding box vertex buffer.
   const Handle(OpenGl_VertexBuffer)& BoundBoxVertBuffer() const { return myBoundBoxVertBuffer; }
 
+  //! Generates shader program to render environment cubemap as background.
+  Standard_EXPORT const Handle(Graphic3d_ShaderProgram)& GetBgCubeMapProgram ();
+
 public:
 
   //! Returns current state of OCCT light sources.
@@ -765,6 +768,8 @@ protected:
   Handle(OpenGl_ShaderProgram)       myOitCompositingProgram[2]; //!< standard program for OIT compositing (default and MSAA).
   OpenGl_MapOfShaderPrograms         myMapOfLightPrograms; //!< map of lighting programs depending on lights configuration
 
+  Handle(Graphic3d_ShaderProgram)    myBgCubeMapProgram;   //!< program for background cubemap rendering
+
   Handle(OpenGl_ShaderProgram)       myStereoPrograms[Graphic3d_StereoMode_NB]; //!< standard stereo programs
 
   Handle(OpenGl_VertexBuffer)        myBoundBoxVertBuffer; //!< bounding box vertex buffer
index a87bb9f..6a354d1 100644 (file)
@@ -182,7 +182,7 @@ bool OpenGl_Texture::InitSamplerObject (const Handle(OpenGl_Context)& theCtx)
 //purpose  :
 //=======================================================================
 bool OpenGl_Texture::GetDataFormat (const Handle(OpenGl_Context)& theCtx,
-                                    const Image_PixMap&           theData,
+                                    const Image_Format            theFormat,
                                     GLint&                        theTextFormat,
                                     GLenum&                       thePixelFormat,
                                     GLenum&                       theDataType)
@@ -190,7 +190,7 @@ bool OpenGl_Texture::GetDataFormat (const Handle(OpenGl_Context)& theCtx,
   theTextFormat  = GL_RGBA8;
   thePixelFormat = 0;
   theDataType    = 0;
-  switch (theData.Format())
+  switch (theFormat)
   {
     case Image_Format_GrayF:
     {
@@ -733,6 +733,12 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx,
       Unbind (theCtx);
       return true;
     }
+    case Graphic3d_TOT_CUBEMAP:
+    {
+      Unbind (theCtx);
+      Release (theCtx.get());
+      return false;
+    }
   }
 
   Release (theCtx.operator->());
@@ -770,6 +776,36 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx,
 }
 
 // =======================================================================
+// function : Init
+// purpose  :
+// =======================================================================
+bool OpenGl_Texture::Init (const Handle(OpenGl_Context)&       theCtx,
+                           const Handle(Graphic3d_TextureMap)& theTextureMap)
+{
+  if (theTextureMap.IsNull())
+  {
+    return false;
+  }
+
+  switch (theTextureMap->Type())
+  {
+    case Graphic3d_TOT_CUBEMAP:
+    {
+      return InitCubeMap (theCtx, Handle(Graphic3d_CubeMap)::DownCast(theTextureMap));
+    }
+    default:
+    {
+      Handle(Image_PixMap) anImage = theTextureMap->GetImage();
+      if (anImage.IsNull())
+      {
+        return false;
+      }
+      return Init (theCtx, *anImage, theTextureMap->Type());
+    }
+  }
+}
+
+// =======================================================================
 // function : Init2DMultisample
 // purpose  :
 // =======================================================================
@@ -998,6 +1034,141 @@ bool OpenGl_Texture::Init3D (const Handle(OpenGl_Context)& theCtx,
 }
 
 // =======================================================================
+// function : InitCubeMap
+// purpose  :
+// =======================================================================
+bool OpenGl_Texture::InitCubeMap (const Handle(OpenGl_Context)&    theCtx,
+                                  const Handle(Graphic3d_CubeMap)& theCubeMap,
+                                  Standard_Size                    theSize,
+                                  Image_Format                     theFormat,
+                                  Standard_Boolean                 theToGenMipmap)
+{
+  if (!Create (theCtx))
+  {
+    Release (theCtx.get());
+    return false;
+  }
+
+  if (!theCubeMap.IsNull())
+  {
+    Handle(Image_PixMap) anImage = theCubeMap->Reset().Value();
+    if (!anImage.IsNull())
+    {
+      theSize   = anImage->SizeX();
+      theFormat = anImage->Format();
+    }
+    else
+    {
+      theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
+        "Unable to get the first side of cubemap");
+      Release(theCtx.get());
+      return false;
+    }
+  }
+
+  GLenum aPixelFormat = GL_RGB;
+  GLenum aDataType = 0;
+  GLint aTextFormat = 0;
+
+  if (!GetDataFormat (theCtx, theFormat, aTextFormat, aPixelFormat, aDataType))
+  {
+    Unbind(theCtx);
+    Release(theCtx.get());
+    return false;
+  }
+
+  myTarget = GL_TEXTURE_CUBE_MAP;
+  myHasMipmaps = theToGenMipmap;
+  myNbSamples = 1;
+  Bind (theCtx);
+  applyDefaultSamplerParams (theCtx);
+
+  for (Standard_Integer i = 0; i < 6; ++i)
+  {
+    const void* aData = NULL;
+    Handle(Image_PixMap) anImage;
+
+    if (!theCubeMap.IsNull())
+    {
+      anImage = theCubeMap->Value();
+      if (!anImage.IsNull())
+      {
+#if !defined(GL_ES_VERSION_2_0)
+        const GLint anAligment = Min ((GLint)anImage->MaxRowAligmentBytes(), 8); // OpenGL supports alignment upto 8 bytes
+        glPixelStorei (GL_UNPACK_ALIGNMENT, anAligment);
+
+        // notice that GL_UNPACK_ROW_LENGTH is not available on OpenGL ES 2.0 without GL_EXT_unpack_subimage extension
+        const GLint anExtraBytes = GLint(anImage->RowExtraBytes());
+        const GLint aPixelsWidth = GLint(anImage->SizeRowBytes() / anImage->SizePixelBytes());
+        const GLint aRowLength = (anExtraBytes >= anAligment) ? aPixelsWidth : 0;
+        glPixelStorei (GL_UNPACK_ROW_LENGTH, aRowLength);
+#else
+        Handle(Image_PixMap) aCopyImage = new Image_PixMap();
+        aCopyImage->InitTrash (theFormat, theSize, theSize);
+        for (unsigned int y = 0; y < theSize; ++y)
+        {
+          for (unsigned int x = 0; x < theSize; ++x)
+          {
+            for (unsigned int aByte = 0; aByte < anImage->SizePixelBytes(); ++aByte)
+            {
+              aCopyImage->ChangeRawValue (y, x)[aByte] = anImage->RawValue (y, x)[aByte];
+            }
+          }
+        }
+        anImage = aCopyImage;
+        const GLint anAligment = Min((GLint)anImage->MaxRowAligmentBytes(), 8); // OpenGL supports alignment upto 8 bytes
+        glPixelStorei (GL_UNPACK_ALIGNMENT, anAligment);
+#endif
+        aData = anImage->Data();
+      }
+      else
+      {
+        theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, TCollection_AsciiString() +
+          "Unable to get [" + i + "] side of cubemap");
+        Unbind (theCtx);
+        Release (theCtx.get());
+        return false;
+      }
+      theCubeMap->Next();
+    }
+
+    glTexImage2D (GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0,
+                  aTextFormat,
+                  GLsizei(theSize), GLsizei(theSize),
+                  0, aPixelFormat, aDataType,
+                  aData);
+
+    OpenGl_UnpackAlignmentSentry::Reset();
+
+    if (glGetError() != GL_NO_ERROR)
+    {
+      theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
+        "Unable to initialize side of cubemap");
+      Unbind (theCtx);
+      Release (theCtx.get());
+      return false;
+    }
+  }
+
+  if (theToGenMipmap && theCtx->arbFBO != NULL)
+  {
+      theCtx->arbFBO->glGenerateMipmap (myTarget);
+
+      if (glGetError() != GL_NO_ERROR)
+      {
+        theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
+          "Unable to generate mipmap of cubemap");
+        Unbind(theCtx);
+        Release(theCtx.get());
+        return false;
+      }
+  }
+
+  Unbind (theCtx.get());
+  return true;
+}
+
+// =======================================================================
 // function : PixelSizeOfPixelFormat
 // purpose  :
 // =======================================================================
index 7943dad..9b0061a 100644 (file)
 #ifndef _OpenGl_Texture_H__
 #define _OpenGl_Texture_H__
 
+#include <Graphic3d_CubeMap.hxx>
 #include <OpenGl_GlCore13.hxx>
 #include <OpenGl_NamedResource.hxx>
 #include <OpenGl_Sampler.hxx>
-#include <Graphic3d_TypeOfTexture.hxx>
 #include <Graphic3d_TextureUnit.hxx>
+#include <Graphic3d_TypeOfTexture.hxx>
 
 class Graphic3d_TextureParams;
 class Image_PixMap;
@@ -422,6 +423,12 @@ public:
                              const Graphic3d_TypeOfTexture theType,
                              const Image_PixMap*           theImage = NULL);
 
+  //! Initialize the texture with Graphic3d_TextureMap.
+  //! It is an universal way to initialize.
+  //! Sitable initialization method will be chosen. 
+  Standard_EXPORT bool Init (const Handle(OpenGl_Context)&       theCtx,
+                             const Handle(Graphic3d_TextureMap)& theTextureMap);
+
   //! Initialize the 2D multisampling texture using glTexImage2DMultisample().
   Standard_EXPORT bool Init2DMultisample (const Handle(OpenGl_Context)& theCtx,
                                           const GLsizei                 theNbSamples,
@@ -446,16 +453,47 @@ public:
                                const Standard_Integer        theSizeZ,
                                const void*                   thePixels);
 
+  //! Initializes 6 sides of cubemap.
+  //! If theCubeMap is not NULL then size and format will be taken from it
+  //! and corresponding arguments will be ignored.
+  //! Otherwise this parametres will be taken from arguments.
+  //! theToGenMipmap allows to generate mipmaped cubemap.
+  Standard_EXPORT bool InitCubeMap (const Handle(OpenGl_Context)&    theCtx,
+                                    const Handle(Graphic3d_CubeMap)& theCubeMap,
+                                    Standard_Size                    theSize = 0,
+                                    Image_Format                     theFormat = Image_Format_RGB,
+                                    Standard_Boolean                 theToGenMipmap = Standard_False);
+
+  //! The same InitCubeMap but there is another order of arguments.
+  bool InitCubeMap (const Handle(OpenGl_Context)&    theCtx,
+                    const Handle(Graphic3d_CubeMap)& theCubeMap,
+                    Standard_Boolean                 theToGenMipmap,
+                    Standard_Size                    theSize = 0,
+                    Image_Format                     theFormat = Image_Format_RGB)
+  {
+    return InitCubeMap (theCtx, theCubeMap, theSize, theFormat, theToGenMipmap);
+  }
+
   //! @return true if texture was generated within mipmaps
   Standard_Boolean HasMipmaps() const { return myHasMipmaps; }
 
-  //! Return texture type and format by Image_PixMap data format.
+  //! Return texture type and format by Image_Format.
   Standard_EXPORT static bool GetDataFormat (const Handle(OpenGl_Context)& theCtx,
-                                             const Image_PixMap&           theData,
+                                             const Image_Format            theFromat,
                                              GLint&                        theTextFormat,
                                              GLenum&                       thePixelFormat,
                                              GLenum&                       theDataType);
 
+  //! Return texture type and format by Image_PixMap data format.
+  static bool GetDataFormat (const Handle(OpenGl_Context)& theCtx,
+                             const Image_PixMap&           theData,
+                             GLint&                        theTextFormat,
+                             GLenum&                       thePixelFormat,
+                             GLenum&                       theDataType)
+  {
+    return GetDataFormat (theCtx, theData.Format(), theTextFormat, thePixelFormat, theDataType);
+  }
+
   //! Returns estimated GPU memory usage for holding data without considering overheads and allocation alignment rules.
   Standard_EXPORT virtual Standard_Size EstimatedDataSize() const Standard_OVERRIDE;
 
index b4b9966..17f44ef 100644 (file)
@@ -69,8 +69,8 @@ OpenGl_View::OpenGl_View (const Handle(Graphic3d_StructureManager)& theMgr,
   myBackBufferRestored   (Standard_False),
   myIsImmediateDrawn     (Standard_False),
   myTextureParams   (new OpenGl_Aspects()),
-  myBgGradientArray (new OpenGl_BackgroundArray (Graphic3d_TOB_GRADIENT)),
-  myBgTextureArray  (new OpenGl_BackgroundArray (Graphic3d_TOB_TEXTURE)),
+  myCubeMapParams   (new OpenGl_Aspects()),
+  myBackgroundType  (Graphic3d_TOB_NONE),
   // ray-tracing fields initialization
   myRaytraceInitStatus     (OpenGl_RT_NONE),
   myIsRaytraceDataValid    (Standard_False),
@@ -86,6 +86,11 @@ OpenGl_View::OpenGl_View (const Handle(Graphic3d_StructureManager)& theMgr,
   myPrevCameraApertureRadius(0.f),
   myPrevCameraFocalPlaneDist(0.f)
 {
+  for (int i = 0; i < Graphic3d_TypeOfBackground_NB; ++i)
+  {
+    myBackgrounds[i] = new OpenGl_BackgroundArray(Graphic3d_TypeOfBackground(i));
+  }
+
   myWorkspace = new OpenGl_Workspace (this, NULL);
 
   Handle(Graphic3d_CLight) aLight = new Graphic3d_CLight (Graphic3d_TOLS_AMBIENT);
@@ -117,9 +122,13 @@ OpenGl_View::OpenGl_View (const Handle(Graphic3d_StructureManager)& theMgr,
 OpenGl_View::~OpenGl_View()
 {
   ReleaseGlResources (NULL); // ensure ReleaseGlResources() was called within valid context
-  OpenGl_Element::Destroy (NULL, myBgGradientArray);
-  OpenGl_Element::Destroy (NULL, myBgTextureArray);
+  for (int i = 0; i < Graphic3d_TypeOfBackground_NB; ++i)
+  {
+    OpenGl_Element::Destroy(NULL, myBackgrounds[i]);
+  }
+
   OpenGl_Element::Destroy (NULL, myTextureParams);
+  OpenGl_Element::Destroy (NULL, myCubeMapParams);
 }
 
 // =======================================================================
@@ -148,13 +157,18 @@ void OpenGl_View::ReleaseGlResources (const Handle(OpenGl_Context)& theCtx)
   {
     myTextureParams->Release (theCtx.get());
   }
-  if (myBgGradientArray != NULL)
+
+  if (myCubeMapParams != NULL)
   {
-    myBgGradientArray->Release (theCtx.get());
+    myCubeMapParams->Release (theCtx.get());
   }
-  if (myBgTextureArray != NULL)
+
+  for (int i = 0; i < Graphic3d_TypeOfBackground_NB; ++i)
   {
-    myBgTextureArray->Release (theCtx.get());
+    if (myBackgrounds[i] != NULL)
+    {
+      myBackgrounds[i]->Release (theCtx.get());
+    }
   }
 
   myMainSceneFbos[0]        ->Release (theCtx.get());
@@ -416,13 +430,13 @@ Standard_Boolean OpenGl_View::BufferDump (Image_PixMap& theImage, const Graphic3
 Aspect_GradientBackground OpenGl_View::GradientBackground() const
 {
   Quantity_Color aColor1, aColor2;
-  aColor1.SetValues (myBgGradientArray->GradientColor (0).r(),
-                     myBgGradientArray->GradientColor (0).g(),
-                     myBgGradientArray->GradientColor (0).b(), Quantity_TOC_RGB);
-  aColor2.SetValues (myBgGradientArray->GradientColor (1).r(),
-                     myBgGradientArray->GradientColor (1).g(),
-                     myBgGradientArray->GradientColor (1).b(), Quantity_TOC_RGB);
-  return Aspect_GradientBackground (aColor1, aColor2, myBgGradientArray->GradientFillMethod());
+  aColor1.SetValues (myBackgrounds[Graphic3d_TOB_GRADIENT]->GradientColor (0).r(),
+                     myBackgrounds[Graphic3d_TOB_GRADIENT]->GradientColor (0).g(),
+                     myBackgrounds[Graphic3d_TOB_GRADIENT]->GradientColor (0).b(), Quantity_TOC_RGB);
+  aColor2.SetValues (myBackgrounds[Graphic3d_TOB_GRADIENT]->GradientColor (1).r(),
+                     myBackgrounds[Graphic3d_TOB_GRADIENT]->GradientColor (1).g(),
+                     myBackgrounds[Graphic3d_TOB_GRADIENT]->GradientColor (1).b(), Quantity_TOC_RGB);
+  return Aspect_GradientBackground (aColor1, aColor2, myBackgrounds[Graphic3d_TOB_GRADIENT]->GradientFillMethod());
 }
 
 // =======================================================================
@@ -433,7 +447,9 @@ void OpenGl_View::SetGradientBackground (const Aspect_GradientBackground& theBac
 {
   Quantity_Color aColor1, aColor2;
   theBackground.Colors (aColor1, aColor2);
-  myBgGradientArray->SetGradientParameters (aColor1, aColor2, theBackground.BgGradientFillMethod());
+  myBackgrounds[Graphic3d_TOB_GRADIENT]->SetGradientParameters (aColor1, aColor2, theBackground.BgGradientFillMethod());
+
+  myBackgroundType = Graphic3d_TOB_GRADIENT;
 }
 
 // =======================================================================
@@ -467,6 +483,8 @@ void OpenGl_View::SetBackgroundImage (const TCollection_AsciiString& theFilePath
 
   // Set texture parameters
   myTextureParams->SetAspect (anAspect);
+
+  myBackgroundType = Graphic3d_TOB_TEXTURE;
 }
 
 // =======================================================================
@@ -475,7 +493,7 @@ void OpenGl_View::SetBackgroundImage (const TCollection_AsciiString& theFilePath
 // =======================================================================
 Aspect_FillMethod OpenGl_View::BackgroundImageStyle() const
 {
-  return myBgTextureArray->TextureFillMethod();
+  return myBackgrounds[Graphic3d_TOB_TEXTURE]->TextureFillMethod();
 }
 
 // =======================================================================
@@ -484,7 +502,54 @@ Aspect_FillMethod OpenGl_View::BackgroundImageStyle() const
 // =======================================================================
 void OpenGl_View::SetBackgroundImageStyle (const Aspect_FillMethod theFillStyle)
 {
-  myBgTextureArray->SetTextureFillMethod (theFillStyle);
+  myBackgrounds[Graphic3d_TOB_TEXTURE]->SetTextureFillMethod (theFillStyle);
+}
+
+// =======================================================================
+// function : BackgroundCubeMap
+// purpose  :
+// =======================================================================
+Handle(Graphic3d_CubeMap) OpenGl_View::BackgroundCubeMap() const
+{
+  return myBackgroundCubeMap;
+}
+// =======================================================================
+// function : SetBackgroundCubeMap
+// purpose  :
+// =======================================================================
+void OpenGl_View::SetBackgroundCubeMap (const Handle(Graphic3d_CubeMap)& theCubeMap)
+{
+  myBackgroundCubeMap = theCubeMap;
+  Handle(Graphic3d_AspectFillArea3d) anAspect = new Graphic3d_AspectFillArea3d;
+  Handle(Graphic3d_TextureSet) aTextureSet = new Graphic3d_TextureSet (myBackgroundCubeMap);
+
+  anAspect->SetInteriorStyle(Aspect_IS_SOLID);
+  anAspect->SetSuppressBackFaces(false);
+  anAspect->SetTextureSet(aTextureSet);
+
+  const Handle(OpenGl_Context)& aCtx = myWorkspace->GetGlContext();
+  if (!aCtx.IsNull())
+  {
+    anAspect->SetShaderProgram (aCtx->ShaderManager()->GetBgCubeMapProgram());
+  }
+
+  if (theCubeMap->IsDone())
+  {
+    anAspect->SetTextureMapOn();
+  }
+  else
+  {
+    anAspect->SetTextureMapOff();
+  }
+
+  myCubeMapParams->SetAspect(anAspect);
+  const OpenGl_Aspects* anAspectsBackup = myWorkspace->SetAspects (myCubeMapParams);
+  myWorkspace->ApplyAspects();
+  myWorkspace->SetAspects (anAspectsBackup);
+  myWorkspace->ApplyAspects();
+
+  myBackgroundType = Graphic3d_TOB_CUBEMAP;
 }
 
 //=======================================================================
@@ -492,8 +557,8 @@ void OpenGl_View::SetBackgroundImageStyle (const Aspect_FillMethod theFillStyle)
 //purpose  :
 //=======================================================================
 void OpenGl_View::InsertLayerBefore (const Graphic3d_ZLayerId theLayerId,
-                                     const Graphic3d_ZLayerSettings& theSettings,
-                                     const Graphic3d_ZLayerId theLayerAfter)
+  const Graphic3d_ZLayerSettings& theSettings,
+  const Graphic3d_ZLayerId theLayerAfter)
 {
   myZLayers.InsertLayerBefore (theLayerId, theSettings, theLayerAfter);
 }
@@ -503,8 +568,8 @@ void OpenGl_View::InsertLayerBefore (const Graphic3d_ZLayerId theLayerId,
 //purpose  :
 //=======================================================================
 void OpenGl_View::InsertLayerAfter (const Graphic3d_ZLayerId theLayerId,
-                                    const Graphic3d_ZLayerSettings& theSettings,
-                                    const Graphic3d_ZLayerId theLayerBefore)
+  const Graphic3d_ZLayerSettings& theSettings,
+  const Graphic3d_ZLayerId theLayerBefore)
 {
   myZLayers.InsertLayerAfter (theLayerId, theSettings, theLayerBefore);
 }
@@ -580,8 +645,8 @@ Bnd_Box OpenGl_View::MinMaxValues (const Standard_Boolean theToIncludeAuxiliary)
 
   // add bounding box of gradient/texture background for proper Z-fit
   if (theToIncludeAuxiliary
-   && (myBgTextureArray->IsDefined()
-    || myBgGradientArray->IsDefined()))
+    && (myBackgrounds[Graphic3d_TOB_TEXTURE]->IsDefined()
+     || myBackgrounds[Graphic3d_TOB_GRADIENT]->IsDefined()))
   {
     const Handle(Graphic3d_Camera)& aCamera = Camera();
     Graphic3d_Vec2i aWinSize;
index 225bfe8..1b05ee7 100644 (file)
@@ -222,6 +222,12 @@ public:
   //! Sets background image fill style.
   Standard_EXPORT virtual void SetBackgroundImageStyle (const Aspect_FillMethod theFillStyle) Standard_OVERRIDE;
 
+  //! Returns cubemap being set last time on background.
+  Standard_EXPORT Handle(Graphic3d_CubeMap) BackgroundCubeMap() const Standard_OVERRIDE;
+
+  //! Sets environment cubemap as background.
+  Standard_EXPORT virtual void SetBackgroundCubeMap (const Handle(Graphic3d_CubeMap)& theCubeMap) Standard_OVERRIDE;
+
   //! Returns environment texture set for the view.
   virtual Handle(Graphic3d_TextureEnv) TextureEnv() const Standard_OVERRIDE { return myTextureEnvData; }
 
@@ -506,9 +512,11 @@ protected: //! @name Rendering properties
 
 protected: //! @name Background parameters
 
-  OpenGl_Aspects*         myTextureParams;   //!< Stores texture and its parameters for textured background
-  OpenGl_BackgroundArray* myBgGradientArray; //!< Primitive array for gradient background
-  OpenGl_BackgroundArray* myBgTextureArray;  //!< Primitive array for texture  background
+  OpenGl_Aspects*            myTextureParams;                     //!< Stores texture and its parameters for textured background
+  OpenGl_Aspects*            myCubeMapParams;                     //!< Stores cubemap and its parameters for cubemap background
+  Handle(Graphic3d_CubeMap)  myBackgroundCubeMap;                 //!< Cubemap has been setted as background
+  Graphic3d_TypeOfBackground myBackgroundType;                    //!< Current typy of background
+  OpenGl_BackgroundArray*    myBackgrounds[Graphic3d_TypeOfBackground_NB]; //!< Array of primitive arrays of different background types
 
 protected: //! @name data types related to ray-tracing
 
index 7f1cf49..33dec76 100644 (file)
@@ -2592,12 +2592,13 @@ Standard_Boolean OpenGl_View::setUniformState (const Standard_Integer        the
   }
 
   // Set background colors (only gradient background supported)
-  if (myBgGradientArray != NULL && myBgGradientArray->IsDefined())
+  if (myBackgrounds[Graphic3d_TOB_GRADIENT] != NULL
+   && myBackgrounds[Graphic3d_TOB_GRADIENT]->IsDefined())
   {
     theProgram->SetUniform (theGlContext,
-      myUniformLocations[theProgramId][OpenGl_RT_uBackColorTop], myBgGradientArray->GradientColor (0));
+      myUniformLocations[theProgramId][OpenGl_RT_uBackColorTop], myBackgrounds[Graphic3d_TOB_GRADIENT]->GradientColor (0));
     theProgram->SetUniform (theGlContext,
-      myUniformLocations[theProgramId][OpenGl_RT_uBackColorBot], myBgGradientArray->GradientColor (1));
+      myUniformLocations[theProgramId][OpenGl_RT_uBackColorBot], myBackgrounds[Graphic3d_TOB_GRADIENT]->GradientColor (1));
   }
   else
   {
index fa2877a..5f83913 100644 (file)
@@ -74,60 +74,76 @@ namespace
 void OpenGl_View::drawBackground (const Handle(OpenGl_Workspace)& theWorkspace)
 {
   const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext();
-
-  if (!myBgTextureArray->IsDefined()   // no texture
-   && !myBgGradientArray->IsDefined()) // no gradient
-  {
-    return;
-  }
-
   const Standard_Boolean wasUsedZBuffer = theWorkspace->SetUseZBuffer (Standard_False);
   if (wasUsedZBuffer)
   {
     aCtx->core11fwd->glDisable (GL_DEPTH_TEST);
   }
 
-  // Drawing background gradient if:
-  // - gradient fill type is not Aspect_GFM_NONE and
-  // - either background texture is no specified or it is drawn in Aspect_FM_CENTERED mode
-  if (myBgGradientArray->IsDefined()
-    && (!myTextureParams->Aspect()->ToMapTexture()
-      || myBgTextureArray->TextureFillMethod() == Aspect_FM_CENTERED
-      || myBgTextureArray->TextureFillMethod() == Aspect_FM_NONE))
+  if (myBackgroundType == Graphic3d_TOB_CUBEMAP)
   {
-  #if !defined(GL_ES_VERSION_2_0)
-    GLint aShadingModelOld = GL_SMOOTH;
-    if (aCtx->core11 != NULL
-     && aCtx->caps->ffpEnable)
-    {
-      aCtx->core11fwd->glDisable (GL_LIGHTING);
-      aCtx->core11fwd->glGetIntegerv (GL_SHADE_MODEL, &aShadingModelOld);
-      aCtx->core11->glShadeModel (GL_SMOOTH);
-    }
-  #endif
+    Graphic3d_Camera aCamera (theWorkspace->View()->Camera());
+    aCamera.SetZRange (0.01, 1.0); // is needed to avoid perspective camera exception
+    aCamera.SetProjectionType (Graphic3d_Camera::Projection_Perspective);
 
-    myBgGradientArray->Render (theWorkspace);
+    aCtx->ProjectionState.Push();
+    aCtx->ProjectionState.SetCurrent (aCamera.ProjectionMatrixF());
 
-  #if !defined(GL_ES_VERSION_2_0)
-    if (aCtx->core11 != NULL
-     && aCtx->caps->ffpEnable)
-    {
-      aCtx->core11->glShadeModel (aShadingModelOld);
-    }
-  #endif
-  }
+    myCubeMapParams->Aspect()->ShaderProgram()->PushVariableInt ("uZCoeff", myBackgroundCubeMap->ZIsInverted() ? -1 : 1);
+    myCubeMapParams->Aspect()->ShaderProgram()->PushVariableInt ("uYCoeff", myBackgroundCubeMap->IsTopDown() ? 1 : -1);
+    const OpenGl_Aspects* anOldAspectFace = theWorkspace->SetAspects (myCubeMapParams);
 
-  // Drawing background image if it is defined
-  // (texture is defined and fill type is not Aspect_FM_NONE)
-  if (myBgTextureArray->IsDefined()
-   && myTextureParams->Aspect()->ToMapTexture())
-  {
-    aCtx->core11fwd->glDisable (GL_BLEND);
+    myBackgrounds[Graphic3d_TOB_CUBEMAP]->Render (theWorkspace);
 
-    const OpenGl_Aspects* anOldAspectFace = theWorkspace->SetAspects (myTextureParams);
-    myBgTextureArray->Render (theWorkspace);
+    aCtx->ProjectionState.Pop();
+    aCtx->ApplyProjectionMatrix();
     theWorkspace->SetAspects (anOldAspectFace);
   }
+  else if (myBackgroundType == Graphic3d_TOB_GRADIENT
+        || myBackgroundType == Graphic3d_TOB_TEXTURE)
+  {
+    // Drawing background gradient if:
+    // - gradient fill type is not Aspect_GFM_NONE and
+    // - either background texture is no specified or it is drawn in Aspect_FM_CENTERED mode
+    if (myBackgrounds[Graphic3d_TOB_GRADIENT]->IsDefined()
+      && (!myTextureParams->Aspect()->ToMapTexture()
+        || myBackgrounds[Graphic3d_TOB_TEXTURE]->TextureFillMethod() == Aspect_FM_CENTERED
+        || myBackgrounds[Graphic3d_TOB_TEXTURE]->TextureFillMethod() == Aspect_FM_NONE))
+    {
+      #if !defined(GL_ES_VERSION_2_0)
+      GLint aShadingModelOld = GL_SMOOTH;
+      if (aCtx->core11 != NULL
+        && aCtx->caps->ffpEnable)
+      {
+        aCtx->core11fwd->glDisable (GL_LIGHTING);
+        aCtx->core11fwd->glGetIntegerv (GL_SHADE_MODEL, &aShadingModelOld);
+        aCtx->core11->glShadeModel (GL_SMOOTH);
+      }
+      #endif
+
+      myBackgrounds[Graphic3d_TOB_GRADIENT]->Render(theWorkspace);
+
+      #if !defined(GL_ES_VERSION_2_0)
+      if (aCtx->core11 != NULL
+        && aCtx->caps->ffpEnable)
+      {
+        aCtx->core11->glShadeModel (aShadingModelOld);
+      }
+      #endif
+    }
+
+    // Drawing background image if it is defined
+    // (texture is defined and fill type is not Aspect_FM_NONE)
+    if (myBackgrounds[Graphic3d_TOB_TEXTURE]->IsDefined()
+      && myTextureParams->Aspect()->ToMapTexture())
+    {
+      aCtx->core11fwd->glDisable (GL_BLEND);
+
+      const OpenGl_Aspects* anOldAspectFace = theWorkspace->SetAspects (myTextureParams);
+      myBackgrounds[Graphic3d_TOB_TEXTURE]->Render (theWorkspace);
+      theWorkspace->SetAspects (anOldAspectFace);
+    }
+  }
 
   if (wasUsedZBuffer)
   {
index c46590a..599581d 100644 (file)
@@ -502,6 +502,21 @@ void V3d_View::SetBgImageStyle (const Aspect_FillMethod theFillStyle, const Stan
 }
 
 //=============================================================================
+//function : SetBackgroundCubeMap
+//purpose  :
+//=============================================================================
+void V3d_View::SetBackgroundCubeMap (const Handle(Graphic3d_CubeMap)& theCubeMap,
+                                     Standard_Boolean                 theToUpdate)
+{
+  myView->SetBackgroundCubeMap (theCubeMap);
+
+  if (myImmediateUpdate || theToUpdate)
+  {
+    Redraw();
+  }
+}
+
+//=============================================================================
 //function : SetAxis
 //purpose  :
 //=============================================================================
index e6a1dd5..1c1cdcf 100644 (file)
@@ -228,6 +228,10 @@ public:
   Standard_EXPORT void SetBgImageStyle (const Aspect_FillMethod theFillStyle,
                                         const Standard_Boolean theToUpdate = Standard_False);
 
+  //! Sets environment cubemap as interactive background.
+  Standard_EXPORT void SetBackgroundCubeMap (const Handle(Graphic3d_CubeMap)& theCubeMap,
+                                             Standard_Boolean                 theToUpdate = Standard_False);
+
   //! Definition of an axis from its origin and
   //! its orientation .
   //! This will be the current axis for rotations and movements.
index 4d1fcd9..b7a2b56 100644 (file)
@@ -41,6 +41,8 @@
 #include <Graphic3d_AspectFillArea3d.hxx>
 #include <Graphic3d_AspectMarker3d.hxx>
 #include <Graphic3d_ClipPlane.hxx>
+#include <Graphic3d_CubeMapPacked.hxx>
+#include <Graphic3d_CubeMapSeparate.hxx>
 #include <Graphic3d_GraduatedTrihedron.hxx>
 #include <Graphic3d_NameOfTextureEnv.hxx>
 #include <Graphic3d_Texture2Dmanual.hxx>
@@ -241,13 +243,13 @@ namespace
   // Defines possible commands related to background changing
   enum BackgroundCommand
   {
-    BackgroundCommand_Main,         //!< The main command that manages other commands through options
-    BackgroundCommand_Image,        //!< Sets an image as a background
-    BackgroundCommand_ImageMode,    //!< Changes a background image mode
-    BackgroundCommand_Gradient,     //!< Sets a gradient as a background
-    BackgroundCommand_GradientMode, //!< Changes a background gradient mode
-    BackgroundCommand_Color,        //!< Fills background with a specified color
-    BackgroundCommand_Default       //!< Sets the background default color or gradient
+    BackgroundCommand_Main,              //!< The main command that manages other commands through options
+    BackgroundCommand_Image,             //!< Sets an image as a background
+    BackgroundCommand_ImageMode,         //!< Changes a background image mode
+    BackgroundCommand_Gradient,          //!< Sets a gradient as a background
+    BackgroundCommand_GradientMode,      //!< Changes a background gradient mode
+    BackgroundCommand_Color,             //!< Fills background with a specified color
+    BackgroundCommand_Default            //!< Sets the background default color or gradient
   };
 
   //! Map from background command names to its codes
@@ -258,13 +260,13 @@ namespace
   static BackgroundCommandNameMap createBackgroundCommandNameMap()
   {
     BackgroundCommandNameMap aBackgroundCommandNameMap;
-    aBackgroundCommandNameMap["vbackground"]    = BackgroundCommand_Main;
-    aBackgroundCommandNameMap["vsetbg"]         = BackgroundCommand_Image;
-    aBackgroundCommandNameMap["vsetbgmode"]     = BackgroundCommand_ImageMode;
-    aBackgroundCommandNameMap["vsetgradientbg"] = BackgroundCommand_Gradient;
-    aBackgroundCommandNameMap["vsetgrbgmode"]   = BackgroundCommand_GradientMode;
-    aBackgroundCommandNameMap["vsetcolorbg"]    = BackgroundCommand_Color;
-    aBackgroundCommandNameMap["vsetdefaultbg"]  = BackgroundCommand_Default;
+    aBackgroundCommandNameMap["vbackground"]      = BackgroundCommand_Main;
+    aBackgroundCommandNameMap["vsetbg"]           = BackgroundCommand_Image;
+    aBackgroundCommandNameMap["vsetbgmode"]       = BackgroundCommand_ImageMode;
+    aBackgroundCommandNameMap["vsetgradientbg"]   = BackgroundCommand_Gradient;
+    aBackgroundCommandNameMap["vsetgrbgmode"]     = BackgroundCommand_GradientMode;
+    aBackgroundCommandNameMap["vsetcolorbg"]      = BackgroundCommand_Color;
+    aBackgroundCommandNameMap["vsetdefaultbg"]    = BackgroundCommand_Default;
     return aBackgroundCommandNameMap;
   }
 
@@ -405,9 +407,21 @@ namespace
     //! the option key for the command that sets default background gradient or color
     ViewerTest_CommandOptionKey myDefaultOptionKey;
 
+    //! the option key for the command that sets an environment cubemap as a background
+    ViewerTest_CommandOptionKey myCubeMapOptionKey;
+
+    //! the option key for the command that defines order of tiles in one image packed cubemap
+    ViewerTest_CommandOptionKey myCubeMapOrderOptionKey;
+
+    //! the option key for the command that sets inversion of Z axis for background cubemap
+    ViewerTest_CommandOptionKey myCubeMapInvertedZOptionKey;
+
     //! the variable set of options that are allowed for the old scenario (without any option passed)
     CommandOptionKeyVariableSet myUnnamedOptionVariableSet;
 
+    //! the variable set of options that are allowed for setting an environment cubemap as background
+    CommandOptionKeyVariableSet myCubeMapOptionVariableSet;
+
     //! the variable set of options that are allowed for setting an image as a background
     CommandOptionKeyVariableSet myImageOptionVariableSet;
 
@@ -447,6 +461,11 @@ namespace
                                    "DIAG[ONAL]1, DIAG[ONAL]2, CORNER1, CORNER2, CORNER3, CORNER4");
       myColorOptionKey   = myCommandParser.AddOption ("color|col", "background color");
       myDefaultOptionKey = myCommandParser.AddOption ("default|def", "sets background default gradient or color");
+
+      myCubeMapOptionKey           = myCommandParser.AddOption ("cubemap|cmap|cm", "background cubemap");
+      myCubeMapOrderOptionKey      = myCommandParser.AddOption ("order|o", "order of sides in one image packed cubemap");
+      myCubeMapInvertedZOptionKey = myCommandParser.AddOption (
+        "invertedz|invz|iz", "whether Z axis is inverted or not during background cubemap rendering");
     }
 
     //! Creates option sets used to determine if a passed option set is valid or not
@@ -456,6 +475,13 @@ namespace
       anUnnamedOptionSet.insert (ViewerTest_CmdParser::THE_UNNAMED_COMMAND_OPTION_KEY);
       myUnnamedOptionVariableSet = CommandOptionKeyVariableSet (anUnnamedOptionSet);
 
+      ViewerTest_CommandOptionKeySet aCubeMapOptionSet;
+      aCubeMapOptionSet.insert (myCubeMapOptionKey);
+      ViewerTest_CommandOptionKeySet aCubeMapAdditionalOptionKeySet;
+      aCubeMapAdditionalOptionKeySet.insert (myCubeMapInvertedZOptionKey);
+      aCubeMapAdditionalOptionKeySet.insert (myCubeMapOrderOptionKey);
+      myCubeMapOptionVariableSet     = CommandOptionKeyVariableSet (aCubeMapOptionSet, aCubeMapAdditionalOptionKeySet);
+
       ViewerTest_CommandOptionKeySet anImageOptionSet;
       anImageOptionSet.insert (myImageOptionKey);
       ViewerTest_CommandOptionKeySet anImageModeOptionSet;
@@ -748,6 +774,10 @@ namespace
     {
       const bool                           isMain       = (theBackgroundCommand == BackgroundCommand_Main);
       const ViewerTest_CommandOptionKeySet aUsedOptions = myCommandParser.GetUsedOptions();
+      if (myCubeMapOptionVariableSet.IsInSet (aUsedOptions) && isMain)
+      {
+        return processCubeMapOptionSet();
+      }
       if (myImageOptionVariableSet.IsInSet (aUsedOptions)
           && (isMain || (theBackgroundCommand == BackgroundCommand_Image)))
       {
@@ -791,6 +821,41 @@ namespace
       return false;
     }
 
+    //! Process the cubemap option set in named and unnamed case.
+    //! @return true if processing was successful, or false otherwise
+    bool processCubeMapOptionSet() const
+    {
+      NCollection_Array1<TCollection_AsciiString> aFilePaths;
+
+      if (!processCubeMapOptions (aFilePaths))
+      {
+        return false;
+      }
+
+      Graphic3d_CubeMapOrder anOrder = Graphic3d_CubeMapOrder::Default();
+
+      if (myCommandParser.HasOption (myCubeMapOrderOptionKey))
+      {
+        if (!processCubeMapOrderOptions (anOrder))
+        {
+          return false;
+        }
+      }
+
+      bool aZIsInverted = false;
+      if (myCommandParser.HasOption (myCubeMapInvertedZOptionKey))
+      {
+        if (!processCubeMapInvertedZOptionSet())
+        {
+          return false;
+        }
+        aZIsInverted = true;
+      }
+
+      setCubeMap (aFilePaths, anOrder.Validated(), aZIsInverted);
+      return true;
+    }
+
     //! Processes the image option set
     //! @return true if processing was successful, or false otherwise
     bool processImageOptionSet() const
@@ -924,6 +989,79 @@ namespace
       return printHelp (theBackgroundCommandName, theDrawInterpretor);
     }
 
+    //! Processes the cubemap option
+    //! @param theFilePaths the array of filenames of cubemap sides
+    //! @return true if processing was successful, or false otherwise
+    bool processCubeMapOptions (NCollection_Array1<TCollection_AsciiString> &theFilePaths) const
+    {
+      const Standard_Integer aNumberOfCubeMapOptionArguments = myCommandParser.GetNumberOfOptionArguments (myCubeMapOptionKey);
+
+      if (aNumberOfCubeMapOptionArguments != 1
+       && aNumberOfCubeMapOptionArguments != 6)
+      {
+        return false;
+      }
+
+      theFilePaths.Resize(0, aNumberOfCubeMapOptionArguments - 1, Standard_False);
+
+      for (int i = 0; i < aNumberOfCubeMapOptionArguments; ++i)
+      {
+        std::string aCubeMapFileName;
+        if (!myCommandParser.Arg (myCubeMapOptionKey, i, aCubeMapFileName))
+        {
+          return false;
+        }
+        theFilePaths[i] = aCubeMapFileName.c_str();
+      }
+
+      return true;
+    }
+
+    //! Processes the cubemap option
+    //! @param theIsNeededToRedraw defines need of redraw after option's processing 
+    //! @return true if processing was successful, or false otherwise
+    bool processCubeMapInvertedZOptionSet () const
+    {
+      const Standard_Integer aNumberOfCubeMapZInversionOptionArguments =
+        myCommandParser.GetNumberOfOptionArguments (myCubeMapInvertedZOptionKey);
+
+      if (aNumberOfCubeMapZInversionOptionArguments != 0)
+      {
+        return false;
+      }
+
+      return true;
+    }
+
+    //! Processes the tiles order option
+    //! @param theOrder the array of indexes if cubemap sides in tile grid
+    //! @return true if processing was successful, or false otherwise
+    bool processCubeMapOrderOptions (Graphic3d_CubeMapOrder& theOrder) const
+    {
+      const Standard_Integer aNumberOfCubeMapOrderOptionArguments = myCommandParser.GetNumberOfOptionArguments(
+        myCubeMapOrderOptionKey);
+
+      if (aNumberOfCubeMapOrderOptionArguments != 6)
+      {
+        return false;
+      }
+
+
+      for (unsigned int i = 0; i < 6; ++i)
+      {
+        std::string anOrderItem;
+        if (!myCommandParser.Arg (myCubeMapOrderOptionKey, i, anOrderItem)) 
+        {
+          return false;
+        }
+
+        theOrder.Set (Graphic3d_CubeMapSide (i),
+                      static_cast<unsigned char> (Draw::Atoi (anOrderItem.c_str())));
+      }
+
+      return theOrder.IsValid();
+    }
+
     //! Processes the image option
     //! @param theImageFileName the filename of the image to be used as a background
     //! @return true if processing was successful, or false otherwise
@@ -1078,6 +1216,30 @@ namespace
       return theDrawInterpretor.PrintHelp (theBackgroundCommandName) == TCL_OK;
     }
 
+    //! Sets the cubemap as a background
+    //! @param theFileNames the array of filenames of packed or multifile cubemap
+    //! @param theOrder array of cubemap sides indexes mapping them from tiles in packed cubemap
+    static void setCubeMap (const NCollection_Array1<TCollection_AsciiString>& theFileNames,
+                            const Graphic3d_ValidatedCubeMapOrder              theOrder = Graphic3d_CubeMapOrder::Default(),
+                            bool                                               theZIsInverted = false)
+    {
+      const Handle(V3d_View)& aCurrentView = ViewerTest::CurrentView();
+      Handle(Graphic3d_CubeMap) aCubeMap;
+
+      if (theFileNames.Size() == 1)
+        aCubeMap = new Graphic3d_CubeMapPacked(theFileNames[0], theOrder);
+      else
+        aCubeMap = new Graphic3d_CubeMapSeparate(theFileNames);
+
+      aCubeMap->SetZInversion (theZIsInverted);
+
+      aCubeMap->GetParams()->SetFilter(Graphic3d_TOTF_BILINEAR);
+      aCubeMap->GetParams()->SetRepeat(Standard_False);
+      aCubeMap->GetParams()->SetTextureUnit(Graphic3d_TextureUnit_EnvMap);
+
+      aCurrentView->SetBackgroundCubeMap (aCubeMap, Standard_True);
+    }
+
     //! Sets the image as a background
     //! @param theImageFileName the filename of the image to be used as a background
     //! @param theImageMode the fill type used for a background image
@@ -13502,6 +13664,7 @@ void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands)
     "  vbackground -imageMode FillType\n"
     "  vbackground -gradient Color1 Color2 [-gradientMode FillMethod]\n"
     "  vbackground -gradientMode FillMethod\n"
+    "  vbackground -cubemap CubemapFile1 [CubeMapFiles2-5] [-order TilesIndexes1-6] [-invertedz]\n"
     "  vbackground -color Color\n"
     "  vbackground -default -gradient Color1 Color2 [-gradientMode FillType]\n"
     "  vbackground -default -color Color\n"
@@ -13512,19 +13675,25 @@ void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands)
     "  -imageMode    (-imgMode, -imageMd, -imgMd):         sets image fill type\n"
     "  -gradient     (-grad, -gr):                         sets background gradient starting and ending colors\n"
     "  -gradientMode (-gradMode, -gradMd, -grMode, -grMd): sets gradient fill method\n"
+    "  -cubemap      (-cmap, -cm):                         sets environmet cubemap as background\n"
+    "  -invertedz    (-invz, -iz):                         sets inversion of Z axis for background cubemap rendering\n"
+    "  -order        (-o):                                 defines order of tiles in one image cubemap\n"
+    "                                                      (has no effect in case of multi image cubemaps)\n"
     "  -color        (-col):                               sets background color\n"
     "  -default      (-def):                               sets background default gradient or color\n"
     "  -help         (-h):                                 outputs short help message\n"
     "\n"
     "Arguments:\n"
-    "  Color:      Red Green Blue  - where Red, Green, Blue must be integers within the range [0, 255]\n"
+    "  Color:        Red Green Blue  - where Red, Green, Blue must be integers within the range [0, 255]\n"
     "                                  or reals within the range [0.0, 1.0]\n"
-    "              ColorName       - one of WHITE, BLACK, RED, GREEN, BLUE, etc.\n"
-    "              #HHH, [#]HHHHHH - where H is a hexadecimal digit (0 .. 9, a .. f, or A .. F)\n"
-    "  FillMethod: one of NONE, HOR[IZONTAL], VER[TICAL], DIAG[ONAL]1, DIAG[ONAL]2, CORNER1, CORNER2, CORNER3, "
+    "                ColorName       - one of WHITE, BLACK, RED, GREEN, BLUE, etc.\n"
+    "                #HHH, [#]HHHHHH - where H is a hexadecimal digit (0 .. 9, a .. f, or A .. F)\n"
+    "  FillMethod:   one of NONE, HOR[IZONTAL], VER[TICAL], DIAG[ONAL]1, DIAG[ONAL]2, CORNER1, CORNER2, CORNER3, "
     "CORNER4\n"
-    "  FillType:   one of CENTERED, TILED, STRETCH, NONE\n"
-    "  ImageFile:  a name of the file with the image used as a background\n",
+    "  FillType:     one of CENTERED, TILED, STRETCH, NONE\n"
+    "  ImageFile:    a name of the file with the image used as a background\n"
+    "  CubemapFilei: a name of the file with one image packed cubemap or names of separate files with every cubemap side\n"
+    "  TileIndexi:   a cubemap side index in range [0, 5] for i tile of one image packed cubemap\n",
     __FILE__,
     vbackground,
     group);
diff --git a/tests/v3d/glsl/cubemap b/tests/v3d/glsl/cubemap
new file mode 100644 (file)
index 0000000..5489325
--- /dev/null
@@ -0,0 +1,158 @@
+puts "============"
+puts "0030807: Visualization, TKOpenGl - supporting cubemaps"
+puts "============"
+puts ""
+
+set aCubeMap_V [locate_data_file Circus_CubeMap_V.png]
+set aCubeMap_V_021345 [locate_data_file Circus_CubeMap_V_021345.png]
+set aCubeMap_H [locate_data_file Circus_CubeMap_H.png]
+set aCubeMap_GridV [locate_data_file Circus_CubeMap_GridV.png]
+set aCubeMap_GridV_021345 [locate_data_file Circus_CubeMap_GridV_021345.png]
+set aCubeMap_GridH [locate_data_file Circus_CubeMap_GridH.png]
+set aCubeMap_GridH_021345 [locate_data_file Circus_CubeMap_GridH_021345.png]
+set aCubeMap_posx [locate_data_file SF_CubeMap_posx.jpg]
+set aCubeMap_negx [locate_data_file SF_CubeMap_negx.jpg]
+set aCubeMap_posy [locate_data_file SF_CubeMap_posy.jpg]
+set aCubeMap_negy [locate_data_file SF_CubeMap_negy.jpg]
+set aCubeMap_posz [locate_data_file SF_CubeMap_posz.jpg]
+set aCubeMap_negz [locate_data_file SF_CubeMap_negz.jpg]
+
+vclear
+vclose ALL
+vinit v -w 512 -h 512
+vcamera -fovy 100
+
+#vertical tiles orientation
+vbackground -cubemap $aCubeMap_V
+vfront
+vdump $imagedir/${casename}_V_front.png
+vback
+vdump $imagedir/${casename}_V_back.png
+vtop
+vdump $imagedir/${casename}_V_top.png
+vbottom
+vdump $imagedir/${casename}_V_bottom.png
+vleft
+vdump $imagedir/${casename}_V_left.png
+vright
+vdump $imagedir/${casename}_V_right.png
+
+#test of flipping
+vbackground -cubemap $aCubeMap_V -invertedz
+vfront
+vdump $imagedir/${casename}_flip_front.png
+vback
+vdump $imagedir/${casename}_flip_back.png
+vtop
+vdump $imagedir/${casename}_flip_top.png
+vbottom
+vdump $imagedir/${casename}_flip_bottom.png
+vleft
+vdump $imagedir/${casename}_flip_left.png
+vright
+vdump $imagedir/${casename}_flip_right.png
+
+#vertical tiles orientation (disordered)
+vbackground -cubemap $aCubeMap_V_021345 -order 0 2 1 3 4 5
+vfront
+vdump $imagedir/${casename}_V_021345_front.png
+vback
+vdump $imagedir/${casename}_V_021345_back.png
+vtop
+vdump $imagedir/${casename}_V_021345_top.png
+vbottom
+vdump $imagedir/${casename}_V_021345_bottom.png
+vleft
+vdump $imagedir/${casename}_V_021345_left.png
+vright
+vdump $imagedir/${casename}_V_021345_right.png
+
+#horizontal tile orientation
+vbackground -cubemap $aCubeMap_H
+vfront
+vdump $imagedir/${casename}_H_front.png
+vback
+vdump $imagedir/${casename}_H_back.png
+vtop
+vdump $imagedir/${casename}_H_top.png
+vbottom
+vdump $imagedir/${casename}_H_bottom.png
+vleft
+vdump $imagedir/${casename}_H_left.png
+vright
+vdump $imagedir/${casename}_H_right.png
+
+#vertical grid tile orientation
+vbackground -cubemap $aCubeMap_GridV
+vfront
+vdump $imagedir/${casename}_GridV_front.png
+vback
+vdump $imagedir/${casename}_GridV_back.png
+vtop
+vdump $imagedir/${casename}_GridV_top.png
+vbottom
+vdump $imagedir/${casename}_GridV_bottom.png
+vleft
+vdump $imagedir/${casename}_GridV_left.png
+vright
+vdump $imagedir/${casename}_GridV_right.png
+
+#vertical grid tile orientation (disordered)
+vbackground -cubemap $aCubeMap_GridV_021345 -order 0 2 1 3 4 5
+vfront
+vdump $imagedir/${casename}_GridV_021345_front.png
+vback
+vdump $imagedir/${casename}_GridV_021345_back.png
+vtop
+vdump $imagedir/${casename}_GridV_021345_top.png
+vbottom
+vdump $imagedir/${casename}_GridV_021345_bottom.png
+vleft
+vdump $imagedir/${casename}_GridV_021345_left.png
+vright
+vdump $imagedir/${casename}_GridV_021345_right.png
+
+#horizontal grid tile orientation
+vbackground -cubemap $aCubeMap_GridH
+vfront
+vdump $imagedir/${casename}_GridH_front.png
+vback
+vdump $imagedir/${casename}_GridH_back.png
+vtop
+vdump $imagedir/${casename}_GridH_top.png
+vbottom
+vdump $imagedir/${casename}_GridH_bottom.png
+vleft
+vdump $imagedir/${casename}_GridH_left.png
+vright
+vdump $imagedir/${casename}_GridH_right.png
+
+#horizontal grid tile orientation (disordered)
+vbackground -cubemap $aCubeMap_GridH_021345 -order 0 2 1 3 4 5
+vfront
+vdump $imagedir/${casename}_GridH_021345_front.png
+vback
+vdump $imagedir/${casename}_GridH_021345_back.png
+vtop
+vdump $imagedir/${casename}_GridH_021345_top.png
+vbottom
+vdump $imagedir/${casename}_GridH_021345_bottom.png
+vleft
+vdump $imagedir/${casename}_GridH_021345_left.png
+vright
+vdump $imagedir/${casename}_GridH_021345_right.png
+
+#multiimage cubemap
+vbackground -cubemap $aCubeMap_posx $aCubeMap_negx $aCubeMap_posy $aCubeMap_negy $aCubeMap_posz $aCubeMap_negz
+vfront
+vdump $imagedir/${casename}_multi_front.png
+vback
+vdump $imagedir/${casename}_multi_back.png
+vtop
+vdump $imagedir/${casename}_multi_top.png
+vbottom
+vdump $imagedir/${casename}_multi_bottom.png
+vleft
+vdump $imagedir/${casename}_multi_left.png
+vright
+vdump $imagedir/${casename}_multi_right.png
\ No newline at end of file