mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-08-14 13:30:48 +03:00
0032349: Visualization, TKOpenGl - move base buffer interface out from OpenGl_VertexBuffer class to OpenGl_Buffer
OpenGl_Buffer - added new class as a base for OpenGl_VertexBuffer, OpenGl_IndexBuffer, OpenGl_TextureBuffer. OpenGl_TextureBufferArb has been renamed to OpenGl_TextureBuffer. OpenGl_FrameBuffer - added initializers taking vec2i instead of (int,int) for dimensions.
This commit is contained in:
446
src/OpenGl/OpenGl_Buffer.cxx
Normal file
446
src/OpenGl/OpenGl_Buffer.cxx
Normal file
@@ -0,0 +1,446 @@
|
||||
// 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 <OpenGl_Buffer.hxx>
|
||||
|
||||
#include <OpenGl_GlCore30.hxx>
|
||||
#include <OpenGl_Context.hxx>
|
||||
#include <OpenGl_ShaderManager.hxx>
|
||||
#include <Standard_Assert.hxx>
|
||||
|
||||
IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Buffer, OpenGl_Resource)
|
||||
|
||||
// =======================================================================
|
||||
// function : sizeOfGlType
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
size_t OpenGl_Buffer::sizeOfGlType (unsigned int theType)
|
||||
{
|
||||
switch (theType)
|
||||
{
|
||||
case GL_BYTE:
|
||||
case GL_UNSIGNED_BYTE: return sizeof(Standard_Byte);
|
||||
case GL_SHORT:
|
||||
case GL_UNSIGNED_SHORT: return sizeof(unsigned short);
|
||||
#ifdef GL_INT
|
||||
case GL_INT:
|
||||
#endif
|
||||
case GL_UNSIGNED_INT: return sizeof(unsigned int);
|
||||
case GL_FLOAT: return sizeof(float);
|
||||
#ifdef GL_DOUBLE
|
||||
case GL_DOUBLE: return sizeof(double);
|
||||
#endif
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : FormatTarget
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
TCollection_AsciiString OpenGl_Buffer::FormatTarget (unsigned int theTarget)
|
||||
{
|
||||
switch (theTarget)
|
||||
{
|
||||
case GL_ARRAY_BUFFER: return "GL_ARRAY_BUFFER";
|
||||
case GL_ELEMENT_ARRAY_BUFFER: return "GL_ELEMENT_ARRAY_BUFFER";
|
||||
case GL_PIXEL_UNPACK_BUFFER: return "GL_PIXEL_UNPACK_BUFFER";
|
||||
case GL_PIXEL_PACK_BUFFER: return "GL_PIXEL_PACK_BUFFER";
|
||||
case GL_UNIFORM_BUFFER: return "GL_UNIFORM_BUFFER";
|
||||
case GL_TEXTURE_BUFFER: return "GL_TEXTURE_BUFFER";
|
||||
case GL_COPY_READ_BUFFER: return "GL_COPY_READ_BUFFER";
|
||||
case GL_COPY_WRITE_BUFFER: return "GL_COPY_WRITE_BUFFER";
|
||||
case GL_TRANSFORM_FEEDBACK_BUFFER: return "GL_TRANSFORM_FEEDBACK_BUFFER";
|
||||
#ifdef GL_QUERY_BUFFER
|
||||
case GL_QUERY_BUFFER: return "GL_QUERY_BUFFER";
|
||||
case GL_DRAW_INDIRECT_BUFFER: return "GL_DRAW_INDIRECT_BUFFER";
|
||||
case GL_ATOMIC_COUNTER_BUFFER: return "GL_ATOMIC_COUNTER_BUFFER";
|
||||
case GL_DISPATCH_INDIRECT_BUFFER: return "GL_DISPATCH_INDIRECT_BUFFER";
|
||||
case GL_SHADER_STORAGE_BUFFER: return "GL_SHADER_STORAGE_BUFFER";
|
||||
#endif
|
||||
}
|
||||
return OpenGl_Context::FormatGlEnumHex (theTarget);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : OpenGl_Buffer
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
OpenGl_Buffer::OpenGl_Buffer()
|
||||
: OpenGl_Resource(),
|
||||
myOffset (NULL),
|
||||
myBufferId (NO_BUFFER),
|
||||
myComponentsNb (4),
|
||||
myElemsNb (0),
|
||||
myDataType (GL_FLOAT)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : ~OpenGl_Buffer
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
OpenGl_Buffer::~OpenGl_Buffer()
|
||||
{
|
||||
Release (NULL);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : Create
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
bool OpenGl_Buffer::Create (const Handle(OpenGl_Context)& theGlCtx)
|
||||
{
|
||||
if (myBufferId == NO_BUFFER && theGlCtx->core15fwd != NULL)
|
||||
{
|
||||
theGlCtx->core15fwd->glGenBuffers (1, &myBufferId);
|
||||
}
|
||||
return myBufferId != NO_BUFFER;
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : Release
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
void OpenGl_Buffer::Release (OpenGl_Context* theGlCtx)
|
||||
{
|
||||
if (myBufferId == NO_BUFFER)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// application can not handle this case by exception - this is bug in code
|
||||
Standard_ASSERT_RETURN (theGlCtx != NULL,
|
||||
"OpenGl_Buffer destroyed without GL context! Possible GPU memory leakage...",);
|
||||
|
||||
if (theGlCtx->IsValid())
|
||||
{
|
||||
theGlCtx->core15fwd->glDeleteBuffers (1, &myBufferId);
|
||||
}
|
||||
myOffset = NULL;
|
||||
myBufferId = NO_BUFFER;
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : Bind
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
void OpenGl_Buffer::Bind (const Handle(OpenGl_Context)& theGlCtx) const
|
||||
{
|
||||
theGlCtx->core15fwd->glBindBuffer (GetTarget(), myBufferId);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : Unbind
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
void OpenGl_Buffer::Unbind (const Handle(OpenGl_Context)& theGlCtx) const
|
||||
{
|
||||
theGlCtx->core15fwd->glBindBuffer (GetTarget(), NO_BUFFER);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : BindBufferBase
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
void OpenGl_Buffer::BindBufferBase (const Handle(OpenGl_Context)& theGlCtx,
|
||||
unsigned int theIndex)
|
||||
{
|
||||
theGlCtx->core30->glBindBufferBase (GetTarget(), theIndex, myBufferId);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : UnbindBufferBase
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
void OpenGl_Buffer::UnbindBufferBase (const Handle(OpenGl_Context)& theGlCtx,
|
||||
unsigned int theIndex)
|
||||
{
|
||||
theGlCtx->core30->glBindBufferBase (GetTarget(), theIndex, NO_BUFFER);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : BindBufferRange
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
void OpenGl_Buffer::BindBufferRange (const Handle(OpenGl_Context)& theGlCtx,
|
||||
unsigned int theIndex,
|
||||
const intptr_t theOffset,
|
||||
const size_t theSize)
|
||||
{
|
||||
theGlCtx->core30->glBindBufferRange (GetTarget(), theIndex, myBufferId, (GLintptr )theOffset, (GLsizeiptr )theSize);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : Init
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
bool OpenGl_Buffer::Init (const Handle(OpenGl_Context)& theGlCtx,
|
||||
const unsigned int theComponentsNb,
|
||||
const Standard_Integer theElemsNb,
|
||||
const float* theData)
|
||||
{
|
||||
return init (theGlCtx, theComponentsNb, theElemsNb, theData, GL_FLOAT);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : Init
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
bool OpenGl_Buffer::Init (const Handle(OpenGl_Context)& theGlCtx,
|
||||
const unsigned int theComponentsNb,
|
||||
const Standard_Integer theElemsNb,
|
||||
const unsigned int* theData)
|
||||
{
|
||||
return init (theGlCtx, theComponentsNb, theElemsNb, theData, GL_UNSIGNED_INT);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : Init
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
bool OpenGl_Buffer::Init (const Handle(OpenGl_Context)& theGlCtx,
|
||||
const unsigned int theComponentsNb,
|
||||
const Standard_Integer theElemsNb,
|
||||
const unsigned short* theData)
|
||||
{
|
||||
return init (theGlCtx, theComponentsNb, theElemsNb, theData, GL_UNSIGNED_SHORT);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : Init
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
bool OpenGl_Buffer::Init (const Handle(OpenGl_Context)& theGlCtx,
|
||||
const unsigned int theComponentsNb,
|
||||
const Standard_Integer theElemsNb,
|
||||
const Standard_Byte* theData)
|
||||
{
|
||||
return init (theGlCtx, theComponentsNb, theElemsNb, theData, GL_UNSIGNED_BYTE);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : init
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
bool OpenGl_Buffer::init (const Handle(OpenGl_Context)& theGlCtx,
|
||||
const unsigned int theComponentsNb,
|
||||
const Standard_Integer theElemsNb,
|
||||
const void* theData,
|
||||
const unsigned int theDataType,
|
||||
const Standard_Integer theStride)
|
||||
{
|
||||
if (!Create (theGlCtx))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Bind (theGlCtx);
|
||||
myDataType = theDataType;
|
||||
myComponentsNb = theComponentsNb;
|
||||
myElemsNb = theElemsNb;
|
||||
theGlCtx->core15fwd->glBufferData (GetTarget(), GLsizeiptr(myElemsNb) * theStride, theData, GL_STATIC_DRAW);
|
||||
const int anErr = theGlCtx->core15fwd->glGetError();
|
||||
if (anErr != GL_NO_ERROR
|
||||
&& anErr != GL_OUT_OF_MEMORY) // pass-through out-of-memory error, but log unexpected errors
|
||||
{
|
||||
theGlCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
|
||||
TCollection_AsciiString ("Error: glBufferData (")
|
||||
+ FormatTarget (GetTarget()) + ","
|
||||
+ OpenGl_Context::FormatSize (GLsizeiptr(myElemsNb) * theStride) + ","
|
||||
+ OpenGl_Context::FormatPointer (theData) + ") Id: " + (int )myBufferId
|
||||
+ " failed with " + OpenGl_Context::FormatGlError (anErr));
|
||||
}
|
||||
Unbind (theGlCtx);
|
||||
return anErr == GL_NO_ERROR;
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : SubData
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
bool OpenGl_Buffer::SubData (const Handle(OpenGl_Context)& theGlCtx,
|
||||
const Standard_Integer theElemFrom,
|
||||
const Standard_Integer theElemsNb,
|
||||
const float* theData)
|
||||
{
|
||||
return subData (theGlCtx, theElemFrom, theElemsNb, theData, GL_FLOAT);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : SubData
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
bool OpenGl_Buffer::SubData (const Handle(OpenGl_Context)& theGlCtx,
|
||||
const Standard_Integer theElemFrom,
|
||||
const Standard_Integer theElemsNb,
|
||||
const unsigned int* theData)
|
||||
{
|
||||
return subData (theGlCtx, theElemFrom, theElemsNb, theData, GL_UNSIGNED_INT);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : SubData
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
bool OpenGl_Buffer::SubData (const Handle(OpenGl_Context)& theGlCtx,
|
||||
const Standard_Integer theElemFrom,
|
||||
const Standard_Integer theElemsNb,
|
||||
const unsigned short* theData)
|
||||
{
|
||||
return subData (theGlCtx, theElemFrom, theElemsNb, theData, GL_UNSIGNED_SHORT);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : SubData
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
bool OpenGl_Buffer::SubData (const Handle(OpenGl_Context)& theGlCtx,
|
||||
const Standard_Integer theElemFrom,
|
||||
const Standard_Integer theElemsNb,
|
||||
const Standard_Byte* theData)
|
||||
{
|
||||
return subData (theGlCtx, theElemFrom, theElemsNb, theData, GL_UNSIGNED_BYTE);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : subData
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
bool OpenGl_Buffer::subData (const Handle(OpenGl_Context)& theGlCtx,
|
||||
const Standard_Integer theElemFrom,
|
||||
const Standard_Integer theElemsNb,
|
||||
const void* theData,
|
||||
const unsigned int theDataType)
|
||||
{
|
||||
if (!IsValid() || myDataType != theDataType ||
|
||||
theElemFrom < 0 || ((theElemFrom + theElemsNb) > myElemsNb))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Bind (theGlCtx);
|
||||
const size_t aDataSize = sizeOfGlType (theDataType);
|
||||
theGlCtx->core15fwd->glBufferSubData (GetTarget(),
|
||||
GLintptr(theElemFrom) * GLintptr (myComponentsNb) * aDataSize, // offset in bytes
|
||||
GLsizeiptr(theElemsNb) * GLsizeiptr(myComponentsNb) * aDataSize, // size in bytes
|
||||
theData);
|
||||
const int anErr = theGlCtx->core15fwd->glGetError();
|
||||
if (anErr != GL_NO_ERROR)
|
||||
{
|
||||
theGlCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
|
||||
TCollection_AsciiString ("Error: glBufferSubData (")
|
||||
+ FormatTarget (GetTarget()) + ","
|
||||
+ OpenGl_Context::FormatSize (GLintptr(theElemFrom) * GLintptr (myComponentsNb) * aDataSize) + ","
|
||||
+ OpenGl_Context::FormatSize (GLsizeiptr(theElemsNb) * GLsizeiptr(myComponentsNb) * aDataSize) + ","
|
||||
+ OpenGl_Context::FormatPointer (theData) + ") Id: " + (int )myBufferId
|
||||
+ " failed with " + OpenGl_Context::FormatGlError (anErr));
|
||||
}
|
||||
Unbind (theGlCtx);
|
||||
return anErr == GL_NO_ERROR;
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : subData
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
bool OpenGl_Buffer::GetSubData (const Handle(OpenGl_Context)& theGlCtx,
|
||||
const Standard_Integer theElemFrom,
|
||||
const Standard_Integer theElemsNb,
|
||||
float* theData)
|
||||
{
|
||||
return getSubData (theGlCtx, theElemFrom, theElemsNb, theData, GL_FLOAT);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : GetSubData
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
bool OpenGl_Buffer::GetSubData (const Handle(OpenGl_Context)& theGlCtx,
|
||||
const Standard_Integer theElemFrom,
|
||||
const Standard_Integer theElemsNb,
|
||||
unsigned short* theData)
|
||||
{
|
||||
return getSubData (theGlCtx, theElemFrom, theElemsNb, theData, GL_UNSIGNED_SHORT);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : GetSubData
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
bool OpenGl_Buffer::GetSubData (const Handle(OpenGl_Context)& theGlCtx,
|
||||
const Standard_Integer theElemFrom,
|
||||
const Standard_Integer theElemsNb,
|
||||
unsigned int* theData)
|
||||
{
|
||||
return getSubData (theGlCtx, theElemFrom, theElemsNb, theData, GL_UNSIGNED_INT);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : GetSubData
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
bool OpenGl_Buffer::GetSubData (const Handle(OpenGl_Context)& theGlCtx,
|
||||
const Standard_Integer theElemFrom,
|
||||
const Standard_Integer theElemsNb,
|
||||
Standard_Byte* theData)
|
||||
{
|
||||
return getSubData (theGlCtx, theElemFrom, theElemsNb, theData, GL_UNSIGNED_BYTE);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : getSubData
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
bool OpenGl_Buffer::getSubData (const Handle(OpenGl_Context)& theGlCtx,
|
||||
const Standard_Integer theElemFrom,
|
||||
const Standard_Integer theElemsNb,
|
||||
void* theData,
|
||||
const unsigned int 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 && (theGlCtx->core15fwd->glGetError() == GL_NO_ERROR);
|
||||
Unbind (theGlCtx);
|
||||
return isDone;
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : DumpJson
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
void OpenGl_Buffer::DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth) const
|
||||
{
|
||||
OCCT_DUMP_TRANSIENT_CLASS_BEGIN (theOStream)
|
||||
OCCT_DUMP_BASE_CLASS (theOStream, theDepth, OpenGl_Resource)
|
||||
|
||||
OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, GetTarget())
|
||||
OCCT_DUMP_FIELD_VALUE_POINTER (theOStream, myOffset)
|
||||
|
||||
OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myBufferId)
|
||||
OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myComponentsNb)
|
||||
OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myElemsNb)
|
||||
OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myDataType)
|
||||
}
|
Reference in New Issue
Block a user