#else
di << "FreeImage disabled\n";
#endif
-#ifdef HAVE_OPENCL
- di << "OpenCL enabled (HAVE_OPENCL)\n";
+#ifdef HAVE_GLES2
+ di << "OpenGL: ES2\n";
#else
- di << "OpenCL disabled\n";
+ di << "OpenGL: desktop\n";
#endif
#ifdef HAVE_VTK
di << "VTK enabled (HAVE_VTK)\n";
#elif defined(__SUNPRO_C)
di << "Compiler: Sun Studio (__SUNPRO_C = " << __SUNPROC_C << ")\n";
#elif defined(_MSC_VER)
- di << "Compiler: MS Visual C++ " << (int)(_MSC_VER/100-6) << "." << (int)((_MSC_VER/10)-60-10*(int)(_MSC_VER/100-6)) << " (_MSC_FULL_VER = " << _MSC_FULL_VER << ")\n";
+ #if _MSC_VER < 1900
+ di << "Compiler: MS Visual C++ " << (int)(_MSC_VER/100-6) << "." << (int)((_MSC_VER/10)-60-10*(int)(_MSC_VER/100-6)) << " (_MSC_FULL_VER = " << _MSC_FULL_VER << ")\n";
+ #else
+ di << "Compiler: MS Visual C++ " << (int)(_MSC_VER/100-5) << "." << (int)((_MSC_VER/10)-50-10*(int)(_MSC_VER/100-5)) << " (_MSC_FULL_VER = " << _MSC_FULL_VER << ")\n";
+ #endif
#elif defined(__GNUC__)
di << "Compiler: GCC " << __GNUC__ << "." << __GNUC_MINOR__ << "." << __GNUC_PATCHLEVEL__ << "\n";
#else
theAlpha = 0.0; // transparent
return Quantity_Color (0.0, 0.0, 0.0, Quantity_TOC_RGB);
}
+
+// =======================================================================
+// function : SwapRgbaBgra
+// purpose :
+// =======================================================================
+bool Image_PixMap::SwapRgbaBgra (Image_PixMap& theImage)
+{
+ switch (theImage.Format())
+ {
+ case Image_PixMap::ImgBGR32:
+ case Image_PixMap::ImgRGB32:
+ case Image_PixMap::ImgBGRA:
+ case Image_PixMap::ImgRGBA:
+ {
+ const bool toResetAlpha = theImage.Format() == Image_PixMap::ImgBGR32
+ || theImage.Format() == Image_PixMap::ImgRGB32;
+ for (Standard_Size aRow = 0; aRow < theImage.SizeY(); ++aRow)
+ {
+ for (Standard_Size aCol = 0; aCol < theImage.SizeX(); ++aCol)
+ {
+ Image_ColorRGBA& aPixel = theImage.ChangeValue<Image_ColorRGBA> (aRow, aCol);
+ Image_ColorBGRA aPixelCopy = theImage.Value <Image_ColorBGRA> (aRow, aCol);
+ aPixel.r() = aPixelCopy.r();
+ aPixel.g() = aPixelCopy.g();
+ aPixel.b() = aPixelCopy.b();
+ if (toResetAlpha)
+ {
+ aPixel.a() = 255;
+ }
+ }
+ }
+ return true;
+ }
+ case Image_PixMap::ImgBGR:
+ case Image_PixMap::ImgRGB:
+ {
+ for (Standard_Size aRow = 0; aRow < theImage.SizeY(); ++aRow)
+ {
+ for (Standard_Size aCol = 0; aCol < theImage.SizeX(); ++aCol)
+ {
+ Image_ColorRGB& aPixel = theImage.ChangeValue<Image_ColorRGB> (aRow, aCol);
+ Image_ColorBGR aPixelCopy = theImage.Value <Image_ColorBGR> (aRow, aCol);
+ aPixel.r() = aPixelCopy.r();
+ aPixel.g() = aPixelCopy.g();
+ aPixel.b() = aPixelCopy.b();
+ }
+ }
+ return true;
+ }
+ case Image_PixMap::ImgBGRF:
+ case Image_PixMap::ImgRGBF:
+ case Image_PixMap::ImgBGRAF:
+ case Image_PixMap::ImgRGBAF:
+ {
+ for (Standard_Size aRow = 0; aRow < theImage.SizeY(); ++aRow)
+ {
+ for (Standard_Size aCol = 0; aCol < theImage.SizeX(); ++aCol)
+ {
+ Image_ColorRGBF& aPixel = theImage.ChangeValue<Image_ColorRGBF> (aRow, aCol);
+ Image_ColorBGRF aPixelCopy = theImage.Value <Image_ColorBGRF> (aRow, aCol);
+ aPixel.r() = aPixelCopy.r();
+ aPixel.g() = aPixelCopy.g();
+ aPixel.b() = aPixelCopy.b();
+ }
+ }
+ return true;
+ }
+ default: return false;
+ }
+}
return !aUnion.myChar[0];
}
+ //! Auxiliary method for swapping bytes between RGB and BGR formats.
+ //! This method modifies the image data but does not change pixel format!
+ //! Method will fail if pixel format is not one of the following:
+ //! - ImgRGB32 / ImgBGR32
+ //! - ImgRGBA / ImgBGRA
+ //! - ImgRGB / ImgBGR
+ //! - ImgRGBF / ImgBGRF
+ //! - ImgRGBAF / ImgBGRAF
+ Standard_EXPORT static bool SwapRgbaBgra (Image_PixMap& theImage);
+
public: // high-level API
inline ImgFormat Format() const
// function : ResetErrors
// purpose :
// =======================================================================
-void OpenGl_Context::ResetErrors (const bool theToPrintErrors)
+bool OpenGl_Context::ResetErrors (const bool theToPrintErrors)
{
int aPrevErr = 0;
int anErr = ::glGetError();
+ const bool hasError = anErr != GL_NO_ERROR;
if (!theToPrintErrors)
{
for (; anErr != GL_NO_ERROR && aPrevErr != anErr; aPrevErr = anErr, anErr = ::glGetError())
{
//
}
- return;
+ return hasError;
}
for (; anErr != GL_NO_ERROR && aPrevErr != anErr; aPrevErr = anErr, anErr = ::glGetError())
const TCollection_ExtendedString aMsg = TCollection_ExtendedString ("Unhandled GL error: ") + anErrId;
PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_OTHER, 0, GL_DEBUG_SEVERITY_LOW, aMsg);
}
+ return hasError;
}
// =======================================================================
const OpenGl_GlFunctions* Functions() const { return myFuncs.operator->(); }
//! Clean up errors stack for this GL context (glGetError() in loop).
- Standard_EXPORT void ResetErrors (const bool theToPrintErrors = false);
+ //! @return true if some error has been cleared
+ Standard_EXPORT bool ResetErrors (const bool theToPrintErrors = false);
//! This method uses system-dependent API to retrieve information
//! about GL context bound to the current thread.
char aPsFont[64];
getGL2PSFontName (theAspect.Aspect()->Font().ToCString(), aPsFont);
+ (void)theIs2d;
#if !defined(GL_ES_VERSION_2_0)
if (theIs2d)
{
#include <Graphic3d_TextureParams.hxx>
#include <Graphic3d_TransformUtils.hxx>
+#include <NCollection_AlignedAllocator.hxx>
IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Workspace,Standard_Transient)
IMPLEMENT_STANDARD_RTTIEXT(OpenGl_RaytraceFilter,OpenGl_RenderFilter)
theFbo.Nullify();
}
-inline bool getDataFormat (const Image_PixMap& theData,
- GLenum& thePixelFormat,
- GLenum& theDataType)
+// =======================================================================
+// function : getAligned
+// purpose :
+// =======================================================================
+inline Standard_Size getAligned (const Standard_Size theNumber,
+ const Standard_Size theAlignment)
+{
+ return theNumber + theAlignment - 1 - (theNumber - 1) % theAlignment;
+}
+
+template<typename T>
+inline void convertRowFromRgba (T* theRgbRow,
+ const Image_ColorRGBA* theRgbaRow,
+ const Standard_Size theWidth)
+{
+ for (Standard_Size aCol = 0; aCol < theWidth; ++aCol)
+ {
+ const Image_ColorRGBA& anRgba = theRgbaRow[aCol];
+ T& anRgb = theRgbRow[aCol];
+ anRgb.r() = anRgba.r();
+ anRgb.g() = anRgba.g();
+ anRgb.b() = anRgba.b();
+ }
+}
+
+// =======================================================================
+// function : BufferDump
+// purpose :
+// =======================================================================
+Standard_Boolean OpenGl_Workspace::BufferDump (const Handle(OpenGl_FrameBuffer)& theFbo,
+ Image_PixMap& theImage,
+ const Graphic3d_BufferType& theBufferType)
{
- thePixelFormat = GL_RGB;
- theDataType = GL_UNSIGNED_BYTE;
- switch (theData.Format())
+ if (theImage.IsEmpty()
+ || !Activate())
+ {
+ return Standard_False;
+ }
+
+ GLenum aFormat = 0;
+ GLenum aType = 0;
+ bool toSwapRgbaBgra = false;
+ bool toConvRgba2Rgb = false;
+ switch (theImage.Format())
{
#if !defined(GL_ES_VERSION_2_0)
case Image_PixMap::ImgGray:
- thePixelFormat = GL_DEPTH_COMPONENT;
- theDataType = GL_UNSIGNED_BYTE;
- return true;
+ aFormat = GL_DEPTH_COMPONENT;
+ aType = GL_UNSIGNED_BYTE;
+ break;
case Image_PixMap::ImgGrayF:
- thePixelFormat = GL_DEPTH_COMPONENT;
- theDataType = GL_FLOAT;
- return true;
+ aFormat = GL_DEPTH_COMPONENT;
+ aType = GL_FLOAT;
+ break;
+ case Image_PixMap::ImgRGB:
+ aFormat = GL_RGB;
+ aType = GL_UNSIGNED_BYTE;
+ break;
case Image_PixMap::ImgBGR:
- thePixelFormat = GL_BGR;
- theDataType = GL_UNSIGNED_BYTE;
- return true;
+ aFormat = GL_BGR;
+ aType = GL_UNSIGNED_BYTE;
+ break;
case Image_PixMap::ImgBGRA:
case Image_PixMap::ImgBGR32:
- thePixelFormat = GL_BGRA;
- theDataType = GL_UNSIGNED_BYTE;
- return true;
+ aFormat = GL_BGRA;
+ aType = GL_UNSIGNED_BYTE;
+ break;
case Image_PixMap::ImgBGRF:
- thePixelFormat = GL_BGR;
- theDataType = GL_FLOAT;
- return true;
+ aFormat = GL_BGR;
+ aType = GL_FLOAT;
+ break;
case Image_PixMap::ImgBGRAF:
- thePixelFormat = GL_BGRA;
- theDataType = GL_FLOAT;
- return true;
+ aFormat = GL_BGRA;
+ aType = GL_FLOAT;
+ break;
#else
case Image_PixMap::ImgGray:
case Image_PixMap::ImgGrayF:
- case Image_PixMap::ImgBGR:
- case Image_PixMap::ImgBGRA:
- case Image_PixMap::ImgBGR32:
case Image_PixMap::ImgBGRF:
case Image_PixMap::ImgBGRAF:
- return false;
- #endif
+ return Standard_False;
+ case Image_PixMap::ImgBGRA:
+ case Image_PixMap::ImgBGR32:
+ aFormat = GL_RGBA;
+ aType = GL_UNSIGNED_BYTE;
+ toSwapRgbaBgra = true;
+ break;
+ case Image_PixMap::ImgBGR:
case Image_PixMap::ImgRGB:
- thePixelFormat = GL_RGB;
- theDataType = GL_UNSIGNED_BYTE;
- return true;
+ aFormat = GL_RGBA;
+ aType = GL_UNSIGNED_BYTE;
+ toConvRgba2Rgb = true;
+ break;
+ #endif
case Image_PixMap::ImgRGBA:
case Image_PixMap::ImgRGB32:
- thePixelFormat = GL_RGBA;
- theDataType = GL_UNSIGNED_BYTE;
- return true;
+ aFormat = GL_RGBA;
+ aType = GL_UNSIGNED_BYTE;
+ break;
case Image_PixMap::ImgRGBF:
- thePixelFormat = GL_RGB;
- theDataType = GL_FLOAT;
- return true;
+ aFormat = GL_RGB;
+ aType = GL_FLOAT;
+ break;
case Image_PixMap::ImgRGBAF:
- thePixelFormat = GL_RGBA;
- theDataType = GL_FLOAT;
- return true;
+ aFormat = GL_RGBA;
+ aType = GL_FLOAT;
+ break;
case Image_PixMap::ImgAlpha:
case Image_PixMap::ImgAlphaF:
- return false; // GL_ALPHA is no more supported in core context
+ return Standard_False; // GL_ALPHA is no more supported in core context
case Image_PixMap::ImgUNKNOWN:
- return false;
+ return Standard_False;
}
- return false;
-}
-
-// =======================================================================
-// function : getAligned
-// purpose :
-// =======================================================================
-inline Standard_Size getAligned (const Standard_Size theNumber,
- const Standard_Size theAlignment)
-{
- return theNumber + theAlignment - 1 - (theNumber - 1) % theAlignment;
-}
-// =======================================================================
-// function : BufferDump
-// purpose :
-// =======================================================================
-Standard_Boolean OpenGl_Workspace::BufferDump (const Handle(OpenGl_FrameBuffer)& theFbo,
- Image_PixMap& theImage,
- const Graphic3d_BufferType& theBufferType)
-{
- GLenum aFormat, aType;
- if (theImage.IsEmpty()
- || !getDataFormat (theImage, aFormat, aType)
- || !Activate())
+ if (aFormat == 0)
{
return Standard_False;
}
+
#if !defined(GL_ES_VERSION_2_0)
GLint aReadBufferPrev = GL_BACK;
if (theBufferType == Graphic3d_BT_Depth
isBatchCopy = false;
}
#endif
+ if (toConvRgba2Rgb)
+ {
+ Handle(NCollection_BaseAllocator) anAlloc = new NCollection_AlignedAllocator (16);
+ const Standard_Size aRowSize = theImage.SizeX() * 4;
+ NCollection_Buffer aRowBuffer (anAlloc);
+ if (!aRowBuffer.Allocate (aRowSize))
+ {
+ return Standard_False;
+ }
- if (!isBatchCopy)
+ for (Standard_Size aRow = 0; aRow < theImage.SizeY(); ++aRow)
+ {
+ // Image_PixMap rows indexation always starts from the upper corner
+ // while order in memory depends on the flag and processed by ChangeRow() method
+ glReadPixels (0, GLint(theImage.SizeY() - aRow - 1), GLsizei (theImage.SizeX()), 1, aFormat, aType, aRowBuffer.ChangeData());
+ const Image_ColorRGBA* aRowDataRgba = (const Image_ColorRGBA* )aRowBuffer.Data();
+ if (theImage.Format() == Image_PixMap::ImgBGR)
+ {
+ convertRowFromRgba ((Image_ColorBGR* )theImage.ChangeRow (aRow), aRowDataRgba, theImage.SizeX());
+ }
+ else
+ {
+ convertRowFromRgba ((Image_ColorRGB* )theImage.ChangeRow (aRow), aRowDataRgba, theImage.SizeX());
+ }
+ }
+ }
+ else if (!isBatchCopy)
{
// copy row by row
for (Standard_Size aRow = 0; aRow < theImage.SizeY(); ++aRow)
{
glReadPixels (0, 0, GLsizei (theImage.SizeX()), GLsizei (theImage.SizeY()), aFormat, aType, theImage.ChangeData());
}
+ const bool hasErrors = myGlContext->ResetErrors (true);
glPixelStorei (GL_PACK_ALIGNMENT, 1);
#if !defined(GL_ES_VERSION_2_0)
glReadBuffer (aReadBufferPrev);
#endif
}
- return Standard_True;
+
+ if (toSwapRgbaBgra)
+ {
+ Image_PixMap::SwapRgbaBgra (theImage);
+ }
+
+ return !hasErrors;
}
// =======================================================================
|| theImage.SizeX() != Standard_Size(aTargetSize.x())
|| theImage.SizeY() != Standard_Size(aTargetSize.y()))
{
- const bool isBigEndian = Image_PixMap::IsBigEndianHost();
Image_PixMap::ImgFormat aFormat = Image_PixMap::ImgUNKNOWN;
switch (theParams.BufferType)
{
- case Graphic3d_BT_RGB: aFormat = isBigEndian ? Image_PixMap::ImgRGB : Image_PixMap::ImgBGR; break;
- case Graphic3d_BT_RGBA: aFormat = isBigEndian ? Image_PixMap::ImgRGBA : Image_PixMap::ImgBGRA; break;
+ case Graphic3d_BT_RGB: aFormat = Image_PixMap::ImgRGB; break;
+ case Graphic3d_BT_RGBA: aFormat = Image_PixMap::ImgRGBA; break;
case Graphic3d_BT_Depth: aFormat = Image_PixMap::ImgGrayF; break;
}
}
Image_AlienPixMap aPixMap;
-
- bool isBigEndian = Image_PixMap::IsBigEndianHost();
Image_PixMap::ImgFormat aFormat = Image_PixMap::ImgUNKNOWN;
switch (aParams.BufferType)
{
- case Graphic3d_BT_RGB: aFormat = isBigEndian ? Image_PixMap::ImgRGB : Image_PixMap::ImgBGR; break;
- case Graphic3d_BT_RGBA: aFormat = isBigEndian ? Image_PixMap::ImgRGBA : Image_PixMap::ImgBGRA; break;
+ case Graphic3d_BT_RGB: aFormat = Image_PixMap::ImgRGB; break;
+ case Graphic3d_BT_RGBA: aFormat = Image_PixMap::ImgRGBA; break;
case Graphic3d_BT_Depth: aFormat = Image_PixMap::ImgGrayF; break;
}
}
Image_PixMap aPixMapL, aPixMapR;
- aPixMapL.InitWrapper (aFormat, aPixMap.ChangeData(),
+ aPixMapL.InitWrapper (aPixMap.Format(), aPixMap.ChangeData(),
aParams.Width, aParams.Height, aPixMap.SizeRowBytes());
- aPixMapR.InitWrapper (aFormat, aPixMap.ChangeData() + aPixMap.SizeRowBytes() * aParams.Height,
+ aPixMapR.InitWrapper (aPixMap.Format(), aPixMap.ChangeData() + aPixMap.SizeRowBytes() * aParams.Height,
aParams.Width, aParams.Height, aPixMap.SizeRowBytes());
aParams.StereoOptions = V3d_SDO_LEFT_EYE;
return 1;
}
- Image_PixMap::ImgFormat aFormat = Image_PixMap::IsBigEndianHost() ? Image_PixMap::ImgRGBA : Image_PixMap::ImgBGRA;
+ Image_PixMap::ImgFormat aFormat = Image_PixMap::ImgRGBA;
Graphic3d_BufferType aBufferType = Graphic3d_BT_RGBA;
Standard_Integer aWidth, aHeight;
const char* aParam = theArgVec[anIter];
if ( strcasecmp( aParam, "rgb" ) == 0 )
{
- aFormat = Image_PixMap::IsBigEndianHost() ? Image_PixMap::ImgRGB : Image_PixMap::ImgBGR;
+ aFormat = Image_PixMap::ImgRGB;
aBufferType = Graphic3d_BT_RGB;
}
else if ( strcasecmp( aParam, "hls" ) == 0 )
{
- aFormat = Image_PixMap::IsBigEndianHost() ? Image_PixMap::ImgRGB : Image_PixMap::ImgBGR;
+ aFormat = Image_PixMap::ImgRGB;
aBufferType = Graphic3d_BT_RGB;
toShowHls = Standard_True;
}
}
else if ( strcasecmp( aParam, "rgba" ) == 0 )
{
- aFormat = Image_PixMap::IsBigEndianHost() ? Image_PixMap::ImgRGBA : Image_PixMap::ImgBGRA;
+ aFormat = Image_PixMap::ImgRGBA;
aBufferType = Graphic3d_BT_RGBA;
}
else if ( strcasecmp( aParam, "rgbaf" ) == 0 )
puts "ERROR: Wrong number of entities in vertice-edge-face shift selection with overlap allowed!"
}
-vdump $imagedir/${casename}
+vdump $imagedir/${casename}.png
# to print tolerance in case of failure:
puts [vselprops -print]
-vdump $imagedir/${casename}
+vdump $imagedir/${casename}.png
checkcolor ${x_on_edge} ${y_on_edge} 1 1 0
checkcolor $x_on_vert $y_on_vert 0 1 1
-vdump ${imagedir}/${casename}
+vdump ${imagedir}/${casename}.png
puts "ERROR: Vertex was not selected!"
}
-vdump ${imagedir}/${casename}
+vdump ${imagedir}/${casename}.png