Image_PixMap::ImgFormat - extend enumeration by ImgAlpha and ImgAlphaF.
OpenGl_Workspace::setTextureParams() - specify GL_REPLACE for 1-component textures with disabled modulation.
OpenGl_Texture::GetDataFormat() - return GL_LUMINANCE format for ImgGray format and GL_ALPHA for ImgAlpha.
vmarkerstest - override pixel format for grayscale images to ImgAlpha.
Add test case bugs/vis/bug25544_graytexture.
{
return false;
}
- if (!myGlyphImg.InitWrapper (Image_PixMap::ImgGray, aBitmap.buffer,
+ if (!myGlyphImg.InitWrapper (Image_PixMap::ImgAlpha, aBitmap.buffer,
aBitmap.width, aBitmap.rows, Abs (aBitmap.pitch)))
{
return false;
Quantity_Color aColor = myImage->PixelColor (aColumn, aRow, anAlphaValue);
Standard_Boolean aBitOn = Standard_False;
- if (myImage->Format() == Image_PixMap::ImgGray)
+ if (myImage->Format() == Image_PixMap::ImgAlpha)
+ {
+ aBitOn = anAlphaValue > theAlphaValue;
+ }
+ else if (myImage->Format() == Image_PixMap::ImgGray)
{
aBitOn = aColor.Red() > theAlphaValue;
}
const Standard_Integer aLowerIndex = myBitMap->Lower();
myImage = new Image_PixMap();
- myImage->InitZero (Image_PixMap::ImgGray, aSize + myMargin * 2, aSize + myMargin * 2);
+ myImage->InitZero (Image_PixMap::ImgAlpha, aSize + myMargin * 2, aSize + myMargin * 2);
for (Standard_Integer aRowIter = 0; aRowIter < myHeight; aRowIter++)
{
Standard_Byte* anImageRow = myImage->ChangeRow (aRowIter + aRowOffset);
if (!myImage.IsNull())
{
- if (myImage->Format() == Image_PixMap::ImgGray)
+ if (myImage->Format() == Image_PixMap::ImgGray
+ || myImage->Format() == Image_PixMap::ImgAlpha)
{
myImageAlpha = myImage;
}
else
{
myImageAlpha = new Image_PixMap();
- myImageAlpha->InitZero (Image_PixMap::ImgGray, myImage->Width(), myImage->Height());
+ myImageAlpha->InitZero (Image_PixMap::ImgAlpha, myImage->Width(), myImage->Height());
myImageAlpha->SetTopDown (Standard_False);
Quantity_Parameter anAlpha;
for (Standard_Size aRowIter = 0; aRowIter < myImage->Height(); aRowIter++)
switch (theFormat)
{
case Image_PixMap::ImgGrayF:
+ case Image_PixMap::ImgAlphaF:
return FIT_FLOAT;
case Image_PixMap::ImgRGBAF:
return FIT_RGBAF;
case Image_PixMap::ImgRGB:
case Image_PixMap::ImgBGR:
case Image_PixMap::ImgGray:
+ case Image_PixMap::ImgAlpha:
return FIT_BITMAP;
default:
return FIT_UNKNOWN;
}
case FIF_EXR:
{
- if (Format() == Image_PixMap::ImgGray)
+ if (Format() == Image_PixMap::ImgGray
+ || Format() == Image_PixMap::ImgAlpha)
{
anImageToDump = FreeImage_ConvertToType (myLibImage, FIT_FLOAT);
}
#include <Image_PixMap.hxx>
#include <NCollection_AlignedAllocator.hxx>
+#include <Standard_ProgramError.hxx>
#include <algorithm>
switch (thePixelFormat)
{
case ImgGrayF:
+ case ImgAlphaF:
return sizeof(float);
case ImgRGBAF:
case ImgBGRAF:
case ImgBGR:
return 3;
case ImgGray:
- default:
+ case ImgAlpha:
+ return 1;
+ case ImgUNKNOWN:
return 1;
}
+ return 1;
}
// =======================================================================
-// function : setFormat
+// function : SetFormat
// purpose :
// =======================================================================
-void Image_PixMap::setFormat (Image_PixMap::ImgFormat thePixelFormat)
+void Image_PixMap::SetFormat (Image_PixMap::ImgFormat thePixelFormat)
{
+ if (myImgFormat == thePixelFormat)
+ {
+ return;
+ }
+
+ if (!IsEmpty()
+ && SizePixelBytes (myImgFormat) != SizePixelBytes (thePixelFormat))
+ {
+ Standard_ProgramError::Raise ("Image_PixMap::SetFormat() - incompatible pixel format");
+ return;
+ }
+
myImgFormat = thePixelFormat;
}
Quantity_Parameter (Standard_Real (aPixel)),
Quantity_TOC_RGB);
}
+ case ImgAlphaF:
+ {
+ const Standard_ShortReal& aPixel = Value<Standard_ShortReal> (theY, theX);
+ theAlpha = aPixel;
+ return Quantity_Color (1.0, 1.0, 1.0, Quantity_TOC_RGB);
+ }
case ImgRGBAF:
{
const Image_ColorRGBAF& aPixel = Value<Image_ColorRGBAF> (theY, theX);
Quantity_Parameter (Standard_Real (aPixel) / 255.0),
Quantity_TOC_RGB);
}
- default:
+ case ImgAlpha:
{
- // not supported image type
- theAlpha = 0.0; // transparent
- return Quantity_Color (0.0, 0.0, 0.0, Quantity_TOC_RGB);
+ const Standard_Byte& aPixel = Value<Standard_Byte> (theY, theX);
+ theAlpha = Standard_Real (aPixel) / 255.0;
+ return Quantity_Color (1.0, 1.0, 1.0, Quantity_TOC_RGB);
+ }
+ case ImgUNKNOWN:
+ {
+ break;
}
}
+
+ // unsupported image type
+ theAlpha = 0.0; // transparent
+ return Quantity_Color (0.0, 0.0, 0.0, Quantity_TOC_RGB);
}
//! This enumeration define packed image plane formats
typedef enum tagFormat {
ImgUNKNOWN = 0, //!< unsupported or unknown format
- ImgGray = 1, //!< 1 byte per pixel
+ ImgGray = 1, //!< 1 byte per pixel, intensity of the color
+ ImgAlpha, //!< 1 byte per pixel, transparency
ImgRGB, //!< 3 bytes packed RGB image plane
ImgBGR, //!< same as RGB but with different components order
ImgRGB32, //!< 4 bytes packed RGB image plane (1 extra byte for alignment, may have undefined value)
ImgBGR32, //!< same as RGB but with different components order
ImgRGBA, //!< 4 bytes packed RGBA image plane
ImgBGRA, //!< same as RGBA but with different components order
- ImgGrayF, //!< 1 float (4-bytes) per pixel (1-component plane)
+ ImgGrayF, //!< 1 float (4-bytes) per pixel (1-component plane), intensity of the color
+ ImgAlphaF, //!< 1 float (4-bytes) per pixel (1-component plane), transparency
ImgRGBF, //!< 3 floats (12-bytes) RGB image plane
ImgBGRF, //!< same as RGBF but with different components order
ImgRGBAF, //!< 4 floats (16-bytes) RGBA image plane
return myImgFormat;
}
+ //! Override pixel format specified by InitXXX() methods.
+ //! Will throw exception if pixel size of new format is not equal to currently initialized format.
+ //! Intended to switch formats indicating different interpretation of the same data
+ //! (e.g. ImgGray and ImgAlpha).
+ Standard_EXPORT void SetFormat (const ImgFormat thePixelFormat);
+
//! @return image width in pixels
inline Standard_Size Width() const
{
return *reinterpret_cast<ColorType_t* >(myData.ChangeValue (theRow, theCol));
}
-protected:
-
- //! Setup pixel format
- Standard_EXPORT void setFormat (ImgFormat thePixelFormat);
-
protected:
Image_PixMapData myData; //!< data buffer
const Standard_Integer aMaxHeight = Max (aHeight1, aHeight2);
const Standard_Integer aSize = Max (aMaxWidth, aMaxHeight);
- aResultImage->InitZero (Image_PixMap::ImgGray, aSize, aSize);
+ aResultImage->InitZero (Image_PixMap::ImgAlpha, aSize, aSize);
if (!theImage1.IsNull())
{
const Standard_Integer aSize = Max (aWidth + 2, aHeight + 2); // includes extra margin
anImage = new Image_PixMap();
anImageA = new Image_PixMap();
- anImage ->InitZero (Image_PixMap::ImgBGRA, aSize, aSize);
- anImageA->InitZero (Image_PixMap::ImgGray, aSize, aSize);
+ anImage ->InitZero (Image_PixMap::ImgBGRA, aSize, aSize);
+ anImageA->InitZero (Image_PixMap::ImgAlpha, aSize, aSize);
// we draw a set of circles
Image_ColorBGRA aColor32;
Handle(OpenGl_Texture)& aTexture = myTextures.ChangeLast();
Image_PixMap aBlackImg;
- if (!aBlackImg.InitZero (Image_PixMap::ImgGray, Standard_Size(aTextureSizeX), Standard_Size(aTextureSizeY))
+ if (!aBlackImg.InitZero (Image_PixMap::ImgAlpha, Standard_Size(aTextureSizeX), Standard_Size(aTextureSizeY))
|| !aTexture->Init (theCtx, aBlackImg, Graphic3d_TOT_2D)) // myTextureFormat
{
TCollection_ExtendedString aMsg;
thePixelFormat = GL_BGRA;
theDataType = GL_FLOAT;
return true;
+ #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
case Image_PixMap::ImgRGB:
thePixelFormat = GL_RGB;
thePixelFormat = GL_RGBA;
theDataType = GL_FLOAT;
return true;
- default:
+ case Image_PixMap::ImgAlpha:
+ case Image_PixMap::ImgAlphaF:
+ return false; // GL_ALPHA is no more supported in core context
+ case Image_PixMap::ImgUNKNOWN:
return false;
}
+ return false;
}
Standard_Boolean OpenGl_GraphicDriver::BufferDump (const Graphic3d_CView& theCView,
myBitmapList (0)
{
//myParams->SetFilter (Graphic3d_TOTF_NEAREST);
+ myParams->SetModulate (Standard_False);
myParams->SetGenMode (Graphic3d_TOTM_SPRITE,
Graphic3d_Vec4 (0.0f, 0.0f, 0.0f, 0.0f),
Graphic3d_Vec4 (0.0f, 0.0f, 0.0f, 0.0f));
{
case Image_PixMap::ImgGrayF:
{
- theTextFormat = GL_ALPHA8; // GL_R8, GL_R32F
- thePixelFormat = GL_ALPHA; // GL_RED
- theDataType = GL_FLOAT;
+ if (theCtx->core11 == NULL)
+ {
+ theTextFormat = GL_R8; // GL_R32F
+ thePixelFormat = GL_RED;
+ }
+ else
+ {
+ theTextFormat = GL_LUMINANCE8;
+ thePixelFormat = GL_LUMINANCE;
+ }
+ theDataType = GL_FLOAT;
+ return true;
+ }
+ case Image_PixMap::ImgAlphaF:
+ {
+ if (theCtx->core11 == NULL)
+ {
+ theTextFormat = GL_R8; // GL_R32F
+ thePixelFormat = GL_RED;
+ }
+ else
+ {
+ theTextFormat = GL_ALPHA8;
+ thePixelFormat = GL_ALPHA;
+ }
+ theDataType = GL_FLOAT;
return true;
}
case Image_PixMap::ImgRGBAF:
{
- theTextFormat = GL_RGBA8; // GL_RGBA32F
+ theTextFormat = GL_RGBA8; // GL_RGBA32F
thePixelFormat = GL_RGBA;
theDataType = GL_FLOAT;
return true;
}
case Image_PixMap::ImgRGBF:
{
- theTextFormat = GL_RGB8; // GL_RGB32F
+ theTextFormat = GL_RGB8; // GL_RGB32F
thePixelFormat = GL_RGB;
theDataType = GL_FLOAT;
return true;
}
case Image_PixMap::ImgGray:
{
- theTextFormat = GL_ALPHA8; // GL_R8
- thePixelFormat = GL_ALPHA; // GL_RED
- theDataType = GL_UNSIGNED_BYTE;
+ if (theCtx->core11 == NULL)
+ {
+ theTextFormat = GL_R8;
+ thePixelFormat = GL_RED;
+ }
+ else
+ {
+ theTextFormat = GL_LUMINANCE8;
+ thePixelFormat = GL_LUMINANCE;
+ }
+ theDataType = GL_UNSIGNED_BYTE;
return true;
}
- default:
+ case Image_PixMap::ImgAlpha:
+ {
+ if (theCtx->core11 == NULL)
+ {
+ theTextFormat = GL_R8;
+ thePixelFormat = GL_RED;
+ }
+ else
+ {
+ theTextFormat = GL_ALPHA8;
+ thePixelFormat = GL_ALPHA;
+ }
+ theDataType = GL_UNSIGNED_BYTE;
+ return true;
+ }
+ case Image_PixMap::ImgUNKNOWN:
{
return false;
}
}
+ return false;
}
// =======================================================================
OpenGl_Utils::Rotate (aTextureMat, -aParams->Rotation(), 0.0f, 0.0f, 1.0f);
glLoadMatrixf (aTextureMat);
+ GLint anEnvMode = GL_MODULATE; // lighting mode
+ if (!aParams->IsModulate())
+ {
+ anEnvMode = GL_DECAL;
+ if (theTexture->GetFormat() == GL_ALPHA
+ || theTexture->GetFormat() == GL_LUMINANCE)
+ {
+ anEnvMode = GL_REPLACE;
+ }
+ }
+
// setup generation of texture coordinates
switch (aParams->GenMode())
{
{
glEnable (GL_POINT_SPRITE);
glTexEnvi (GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE);
- glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+ anEnvMode = GL_REPLACE;
GetGlContext()->core15->glPointParameteri (GL_POINT_SPRITE_COORD_ORIGIN, GL_LOWER_LEFT);
}
break;
}
// setup lighting
- if (aParams->GenMode() != Graphic3d_TOTM_SPRITE)
- {
- glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, aParams->IsModulate() ? GL_MODULATE : GL_DECAL);
- }
+ glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, anEnvMode);
#endif
// get active sampler object to override default texture parameters
std::cerr << "Could not load image from file '" << aFileName << "'!\n";
return 1;
}
+ if (anImage->Format() == Image_PixMap::ImgGray)
+ {
+ anImage->SetFormat (Image_PixMap::ImgAlpha);
+ }
+ else if (anImage->Format() == Image_PixMap::ImgGrayF)
+ {
+ anImage->SetFormat (Image_PixMap::ImgAlphaF);
+ }
anAspect = new Graphic3d_AspectMarker3d (anImage);
}
else
--- /dev/null
+puts "============"
+puts "0025544: Visualization, TKOpenGl - support grayscale textures"
+puts "============"
+puts ""
+
+vinit View1
+vclear
+
+box b 1 2 3
+vaxo
+vsetdispmode 1
+vdisplay b
+vtexture b 1 -modulate on
+vfit
+
+set aColorMod [vreadpixel 290 180 rgb name]
+vdump $imagedir/${casename}_modulated.png
+
+vtexture b 1 -modulate off
+set aColorDec [vreadpixel 290 180 rgb name]
+vdump $imagedir/${casename}_decal.png
+
+if {"$aColorMod" != "GOLDENROD4"} {
+ puts "Error: wrong color with modulation ON"
+}
+if {"$aColorDec" != "GRAY80"} {
+ puts "Error: wrong color with modulation OFF"
+}