Commit 0f1ceeed authored by Robert Menzel's avatar Robert Menzel
Browse files

updated Buffer base class

parent 9de3c273
......@@ -31,46 +31,100 @@
namespace ACGL{
namespace OpenGL{
class Buffer
{
ACGL_NOT_COPYABLE(Buffer)
// ========================================================================================================= \/
// ============================================================================================ CONSTRUCTORS \/
// ========================================================================================================= \/
/*
* A minimal(!) wrapper to allow multiple Buffer objects pointing to the same
* OpenGL resource (like an ArrayBuffer and a TransformFeedbackBuffer).
*
* This has to be an extra object so all Buffer types can inherit from Buffer
* below to allow a unified API.
*/
class BufferObject {
public:
Buffer(void) : mLastTarget(GL_INVALID_VALUE), mObjectName(0)
BufferObject()
{
glGenBuffers(1, &mObjectName);
if (openGLCriticalErrorOccured() ) {
ACGL::Utils::error() << "could not generate buffer!" << std::endl;
mObjectName = 0;
return;
}
}
virtual ~Buffer(void)
~BufferObject(void)
{
// buffer 0 will get ignored by OpenGL
glDeleteBuffers(1, &mObjectName);
}
GLuint mObjectName;
};
typedef std::tr1::shared_ptr<BufferObject> SharedBufferObject;
/**
* Buffers are general OpenGL Buffer Wrapper.
* The OpenGL resource itself is attached via a shared pointer (GLBufferObject).
* This was multiple Buffers can use internaly the same OpenGL resource, this is
* useful if one resource should get interpreted as _different_ buffer types
* so in that case the same GLBufferObject will get attached to different
* Subclass Objects.
*
* Note: Subclasses should set the mTarget in there constructors!
*/
class Buffer
{
// ========================================================================================================= \/
// ============================================================================================ CONSTRUCTORS \/
// ========================================================================================================= \/
public:
//! Most common default: a new Buffer corresponds to a new GL resource. You might decide on a binding point
//! now or later.
Buffer( GLenum _target ) : mTarget(_target)
{
mBuffer = SharedBufferObject( new BufferObject() );
}
/**
* Init with a given, external GL resource.
*
* Calling this with:
* Buffer b( SharedGLBufferObject(NULL) );
* Is the way to _explicitly_ state that a real OpenGL resource will get added later.
* In this case no GL wrapper calls should ever get called until one gets set!
*/
Buffer( SharedBufferObject _pBuffer, GLenum _target )
: mTarget(_target),
mBuffer( _pBuffer )
{}
// ==================================================================================================== \/
// ============================================================================================ GETTERS \/
// ==================================================================================================== \/
public:
inline GLuint operator() (void) const { return mObjectName; }
inline GLuint getObjectName (void) const { return mObjectName; }
inline bool isValid (void) const { return glIsBuffer( mObjectName ); }
inline GLuint getObjectName (void) const { return mBuffer->mObjectName; }
inline bool isValid (void) const { return (mBuffer && glIsBuffer( mBuffer->mObjectName ) ); }
inline SharedBufferObject getBufferObject () const { return mBuffer; }
// ==================================================================================================== \/
// ============================================================================================ SETTERS \/
// ==================================================================================================== \/
//! the GL buffer can get changed at any time
void setBufferObject( SharedBufferObject _pBuffer ) { mBuffer = _pBuffer; }
private:
inline GLint getParameter( GLenum _parameter ) {
bind( mLastTarget );
bind( mTarget );
GLint value;
glGetBufferParameteriv( mLastTarget, _parameter, &value );
glGetBufferParameteriv( mTarget, _parameter, &value );
return value;
}
#if (ACGL_OPENGL_VERSION >= 32)
inline GLint64 getParameter64( GLenum _parameter ) {
bind( mLastTarget );
bind( mTarget );
GLint64 value;
glGetBufferParameteri64v( mLastTarget, _parameter, &value );
glGetBufferParameteri64v( mTarget, _parameter, &value );
return value;
}
......@@ -89,8 +143,6 @@ private:
inline GLint getAccessFlags() { return (GLint) getParameter ( GL_BUFFER_ACCESS_FLAGS ); }
inline GLboolean isMapped() { return (GLboolean) getParameter ( GL_BUFFER_MAPPED ); }
// ===================================================================================================== \/
// ============================================================================================ WRAPPERS \/
// ===================================================================================================== \/
......@@ -98,15 +150,14 @@ public:
//! Bind this buffer
inline void bind( GLenum _target )
{
glBindBuffer( _target, mObjectName );
glBindBuffer( _target, mBuffer->mObjectName );
openGLRareError();
mLastTarget = _target;
}
//! Bind this buffer to its last target
//! Bind this buffer to its target
inline void bind()
{
glBindBuffer( mLastTarget, mObjectName );
glBindBuffer( mTarget, mBuffer->mObjectName );
openGLRareError();
}
......@@ -120,7 +171,7 @@ public:
//! Set data for this buffer at the last used target. Use only to init the buffer!
inline void setData( GLsizeiptr _size, const GLvoid *_pData = NULL, GLenum _usage = GL_STATIC_DRAW ) {
setData( mLastTarget, _size, _pData, _usage );
setData( mTarget, _size, _pData, _usage );
}
//! Use this to modify the buffer
......@@ -133,7 +184,7 @@ public:
//! Use this to modify the buffer
inline void setSubData( GLintptr _offset, GLsizeiptr _size, const GLvoid *_pData ) {
setSubData( mLastTarget, _offset, _size, _pData );
setSubData( mTarget, _offset, _size, _pData );
}
......@@ -154,7 +205,7 @@ public:
}
inline GLvoid *mapRange( GLintptr _offset, GLsizeiptr _length, GLbitfield _access ) {
return mapRange( mLastTarget, _offset, _length, _access );
return mapRange( mTarget, _offset, _length, _access );
}
/**
......@@ -173,7 +224,7 @@ public:
}
inline void flushMappedRange( GLintptr _offset, GLsizeiptr _length ) {
flushMappedRange( mLastTarget, _offset, _length );
flushMappedRange( mTarget, _offset, _length );
}
// TODO: bindBufferRange
......@@ -189,7 +240,7 @@ public:
return ret;
}
inline GLvoid *map( GLenum _access ) {
return map( mLastTarget, _access );
return map( mTarget, _access );
}
GLboolean unmap( GLenum _target ) {
......@@ -200,7 +251,7 @@ public:
}
inline GLboolean unmap() {
return unmap( mLastTarget );
return unmap( mTarget );
}
// TODO: CopyBufferSubData
......@@ -218,19 +269,30 @@ public:
GL_TEXTURE_BUFFER
GL_TRANSFORM_FEEDBACK_BUFFER
GL_UNIFORM_BUFFER
* Can be changed at any time. Will get changed if a _target gets specified at any call.
* Can be changed at any time.
*
* Subclasses should overload this with a non-working function (+ a warning)
* because an X-Buffer should not be attached _per default_ to Y!
* Subclass buffers can however always use the method calls / binds with an
* _explicit_ target (that doesn't match there one ones):
*
* XBuffer x;
* x.bind( Y ); // ok, hope the programmer knowns what s/he does
*
* x.setTarget( Y ); // this is just calling for unintended side-effects!
* x.bind();
*/
inline void setTarget( GLenum _target ) { mLastTarget = _target; }
virtual inline void setTarget( GLenum _target ) { mTarget = _target; }
// =================================================================================================== \/
// ============================================================================================ FIELDS \/
// =================================================================================================== \/
protected:
GLenum mLastTarget;
GLuint mObjectName;
GLenum mTarget;
SharedBufferObject mBuffer;
};
ACGL_SHARED_TYPEDEF(ArrayBuffer)
ACGL_SHARED_TYPEDEF(Buffer)
} // OpenGL
} // ACGL
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment