From: iko Date: Tue, 9 Jul 2019 13:55:49 +0000 (+0300) Subject: 0030807: Visualization, TKOpenGl - supporting cubemaps X-Git-Tag: V7_4_0_beta~44 X-Git-Url: http://git.dev.opencascade.org/gitweb/?p=occt.git;a=commitdiff_plain;h=077a220c51c8be71d118b87912a1328e540de985 0030807: Visualization, TKOpenGl - supporting cubemaps A cubemap texture initialization has been implemented. Setting environment cubemap as interactive background is posssible now. --- diff --git a/src/Graphic3d/FILES b/src/Graphic3d/FILES index f3e0acb83f..c19fc1b0a0 100755 --- a/src/Graphic3d/FILES +++ b/src/Graphic3d/FILES @@ -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 diff --git a/src/Graphic3d/Graphic3d_CView.hxx b/src/Graphic3d/Graphic3d_CView.hxx index e79d24f027..ac0df39b97 100644 --- a/src/Graphic3d/Graphic3d_CView.hxx +++ b/src/Graphic3d/Graphic3d_CView.hxx @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -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 index 0000000000..f4c95aa738 --- /dev/null +++ b/src/Graphic3d/Graphic3d_CubeMap.cxx @@ -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 + +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 index 0000000000..c9e859af61 --- /dev/null +++ b/src/Graphic3d/Graphic3d_CubeMap.hxx @@ -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 +#include + +//! 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 index 0000000000..52c1c309f5 --- /dev/null +++ b/src/Graphic3d/Graphic3d_CubeMapOrder.cxx @@ -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 + +#include + +#include + +// ======================================================================= +// 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 (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 (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 index 0000000000..ed0eeb1d5d --- /dev/null +++ b/src/Graphic3d/Graphic3d_CubeMapOrder.hxx @@ -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 +#include + +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 index 0000000000..ac57c48fa7 --- /dev/null +++ b/src/Graphic3d/Graphic3d_CubeMapPacked.cxx @@ -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 +#include + +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& 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 index 0000000000..4a6da463dc --- /dev/null +++ b/src/Graphic3d/Graphic3d_CubeMapPacked.hxx @@ -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 +#include +#include + +//! 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& 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 index 0000000000..6c9c2bfd46 --- /dev/null +++ b/src/Graphic3d/Graphic3d_CubeMapSeparate.cxx @@ -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 +#include +#include +#include +#include + +IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_CubeMapSeparate, Graphic3d_CubeMap) + +// ======================================================================= +// function : Graphic3d_CubeMapSeparate +// purpose : +// ======================================================================= +Graphic3d_CubeMapSeparate::Graphic3d_CubeMapSeparate (const NCollection_Array1& 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& 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 index 0000000000..6f0012d616 --- /dev/null +++ b/src/Graphic3d/Graphic3d_CubeMapSeparate.hxx @@ -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 +#include +#include + +//! 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& 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& 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 index 0000000000..8495f645f0 --- /dev/null +++ b/src/Graphic3d/Graphic3d_CubeMapSide.hxx @@ -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 diff --git a/src/Graphic3d/Graphic3d_TextureUnit.hxx b/src/Graphic3d/Graphic3d_TextureUnit.hxx index c587f68734..477147b641 100644 --- a/src/Graphic3d/Graphic3d_TextureUnit.hxx +++ b/src/Graphic3d/Graphic3d_TextureUnit.hxx @@ -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 { diff --git a/src/Graphic3d/Graphic3d_TypeOfBackground.hxx b/src/Graphic3d/Graphic3d_TypeOfBackground.hxx index 52db76b83f..d537cdd07c 100644 --- a/src/Graphic3d/Graphic3d_TypeOfBackground.hxx +++ b/src/Graphic3d/Graphic3d_TypeOfBackground.hxx @@ -20,9 +20,15 @@ //! 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 diff --git a/src/Graphic3d/Graphic3d_TypeOfTexture.hxx b/src/Graphic3d/Graphic3d_TypeOfTexture.hxx index d482830514..c457e94de8 100644 --- a/src/Graphic3d/Graphic3d_TypeOfTexture.hxx +++ b/src/Graphic3d/Graphic3d_TypeOfTexture.hxx @@ -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 diff --git a/src/OpenGl/OpenGl_AspectsTextureSet.cxx b/src/OpenGl/OpenGl_AspectsTextureSet.cxx index ac3906f738..2ad97297bc 100644 --- a/src/OpenGl/OpenGl_AspectsTextureSet.cxx +++ b/src/OpenGl/OpenGl_AspectsTextureSet.cxx @@ -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 (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()); } } diff --git a/src/OpenGl/OpenGl_BackgroundArray.cxx b/src/OpenGl/OpenGl_BackgroundArray.cxx index fb6f6602c2..cf49fe1244 100644 --- a/src/OpenGl/OpenGl_BackgroundArray.cxx +++ b/src/OpenGl/OpenGl_BackgroundArray.cxx @@ -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(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(); diff --git a/src/OpenGl/OpenGl_BackgroundArray.hxx b/src/OpenGl/OpenGl_BackgroundArray.hxx index 0078aa768b..65e2b4a83d 100644 --- a/src/OpenGl/OpenGl_BackgroundArray.hxx +++ b/src/OpenGl/OpenGl_BackgroundArray.hxx @@ -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(); diff --git a/src/OpenGl/OpenGl_ShaderManager.cxx b/src/OpenGl/OpenGl_ShaderManager.cxx index 2ee04208b8..4bc3ab1a98 100644 --- a/src/OpenGl/OpenGl_ShaderManager.cxx +++ b/src/OpenGl/OpenGl_ShaderManager.cxx @@ -2676,6 +2676,53 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramBoundBox() return Standard_True; } +// ======================================================================= +// 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 : diff --git a/src/OpenGl/OpenGl_ShaderManager.hxx b/src/OpenGl/OpenGl_ShaderManager.hxx index ec3661fe94..be560c083b 100644 --- a/src/OpenGl/OpenGl_ShaderManager.hxx +++ b/src/OpenGl/OpenGl_ShaderManager.hxx @@ -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 diff --git a/src/OpenGl/OpenGl_Texture.cxx b/src/OpenGl/OpenGl_Texture.cxx index a87bb9f142..6a354d165a 100644 --- a/src/OpenGl/OpenGl_Texture.cxx +++ b/src/OpenGl/OpenGl_Texture.cxx @@ -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->()); @@ -769,6 +775,36 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx, theType, &theImage); } +// ======================================================================= +// 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 : @@ -997,6 +1033,141 @@ bool OpenGl_Texture::Init3D (const Handle(OpenGl_Context)& theCtx, return true; } +// ======================================================================= +// 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 : diff --git a/src/OpenGl/OpenGl_Texture.hxx b/src/OpenGl/OpenGl_Texture.hxx index 7943dad4af..9b0061a55b 100644 --- a/src/OpenGl/OpenGl_Texture.hxx +++ b/src/OpenGl/OpenGl_Texture.hxx @@ -15,11 +15,12 @@ #ifndef _OpenGl_Texture_H__ #define _OpenGl_Texture_H__ +#include #include #include #include -#include #include +#include 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; diff --git a/src/OpenGl/OpenGl_View.cxx b/src/OpenGl/OpenGl_View.cxx index b4b9966188..17f44efa7c 100644 --- a/src/OpenGl/OpenGl_View.cxx +++ b/src/OpenGl/OpenGl_View.cxx @@ -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; diff --git a/src/OpenGl/OpenGl_View.hxx b/src/OpenGl/OpenGl_View.hxx index 225bfe85f2..1b05ee7200 100644 --- a/src/OpenGl/OpenGl_View.hxx +++ b/src/OpenGl/OpenGl_View.hxx @@ -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 diff --git a/src/OpenGl/OpenGl_View_Raytrace.cxx b/src/OpenGl/OpenGl_View_Raytrace.cxx index 7f1cf49573..33dec76c21 100644 --- a/src/OpenGl/OpenGl_View_Raytrace.cxx +++ b/src/OpenGl/OpenGl_View_Raytrace.cxx @@ -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 { diff --git a/src/OpenGl/OpenGl_View_Redraw.cxx b/src/OpenGl/OpenGl_View_Redraw.cxx index fa2877a865..5f83913b0d 100644 --- a/src/OpenGl/OpenGl_View_Redraw.cxx +++ b/src/OpenGl/OpenGl_View_Redraw.cxx @@ -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) { diff --git a/src/V3d/V3d_View.cxx b/src/V3d/V3d_View.cxx index c46590ae4f..599581d507 100644 --- a/src/V3d/V3d_View.cxx +++ b/src/V3d/V3d_View.cxx @@ -501,6 +501,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 : diff --git a/src/V3d/V3d_View.hxx b/src/V3d/V3d_View.hxx index e6a1dd51f9..1c1cdcf2a7 100644 --- a/src/V3d/V3d_View.hxx +++ b/src/V3d/V3d_View.hxx @@ -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. diff --git a/src/ViewerTest/ViewerTest_ViewerCommands.cxx b/src/ViewerTest/ViewerTest_ViewerCommands.cxx index 4d1fcd9a00..b7a2b56d0f 100644 --- a/src/ViewerTest/ViewerTest_ViewerCommands.cxx +++ b/src/ViewerTest/ViewerTest_ViewerCommands.cxx @@ -41,6 +41,8 @@ #include #include #include +#include +#include #include #include #include @@ -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 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 &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 (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& 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 index 0000000000..54893254c1 --- /dev/null +++ b/tests/v3d/glsl/cubemap @@ -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