1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-04 18:06:22 +03:00

0031477: Visualization, TKOpenGl - fetch/wrap getBufferSubData() function from WebGL 2.0

Added OpenGl_Context::GetBufferSubData() implementing getBufferSubData() based on capabilities of various APIs.
Added OpenGl_VertexBuffer::GetSubData() similar to OpenGl_VertexBuffer::SubData().
This commit is contained in:
kgv 2020-05-28 19:42:13 +03:00 committed by bugmaster
parent 872f98d9ef
commit d4cefcc0da
7 changed files with 179 additions and 0 deletions

View File

@ -65,6 +65,7 @@ IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Context,Standard_Transient)
#endif
#ifdef __EMSCRIPTEN__
#include <emscripten.h>
#include <emscripten/html5.h>
//! Check if WebGL extension is available and activate it
@ -138,6 +139,7 @@ OpenGl_Context::OpenGl_Context (const Handle(OpenGl_Caps)& theCaps)
core45 (NULL),
core45back (NULL),
caps (!theCaps.IsNull() ? theCaps : new OpenGl_Caps()),
hasGetBufferData (Standard_False),
#if defined(GL_ES_VERSION_2_0)
hasHighp (Standard_False),
hasUintIndex(Standard_False),
@ -1677,6 +1679,7 @@ void OpenGl_Context::init (const Standard_Boolean theIsCoreProfile)
{
core30 = (OpenGl_GlCore30* )(&(*myFuncs));
core30fwd = (OpenGl_GlCore30Fwd* )(&(*myFuncs));
hasGetBufferData = true;
}
// load OpenGL ES 3.1 new functions
@ -2183,6 +2186,7 @@ void OpenGl_Context::init (const Standard_Boolean theIsCoreProfile)
core15 = (OpenGl_GlCore15* )(&(*myFuncs));
}
core15fwd = (OpenGl_GlCore15Fwd* )(&(*myFuncs));
hasGetBufferData = true;
}
else
{
@ -4612,6 +4616,36 @@ bool OpenGl_Context::SetSampleAlphaToCoverage (bool theToEnable)
return anOldValue;
}
// =======================================================================
// function : GetBufferSubData
// purpose :
// =======================================================================
bool OpenGl_Context::GetBufferSubData (GLenum theTarget, GLintptr theOffset, GLsizeiptr theSize, void* theData)
{
if (!hasGetBufferData)
{
return false;
}
#ifdef __EMSCRIPTEN__
EM_ASM_(
{
Module.ctx.getBufferSubData($0, $1, HEAPU8.subarray($2, $2 + $3));
}, theTarget, theOffset, theData, theSize);
return true;
#elif defined(GL_ES_VERSION_2_0)
if (void* aData = core30fwd->glMapBufferRange (theTarget, theOffset, theSize, GL_MAP_READ_BIT))
{
memcpy (theData, aData, theSize);
core30fwd->glUnmapBuffer (theTarget);
return true;
}
return false;
#else
core15fwd->glGetBufferSubData (theTarget, theOffset, theSize, theData);
return true;
#endif
}
// =======================================================================
// function : DumpJson
// purpose :

View File

@ -987,6 +987,17 @@ public: //! @name methods to alter or retrieve current state
//! Set line feater width.
void SetLineFeather(Standard_ShortReal theValue) { myLineFeather = theValue; }
//! Wrapper over glGetBufferSubData(), implemented as:
//! - OpenGL 1.5+ (desktop) via glGetBufferSubData();
//! - OpenGL ES 3.0+ via glMapBufferRange();
//! - WebGL 2.0+ via gl.getBufferSubData().
//! @param theTarget [in] target buffer to map
//! @param theOffset [in] offset to the beginning of sub-data
//! @param theSize [in] number of bytes to read
//! @param theData [out] destination pointer to fill
//! @return FALSE if functionality is unavailable
Standard_EXPORT bool GetBufferSubData (GLenum theTarget, GLintptr theOffset, GLsizeiptr theSize, void* theData);
//! Return Graphics Driver's vendor.
const TCollection_AsciiString& Vendor() const { return myVendor; }
@ -1044,6 +1055,7 @@ public: //! @name core profiles
public: //! @name extensions
Standard_Boolean hasGetBufferData; //!< flag indicating if GetBufferSubData() is supported
Standard_Boolean hasHighp; //!< highp in GLSL ES fragment shader is supported
Standard_Boolean hasUintIndex; //!< GLuint for index buffer is supported (always available on desktop; on OpenGL ES - since 3.0 or as extension GL_OES_element_index_uint)
Standard_Boolean hasTexRGBA8; //!< always available on desktop; on OpenGL ES - since 3.0 or as extension GL_OES_rgb8_rgba8

View File

@ -132,6 +132,18 @@ public: //! @name OpenGL 3.0 additives to 2.1
using theBaseClass_t::glVertexAttribI4ubv;
using theBaseClass_t::glVertexAttribI4usv;
#endif
#if defined(GL_ES_VERSION_2_0)
// the following functions from OpenGL 1.5 have been added only in OpenGL ES 3.0
using theBaseClass_t::glGenQueries;
using theBaseClass_t::glDeleteQueries;
using theBaseClass_t::glIsQuery;
using theBaseClass_t::glBeginQuery;
using theBaseClass_t::glEndQuery;
using theBaseClass_t::glGetQueryiv;
using theBaseClass_t::glGetQueryObjectuiv;
using theBaseClass_t::glUnmapBuffer;
#endif
};
//! OpenGL 3.0 core based on 2.1 version.

View File

@ -160,6 +160,33 @@ bool OpenGl_VertexBuffer::subData (const Handle(OpenGl_Context)& theGlCtx,
return isDone;
}
// =======================================================================
// function : getSubData
// purpose :
// =======================================================================
bool OpenGl_VertexBuffer::getSubData (const Handle(OpenGl_Context)& theGlCtx,
const GLsizei theElemFrom,
const GLsizei theElemsNb,
void* theData,
const GLenum theDataType)
{
if (!IsValid() || myDataType != theDataType
|| theElemFrom < 0 || ((theElemFrom + theElemsNb) > myElemsNb)
|| !theGlCtx->hasGetBufferData)
{
return false;
}
Bind (theGlCtx);
const size_t aDataSize = sizeOfGlType (theDataType);
const GLintptr anOffset = GLintptr (theElemFrom) * GLintptr (myComponentsNb) * aDataSize;
const GLsizeiptr aSize = GLsizeiptr(theElemsNb) * GLsizeiptr(myComponentsNb) * aDataSize;
bool isDone = theGlCtx->GetBufferSubData (GetTarget(), anOffset, aSize, theData);
isDone = isDone && (glGetError() == GL_NO_ERROR);
Unbind (theGlCtx);
return isDone;
}
// =======================================================================
// function : BindVertexAttrib
// purpose :

View File

@ -154,6 +154,20 @@ public:
return subData (theGlCtx, theElemFrom, theElemsNb, theData, GL_FLOAT);
}
//! Read back buffer sub-range.
//! Notice that VBO will be unbound after this call.
//! Function reads portion of data from this VBO using glGetBufferSubData().
//! @param theElemFrom [in] element id from which replace buffer data (>=0);
//! @param theElemsNb [in] elements count (theElemFrom + theElemsNb <= GetElemsNb());
//! @param theData [out] destination pointer to GLfloat data.
bool GetSubData (const Handle(OpenGl_Context)& theGlCtx,
const GLsizei theElemFrom,
const GLsizei theElemsNb,
GLfloat* theData)
{
return getSubData (theGlCtx, theElemFrom, theElemsNb, theData, GL_FLOAT);
}
//! Notice that VBO will be unbound after this call.
//! Function replaces portion of data within this VBO using glBufferSubData().
//! The VBO should be initialized before call.
@ -168,6 +182,20 @@ public:
return subData (theGlCtx, theElemFrom, theElemsNb, theData, GL_UNSIGNED_INT);
}
//! Read back buffer sub-range.
//! Notice that VBO will be unbound after this call.
//! Function reads portion of data from this VBO using glGetBufferSubData().
//! @param theElemFrom [in] element id from which replace buffer data (>=0);
//! @param theElemsNb [in] elements count (theElemFrom + theElemsNb <= GetElemsNb());
//! @param theData [out] destination pointer to GLuint data.
bool GetSubData (const Handle(OpenGl_Context)& theGlCtx,
const GLsizei theElemFrom,
const GLsizei theElemsNb,
GLuint* theData)
{
return getSubData (theGlCtx, theElemFrom, theElemsNb, theData, GL_UNSIGNED_INT);
}
//! Notice that VBO will be unbound after this call.
//! Function replaces portion of data within this VBO using glBufferSubData().
//! The VBO should be initialized before call.
@ -182,6 +210,20 @@ public:
return subData (theGlCtx, theElemFrom, theElemsNb, theData, GL_UNSIGNED_SHORT);
}
//! Read back buffer sub-range.
//! Notice that VBO will be unbound after this call.
//! Function reads portion of data from this VBO using glGetBufferSubData().
//! @param theElemFrom [in] element id from which replace buffer data (>=0);
//! @param theElemsNb [in] elements count (theElemFrom + theElemsNb <= GetElemsNb());
//! @param theData [out] destination pointer to GLushort data.
bool GetSubData (const Handle(OpenGl_Context)& theGlCtx,
const GLsizei theElemFrom,
const GLsizei theElemsNb,
GLushort* theData)
{
return getSubData (theGlCtx, theElemFrom, theElemsNb, theData, GL_UNSIGNED_SHORT);
}
//! Notice that VBO will be unbound after this call.
//! Function replaces portion of data within this VBO using glBufferSubData().
//! The VBO should be initialized before call.
@ -196,6 +238,20 @@ public:
return subData (theGlCtx, theElemFrom, theElemsNb, theData, GL_UNSIGNED_BYTE);
}
//! Read back buffer sub-range.
//! Notice that VBO will be unbound after this call.
//! Function reads portion of data from this VBO using glGetBufferSubData().
//! @param theElemFrom [in] element id from which replace buffer data (>=0);
//! @param theElemsNb [in] elements count (theElemFrom + theElemsNb <= GetElemsNb());
//! @param theData [out] destination pointer to GLubyte data.
bool GetSubData (const Handle(OpenGl_Context)& theGlCtx,
const GLsizei theElemFrom,
const GLsizei theElemsNb,
GLubyte* theData)
{
return getSubData (theGlCtx, theElemFrom, theElemsNb, theData, GL_UNSIGNED_BYTE);
}
//! Bind this VBO to active GLSL program.
Standard_EXPORT void BindVertexAttrib (const Handle(OpenGl_Context)& theGlCtx,
const GLuint theAttribLoc) const;
@ -286,6 +342,13 @@ public: //! @name advanced methods
const void* theData,
const GLenum theDataType);
//! Read back buffer sub-range.
Standard_EXPORT virtual bool getSubData (const Handle(OpenGl_Context)& theGlCtx,
const GLsizei theElemFrom,
const GLsizei theElemsNb,
void* theData,
const GLenum theDataType);
//! Setup array pointer - either for active GLSL program OpenGl_Context::ActiveProgram()
//! or for FFP using bindFixed() when no program bound.
static void bindAttribute (const Handle(OpenGl_Context)& theGlCtx,

View File

@ -175,3 +175,27 @@ bool OpenGl_VertexBufferCompat::subData (const Handle(OpenGl_Context)& ,
memcpy (myData->ChangeData() + anOffset, theData, aNbBytes);
return true;
}
// =======================================================================
// function : getSubData
// purpose :
// =======================================================================
bool OpenGl_VertexBufferCompat::getSubData (const Handle(OpenGl_Context)& ,
const GLsizei theElemFrom,
const GLsizei theElemsNb,
void* theData,
const GLenum theDataType)
{
if (!IsValid() || myDataType != theDataType
|| theElemFrom < 0 || ((theElemFrom + theElemsNb) > myElemsNb)
|| theData == NULL)
{
return false;
}
const size_t aDataSize = sizeOfGlType (theDataType);
const size_t anOffset = size_t(theElemFrom) * size_t(myComponentsNb) * aDataSize;
const size_t aNbBytes = size_t(theElemsNb) * size_t(myComponentsNb) * aDataSize;
memcpy (theData, myData->Data() + anOffset, aNbBytes);
return true;
}

View File

@ -82,6 +82,13 @@ public: //! @name advanced methods
const void* theData,
const GLenum theDataType) Standard_OVERRIDE;
//! Read back buffer sub-range.
Standard_EXPORT virtual bool getSubData (const Handle(OpenGl_Context)& theGlCtx,
const GLsizei theElemFrom,
const GLsizei theElemsNb,
void* theData,
const GLenum theDataType) Standard_OVERRIDE;
protected:
Handle(NCollection_Buffer) myData; //!< buffer data