// Created by: Kirill GAVRILOV // Copyright (c) 2013-2014 OPEN CASCADE SAS // // This file is part of Open CASCADE Technology software library. // // This library is free software; you can redistribute it and/or modify it under // the terms of the GNU Lesser General Public License version 2.1 as published // by the Free Software Foundation, with special exception defined in the file // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT // distribution for complete text of the license and disclaimer of any warranty. // // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. #include #include #include #include #include IMPLEMENT_STANDARD_RTTIEXT(OpenGl_TextureBuffer, OpenGl_Buffer) // ======================================================================= // function : OpenGl_TextureBuffer // purpose : // ======================================================================= OpenGl_TextureBuffer::OpenGl_TextureBuffer() : OpenGl_Buffer(), myTextureId (NO_TEXTURE), myTexFormat (GL_RGBA32F) { // } // ======================================================================= // function : ~OpenGl_TextureBuffer // purpose : // ======================================================================= OpenGl_TextureBuffer::~OpenGl_TextureBuffer() { Release (NULL); } // ======================================================================= // function : GetTarget // purpose : // ======================================================================= unsigned int OpenGl_TextureBuffer::GetTarget() const { return GL_TEXTURE_BUFFER; // GL_TEXTURE_BUFFER for OpenGL 3.1+, OpenGL ES 3.2 } // ======================================================================= // function : Release // purpose : // ======================================================================= void OpenGl_TextureBuffer::Release (OpenGl_Context* theGlCtx) { if (myTextureId != NO_TEXTURE) { // application can not handle this case by exception - this is bug in code Standard_ASSERT_RETURN (theGlCtx != NULL, "OpenGl_TextureBuffer destroyed without GL context! Possible GPU memory leakage...",); if (theGlCtx->IsValid()) { theGlCtx->core20fwd->glDeleteTextures (1, &myTextureId); } myTextureId = NO_TEXTURE; } base_type::Release (theGlCtx); } // ======================================================================= // function : Create // purpose : // ======================================================================= bool OpenGl_TextureBuffer::Create (const Handle(OpenGl_Context)& theGlCtx) { if (!base_type::Create (theGlCtx)) { return false; } if (myTextureId == NO_TEXTURE) { theGlCtx->core20fwd->glGenTextures (1, &myTextureId); } return myTextureId != NO_TEXTURE; } // ======================================================================= // function : Init // purpose : // ======================================================================= bool OpenGl_TextureBuffer::Init (const Handle(OpenGl_Context)& theGlCtx, const unsigned int theComponentsNb, const Standard_Integer theElemsNb, const float* theData) { if (theGlCtx->arbTBO == NULL) { return false; } else if (theComponentsNb < 1 || theComponentsNb > 4) { // unsupported format return false; } else if (theComponentsNb == 3 && !theGlCtx->arbTboRGB32) { return false; } else if (!Create (theGlCtx) || !base_type::Init (theGlCtx, theComponentsNb, theElemsNb, theData)) { return false; } switch (theComponentsNb) { case 1: myTexFormat = GL_R32F; break; case 2: myTexFormat = GL_RG32F; break; case 3: myTexFormat = GL_RGB32F; break; // GL_ARB_texture_buffer_object_rgb32 case 4: myTexFormat = GL_RGBA32F; break; } Bind (theGlCtx); BindTexture (theGlCtx, Graphic3d_TextureUnit_0); theGlCtx->arbTBO->glTexBuffer (GetTarget(), myTexFormat, myBufferId); UnbindTexture(theGlCtx, Graphic3d_TextureUnit_0); Unbind (theGlCtx); return true; } // ======================================================================= // function : Init // purpose : // ======================================================================= bool OpenGl_TextureBuffer::Init (const Handle(OpenGl_Context)& theGlCtx, const unsigned int theComponentsNb, const Standard_Integer theElemsNb, const unsigned int* theData) { if (theGlCtx->arbTBO == NULL) { return false; } else if (theComponentsNb < 1 || theComponentsNb > 4) { // unsupported format return false; } else if (theComponentsNb == 3 && !theGlCtx->arbTboRGB32) { return false; } else if (!Create (theGlCtx) || !base_type::Init (theGlCtx, theComponentsNb, theElemsNb, theData)) { return false; } switch (theComponentsNb) { case 1: myTexFormat = GL_R32I; break; case 2: myTexFormat = GL_RG32I; break; case 3: myTexFormat = GL_RGB32I; break; case 4: myTexFormat = GL_RGBA32I; break; } Bind (theGlCtx); BindTexture (theGlCtx, Graphic3d_TextureUnit_0); theGlCtx->arbTBO->glTexBuffer (GetTarget(), myTexFormat, myBufferId); UnbindTexture(theGlCtx, Graphic3d_TextureUnit_0); Unbind (theGlCtx); return true; } // ======================================================================= // function : Init // purpose : // ======================================================================= bool OpenGl_TextureBuffer::Init (const Handle(OpenGl_Context)& theGlCtx, const unsigned int theComponentsNb, const Standard_Integer theElemsNb, const unsigned short* theData) { if (theGlCtx->arbTBO == NULL) { return false; } else if (theComponentsNb < 1 || theComponentsNb > 4) { // unsupported format return false; } else if (!Create (theGlCtx) || !base_type::Init (theGlCtx, theComponentsNb, theElemsNb, theData)) { return false; } switch (theComponentsNb) { case 1: myTexFormat = GL_R16I; break; case 2: myTexFormat = GL_RG16I; break; case 3: myTexFormat = GL_RGB16I; break; case 4: myTexFormat = GL_RGBA16I; break; } Bind (theGlCtx); BindTexture (theGlCtx, Graphic3d_TextureUnit_0); theGlCtx->arbTBO->glTexBuffer (GetTarget(), myTexFormat, myBufferId); UnbindTexture(theGlCtx, Graphic3d_TextureUnit_0); Unbind (theGlCtx); return true; } // ======================================================================= // function : Init // purpose : // ======================================================================= bool OpenGl_TextureBuffer::Init (const Handle(OpenGl_Context)& theGlCtx, const unsigned int theComponentsNb, const Standard_Integer theElemsNb, const Standard_Byte* theData) { if (theGlCtx->arbTBO == NULL) { return false; } else if (theComponentsNb < 1 || theComponentsNb > 4) { // unsupported format return false; } else if (!Create (theGlCtx) || !base_type::Init (theGlCtx, theComponentsNb, theElemsNb, theData)) { return false; } switch (theComponentsNb) { case 1: myTexFormat = GL_R8; break; case 2: myTexFormat = GL_RG8; break; case 3: myTexFormat = GL_RGB8; break; case 4: myTexFormat = GL_RGBA8; break; } Bind (theGlCtx); BindTexture (theGlCtx, Graphic3d_TextureUnit_0); theGlCtx->arbTBO->glTexBuffer (GetTarget(), myTexFormat, myBufferId); UnbindTexture(theGlCtx, Graphic3d_TextureUnit_0); Unbind (theGlCtx); return true; } // ======================================================================= // function : BindTexture // purpose : // ======================================================================= void OpenGl_TextureBuffer::BindTexture (const Handle(OpenGl_Context)& theGlCtx, const Graphic3d_TextureUnit theTextureUnit) const { theGlCtx->core20fwd->glActiveTexture (GL_TEXTURE0 + theTextureUnit); theGlCtx->core20fwd->glBindTexture (GetTarget(), myTextureId); } // ======================================================================= // function : UnbindTexture // purpose : // ======================================================================= void OpenGl_TextureBuffer::UnbindTexture (const Handle(OpenGl_Context)& theGlCtx, const Graphic3d_TextureUnit theTextureUnit) const { theGlCtx->core20fwd->glActiveTexture (GL_TEXTURE0 + theTextureUnit); theGlCtx->core20fwd->glBindTexture (GetTarget(), NO_TEXTURE); }