return;
}
- if ((theImage->Format() == Image_Format_BGR32
- || theImage->Format() == Image_Format_BGR32))
+ switch (theImage->Format())
{
- Image_PixMap::SwapRgbaBgra (*theImage);
- theImage->SetFormat (theImage->Format() == Image_Format_BGR32
- ? Image_Format_RGB32
- : Image_Format_RGBA);
+ // BGR formats are unsupported in OpenGL ES, only RGB
+ case Image_Format_BGR:
+ Image_PixMap::SwapRgbaBgra (*theImage);
+ theImage->SetFormat (Image_Format_RGB);
+ break;
+ case Image_Format_BGRA:
+ case Image_Format_BGR32:
+ Image_PixMap::SwapRgbaBgra (*theImage);
+ theImage->SetFormat (theImage->Format() == Image_Format_BGR32 ? Image_Format_RGB32 : Image_Format_RGBA);
+ break;
+ default:
+ break;
}
}
#include <algorithm>
+namespace
+{
+ //! Structure defining image pixel format description.
+ struct Image_FormatInfo
+ {
+ const char* Name; //!< string representation
+ int Format; //!< enumeration name
+ unsigned int NbComponents; //!< number of components
+ unsigned int PixelSize; //!< bytes per pixel
+
+ Image_FormatInfo (Image_Format theFormat, const char* theName, unsigned int theNbComponents, Standard_Size thePixelSize)
+ : Name (theName), Format (theFormat), NbComponents (theNbComponents), PixelSize ((unsigned int )thePixelSize) {}
+
+ Image_FormatInfo (Image_CompressedFormat theFormat, const char* theName, unsigned int theNbComponents, Standard_Size thePixelSize)
+ : Name (theName), Format (theFormat), NbComponents (theNbComponents), PixelSize ((unsigned int )thePixelSize) {}
+ };
+
+ #define ImageFormatInfo(theName, theNbComponents, thePixelSize) \
+ Image_FormatInfo(Image_Format_##theName, #theName, theNbComponents, thePixelSize)
+
+ #define CompressedImageFormatInfo(theName, theNbComponents, thePixelSize) \
+ Image_FormatInfo(Image_CompressedFormat_##theName, #theName, theNbComponents, thePixelSize)
+
+ //! Table of image pixel formats.
+ static const Image_FormatInfo Image_Table_ImageFormats[Image_CompressedFormat_NB] =
+ {
+ ImageFormatInfo(UNKNOWN, 0, 1),
+ ImageFormatInfo(Gray, 1, 1),
+ ImageFormatInfo(Alpha, 1, 1),
+ ImageFormatInfo(RGB, 3, 3),
+ ImageFormatInfo(BGR, 3, 3),
+ ImageFormatInfo(RGB32, 3, 4),
+ ImageFormatInfo(BGR32, 3, 4),
+ ImageFormatInfo(RGBA, 4, 4),
+ ImageFormatInfo(BGRA, 4, 4),
+ ImageFormatInfo(GrayF, 1, sizeof(float)),
+ ImageFormatInfo(AlphaF, 1, sizeof(float)),
+ ImageFormatInfo(RGF, 2, sizeof(float) * 2),
+ ImageFormatInfo(RGBF, 3, sizeof(float) * 3),
+ ImageFormatInfo(BGRF, 3, sizeof(float) * 3),
+ ImageFormatInfo(RGBAF, 4, sizeof(float) * 4),
+ ImageFormatInfo(BGRAF, 4, sizeof(float) * 4),
+ CompressedImageFormatInfo(RGB_S3TC_DXT1, 3, 1), // DXT1 uses circa half a byte per pixel (64 bits per 4x4 block)
+ CompressedImageFormatInfo(RGBA_S3TC_DXT1, 4, 1),
+ CompressedImageFormatInfo(RGBA_S3TC_DXT3, 4, 1), // DXT3/5 uses circa 1 byte per pixel (128 bits per 4x4 block)
+ CompressedImageFormatInfo(RGBA_S3TC_DXT5, 4, 1)
+ };
+}
+
IMPLEMENT_STANDARD_RTTIEXT(Image_PixMap,Standard_Transient)
// =======================================================================
return THE_ALLOC;
}
+// =======================================================================
+// function : ImageFormatToString
+// purpose :
+// =======================================================================
+Standard_CString Image_PixMap::ImageFormatToString (Image_Format theFormat)
+{
+ return Image_Table_ImageFormats[theFormat].Name;
+}
+
+// =======================================================================
+// function : ImageFormatToString
+// purpose :
+// =======================================================================
+Standard_CString Image_PixMap::ImageFormatToString (Image_CompressedFormat theFormat)
+{
+ return Image_Table_ImageFormats[theFormat].Name;
+}
+
// =======================================================================
// function : Image_PixMap
// purpose :
// =======================================================================
Standard_Size Image_PixMap::SizePixelBytes (const Image_Format thePixelFormat)
{
- switch (thePixelFormat)
- {
- case Image_Format_GrayF:
- case Image_Format_AlphaF:
- return sizeof(float);
- case Image_Format_RGF:
- return sizeof(float) * 2;
- case Image_Format_RGBAF:
- case Image_Format_BGRAF:
- return sizeof(float) * 4;
- case Image_Format_RGBF:
- case Image_Format_BGRF:
- return sizeof(float) * 3;
- case Image_Format_RGBA:
- case Image_Format_BGRA:
- return 4;
- case Image_Format_RGB32:
- case Image_Format_BGR32:
- return 4;
- case Image_Format_RGB:
- case Image_Format_BGR:
- return 3;
- case Image_Format_Gray:
- case Image_Format_Alpha:
- return 1;
- case Image_Format_UNKNOWN:
- return 1;
- }
- return 1;
+ return Image_Table_ImageFormats[thePixelFormat].PixelSize;
}
// =======================================================================
#ifndef _Image_PixMap_H__
#define _Image_PixMap_H__
-#include <Image_Format.hxx>
+#include <Image_CompressedFormat.hxx>
#include <Image_PixMapData.hxx>
#include <Standard_Transient.hxx>
#include <Quantity_ColorRGBA.hxx>
//! Return default image data allocator.
Standard_EXPORT static const Handle(NCollection_BaseAllocator)& DefaultAllocator();
+ //! Return string representation of pixel format.
+ Standard_EXPORT static Standard_CString ImageFormatToString (Image_Format theFormat);
+
+ //! Return string representation of compressed pixel format.
+ Standard_EXPORT static Standard_CString ImageFormatToString (Image_CompressedFormat theFormat);
+
public: // high-level API
Image_Format Format() const { return myImgFormat; }
|| theSizeXY.y() < 1)
{
theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
- "Error: texture of 0 size cannot be created.");
+ TCollection_AsciiString ("Error: texture of 0 size cannot be created [") + myResourceId +"]");
Release (theCtx.get());
return false;
}
&& !theCtx->arbTexFloat)
{
theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
- "Error: floating-point textures are not supported by hardware.");
+ TCollection_AsciiString ("Error: floating-point textures are not supported by hardware [") + myResourceId +"]");
Release (theCtx.get());
return false;
}
{
theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
TCollection_AsciiString ("Error: Texture dimension - ") + theSizeXY.x() + "x" + theSizeXY.y()
- + " exceeds hardware limits (" + aMaxSize + "x" + aMaxSize + ")");
+ + " exceeds hardware limits (" + aMaxSize + "x" + aMaxSize + ")"
+ + " [" + myResourceId +"]");
Release (theCtx.get());
return false;
}
{
theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_HIGH,
TCollection_AsciiString ("Error: NPOT Textures (") + theSizeXY.x() + "x" + theSizeXY.y() + ")"
- " are not supported by hardware.");
+ " are not supported by hardware [" + myResourceId +"]");
Release (theCtx.get());
return false;
}
{
theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_HIGH,
TCollection_AsciiString ("Error: Mipmap NPOT Textures (") + theSizeXY.x() + "x" + theSizeXY.y() + ")"
- " are not supported by OpenGL ES 2.0");
+ " are not supported by OpenGL ES 2.0 [" + myResourceId +"]");
Release (theCtx.get());
return false;
}
return true;
#else
theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
- "Error: 1D textures are not supported by hardware.");
+ TCollection_AsciiString ( "Error: 1D textures are not supported by hardware [") + myResourceId +"]");
Release (theCtx.get());
return false;
#endif
+ " IF: " + OpenGl_TextureFormat::FormatFormat (anIntFormat)
+ " PF: " + OpenGl_TextureFormat::FormatFormat (theFormat.PixelFormat())
+ " DT: " + OpenGl_TextureFormat::FormatDataType (theFormat.DataType())
- + " can not be created with error " + OpenGl_Context::FormatGlError (anErr) + ".");
+ + " can not be created with error " + OpenGl_Context::FormatGlError (anErr)
+ + " [" + myResourceId +"]");
Unbind (theCtx);
Release (theCtx.get());
return false;
if (anErr != GL_NO_ERROR)
{
myMaxMipLevel = 0;
- theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_HIGH,
- "Warning: generating mipmaps requires GL_ARB_framebuffer_object extension which is missing.");
+ #if defined(GL_ES_VERSION_2_0)
+ if (theFormat.InternalFormat() == GL_RGB8
+ || theFormat.InternalFormat() == GL_SRGB8)
+ {
+ theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_HIGH,
+ TCollection_AsciiString ("Warning: generating mipmaps requires color-renderable format, while giving ")
+ + OpenGl_TextureFormat::FormatFormat (anIntFormat) + " [" + myResourceId +"]");
+ }
+ else
+ #endif
+ {
+ theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_HIGH,
+ TCollection_AsciiString ("Warning: generating mipmaps has failed [") + myResourceId +"]");
+ }
}
}
const OpenGl_TextureFormat aFormat = OpenGl_TextureFormat::FindFormat (theCtx, theImage.Format(), theIsColorMap);
if (!aFormat.IsValid())
{
+ theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
+ TCollection_AsciiString ("Error: No suitable texture format for ") + Image_PixMap::ImageFormatToString (theImage.Format()) + " image format"
+ + " [" + myResourceId +"]");
Release (theCtx.get());
return false;
}
const OpenGl_TextureFormat aFormat = OpenGl_TextureFormat::FindCompressedFormat (theCtx, theImage.CompressedFormat(), theIsColorMap);
if (!aFormat.IsValid())
{
+ theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
+ TCollection_AsciiString ("Error: No suitable texture format for ") + Image_PixMap::ImageFormatToString (theImage.CompressedFormat()) + " image format "
+ + " [" + myResourceId +"]");
Release (theCtx.get());
return false;
}
}
if (!aFormat.IsValid())
{
+ theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
+ TCollection_AsciiString ("Error: No suitable texture format for ") + Image_PixMap::ImageFormatToString (theFormat) + " image format"
+ + " [" + myResourceId +"]");
Unbind(theCtx);
Release(theCtx.get());
return false;
if (anErr != GL_NO_ERROR)
{
theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
- TCollection_AsciiString ("Unable to generate mipmap of cubemap. Error ") + OpenGl_Context::FormatGlError (anErr));
- Unbind (theCtx);
- Release (theCtx.get());
- return false;
+ TCollection_AsciiString ("Unable to generate mipmap of cubemap with format ")
+ + OpenGl_TextureFormat::FormatFormat (anIntFormat)
+ + ", error " + OpenGl_Context::FormatGlError (anErr));
+ myMaxMipLevel = 0;
}
}