1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-09 13:22:24 +03:00

0031478: Visualization, TKOpenGl - allow uploading Cubemap in compressed DDS format when supported by GPU

Graphic3d_TextureRoot::GetCompressedImage() - added new interface for fetching compressed texture image.
Default implementation detects DDS image files using Image_DDSParser parser.

Graphic3d_TextureRoot::GetImage() has been extended with new parameter
- the list of image formats supported by OpenGL driver.
Graphic3d_TextureRoot::convertToCompatible() implicitly converts
BGRA image to RGBA on OpenGL ES, which normally does not support BGR formats.

OpenGl_Caps::isTopDownTextureUV - new property defines how application defines
UV texture coordinates in primitive arrays.
OpenGl_Context::SetTextureMatrix() compares this flag with OpenGl_Texture::IsTopDown()
and automatically flips V coordinate in case of mismatch.

OpenGl_Texture now holds exact number of mipmap levels
instead of Boolean flag indicating that they are defined.
This allows loading DDS files with incomplete mipmap level set
by setting GL_TEXTURE_MAX_LEVEL to appropriate value instead of default 1000
(causing black textures in case if mipmap levels are not defined till 1x1).

Fixed order of texture coordinates transformation within GLSL program to match FFP matrix:
Rotate -> Translate -> Scale (previously Rotation was applied afterwards).
This commit is contained in:
kgv
2020-05-16 02:47:20 +03:00
committed by bugmaster
parent 691711cd3e
commit faff37677c
45 changed files with 1625 additions and 301 deletions

View File

@@ -31,7 +31,6 @@ public:
Graphic3d_TextureMap (theFileName, Graphic3d_TOT_CUBEMAP),
myCurrentSide (Graphic3d_CMS_POS_X),
myEndIsReached (false),
myIsTopDown (true),
myZIsInverted (false),
myHasMipmaps (theToGenerateMipmaps)
{}
@@ -42,7 +41,6 @@ public:
Graphic3d_TextureMap (thePixmap, Graphic3d_TOT_CUBEMAP),
myCurrentSide (Graphic3d_CMS_POS_X),
myEndIsReached (false),
myIsTopDown (true),
myZIsInverted (false),
myHasMipmaps (theToGenerateMipmaps)
{}
@@ -67,12 +65,6 @@ public:
}
}
//! 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)
{
@@ -91,9 +83,13 @@ public:
//! Sets whether to generate mipmaps of cubemap or not.
void SetMipmapsGeneration (Standard_Boolean theToGenerateMipmaps) { myHasMipmaps = theToGenerateMipmaps; }
//! Returns current cubemap side as compressed PixMap.
//! Returns null handle if current side is invalid or if image is not in supported compressed format.
virtual Handle(Image_CompressedPixMap) CompressedValue (const Handle(Image_SupportedFormats)& theSupported) = 0;
//! Returns PixMap containing current side of cubemap.
//! Returns null handle if current side is invalid.
virtual Handle(Image_PixMap) Value() = 0;
virtual Handle(Image_PixMap) Value (const Handle(Image_SupportedFormats)& theSupported) = 0;
//! Sets iterator state to +X cubemap side.
Graphic3d_CubeMap& Reset()
@@ -110,7 +106,6 @@ 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
Standard_Boolean myHasMipmaps; //!< Indicates whether mipmaps of cubemap will be generated or not

View File

@@ -13,7 +13,9 @@
// commercial license or contractual agreement.
#include <Graphic3d_CubeMapPacked.hxx>
#include <Image_AlienPixMap.hxx>
#include <Image_DDSParser.hxx>
IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_CubeMapPacked, Graphic3d_CubeMap)
@@ -40,17 +42,46 @@ Graphic3d_CubeMapPacked::Graphic3d_CubeMapPacked (const Handle(Image_PixMap)&
myOrder (theOrder),
myTileNumberX (1)
{
if (checkImage (theImage, myTileNumberX))
if (checkImage (theImage, myTileNumberX))
{
myPixMap = theImage;
}
}
// =======================================================================
// function : CompressedValue
// purpose :
// =======================================================================
Handle(Image_CompressedPixMap) Graphic3d_CubeMapPacked::CompressedValue (const Handle(Image_SupportedFormats)& theSupported)
{
if (myTileNumberX == 0
|| !myPixMap.IsNull())
{
return Handle(Image_CompressedPixMap)();
}
TCollection_AsciiString aFilePath;
myPath.SystemName (aFilePath);
if (!aFilePath.IsEmpty())
{
const unsigned int aTileIndex = myOrder[myCurrentSide];
Handle(Image_CompressedPixMap) anImage = Image_DDSParser::Load (theSupported, aFilePath, (Standard_Integer )aTileIndex);
if (!anImage.IsNull()
&& anImage->NbFaces() == 6
&& anImage->SizeX() == anImage->SizeY())
{
myPixMap = theImage;
myIsTopDown = anImage->IsTopDown();
return anImage;
}
}
return Handle(Image_CompressedPixMap)();
}
// =======================================================================
// function : Value
// purpose :
// =======================================================================
Handle(Image_PixMap) Graphic3d_CubeMapPacked::Value()
Handle(Image_PixMap) Graphic3d_CubeMapPacked::Value (const Handle(Image_SupportedFormats)& theSupported)
{
if (myTileNumberX != 0)
{
@@ -60,7 +91,7 @@ Handle(Image_PixMap) Graphic3d_CubeMapPacked::Value()
myPath.SystemName (aFilePath);
if (!aFilePath.IsEmpty())
{
tryLoadImage (aFilePath);
tryLoadImage (theSupported, aFilePath);
}
}
@@ -183,13 +214,15 @@ Standard_Boolean Graphic3d_CubeMapPacked::checkImage (const Handle(Image_PixMap)
// function : tryLoadImage
// purpose :
// =======================================================================
void Graphic3d_CubeMapPacked::tryLoadImage (const TCollection_AsciiString& theFilePath)
void Graphic3d_CubeMapPacked::tryLoadImage (const Handle(Image_SupportedFormats)& theSupported,
const TCollection_AsciiString& theFilePath)
{
Handle(Image_AlienPixMap) anImage = new Image_AlienPixMap;
if (anImage->Load (theFilePath))
{
if (checkImage (anImage, myTileNumberX))
{
convertToCompatible (theSupported, anImage);
myPixMap = anImage;
}
}

View File

@@ -25,23 +25,26 @@ class Graphic3d_CubeMapPacked : public Graphic3d_CubeMap
DEFINE_STANDARD_RTTIEXT(Graphic3d_CubeMapPacked, Graphic3d_CubeMap)
public:
//! Initialization to load cubemef from file.
//! Initialization to load cubemap from file.
//! @theFileName - path to the cubemap image
//! @theOrder - array conaining six different indexes of cubemap sides which maps tile grid to cubemap sides
//! @theOrder - array containing 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
//! @theOrder - array containing 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 compressed PixMap.
Standard_EXPORT virtual Handle(Image_CompressedPixMap) CompressedValue (const Handle(Image_SupportedFormats)& theSupported) Standard_OVERRIDE;
//! 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;
Standard_EXPORT virtual Handle(Image_PixMap) Value (const Handle(Image_SupportedFormats)& theSupported) Standard_OVERRIDE;
//! Empty destructor.
~Graphic3d_CubeMapPacked() {}
@@ -57,7 +60,8 @@ private:
//! Tries to load image from file and checks it after that.
//! Does nothing in case of fail.
void tryLoadImage (const TCollection_AsciiString &theFilePath);
void tryLoadImage (const Handle(Image_SupportedFormats)& theSupported,
const TCollection_AsciiString &theFilePath);
protected:

View File

@@ -13,7 +13,9 @@
// commercial license or contractual agreement.
#include <Graphic3d_CubeMapSeparate.hxx>
#include <Image_AlienPixMap.hxx>
#include <Image_DDSParser.hxx>
#include <Message.hxx>
#include <Message_Messenger.hxx>
#include <OSD_File.hxx>
@@ -83,11 +85,55 @@ Graphic3d_CubeMapSeparate::Graphic3d_CubeMapSeparate (const NCollection_Array1<H
}
}
// =======================================================================
// function : CompressedValue
// purpose :
// =======================================================================
Handle(Image_CompressedPixMap) Graphic3d_CubeMapSeparate::CompressedValue (const Handle(Image_SupportedFormats)& theSupported)
{
if (!myImages[0].IsNull())
{
return Handle(Image_CompressedPixMap)();
}
const Graphic3d_CubeMapOrder anOrder = Graphic3d_CubeMapOrder::Default();
TCollection_AsciiString aFilePath;
myPaths[anOrder[myCurrentSide]].SystemName(aFilePath);
if (aFilePath.IsEmpty())
{
return Handle(Image_CompressedPixMap)();
}
Handle(Image_CompressedPixMap) anImage = Image_DDSParser::Load (theSupported, aFilePath, 0);
if (anImage.IsNull()
|| anImage->SizeX() != anImage->SizeY())
{
return Handle(Image_CompressedPixMap)();
}
if (myCurrentSide == 0)
{
mySize = anImage->SizeX();
myFormat = anImage->BaseFormat();
myIsTopDown = anImage->IsTopDown();
return anImage;
}
if (anImage->BaseFormat() == myFormat
&& anImage->SizeX() == (Standard_Integer )mySize)
{
return anImage;
}
Message::SendWarning (TCollection_AsciiString() + "'" + aFilePath + "' inconsistent image format or dimension in Graphic3d_CubeMapSeparate");
return Handle(Image_CompressedPixMap)();
}
// =======================================================================
// function : Value
// purpose :
// =======================================================================
Handle(Image_PixMap) Graphic3d_CubeMapSeparate::Value()
Handle(Image_PixMap) Graphic3d_CubeMapSeparate::Value (const Handle(Image_SupportedFormats)& theSupported)
{
Graphic3d_CubeMapOrder anOrder = Graphic3d_CubeMapOrder::Default();
if (!myIsTopDown)
@@ -108,6 +154,7 @@ Handle(Image_PixMap) Graphic3d_CubeMapSeparate::Value()
Handle(Image_AlienPixMap) anImage = new Image_AlienPixMap;
if (anImage->Load(aFilePath))
{
convertToCompatible (theSupported, anImage);
if (anImage->SizeX() == anImage->SizeY())
{
if (myCurrentSide == 0)

View File

@@ -33,13 +33,16 @@ public:
//! @theImages - array if PixMaps (has to have size equal 6).
Standard_EXPORT Graphic3d_CubeMapSeparate(const NCollection_Array1<Handle(Image_PixMap)>& theImages);
//! Returns current cubemap side as compressed PixMap.
Standard_EXPORT virtual Handle(Image_CompressedPixMap) CompressedValue (const Handle(Image_SupportedFormats)& theSupported) Standard_OVERRIDE;
//! 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;
Standard_EXPORT virtual Handle(Image_PixMap) Value (const Handle(Image_SupportedFormats)& theSupported) Standard_OVERRIDE;
//! Returns NULL.
virtual Handle(Image_PixMap) GetImage() const Standard_OVERRIDE
virtual Handle(Image_PixMap) GetImage (const Handle(Image_SupportedFormats)& ) Standard_OVERRIDE
{
return Handle(Image_PixMap)();
}

View File

@@ -56,7 +56,7 @@ Graphic3d_MediaTexture::Graphic3d_MediaTexture (const Handle(Media_HMutex)& theM
// Function : GetImage
// Purpose :
// ================================================================
Handle(Image_PixMap) Graphic3d_MediaTexture::GetImage() const
Handle(Image_PixMap) Graphic3d_MediaTexture::GetImage (const Handle(Image_SupportedFormats)& )
{
Standard_Mutex::Sentry aLock (myMutex.get());
if (myFrame.IsNull()

View File

@@ -34,7 +34,7 @@ public:
Standard_Integer thePlane = -1);
//! Image reader.
Standard_EXPORT virtual Handle(Image_PixMap) GetImage() const Standard_OVERRIDE;
Standard_EXPORT virtual Handle(Image_PixMap) GetImage (const Handle(Image_SupportedFormats)& theSupported) Standard_OVERRIDE;
//! Return the frame.
const Handle(Media_Frame)& Frame() const { return myFrame; }

View File

@@ -72,22 +72,22 @@ public:
//! @param theLevel level of anisontropy texture filter.
Standard_EXPORT void SetAnisoFilter (const Graphic3d_LevelOfTextureAnisotropy theLevel);
//! @return rotation angle in degrees
//! Default value is 0.
//! Return rotation angle in degrees; 0 by default.
//! Complete transformation matrix: Rotation -> Translation -> Scale.
Standard_ShortReal Rotation() const { return myRotAngle; }
//! @param theAngleDegrees rotation angle.
Standard_EXPORT void SetRotation (const Standard_ShortReal theAngleDegrees);
//! @return scale factor
//! Default value is no scaling (1.0; 1.0).
//! Return scale factor; (1.0; 1.0) by default, which means no scaling.
//! Complete transformation matrix: Rotation -> Translation -> Scale.
const Graphic3d_Vec2& Scale() const { return myScale; }
//! @param theScale scale factor.
Standard_EXPORT void SetScale (const Graphic3d_Vec2 theScale);
//! @return translation vector
//! Default value is no translation (0.0; 0.0).
//! Return translation vector; (0.0; 0.0), which means no translation.
//! Complete transformation matrix: Rotation -> Translation -> Scale.
const Graphic3d_Vec2& Translation() const { return myTranslation; }
//! @param theVec translation vector.
@@ -109,7 +109,8 @@ public:
//! @return base texture mipmap level; 0 by default.
Standard_Integer BaseLevel() const { return myBaseLevel; }
//! @return maximum texture mipmap array level; 1000 by default.
//! Return maximum texture mipmap array level; 1000 by default.
//! Real rendering limit will take into account mipmap generation flags and presence of mipmaps in loaded image.
Standard_Integer MaxLevel() const { return myMaxLevel; }
//! Setups texture mipmap array levels range.

View File

@@ -19,9 +19,12 @@
#include <Graphic3d_GraphicDriver.hxx>
#include <Graphic3d_TextureParams.hxx>
#include <Image_AlienPixMap.hxx>
#include <Image_DDSParser.hxx>
#include <Image_SupportedFormats.hxx>
#include <OSD_Directory.hxx>
#include <OSD_Environment.hxx>
#include <OSD_File.hxx>
#include <OSD_OpenFile.hxx>
#include <OSD_Protection.hxx>
#include <Standard_Atomic.hxx>
@@ -90,7 +93,8 @@ Graphic3d_TextureRoot::Graphic3d_TextureRoot (const TCollection_AsciiString& the
myPath (theFileName),
myRevision (0),
myType (theType),
myIsColorMap (true)
myIsColorMap (true),
myIsTopDown (true)
{
generateId();
}
@@ -105,7 +109,8 @@ Graphic3d_TextureRoot::Graphic3d_TextureRoot (const Handle(Image_PixMap)& theP
myPixMap (thePixMap),
myRevision (0),
myType (theType),
myIsColorMap (true)
myIsColorMap (true),
myIsTopDown (true)
{
generateId();
}
@@ -129,15 +134,57 @@ void Graphic3d_TextureRoot::generateId()
+ TCollection_AsciiString (Standard_Atomic_Increment (&THE_TEXTURE_COUNTER));
}
// =======================================================================
// function : GetCompressedImage
// purpose :
// =======================================================================
Handle(Image_CompressedPixMap) Graphic3d_TextureRoot::GetCompressedImage (const Handle(Image_SupportedFormats)& theSupported)
{
if (!myPixMap.IsNull())
{
return Handle(Image_CompressedPixMap)();
}
// Case 2: texture source is specified as path
TCollection_AsciiString aFilePath;
myPath.SystemName (aFilePath);
if (aFilePath.IsEmpty())
{
return Handle(Image_CompressedPixMap)();
}
TCollection_AsciiString aFilePathLower = aFilePath;
aFilePathLower.LowerCase();
if (!aFilePathLower.EndsWith (".dds"))
{
// do not waste time on file system access in case of wrong file extension
return Handle(Image_CompressedPixMap)();
}
if (Handle(Image_CompressedPixMap) anImage = Image_DDSParser::Load (theSupported, aFilePath, 0))
{
myIsTopDown = anImage->IsTopDown();
return anImage;
}
return Handle(Image_CompressedPixMap)();
}
// =======================================================================
// function : GetImage
// purpose :
// =======================================================================
Handle(Image_PixMap) Graphic3d_TextureRoot::GetImage() const
Handle(Image_PixMap) Graphic3d_TextureRoot::GetImage (const Handle(Image_SupportedFormats)& theSupported)
{
if (Handle(Image_PixMap) anOldImage = GetImage())
{
myIsTopDown = anOldImage->IsTopDown();
return anOldImage; // compatibility with old API
}
// Case 1: texture source is specified as pixmap
if (!myPixMap.IsNull())
{
myIsTopDown = myPixMap->IsTopDown();
return myPixMap;
}
@@ -150,12 +197,38 @@ Handle(Image_PixMap) Graphic3d_TextureRoot::GetImage() const
}
Handle(Image_AlienPixMap) anImage = new Image_AlienPixMap();
if (!anImage->Load (aFilePath))
if (anImage->Load (aFilePath))
{
return Handle(Image_PixMap)();
myIsTopDown = anImage->IsTopDown();
convertToCompatible (theSupported, anImage);
return anImage;
}
return anImage;
return Handle(Image_PixMap)();
}
// =======================================================================
// function : convertToCompatible
// purpose :
// =======================================================================
void Graphic3d_TextureRoot::convertToCompatible (const Handle(Image_SupportedFormats)& theSupported,
const Handle(Image_PixMap)& theImage)
{
if (theSupported.IsNull()
|| theSupported->IsSupported (theImage->Format())
|| theImage.IsNull())
{
return;
}
if ((theImage->Format() == Image_Format_BGR32
|| theImage->Format() == Image_Format_BGR32))
{
Image_PixMap::SwapRgbaBgra (*theImage);
theImage->SetFormat (theImage->Format() == Image_Format_BGR32
? Image_Format_RGB32
: Image_Format_RGBA);
}
}
// =======================================================================

View File

@@ -25,6 +25,8 @@
#include <Standard_Type.hxx>
#include <TCollection_AsciiString.hxx>
class Image_CompressedPixMap;
class Image_SupportedFormats;
class Graphic3d_TextureParams;
//! This is the texture root class enable the dialog with the GraphicDriver allows the loading of texture.
@@ -79,6 +81,13 @@ public:
//! without re-creating texture source itself (since unique id should be never modified).
void UpdateRevision() { ++myRevision; }
//! This method will be called by graphic driver each time when texture resource should be created.
//! It is called in front of GetImage() for uploading compressed image formats natively supported by GPU.
//! @param theSupported [in] the list of supported compressed texture formats;
//! returning image in unsupported format will result in texture upload failure
//! @return compressed pixmap or NULL if image is not in supported compressed format
Standard_EXPORT virtual Handle(Image_CompressedPixMap) GetCompressedImage (const Handle(Image_SupportedFormats)& theSupported);
//! This method will be called by graphic driver each time when texture resource should be created.
//! Default constructors allow defining the texture source as path to texture image or directly as pixmap.
//! If the source is defined as path, then the image will be dynamically loaded when this method is called
@@ -86,7 +95,7 @@ public:
//! Inheritors may dynamically generate the image.
//! Notice, image data should be in Bottom-Up order (see Image_PixMap::IsTopDown())!
//! @return the image for texture.
Standard_EXPORT virtual Handle(Image_PixMap) GetImage() const;
Standard_EXPORT virtual Handle(Image_PixMap) GetImage (const Handle(Image_SupportedFormats)& theSupported);
//! @return low-level texture parameters
const Handle(Graphic3d_TextureParams)& GetParams() const { return myParams; }
@@ -104,6 +113,9 @@ public:
//! Set flag indicating color nature of values within the texture.
void SetColorMap (Standard_Boolean theIsColor) { myIsColorMap = theIsColor; }
//! Returns whether row's memory layout is top-down.
Standard_Boolean IsTopDown() const { return myIsTopDown; }
protected:
//! Creates a texture from a file
@@ -119,6 +131,13 @@ protected:
//! Unconditionally generate new texture id. Should be called only within constructor.
Standard_EXPORT void generateId();
//! Try converting image to compatible format.
Standard_EXPORT static void convertToCompatible (const Handle(Image_SupportedFormats)& theSupported,
const Handle(Image_PixMap)& theImage);
//! Method for supporting old API; another GetImage() method should be implemented instead.
virtual Handle(Image_PixMap) GetImage() const { return Handle(Image_PixMap)(); }
protected:
Handle(Graphic3d_TextureParams) myParams; //!< associated texture parameters
@@ -128,6 +147,8 @@ protected:
Standard_Size myRevision; //!< image revision - for signaling changes in the texture source (e.g. file update, pixmap update)
Graphic3d_TypeOfTexture myType; //!< texture type
Standard_Boolean myIsColorMap; //!< flag indicating color nature of values within the texture
Standard_Boolean myIsTopDown; //!< Stores rows's memory layout
};