From: isk Date: Thu, 29 Oct 2015 08:39:18 +0000 (+0300) Subject: 0025464: Visualization - provide package for Volume Rendering. X-Git-Url: http://git.dev.opencascade.org/gitweb/?a=commitdiff_plain;h=8fd140974405cae08de0495cdd29b587e4394512;p=occt-copy.git 0025464: Visualization - provide package for Volume Rendering. Add two functions OSD_OpenStream for std::ifstream. Add four functions SetUnfirom in the OpenGl_ShaderProgram for 64-bit unsigned integer variables. Add OpenGl_Texture::Init3D. Update Declarations.glsl. --- diff --git a/src/BVH/BVH_Box.hxx b/src/BVH/BVH_Box.hxx index 838fb90352..e0755db224 100644 --- a/src/BVH/BVH_Box.hxx +++ b/src/BVH/BVH_Box.hxx @@ -281,4 +281,18 @@ namespace BVH #include +//! 2D box of double precision reals. +typedef BVH_Box BVH_Box2d; +//! 3D box of double precision reals. +typedef BVH_Box BVH_Box3d; +//! 4D box of double precision reals. +typedef BVH_Box BVH_Box4d; + +//! 2D box of single precision reals. +typedef BVH_Box BVH_Box2f; +//! 3D box of single precision reals. +typedef BVH_Box BVH_Box3f; +//! 4D box of single precision reals. +typedef BVH_Box BVH_Box4f; + #endif // _BVH_Box_Header diff --git a/src/NCollection/NCollection_Vec3.hxx b/src/NCollection/NCollection_Vec3.hxx index 73b9743368..82efc597bd 100644 --- a/src/NCollection/NCollection_Vec3.hxx +++ b/src/NCollection/NCollection_Vec3.hxx @@ -351,6 +351,15 @@ public: return NCollection_Vec3 (Element_t(0), Element_t(0), Element_t(1)); } + //! Convert the vector. + template + NCollection_Vec3 Convert() const + { + return NCollection_Vec3 (static_cast (v[0]), + static_cast (v[1]), + static_cast (v[2])); + } + private: Element_t v[3]; //!< define the vector as array to avoid structure alignment issues diff --git a/src/OSD/OSD_OpenFile.cxx b/src/OSD/OSD_OpenFile.cxx index c2e37cd703..d6d29fabd6 100644 --- a/src/OSD/OSD_OpenFile.cxx +++ b/src/OSD/OSD_OpenFile.cxx @@ -123,3 +123,37 @@ void OSD_OpenStream(std::ofstream& theStream, #endif } +// ============================================== +// function : OSD_OpenStream +// purpose : Opens file stream +// ============================================== +void OSD_OpenStream (std::ifstream& theStream, + const char* theName, + const std::ios_base::openmode theMode) +{ +#ifdef _WIN32 + // file name is treated as UTF-8 string and converted to UTF-16 one + const TCollection_ExtendedString aFileNameW (theName, Standard_True); + theStream.open ((const wchar_t* )aFileNameW.ToExtString(), theMode); +#else + theStream.open (theName, theMode); +#endif +} + +// ============================================== +// function : OSD_OpenStream +// purpose : Opens file stream +// ============================================== +void OSD_OpenStream (std::ifstream& theStream, + const TCollection_ExtendedString& theName, + const std::ios_base::openmode theMode) +{ +#ifdef _WIN32 + theStream.open ((const wchar_t* )theName.ToExtString(), theMode); +#else + // conversion in UTF-8 for linux + NCollection_Utf8String aString ((const Standard_Utf16Char*)theName.ToExtString()); + theStream.open (aString.ToCString(),theMode); +#endif +} + diff --git a/src/OSD/OSD_OpenFile.hxx b/src/OSD/OSD_OpenFile.hxx index 5c4a70aafd..6254f448a0 100644 --- a/src/OSD/OSD_OpenFile.hxx +++ b/src/OSD/OSD_OpenFile.hxx @@ -40,6 +40,22 @@ __Standard_API void OSD_OpenStream (std::ofstream& theStream, const TCollection_ExtendedString& theName, const std::ios_base::openmode theMode); +//! Function opens the file stream. +//! @param theStream stream to open +//! @param theName name of file encoded in UTF-8 +//! @param theMode opening mode +__Standard_API void OSD_OpenStream (std::ifstream& theStream, + const char* theName, + const std::ios_base::openmode theMode); + +//! Function opens the file stream. +//! @param theStream stream to open +//! @param theName name of file encoded in UTF-16 +//! @param theMode opening mode +__Standard_API void OSD_OpenStream (std::ifstream& theStream, + const TCollection_ExtendedString& theName, + const std::ios_base::openmode theMode); + //! Function opens the file buffer. //! @param theBuff file buffer to open //! @param theName name of file encoded in UTF-8 diff --git a/src/OpenGl/OpenGl_Context.hxx b/src/OpenGl/OpenGl_Context.hxx index 074f467e5d..23053e8f86 100644 --- a/src/OpenGl/OpenGl_Context.hxx +++ b/src/OpenGl/OpenGl_Context.hxx @@ -284,6 +284,12 @@ public: Standard_EXPORT static Standard_Boolean CheckExtension (const char* theExtString, const char* theExtName); + //! Returns true if hardware supports floating-point texture. + bool HasFloatingPointTexture() + { + return (IsGlGreaterEqual (3, 0) || CheckExtension ("GL_ARB_texture_float")); + } + //! Auxiliary template to retrieve GL function pointer. //! Pointer to function retrieved from library is statically casted //! to requested type - there no way to check real signature of exported function. diff --git a/src/OpenGl/OpenGl_Texture.cxx b/src/OpenGl/OpenGl_Texture.cxx index dde0ff748a..f380b125e0 100644 --- a/src/OpenGl/OpenGl_Texture.cxx +++ b/src/OpenGl/OpenGl_Texture.cxx @@ -183,7 +183,7 @@ bool OpenGl_Texture::GetDataFormat (const Handle(OpenGl_Context)& theCtx, { if (theCtx->core11 == NULL) { - theTextFormat = GL_R8; // GL_R32F + theTextFormat = GL_R32F; thePixelFormat = GL_RED; } else @@ -198,7 +198,7 @@ bool OpenGl_Texture::GetDataFormat (const Handle(OpenGl_Context)& theCtx, { if (theCtx->core11 == NULL) { - theTextFormat = GL_R8; // GL_R32F + theTextFormat = GL_R32F; thePixelFormat = GL_RED; } else @@ -211,7 +211,7 @@ bool OpenGl_Texture::GetDataFormat (const Handle(OpenGl_Context)& theCtx, } case Image_PixMap::ImgRGBAF: { - theTextFormat = GL_RGBA8; // GL_RGBA32F + theTextFormat = GL_RGBA32F; thePixelFormat = GL_RGBA; theDataType = GL_FLOAT; return true; @@ -222,14 +222,14 @@ bool OpenGl_Texture::GetDataFormat (const Handle(OpenGl_Context)& theCtx, { return false; } - theTextFormat = GL_RGBA8; // GL_RGBA32F + theTextFormat = GL_RGBA32F; thePixelFormat = GL_BGRA_EXT; // equals to GL_BGRA theDataType = GL_FLOAT; return true; } case Image_PixMap::ImgRGBF: { - theTextFormat = GL_RGB8; // GL_RGB32F + theTextFormat = GL_RGB32F; thePixelFormat = GL_RGB; theDataType = GL_FLOAT; return true; @@ -237,7 +237,7 @@ bool OpenGl_Texture::GetDataFormat (const Handle(OpenGl_Context)& theCtx, case Image_PixMap::ImgBGRF: { #if !defined(GL_ES_VERSION_2_0) - theTextFormat = GL_RGB8; // GL_RGB32F + theTextFormat = GL_RGB32F; thePixelFormat = GL_BGR; // equals to GL_BGR_EXT theDataType = GL_FLOAT; return true; @@ -373,6 +373,19 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx, myHasMipmaps = Standard_False; myTextFormat = thePixelFormat; #if !defined(GL_ES_VERSION_2_0) + if (theTextFormat >= Image_PixMap::ImgGrayF + && !theCtx->HasFloatingPointTexture()) + { + TCollection_ExtendedString aMsg ("Error: floating-point textures are not supproted by hardware."); + theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, + GL_DEBUG_TYPE_ERROR, + 0, + GL_DEBUG_SEVERITY_HIGH, + aMsg); + + Release (theCtx.operator->()); + return false; + } const GLint anIntFormat = theTextFormat; #else // ES does not support sized formats and format conversions - them detected from data type @@ -473,7 +486,7 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx, glTexImage1D (GL_PROXY_TEXTURE_1D, 0, anIntFormat, aWidth, 0, thePixelFormat, theDataType, NULL); - glGetTexLevelParameteriv (GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &aTestWidth); + glGetTexLevelParameteriv (GL_PROXY_TEXTURE_1D, 0, GL_TEXTURE_WIDTH, &aTestWidth); if (aTestWidth == 0) { // no memory or broken input parameters @@ -612,7 +625,7 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx, { const TCollection_ExtendedString aWarnMessage ("Warning: generating mipmaps requires GL_ARB_framebuffer_object extension which is missing."); - theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB, GL_DEBUG_TYPE_PORTABILITY_ARB, 0, GL_DEBUG_SEVERITY_HIGH_ARB, aWarnMessage); + theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_HIGH, aWarnMessage); Unbind (theCtx); Release (theCtx.operator->()); @@ -691,6 +704,22 @@ bool OpenGl_Texture::InitRectangle (const Handle(OpenGl_Context)& theCtx, const GLint anIntFormat = theFormat.Internal(); myTextFormat = theFormat.Format(); + if (anIntFormat == GL_FLOAT + || !theCtx->HasFloatingPointTexture()) + { + TCollection_ExtendedString aMsg ("Error: floating-point textures are not supproted by hardware."); + + theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB, + GL_DEBUG_TYPE_ERROR_ARB, + 0, + GL_DEBUG_SEVERITY_HIGH_ARB, + aMsg); + + Release (theCtx.operator->()); + Unbind (theCtx); + return false; + } + glTexImage2D (GL_PROXY_TEXTURE_RECTANGLE, 0, anIntFormat, @@ -740,3 +769,123 @@ bool OpenGl_Texture::InitRectangle (const Handle(OpenGl_Context)& theCtx, return false; #endif } + +// ======================================================================= +// function : Init3D +// purpose : +// ======================================================================= +bool OpenGl_Texture::Init3D (const Handle(OpenGl_Context)& theCtx, + const Standard_Integer theSizeX, + const Standard_Integer theSizeY, + const Standard_Integer theSizeZ, + const OpenGl_TextureFormat& theFormat, + const void* thePixels) +{ + if (!Create (theCtx) || !theCtx->IsGlGreaterEqual (1, 2)) + { + return false; + } + + myTarget = GL_TEXTURE_3D; + + const GLsizei aSizeX = Min (theCtx->MaxTextureSize(), theSizeX); + const GLsizei aSizeY = Min (theCtx->MaxTextureSize(), theSizeY); + const GLsizei aSizeZ = Min (theCtx->MaxTextureSize(), theSizeZ); + + Bind (theCtx); + + if (myParams->Filter() == Graphic3d_TOTF_NEAREST) + { + glTexParameteri (myTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri (myTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + } + else + { + glTexParameteri (myTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri (myTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + } + + if (theFormat.Internal() == GL_FLOAT + && !theCtx->HasFloatingPointTexture()) + { + TCollection_ExtendedString aMsg ("Error: floating-point textures are not supproted by hardware."); + + theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, + GL_DEBUG_TYPE_ERROR, + 0, + GL_DEBUG_SEVERITY_HIGH, + aMsg); + + Release (theCtx.operator->()); + Unbind (theCtx); + return false; + } + +#if !defined(OPENGL_ES_2_0) + theCtx->core15fwd->glTexImage3D (GL_PROXY_TEXTURE_3D, + 0, + theFormat.Internal(), + aSizeX, + aSizeY, + aSizeZ, + 0, + theFormat.Format(), + theFormat.DataType(), + NULL); + + GLint aTestSizeX = 0; + GLint aTestSizeY = 0; + GLint aTestSizeZ = 0; + + glGetTexLevelParameteriv (GL_PROXY_TEXTURE_3D, 0, GL_TEXTURE_WIDTH, &aTestSizeX); + glGetTexLevelParameteriv (GL_PROXY_TEXTURE_3D, 0, GL_TEXTURE_HEIGHT, &aTestSizeY); + glGetTexLevelParameteriv (GL_PROXY_TEXTURE_3D, 0, GL_TEXTURE_DEPTH, &aTestSizeZ); + + if (aTestSizeX == 0 || aTestSizeY == 0 || aTestSizeZ == 0) + { + Unbind (theCtx); + return false; + } +#endif + + GLint anInternal = theFormat.Internal(); + + if (anInternal == GL_R8_SNORM + || anInternal == GL_R16_SNORM + || anInternal == GL_RED_SNORM) + { + glPixelTransferf (GL_RED_SCALE, 0.5f); + glPixelTransferf (GL_RED_BIAS, 0.5f); + } + + glTexParameteri (GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP); + glTexParameteri (GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP); + glTexParameteri (GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP); + + theCtx->core15fwd->glTexImage3D (GL_TEXTURE_3D, + 0, + anInternal, + aSizeX, + aSizeY, + aSizeZ, + 0, + theFormat.Format(), + theFormat.DataType(), + thePixels); + + glPixelTransferf (GL_RED_SCALE, 1.0f); + glPixelTransferf (GL_RED_BIAS, 0.0f); + + if (glGetError() != GL_NO_ERROR) + { + Unbind (theCtx); + return false; + } + + mySizeX = aSizeX; + mySizeY = aSizeY; + mySizeZ = aSizeZ; + + Unbind (theCtx); + return true; +} diff --git a/src/OpenGl/OpenGl_Texture.hxx b/src/OpenGl/OpenGl_Texture.hxx index 1a1a0ed955..5a1878725c 100644 --- a/src/OpenGl/OpenGl_Texture.hxx +++ b/src/OpenGl/OpenGl_Texture.hxx @@ -49,6 +49,37 @@ struct OpenGl_TextureFormatSelector return GL_NONE; } } + + static GLint DataType() + { + return GL_UNSIGNED_BYTE; + } +}; + +template<> +struct OpenGl_TextureFormatSelector +{ + static GLint Internal (GLuint theChannels) + { + switch (theChannels) + { + case 1: + return GL_R8_SNORM; + case 2: + return GL_RG8_SNORM; + case 3: + return GL_RGB8_SNORM; + case 4: + return GL_RGBA8_SNORM; + default: + return GL_NONE; + } + } + + static GLint DataType() + { + return GL_BYTE; + } }; template<> @@ -70,6 +101,37 @@ struct OpenGl_TextureFormatSelector return GL_NONE; } } + + static GLint DataType() + { + return GL_UNSIGNED_SHORT; + } +}; + +template<> +struct OpenGl_TextureFormatSelector +{ + static GLint Internal (GLuint theChannels) + { + switch (theChannels) + { + case 1: + return GL_R16_SNORM; + case 2: + return GL_RG16_SNORM; + case 3: + return GL_RGB16_SNORM; + case 4: + return GL_RGBA16_SNORM; + default: + return GL_NONE; + } + } + + static GLint DataType() + { + return GL_SHORT; + } }; template<> @@ -91,6 +153,63 @@ struct OpenGl_TextureFormatSelector return GL_NONE; } } + + static GLint DataType() + { + return GL_FLOAT; + } +}; + +template<> +struct OpenGl_TextureFormatSelector +{ + static GLint Internal (GLuint theChannels) + { + switch (theChannels) + { + case 1: + return GL_RED; + case 2: + return GL_RG; + case 3: + return GL_RGB; + case 4: + return GL_RGBA; + default: + return GL_NONE; + } + } + + static GLint DataType() + { + return GL_UNSIGNED_INT; + } +}; + +template<> +struct OpenGl_TextureFormatSelector +{ + static GLint Internal (GLuint theChannels) + { + switch (theChannels) + { + case 1: + return GL_RED_SNORM; + case 2: + return GL_RG_SNORM; + case 3: + return GL_RGB_SNORM; + case 4: + return GL_RGBA_SNORM; + default: + return GL_NONE; + } + } + + static GLint DataType() + { + return GL_INT; + } }; //! Stores parameters of OpenGL texture format. @@ -124,25 +243,36 @@ public: return myInternal; } + //! Returns OpenGL data type of the pixel data. + inline GLint DataType() const + { + return myDataType; + } + //! Returns texture format for specified type and number of channels. template static OpenGl_TextureFormat Create() { - return OpenGl_TextureFormat (N, OpenGl_TextureFormatSelector::Internal (N)); + return OpenGl_TextureFormat (N, + OpenGl_TextureFormatSelector::Internal (N), + OpenGl_TextureFormatSelector::DataType ()); } private: //! Creates new texture format. OpenGl_TextureFormat (const GLint theChannels, - const GLint theInternal) + const GLint theInternal, + const GLint theDataType) : myInternal (theInternal), - myChannels (theChannels) {} + myChannels (theChannels), + myDataType (theDataType) {} private: GLint myInternal; //!< OpenGL internal format of the pixel data GLint myChannels; //!< Number of channels for each pixel (from 1 to 4) + GLint myDataType; //!< OpenGL data type of input pixel data }; @@ -254,6 +384,14 @@ public: const Standard_Integer theSizeY, const OpenGl_TextureFormat& theFormat); + //! Initializes 3D texture rectangle with specified format and size. + Standard_EXPORT bool Init3D (const Handle(OpenGl_Context)& theCtx, + const Standard_Integer theSizeX, + const Standard_Integer theSizeY, + const Standard_Integer theSizeZ, + const OpenGl_TextureFormat& theFormat, + const void* thePixels); + //! @return true if texture was generated within mipmaps Standard_EXPORT const Standard_Boolean HasMipmaps() const; @@ -273,9 +411,10 @@ public: protected: GLuint myTextureId; //!< GL resource ID - GLenum myTarget; //!< GL_TEXTURE_1D/GL_TEXTURE_2D + GLenum myTarget; //!< GL_TEXTURE_1D/GL_TEXTURE_2D/GL_TEXTURE_3D GLsizei mySizeX; //!< texture width GLsizei mySizeY; //!< texture height + GLsizei mySizeZ; //!< texture depth GLenum myTextFormat; //!< texture format - GL_RGB, GL_RGBA,... Standard_Boolean myHasMipmaps; //!< flag indicates that texture was uploaded with mipmaps bool myIsAlpha; //!< indicates alpha format diff --git a/src/Shaders/Declarations.glsl b/src/Shaders/Declarations.glsl index 6dd9f62c3d..e8af5db3d2 100644 --- a/src/Shaders/Declarations.glsl +++ b/src/Shaders/Declarations.glsl @@ -24,13 +24,17 @@ #define THE_SHADER_IN in #define THE_SHADER_OUT out #define THE_OUT out + #define occTexture1D texture #define occTexture2D texture + #define occTexture3D texture #else #define THE_ATTRIBUTE attribute #define THE_SHADER_IN varying #define THE_SHADER_OUT varying #define THE_OUT + #define occTexture1D texture1D #define occTexture2D texture2D + #define occTexture3D texture3D #endif #ifdef GL_ES @@ -46,9 +50,11 @@ THE_ATTRIBUTE vec4 occTexCoord; THE_ATTRIBUTE vec4 occVertColor; #elif (__VERSION__ >= 130) - out vec4 occFragColor; + out vec4 occFragColor; + out float occFragDepth; #else #define occFragColor gl_FragColor + #define occFragDepth gl_FragDepth #endif // Matrix state