first commit of the glw library.
This commit is contained in:
parent
e532ec9751
commit
c70bd419a7
|
@ -0,0 +1,582 @@
|
|||
#ifndef GLW_BOOKKEEPING_H
|
||||
#define GLW_BOOKKEEPING_H
|
||||
|
||||
#include "./common.h"
|
||||
|
||||
namespace glw
|
||||
{
|
||||
|
||||
class Context;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template <typename TObject>
|
||||
class SharedObjectBase
|
||||
{
|
||||
friend class Context;
|
||||
|
||||
public:
|
||||
|
||||
typedef void BaseType;
|
||||
typedef SharedObjectBase<TObject> ThisType;
|
||||
typedef TObject ObjectType;
|
||||
|
||||
bool isNull(void) const
|
||||
{
|
||||
return (this->m_object == 0);
|
||||
}
|
||||
|
||||
void setNull(void)
|
||||
{
|
||||
this->m_object = 0;
|
||||
}
|
||||
|
||||
const ObjectType * object(void) const
|
||||
{
|
||||
return this->m_object;
|
||||
}
|
||||
|
||||
ObjectType * object(void)
|
||||
{
|
||||
return this->m_object;
|
||||
}
|
||||
|
||||
void ref(void)
|
||||
{
|
||||
this->m_refCount++;
|
||||
}
|
||||
|
||||
void unref(void)
|
||||
{
|
||||
GLW_ASSERT(this->m_refCount > 0);
|
||||
this->m_refCount--;
|
||||
if (this->m_refCount == 0)
|
||||
{
|
||||
if (this->m_object != 0)
|
||||
{
|
||||
this->signalDestruction();
|
||||
}
|
||||
delete this;
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
Context * m_context;
|
||||
ObjectType * m_object;
|
||||
int m_refCount;
|
||||
|
||||
SharedObjectBase(Context * Context, ObjectType * Object)
|
||||
: m_context (Context)
|
||||
, m_object (Object)
|
||||
, m_refCount (0)
|
||||
{
|
||||
GLW_ASSERT(this->m_context != 0);
|
||||
GLW_ASSERT(this->m_object != 0);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
SharedObjectBase(const ThisType & other);
|
||||
ThisType & operator = (const ThisType & other);
|
||||
|
||||
inline void signalDestruction(void);
|
||||
};
|
||||
|
||||
template <typename TObject>
|
||||
class SharedObject;
|
||||
|
||||
template <typename TObject, typename TObjectBase>
|
||||
class SharedObjectTraits
|
||||
{
|
||||
public:
|
||||
|
||||
typedef void BaseType;
|
||||
typedef SharedObjectTraits<TObject, TObjectBase> ThisType;
|
||||
typedef TObject ObjectType;
|
||||
typedef TObjectBase ObjectBaseType;
|
||||
typedef SharedObject<ObjectBaseType> SharedObjectBaseType;
|
||||
};
|
||||
|
||||
template <typename TObject>
|
||||
class SharedObjectTraits<TObject, void>
|
||||
{
|
||||
public:
|
||||
|
||||
typedef void BaseType;
|
||||
typedef SharedObjectTraits<TObject, void> ThisType;
|
||||
typedef TObject ObjectType;
|
||||
typedef void ObjectBaseType;
|
||||
typedef SharedObjectBase<ObjectType> SharedObjectBaseType;
|
||||
};
|
||||
|
||||
template <typename TObject>
|
||||
class SharedObject : public SharedObjectTraits<TObject, typename TObject::BaseType>::SharedObjectBaseType
|
||||
{
|
||||
friend class Context;
|
||||
|
||||
public:
|
||||
|
||||
typedef typename SharedObjectTraits<TObject, typename TObject::BaseType>::SharedObjectBaseType BaseType;
|
||||
typedef SharedObject<TObject> ThisType;
|
||||
typedef TObject ObjectType;
|
||||
|
||||
const ObjectType * object(void) const
|
||||
{
|
||||
return static_cast<const ObjectType *>(BaseType::object());
|
||||
}
|
||||
|
||||
ObjectType * object(void)
|
||||
{
|
||||
return static_cast<ObjectType *>(BaseType::object());
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
SharedObject(Context * Context, ObjectType * Object)
|
||||
: BaseType(Context, Object)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
SharedObject(const ThisType & other);
|
||||
ThisType & operator = (const ThisType & other);
|
||||
};
|
||||
|
||||
template <typename TObject>
|
||||
class SharedObjectBinding
|
||||
{
|
||||
friend class Context;
|
||||
|
||||
public:
|
||||
|
||||
typedef void BaseType;
|
||||
typedef SharedObjectBinding<TObject> ThisType;
|
||||
typedef TObject ObjectType;
|
||||
typedef ObjectType UnsafeType;
|
||||
|
||||
~SharedObjectBinding(void)
|
||||
{
|
||||
this->detach();
|
||||
}
|
||||
|
||||
bool isNull(void) const
|
||||
{
|
||||
if (this->m_shared == 0) return true;
|
||||
return this->m_shared->isNull();
|
||||
}
|
||||
|
||||
void setNull(void)
|
||||
{
|
||||
this->m_shared = 0;
|
||||
}
|
||||
|
||||
const ObjectType * object(void) const
|
||||
{
|
||||
GLW_ASSERT(!this->isNull())
|
||||
const ObjectType * obj = this->m_shared->object();
|
||||
obj->setBinding(this->m_target, this->m_unit);
|
||||
return obj;
|
||||
}
|
||||
|
||||
ObjectType * object(void)
|
||||
{
|
||||
GLW_ASSERT(!this->isNull());
|
||||
ObjectType * obj = this->m_shared->object();
|
||||
obj->setBinding(this->m_target, this->m_unit);
|
||||
return obj;
|
||||
}
|
||||
|
||||
GLenum target(void) const
|
||||
{
|
||||
return this->m_target;
|
||||
}
|
||||
|
||||
GLint unit(void) const
|
||||
{
|
||||
return this->m_target;
|
||||
}
|
||||
|
||||
void ref(void)
|
||||
{
|
||||
this->m_refCount++;
|
||||
}
|
||||
|
||||
void unref(void)
|
||||
{
|
||||
GLW_ASSERT(this->m_refCount > 0);
|
||||
this->m_refCount--;
|
||||
if (this->m_refCount == 0)
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
typedef SharedObject<ObjectType> SharedObjectType;
|
||||
|
||||
SharedObjectBinding(SharedObjectType * shared, GLenum target, GLint unit)
|
||||
: m_shared (0)
|
||||
, m_refCount (0)
|
||||
, m_target (target)
|
||||
, m_unit (unit)
|
||||
{
|
||||
this->attach(shared);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
SharedObjectType * m_shared;
|
||||
int m_refCount;
|
||||
GLenum m_target;
|
||||
GLint m_unit;
|
||||
|
||||
SharedObjectBinding(const ThisType & other);
|
||||
ThisType & operator = (const ThisType & other);
|
||||
|
||||
void attach(SharedObjectType * shared)
|
||||
{
|
||||
this->detach();
|
||||
this->m_shared = shared;
|
||||
if (this->m_shared != 0)
|
||||
{
|
||||
this->m_shared->ref();
|
||||
}
|
||||
}
|
||||
|
||||
void detach(void)
|
||||
{
|
||||
if (this->m_shared == 0) return;
|
||||
this->m_shared->unref();
|
||||
this->m_shared = 0;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename TObject>
|
||||
class SafeHandleBase
|
||||
{
|
||||
friend class Context;
|
||||
|
||||
public:
|
||||
|
||||
typedef void BaseType;
|
||||
typedef SafeHandleBase<TObject> ThisType;
|
||||
typedef TObject ObjectType;
|
||||
typedef typename ObjectType::SafeType SafeType;
|
||||
|
||||
SafeHandleBase(void)
|
||||
: m_shared(0)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
SafeHandleBase(const ThisType & other)
|
||||
: m_shared(0)
|
||||
{
|
||||
this->attach(other.shared());
|
||||
}
|
||||
|
||||
~SafeHandleBase(void)
|
||||
{
|
||||
this->detach();
|
||||
}
|
||||
|
||||
bool isNull(void) const
|
||||
{
|
||||
if (this->m_shared == 0) return true;
|
||||
return this->m_shared->isNull();
|
||||
}
|
||||
|
||||
void setNull(void)
|
||||
{
|
||||
this->detach();
|
||||
}
|
||||
|
||||
const SafeType * operator -> (void) const
|
||||
{
|
||||
GLW_ASSERT(!this->isNull());
|
||||
return this->m_shared->object();
|
||||
}
|
||||
|
||||
SafeType * operator -> (void)
|
||||
{
|
||||
GLW_ASSERT(!this->isNull());
|
||||
return this->m_shared->object();
|
||||
}
|
||||
|
||||
ThisType & operator = (const ThisType & other)
|
||||
{
|
||||
this->attach(other.shared());
|
||||
return (*this);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
typedef SharedObject<ObjectType> SharedObjectType;
|
||||
|
||||
SafeHandleBase(SharedObjectType * shared)
|
||||
: m_shared(0)
|
||||
{
|
||||
this->attach(shared);
|
||||
}
|
||||
|
||||
const ObjectType * object(void) const
|
||||
{
|
||||
if (this->m_shared == 0) return 0;
|
||||
return this->m_shared->object();
|
||||
}
|
||||
|
||||
ObjectType * object(void)
|
||||
{
|
||||
if (this->m_shared == 0) return 0;
|
||||
return this->m_shared->object();
|
||||
}
|
||||
|
||||
SharedObjectType * shared(void) const
|
||||
{
|
||||
return this->m_shared;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
SharedObjectType * m_shared;
|
||||
|
||||
void attach(SharedObjectType * shared)
|
||||
{
|
||||
this->detach();
|
||||
this->m_shared = shared;
|
||||
if (this->m_shared != 0)
|
||||
{
|
||||
this->m_shared->ref();
|
||||
}
|
||||
}
|
||||
|
||||
void detach(void)
|
||||
{
|
||||
if (this->m_shared == 0) return;
|
||||
this->m_shared->unref();
|
||||
this->m_shared = 0;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename TObject>
|
||||
class SafeHandle;
|
||||
|
||||
template <typename TObject, typename TObjectBase>
|
||||
class SafeHandleTraits
|
||||
{
|
||||
public:
|
||||
|
||||
typedef void BaseType;
|
||||
typedef SafeHandleTraits<TObject, TObjectBase> ThisType;
|
||||
typedef TObject ObjectType;
|
||||
typedef TObjectBase ObjectBaseType;
|
||||
typedef SafeHandle<ObjectBaseType> SafeHandleBaseType;
|
||||
};
|
||||
|
||||
template <typename TObject>
|
||||
class SafeHandleTraits<TObject, void>
|
||||
{
|
||||
public:
|
||||
|
||||
typedef void BaseType;
|
||||
typedef SafeHandleTraits<TObject, void> ThisType;
|
||||
typedef TObject ObjectType;
|
||||
typedef void ObjectBaseType;
|
||||
typedef SafeHandleBase<ObjectType> SafeHandleBaseType;
|
||||
};
|
||||
|
||||
template <typename TObject>
|
||||
class SafeHandle : public SafeHandleTraits<TObject, typename TObject::BaseType>::SafeHandleBaseType
|
||||
{
|
||||
friend class Context;
|
||||
|
||||
public:
|
||||
|
||||
typedef typename SafeHandleTraits<TObject, typename TObject::BaseType>::SafeHandleBaseType BaseType;
|
||||
typedef SafeHandle<TObject> ThisType;
|
||||
typedef TObject ObjectType;
|
||||
typedef typename ObjectType::SafeType SafeType;
|
||||
|
||||
SafeHandle(void)
|
||||
: BaseType()
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
SafeHandle(const ThisType & other)
|
||||
: BaseType(other)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
const SafeType * operator -> (void) const
|
||||
{
|
||||
return dynamic_cast<const SafeType *>(BaseType:: operator ->());
|
||||
}
|
||||
|
||||
SafeType * operator -> (void)
|
||||
{
|
||||
return dynamic_cast<SafeType *>(BaseType:: operator ->());
|
||||
}
|
||||
|
||||
/*
|
||||
ThisType & operator = (const ThisType & other)
|
||||
{
|
||||
this->attach(other.shared());
|
||||
return (*this);
|
||||
}
|
||||
*/
|
||||
|
||||
operator bool (void) const
|
||||
{
|
||||
return !this->isNull();
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
typedef SharedObject<ObjectType> SharedObjectType;
|
||||
|
||||
SafeHandle(SharedObjectType * shared)
|
||||
: BaseType(shared)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
const ObjectType * object(void) const
|
||||
{
|
||||
return static_cast<const ObjectType *>(BaseType::object());
|
||||
}
|
||||
|
||||
ObjectType * object(void)
|
||||
{
|
||||
return static_cast<ObjectType *>(BaseType::object());
|
||||
}
|
||||
|
||||
SharedObjectType * shared(void) const
|
||||
{
|
||||
return static_cast<SharedObjectType *>(BaseType::shared());
|
||||
}
|
||||
};
|
||||
|
||||
template <typename TObject>
|
||||
class UnsafeHandle
|
||||
{
|
||||
friend class Context;
|
||||
|
||||
public:
|
||||
|
||||
typedef void BaseType;
|
||||
typedef UnsafeHandle<TObject> ThisType;
|
||||
typedef TObject ObjectType;
|
||||
typedef ObjectType UnsafeType;
|
||||
|
||||
UnsafeHandle(void)
|
||||
: m_shared(0)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
UnsafeHandle(const ThisType & other)
|
||||
: m_shared(0)
|
||||
{
|
||||
this->attach(other.shared());
|
||||
}
|
||||
|
||||
~UnsafeHandle(void)
|
||||
{
|
||||
this->detach();
|
||||
}
|
||||
|
||||
bool isNull(void) const
|
||||
{
|
||||
if (this->m_shared == 0) return true;
|
||||
return this->m_shared->isNull();
|
||||
}
|
||||
|
||||
void setNull(void)
|
||||
{
|
||||
this->detach();
|
||||
}
|
||||
|
||||
const UnsafeType * operator -> (void) const
|
||||
{
|
||||
GLW_ASSERT(!this->isNull());
|
||||
return this->m_shared->object();
|
||||
}
|
||||
|
||||
UnsafeType * operator -> (void)
|
||||
{
|
||||
GLW_ASSERT(!this->isNull());
|
||||
return this->m_shared->object();
|
||||
}
|
||||
|
||||
ThisType & operator = (const ThisType & other)
|
||||
{
|
||||
this->attach(other.shared());
|
||||
return (*this);
|
||||
}
|
||||
|
||||
operator bool (void) const
|
||||
{
|
||||
return !this->isNull();
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
typedef SharedObjectBinding<ObjectType> SharedObjectBindingType;
|
||||
|
||||
UnsafeHandle(SharedObjectBindingType * shared)
|
||||
: m_shared(0)
|
||||
{
|
||||
this->attach(shared);
|
||||
}
|
||||
|
||||
const ObjectType * Object(void) const
|
||||
{
|
||||
if (this->m_shared == 0) return true;
|
||||
return this->m_shared->object();
|
||||
}
|
||||
|
||||
ObjectType * Object(void)
|
||||
{
|
||||
if (this->m_shared == 0) return true;
|
||||
return this->m_shared->object();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
SharedObjectBindingType * m_shared;
|
||||
|
||||
void attach(SharedObjectBindingType * shared)
|
||||
{
|
||||
this->detach();
|
||||
this->m_shared = shared;
|
||||
if (this->m_shared != 0)
|
||||
{
|
||||
this->m_shared->ref();
|
||||
}
|
||||
}
|
||||
|
||||
void detach(void)
|
||||
{
|
||||
if (this->m_shared == 0) return;
|
||||
this->m_shared->unref();
|
||||
this->m_shared = 0;
|
||||
}
|
||||
|
||||
SharedObjectBindingType * shared(void) const
|
||||
{
|
||||
return this->m_shared;
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
#endif // GLW_BOOKKEEPING_H
|
|
@ -0,0 +1,210 @@
|
|||
#ifndef GLW_BUFFER_H
|
||||
#define GLW_BUFFER_H
|
||||
|
||||
#include "./object.h"
|
||||
|
||||
namespace glw
|
||||
{
|
||||
|
||||
class BufferArguments : public ObjectArguments
|
||||
{
|
||||
public:
|
||||
|
||||
typedef ObjectArguments BaseType;
|
||||
typedef BufferArguments ThisType;
|
||||
|
||||
GLsizeiptr size;
|
||||
GLenum usage;
|
||||
const void * data;
|
||||
|
||||
BufferArguments(void)
|
||||
{
|
||||
this->clear();
|
||||
}
|
||||
|
||||
void clear(void)
|
||||
{
|
||||
BaseType::clear();
|
||||
this->size = 0;
|
||||
this->usage = GL_NONE;
|
||||
this->data = 0;
|
||||
}
|
||||
};
|
||||
|
||||
class SafeBuffer : public virtual SafeObject
|
||||
{
|
||||
public:
|
||||
|
||||
typedef SafeObject BaseType;
|
||||
typedef SafeBuffer ThisType;
|
||||
|
||||
GLsizei size(void) const
|
||||
{
|
||||
return this->m_size;
|
||||
}
|
||||
|
||||
GLenum usage(void) const
|
||||
{
|
||||
return this->m_usage;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
GLsizeiptr m_size;
|
||||
GLenum m_usage;
|
||||
|
||||
SafeBuffer(Context * ctx)
|
||||
: BaseType (ctx)
|
||||
, m_size (0)
|
||||
, m_usage (GL_NONE)
|
||||
{
|
||||
;
|
||||
}
|
||||
};
|
||||
|
||||
class Buffer : public Object, public SafeBuffer
|
||||
{
|
||||
friend class Context;
|
||||
friend class detail::SharedObjectBinding<Buffer>;
|
||||
|
||||
public:
|
||||
|
||||
typedef Object BaseType;
|
||||
typedef SafeBuffer SafeType;
|
||||
typedef Buffer ThisType;
|
||||
|
||||
virtual Type type(void) const
|
||||
{
|
||||
return BufferType;
|
||||
}
|
||||
|
||||
void setData(const GLsizeiptr size, GLenum usage, const void * data)
|
||||
{
|
||||
GLW_ASSERT(this->isValid());
|
||||
glBufferData(this->m_target, size, data, usage);
|
||||
this->m_size = size;
|
||||
this->m_usage = usage;
|
||||
}
|
||||
|
||||
void setSubData(GLintptr offset, GLsizeiptr size, const void * data)
|
||||
{
|
||||
GLW_ASSERT(this->isValid());
|
||||
glBufferSubData(this->m_target, offset, size, data);
|
||||
}
|
||||
|
||||
void getSubData(GLintptr offset, GLsizeiptr size, void * data)
|
||||
{
|
||||
GLW_ASSERT(this->isValid());
|
||||
glGetBufferSubData(this->m_target, offset, size, data);
|
||||
}
|
||||
|
||||
void * map(GLenum access)
|
||||
{
|
||||
GLW_ASSERT(this->isValid());
|
||||
GLW_ASSERT(!this->isMapped());
|
||||
void * ptr = glMapBuffer(this->m_target, access);
|
||||
if (ptr == 0) return 0;
|
||||
this->m_mapAccess = access;
|
||||
this->m_mapPtr = ptr;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void unmap(void)
|
||||
{
|
||||
GLW_ASSERT(this->isValid());
|
||||
GLW_ASSERT(this->isMapped());
|
||||
glUnmapBuffer(this->m_target);
|
||||
this->m_mapAccess = GL_NONE;
|
||||
this->m_mapPtr = 0;
|
||||
}
|
||||
|
||||
GLenum mapAccess(void) const
|
||||
{
|
||||
return this->m_mapAccess;
|
||||
}
|
||||
|
||||
bool isMapped(void) const
|
||||
{
|
||||
return (this->m_mapAccess != GL_NONE);
|
||||
}
|
||||
|
||||
void * mapPointer(void) const
|
||||
{
|
||||
return this->m_mapPtr;
|
||||
}
|
||||
|
||||
void vertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid * offset)
|
||||
{
|
||||
GLW_ASSERT(this->isValid());
|
||||
GLW_ASSERT(this->m_target == GL_ARRAY_BUFFER);
|
||||
glVertexAttribPointer(index, size, type, normalized, stride, offset);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
Buffer(Context * ctx)
|
||||
: SafeObject (ctx)
|
||||
, SafeType (ctx)
|
||||
, BaseType (ctx)
|
||||
, m_mapAccess (GL_NONE)
|
||||
, m_mapPtr (0)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
virtual ~Buffer(void)
|
||||
{
|
||||
this->destroy();
|
||||
}
|
||||
|
||||
bool create(const BufferArguments & args)
|
||||
{
|
||||
this->destroy();
|
||||
|
||||
GLint boundName = 0;
|
||||
glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &boundName);
|
||||
|
||||
glGenBuffers(1, &(this->m_name));
|
||||
this->setBinding(GL_ARRAY_BUFFER, 0);
|
||||
this->bind();
|
||||
this->setData(args.size, args.usage, args.data);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, boundName);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual void doDestroy(Context * ctx, GLuint name)
|
||||
{
|
||||
(void)ctx;
|
||||
if (name == 0) return;
|
||||
if (this->isMapped()) this->unmap();
|
||||
this->m_size = 0;
|
||||
this->m_usage = GL_NONE;
|
||||
this->m_mapAccess = GL_NONE;
|
||||
this->m_mapPtr = 0;
|
||||
glDeleteBuffers(1, &name);
|
||||
}
|
||||
|
||||
virtual void doBind(void)
|
||||
{
|
||||
glBindBuffer(this->m_target, this->m_name);
|
||||
}
|
||||
|
||||
virtual void doUnbind(void)
|
||||
{
|
||||
glBindBuffer(this->m_target, 0);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
GLenum m_mapAccess;
|
||||
void * m_mapPtr;
|
||||
};
|
||||
|
||||
typedef detail::SafeHandle <Buffer> BufferHandle;
|
||||
typedef detail::UnsafeHandle <Buffer> BoundBuffer;
|
||||
|
||||
};
|
||||
|
||||
#endif // GLW_BUFFER_H
|
|
@ -0,0 +1,25 @@
|
|||
#ifndef GLW_COMMON_H
|
||||
#define GLW_COMMON_H
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "./config.h"
|
||||
|
||||
#define GLW_DONT_CARE (0xFFFFFFFF)
|
||||
#define GLW_CARE_OF(X) ((X) != GLW_DONT_CARE)
|
||||
|
||||
#define GLW_CHECK_GL_ERROR GLW_ASSERT(glGetError() == GL_NO_ERROR)
|
||||
#define GLW_CHECK_GL_READ_FRAMEBUFFER_STATUS GLW_ASSERT(glCheckFramebufferStatus(GL_READ_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE)
|
||||
#define GLW_CHECK_GL_DRAW_FRAMEBUFFER_STATUS GLW_ASSERT(glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE)
|
||||
|
||||
namespace glw
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif // GLW_COMMON_H
|
|
@ -0,0 +1,12 @@
|
|||
#ifndef GLW_CONFIG_H
|
||||
#define GLW_CONFIG_H
|
||||
|
||||
#ifndef GLW_ASSERT
|
||||
# define GLW_ASSERT assert
|
||||
#endif
|
||||
|
||||
#ifndef GLW_IMPLEMENT_CUSTOM_UNIFORMS
|
||||
# define GLW_IMPLEMENT_CUSTOM_UNIFORMS
|
||||
#endif
|
||||
|
||||
#endif // GLW_CONFIG_H
|
|
@ -0,0 +1,438 @@
|
|||
#ifndef GLW_CONTEXT_H
|
||||
#define GLW_CONTEXT_H
|
||||
|
||||
#include "./noncopyable.h"
|
||||
#include "./buffer.h"
|
||||
#include "./renderbuffer.h"
|
||||
#include "./vertexshader.h"
|
||||
#include "./geometryshader.h"
|
||||
#include "./fragmentshader.h"
|
||||
#include "./program.h"
|
||||
#include "./texture2d.h"
|
||||
#include "./framebuffer.h"
|
||||
|
||||
#include <string>
|
||||
#include <set>
|
||||
#include <map>
|
||||
|
||||
namespace glw
|
||||
{
|
||||
|
||||
class Context : public detail::NonCopyable
|
||||
{
|
||||
friend class detail::SharedObjectBase<Object>;
|
||||
|
||||
public:
|
||||
|
||||
typedef detail::NonCopyable BaseType;
|
||||
typedef Context ThisType;
|
||||
|
||||
Context(void)
|
||||
: m_acquired (false)
|
||||
, m_textureUnits (0)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
virtual ~Context(void)
|
||||
{
|
||||
this->release();
|
||||
}
|
||||
|
||||
bool acquire(void)
|
||||
{
|
||||
this->release();
|
||||
this->initializeTargets();
|
||||
this->m_acquired = true;
|
||||
return this->m_acquired;
|
||||
}
|
||||
|
||||
void release(void)
|
||||
{
|
||||
if (!this->isAcquired()) return;
|
||||
this->m_acquired = false;
|
||||
this->terminateTargets();
|
||||
this->destroyAllObjects();
|
||||
}
|
||||
|
||||
bool isAcquired(void) const
|
||||
{
|
||||
return this->m_acquired;
|
||||
}
|
||||
|
||||
bool isValid(void) const
|
||||
{
|
||||
return this->isAcquired();
|
||||
}
|
||||
|
||||
BufferHandle createBuffer(const BufferArguments & args)
|
||||
{
|
||||
BufferHandle handle = this->createHandle<Buffer>();
|
||||
handle.object()->create(args);
|
||||
return handle;
|
||||
}
|
||||
|
||||
BoundBuffer bindVertexBuffer(BufferHandle & handle)
|
||||
{
|
||||
return this->bind(BindingTarget(GL_ARRAY_BUFFER, 0), handle);
|
||||
}
|
||||
|
||||
void unbindVertexBuffer(void)
|
||||
{
|
||||
BufferHandle nullHandle;
|
||||
this->bindVertexBuffer(nullHandle);
|
||||
}
|
||||
|
||||
BoundBuffer bindIndexBuffer(BufferHandle & handle)
|
||||
{
|
||||
return this->bind(BindingTarget(GL_ELEMENT_ARRAY_BUFFER, 0), handle);
|
||||
}
|
||||
|
||||
void unbindIndexBuffer(void)
|
||||
{
|
||||
BufferHandle nullHandle;
|
||||
this->bindIndexBuffer(nullHandle);
|
||||
}
|
||||
|
||||
RenderbufferHandle createRenderbuffer(const RenderbufferArguments & args)
|
||||
{
|
||||
RenderbufferHandle handle = this->createHandle<Renderbuffer>();
|
||||
handle.object()->create(args);
|
||||
return handle;
|
||||
}
|
||||
|
||||
BoundRenderbuffer bindRenderbuffer(RenderbufferHandle & handle)
|
||||
{
|
||||
return this->bind(BindingTarget(GL_RENDERBUFFER, 0), handle);
|
||||
}
|
||||
|
||||
void unbindRenderbuffer(void)
|
||||
{
|
||||
RenderbufferHandle nullHandle;
|
||||
this->bindRenderbuffer(nullHandle);
|
||||
}
|
||||
|
||||
VertexShaderHandle createVertexShader(const VertexShaderArguments & args)
|
||||
{
|
||||
VertexShaderHandle handle = this->createHandle<VertexShader>();
|
||||
handle.object()->create(args);
|
||||
return handle;
|
||||
}
|
||||
|
||||
BoundVertexShader bindVertexShader(VertexShaderHandle & handle)
|
||||
{
|
||||
return this->bind(BindingTarget(GL_VERTEX_SHADER, 0), handle);
|
||||
}
|
||||
|
||||
void unbindVertexShader(void)
|
||||
{
|
||||
VertexShaderHandle nullHandle;
|
||||
this->bindVertexShader(nullHandle);
|
||||
}
|
||||
|
||||
GeometryShaderHandle createGeometryShader(const GeometryShaderArguments & args)
|
||||
{
|
||||
GeometryShaderHandle handle = this->createHandle<GeometryShader>();
|
||||
handle.object()->create(args);
|
||||
return handle;
|
||||
}
|
||||
|
||||
BoundGeometryShader bindGeometryShader(GeometryShaderHandle & handle)
|
||||
{
|
||||
return this->bind(BindingTarget(GL_GEOMETRY_SHADER, 0), handle);
|
||||
}
|
||||
|
||||
void unbindGeometryShader(void)
|
||||
{
|
||||
GeometryShaderHandle nullHandle;
|
||||
this->bindGeometryShader(nullHandle);
|
||||
}
|
||||
|
||||
FragmentShaderHandle createFragmentShader(const FragmentShaderArguments & args)
|
||||
{
|
||||
FragmentShaderHandle handle = this->createHandle<FragmentShader>();
|
||||
handle.object()->create(args);
|
||||
return handle;
|
||||
}
|
||||
|
||||
BoundFragmentShader bindFragmentShader(FragmentShaderHandle & handle)
|
||||
{
|
||||
return this->bind(BindingTarget(GL_FRAGMENT_SHADER, 0), handle);
|
||||
}
|
||||
|
||||
void unbindFragmentShader(void)
|
||||
{
|
||||
FragmentShaderHandle nullHandle;
|
||||
this->bindFragmentShader(nullHandle);
|
||||
}
|
||||
|
||||
ProgramHandle createProgram(const ProgramArguments & args)
|
||||
{
|
||||
ProgramHandle handle = this->createHandle<Program>();
|
||||
handle.object()->create(args);
|
||||
return handle;
|
||||
}
|
||||
|
||||
BoundProgram bindProgram(ProgramHandle & handle)
|
||||
{
|
||||
return this->bind(BindingTarget(GL_CURRENT_PROGRAM, 0), handle);
|
||||
}
|
||||
|
||||
void unbindProgram(void)
|
||||
{
|
||||
ProgramHandle nullHandle;
|
||||
this->bindProgram(nullHandle);
|
||||
}
|
||||
|
||||
Texture2DHandle createTexture2D(const Texture2DArguments & args)
|
||||
{
|
||||
Texture2DHandle handle = this->createHandle<Texture2D>();
|
||||
handle.object()->create(args);
|
||||
return handle;
|
||||
}
|
||||
|
||||
BoundTexture2D bindTexture2D(GLint unit, Texture2DHandle & handle)
|
||||
{
|
||||
glActiveTexture(GL_TEXTURE0 + unit);
|
||||
return this->bind(BindingTarget(GL_TEXTURE_2D, unit), handle);
|
||||
}
|
||||
|
||||
void unbindTexture2D(GLint unit)
|
||||
{
|
||||
Texture2DHandle nullHandle;
|
||||
this->bindTexture2D(unit, nullHandle);
|
||||
}
|
||||
|
||||
FramebufferHandle createFramebuffer(const FramebufferArguments & args)
|
||||
{
|
||||
FramebufferHandle handle = this->createHandle<Framebuffer>();
|
||||
handle.object()->create(args);
|
||||
return handle;
|
||||
}
|
||||
|
||||
BoundFramebuffer bindReadFramebuffer(FramebufferHandle & handle)
|
||||
{
|
||||
FramebufferHandle nullHandle;
|
||||
this->bind(BindingTarget(GL_FRAMEBUFFER, 0), nullHandle);
|
||||
return this->bind(BindingTarget(GL_READ_FRAMEBUFFER, 0), handle);
|
||||
}
|
||||
|
||||
void unbindReadFramebuffer(void)
|
||||
{
|
||||
FramebufferHandle nullHandle;
|
||||
this->bindReadFramebuffer(nullHandle);
|
||||
}
|
||||
|
||||
BoundFramebuffer bindDrawFramebuffer(FramebufferHandle & handle)
|
||||
{
|
||||
FramebufferHandle nullHandle;
|
||||
this->bind(BindingTarget(GL_FRAMEBUFFER, 0), nullHandle);
|
||||
return this->bind(BindingTarget(GL_DRAW_FRAMEBUFFER, 0), handle);
|
||||
}
|
||||
|
||||
void unbindDrawFramebuffer(void)
|
||||
{
|
||||
FramebufferHandle nullHandle;
|
||||
this->bindDrawFramebuffer(nullHandle);
|
||||
}
|
||||
|
||||
BoundFramebuffer bindFramebuffer(FramebufferHandle & handle)
|
||||
{
|
||||
FramebufferHandle nullHandle;
|
||||
this->bind(BindingTarget(GL_READ_FRAMEBUFFER, 0), nullHandle);
|
||||
this->bind(BindingTarget(GL_DRAW_FRAMEBUFFER, 0), nullHandle);
|
||||
return this->bind(BindingTarget(GL_FRAMEBUFFER, 0), handle);
|
||||
}
|
||||
|
||||
void unbindFramebuffer(void)
|
||||
{
|
||||
FramebufferHandle nullHandle;
|
||||
this->bindFramebuffer(nullHandle);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
typedef detail::SharedObjectBase<Object> SharedObjectType;
|
||||
|
||||
typedef void * GenericPtr;
|
||||
typedef std::pair<GLenum, GLint> BindingTarget;
|
||||
|
||||
typedef std::set<SharedObjectType *> ShaderObjecPtrSet;
|
||||
typedef ShaderObjecPtrSet::const_iterator ShaderObjecPtrSetConstIterator;
|
||||
typedef ShaderObjecPtrSet::iterator ShaderObjecPtrSetIterator;
|
||||
|
||||
typedef std::map<BindingTarget, GenericPtr> SharedObjectBindingPtrMap;
|
||||
typedef SharedObjectBindingPtrMap::const_iterator SharedObjectBindingPtrConstIterator;
|
||||
typedef SharedObjectBindingPtrMap::iterator SharedObjectBindingPtrIterator;
|
||||
typedef SharedObjectBindingPtrMap::value_type SharedObjectBindingPtrValue;
|
||||
|
||||
bool m_acquired;
|
||||
int m_textureUnits;
|
||||
ShaderObjecPtrSet m_shareds;
|
||||
SharedObjectBindingPtrMap m_bindings;
|
||||
|
||||
template <typename TObject>
|
||||
void initializeTarget(BindingTarget bt)
|
||||
{
|
||||
typedef TObject ObjectType;
|
||||
typedef detail::UnsafeHandle<ObjectType> UnsafeObjectType;
|
||||
|
||||
UnsafeObjectType * unsafeObject = 0;
|
||||
this->m_bindings.insert(SharedObjectBindingPtrValue(bt, unsafeObject));
|
||||
}
|
||||
|
||||
template <typename TObject>
|
||||
void terminateTarget(BindingTarget bt)
|
||||
{
|
||||
typedef TObject ObjectType;
|
||||
typedef detail::SafeHandle<ObjectType> SafeObjectType;
|
||||
|
||||
SafeObjectType nullHandle;
|
||||
this->bind<ObjectType>(bt, nullHandle);
|
||||
}
|
||||
|
||||
void initializeTargets(void)
|
||||
{
|
||||
{
|
||||
GLint texUnits = 0;
|
||||
glGetIntegerv(GL_MAX_TEXTURE_UNITS, &texUnits);
|
||||
this->m_textureUnits = int(texUnits);
|
||||
}
|
||||
|
||||
this->initializeTarget<Buffer >(BindingTarget(GL_ARRAY_BUFFER, 0));
|
||||
this->initializeTarget<Buffer >(BindingTarget(GL_ELEMENT_ARRAY_BUFFER, 0));
|
||||
this->initializeTarget<Renderbuffer >(BindingTarget(GL_RENDERBUFFER, 0));
|
||||
this->initializeTarget<VertexShader >(BindingTarget(GL_VERTEX_SHADER, 0));
|
||||
this->initializeTarget<GeometryShader>(BindingTarget(GL_GEOMETRY_SHADER, 0));
|
||||
this->initializeTarget<FragmentShader>(BindingTarget(GL_FRAGMENT_SHADER, 0));
|
||||
this->initializeTarget<Program >(BindingTarget(GL_CURRENT_PROGRAM, 0));
|
||||
for (int i=0; i<this->m_textureUnits; ++i)
|
||||
{
|
||||
this->initializeTarget<Texture2D>(BindingTarget(GL_TEXTURE_2D, GLint(i)));
|
||||
}
|
||||
this->initializeTarget<Framebuffer >(BindingTarget(GL_READ_FRAMEBUFFER, 0));
|
||||
this->initializeTarget<Framebuffer >(BindingTarget(GL_DRAW_FRAMEBUFFER, 0));
|
||||
this->initializeTarget<Framebuffer >(BindingTarget(GL_FRAMEBUFFER, 0));
|
||||
}
|
||||
|
||||
void terminateTargets(void)
|
||||
{
|
||||
this->terminateTarget<Buffer >(BindingTarget(GL_ARRAY_BUFFER, 0));
|
||||
this->terminateTarget<Buffer >(BindingTarget(GL_ELEMENT_ARRAY_BUFFER, 0));
|
||||
this->terminateTarget<Renderbuffer >(BindingTarget(GL_RENDERBUFFER, 0));
|
||||
this->terminateTarget<VertexShader >(BindingTarget(GL_VERTEX_SHADER, 0));
|
||||
this->terminateTarget<GeometryShader>(BindingTarget(GL_GEOMETRY_SHADER, 0));
|
||||
this->terminateTarget<FragmentShader>(BindingTarget(GL_FRAGMENT_SHADER, 0));
|
||||
this->terminateTarget<Program >(BindingTarget(GL_CURRENT_PROGRAM, 0));
|
||||
for (int i=0; i<this->m_textureUnits; ++i)
|
||||
{
|
||||
this->terminateTarget<Texture2D>(BindingTarget(GL_TEXTURE_2D, GLint(i)));
|
||||
}
|
||||
this->terminateTarget<Framebuffer >(BindingTarget(GL_READ_FRAMEBUFFER, 0));
|
||||
this->terminateTarget<Framebuffer >(BindingTarget(GL_DRAW_FRAMEBUFFER, 0));
|
||||
this->terminateTarget<Framebuffer >(BindingTarget(GL_FRAMEBUFFER, 0));
|
||||
|
||||
this->m_textureUnits = 0;
|
||||
}
|
||||
|
||||
template <typename TObject>
|
||||
detail::UnsafeHandle<TObject> bind(BindingTarget bt, detail::SafeHandle<TObject> & h)
|
||||
{
|
||||
typedef TObject ObjectType;
|
||||
typedef detail::SharedObjectBinding<ObjectType> SharedObjectBindingType;
|
||||
typedef detail::UnsafeHandle<ObjectType> UnsafeObjectType;
|
||||
|
||||
SharedObjectBindingPtrIterator it = this->m_bindings.find(bt);
|
||||
GLW_ASSERT(it != this->m_bindings.end());
|
||||
|
||||
ObjectType * Object = h.object();
|
||||
|
||||
SharedObjectBindingType * currentBinding = static_cast<SharedObjectBindingType *>(it->second);
|
||||
if (currentBinding != 0)
|
||||
{
|
||||
GLW_ASSERT(!currentBinding->isNull());
|
||||
// WARNING: as state could have been changed outside GLW, uncommenting the following line may prevent correct binding.
|
||||
//if (currentBinding->object() == Object) return UnsafeObjectType(currentBinding);
|
||||
if (h.isNull()) currentBinding->object()->unbind();
|
||||
currentBinding->setNull();
|
||||
currentBinding->unref();
|
||||
currentBinding = 0;
|
||||
it->second = 0;
|
||||
}
|
||||
|
||||
if (h.isNull()) return UnsafeObjectType();
|
||||
|
||||
SharedObjectBindingType * newBinding = new SharedObjectBindingType(h.shared(), bt.first, bt.second);
|
||||
newBinding->ref();
|
||||
it->second = newBinding;
|
||||
|
||||
Object->setBinding(bt.first, bt.second);
|
||||
Object->bind();
|
||||
|
||||
return UnsafeObjectType(newBinding);
|
||||
}
|
||||
|
||||
template <typename TObject>
|
||||
TObject * createObject(void)
|
||||
{
|
||||
typedef TObject ObjectType;
|
||||
ObjectType * Object = new ObjectType(this);
|
||||
return Object;
|
||||
}
|
||||
|
||||
void destroyObject(Object * Object)
|
||||
{
|
||||
GLW_ASSERT(Object != 0);
|
||||
Object->destroy();
|
||||
delete Object;
|
||||
}
|
||||
|
||||
void removeShared(SharedObjectType * shared)
|
||||
{
|
||||
GLW_ASSERT(shared != 0);
|
||||
GLW_ASSERT(this->m_shareds.count(shared) > 0);
|
||||
this->m_shareds.erase(shared);
|
||||
this->destroyObject(shared->object());
|
||||
}
|
||||
|
||||
void destroyAllObjects(void)
|
||||
{
|
||||
for (ShaderObjecPtrSetIterator it=this->m_shareds.begin(); it!=this->m_shareds.end(); ++it)
|
||||
{
|
||||
SharedObjectType * shared = *it;
|
||||
Object * Object = shared->object();
|
||||
shared->setNull();
|
||||
this->destroyObject(Object);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename TObject>
|
||||
detail::SafeHandle<TObject> createHandle(void)
|
||||
{
|
||||
typedef TObject ObjectType;
|
||||
typedef detail::SharedObject<ObjectType> SharedObjectType;
|
||||
typedef detail::SafeHandle<ObjectType> SafeType;
|
||||
|
||||
ObjectType * Object = new ObjectType(this);
|
||||
SharedObjectType * shared = new SharedObjectType(this, Object);
|
||||
|
||||
this->m_shareds.insert(shared);
|
||||
|
||||
return SafeType(shared);
|
||||
}
|
||||
};
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template <typename TObject>
|
||||
inline void SharedObjectBase<TObject>::signalDestruction(void)
|
||||
{
|
||||
this->m_context->removeShared(this);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
#endif // GLW_CONTEXT_H
|
|
@ -0,0 +1,87 @@
|
|||
#ifndef GLW_FRAGMENTSHADER_H
|
||||
#define GLW_FRAGMENTSHADER_H
|
||||
|
||||
#include "./shader.h"
|
||||
|
||||
namespace glw
|
||||
{
|
||||
|
||||
class FragmentShaderArguments : public ShaderArguments
|
||||
{
|
||||
public:
|
||||
|
||||
typedef ShaderArguments BaseType;
|
||||
typedef FragmentShaderArguments ThisType;
|
||||
|
||||
FragmentShaderArguments(void)
|
||||
{
|
||||
this->clear();
|
||||
}
|
||||
|
||||
void clear(void)
|
||||
{
|
||||
BaseType::clear();
|
||||
}
|
||||
};
|
||||
|
||||
class SafeFragmentShader : public virtual SafeShader
|
||||
{
|
||||
public:
|
||||
|
||||
typedef SafeShader BaseType;
|
||||
typedef SafeFragmentShader ThisType;
|
||||
|
||||
protected:
|
||||
|
||||
SafeFragmentShader(Context * ctx)
|
||||
: SafeObject (ctx)
|
||||
, BaseType (ctx)
|
||||
{
|
||||
;
|
||||
}
|
||||
};
|
||||
|
||||
class FragmentShader : public Shader, public SafeFragmentShader
|
||||
{
|
||||
friend class Context;
|
||||
friend class detail::SharedObjectBinding<FragmentShader>;
|
||||
|
||||
public:
|
||||
|
||||
typedef Shader BaseType;
|
||||
typedef SafeFragmentShader SafeType;
|
||||
typedef FragmentShader ThisType;
|
||||
|
||||
virtual Type type(void) const
|
||||
{
|
||||
return FragmentShaderType;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
FragmentShader(Context * ctx)
|
||||
: SafeObject (ctx)
|
||||
, SafeShader (ctx)
|
||||
, SafeType (ctx)
|
||||
, BaseType (ctx)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
virtual GLenum shaderType(void) const
|
||||
{
|
||||
return GL_FRAGMENT_SHADER;
|
||||
}
|
||||
|
||||
bool create(const FragmentShaderArguments & args)
|
||||
{
|
||||
return BaseType::create(args);
|
||||
}
|
||||
};
|
||||
|
||||
typedef detail::SafeHandle <FragmentShader> FragmentShaderHandle;
|
||||
typedef detail::UnsafeHandle <FragmentShader> BoundFragmentShader;
|
||||
|
||||
};
|
||||
|
||||
#endif // GLW_FRAGMENTSHADER_H
|
|
@ -0,0 +1,316 @@
|
|||
#ifndef GLW_FRAMEBUFFER_H
|
||||
#define GLW_FRAMEBUFFER_H
|
||||
|
||||
#include "./object.h"
|
||||
#include <vector>
|
||||
|
||||
namespace glw
|
||||
{
|
||||
|
||||
class RenderTarget
|
||||
{
|
||||
public:
|
||||
|
||||
typedef void BaseType;
|
||||
typedef RenderTarget ThisType;
|
||||
|
||||
RenderableHandle target;
|
||||
GLint level;
|
||||
GLint layer;
|
||||
GLenum face;
|
||||
|
||||
RenderTarget(void)
|
||||
{
|
||||
this->clear();
|
||||
}
|
||||
|
||||
RenderTarget(RenderableHandle & rTarget, GLint rLevel, GLint rLayer, GLenum rFace)
|
||||
: target (rTarget)
|
||||
, level (rLevel)
|
||||
, layer (rLayer)
|
||||
, face (rFace)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
void clear(void)
|
||||
{
|
||||
this->target.setNull();
|
||||
this->level = 0;
|
||||
this->layer = -1;
|
||||
this->face = GL_NONE;
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::vector<RenderTarget> RenderTargetVector;
|
||||
|
||||
inline RenderTarget texture2DTarget(Texture2DHandle & handle, GLint level = 0)
|
||||
{
|
||||
return RenderTarget(handle, level, 0, GL_NONE);
|
||||
}
|
||||
|
||||
inline RenderTarget renderbufferTarget(RenderbufferHandle & handle)
|
||||
{
|
||||
return RenderTarget(handle, 0, 0, GL_NONE);
|
||||
}
|
||||
|
||||
class RenderTargetMapping
|
||||
{
|
||||
public:
|
||||
|
||||
typedef void BaseType;
|
||||
typedef RenderTargetMapping ThisType;
|
||||
|
||||
typedef std::map<GLuint, RenderTarget> Map;
|
||||
typedef Map::const_iterator ConstIterator;
|
||||
typedef Map::iterator Iterator;
|
||||
typedef Map::value_type Value;
|
||||
|
||||
Map bindings;
|
||||
|
||||
RenderTargetMapping(void)
|
||||
{
|
||||
this->clear();
|
||||
}
|
||||
|
||||
void clear(void)
|
||||
{
|
||||
this->bindings.clear();
|
||||
}
|
||||
|
||||
const RenderTarget & operator [] (GLuint attachmentIndex) const
|
||||
{
|
||||
return this->bindings.find(attachmentIndex)->second;
|
||||
}
|
||||
|
||||
RenderTarget & operator [] (GLuint attachmentIndex)
|
||||
{
|
||||
return this->bindings[attachmentIndex];
|
||||
}
|
||||
};
|
||||
|
||||
class RenderTargetBinding
|
||||
{
|
||||
public:
|
||||
|
||||
typedef void BaseType;
|
||||
typedef RenderTargetBinding ThisType;
|
||||
|
||||
typedef std::map<GLuint, GLuint> Map;
|
||||
typedef Map::const_iterator ConstIterator;
|
||||
typedef Map::iterator Iterator;
|
||||
typedef Map::value_type Value;
|
||||
|
||||
Map bindings;
|
||||
|
||||
RenderTargetBinding(void)
|
||||
{
|
||||
this->clear();
|
||||
}
|
||||
|
||||
void clear(void)
|
||||
{
|
||||
this->bindings.clear();
|
||||
}
|
||||
|
||||
GLuint operator [] (GLuint attachmentIndex) const
|
||||
{
|
||||
return this->bindings.find(attachmentIndex)->second;
|
||||
}
|
||||
|
||||
GLuint & operator [] (GLuint attachmentIndex)
|
||||
{
|
||||
return this->bindings[attachmentIndex];
|
||||
}
|
||||
};
|
||||
|
||||
class FramebufferArguments : public ObjectArguments
|
||||
{
|
||||
public:
|
||||
|
||||
typedef ObjectArguments BaseType;
|
||||
typedef FramebufferArguments ThisType;
|
||||
|
||||
RenderTargetMapping colorTargets;
|
||||
RenderTarget depthTarget;
|
||||
RenderTarget stencilTarget;
|
||||
RenderTarget depthStencilTarget;
|
||||
RenderTargetBinding targetInputs;
|
||||
|
||||
FramebufferArguments(void)
|
||||
{
|
||||
this->clear();
|
||||
}
|
||||
|
||||
void clear(void)
|
||||
{
|
||||
BaseType::clear();
|
||||
this->colorTargets .clear();
|
||||
this->depthTarget .clear();
|
||||
this->stencilTarget .clear();
|
||||
this->depthStencilTarget .clear();
|
||||
this->targetInputs .clear();
|
||||
}
|
||||
};
|
||||
|
||||
class SafeFramebuffer : public virtual SafeObject
|
||||
{
|
||||
public:
|
||||
|
||||
typedef SafeObject BaseType;
|
||||
typedef SafeFramebuffer ThisType;
|
||||
|
||||
protected:
|
||||
|
||||
SafeFramebuffer(Context * ctx)
|
||||
: BaseType(ctx)
|
||||
{
|
||||
;
|
||||
}
|
||||
};
|
||||
|
||||
class Framebuffer : public Object, public SafeFramebuffer
|
||||
{
|
||||
friend class Context;
|
||||
friend class detail::SharedObjectBinding<Framebuffer>;
|
||||
|
||||
public:
|
||||
|
||||
typedef Object BaseType;
|
||||
typedef SafeFramebuffer SafeType;
|
||||
typedef Framebuffer ThisType;
|
||||
|
||||
virtual Type type(void) const
|
||||
{
|
||||
return FramebufferType;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
Framebuffer(Context * ctx)
|
||||
: SafeObject (ctx)
|
||||
, SafeType (ctx)
|
||||
, BaseType (ctx)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
virtual ~Framebuffer(void)
|
||||
{
|
||||
this->destroy();
|
||||
}
|
||||
|
||||
bool create(const FramebufferArguments & args)
|
||||
{
|
||||
this->destroy();
|
||||
|
||||
this->m_config = args;
|
||||
|
||||
GLint boundNameDraw = 0;
|
||||
glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &boundNameDraw);
|
||||
|
||||
GLint boundNameRead = 0;
|
||||
glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &boundNameRead);
|
||||
|
||||
glGenFramebuffers(1, &(this->m_name));
|
||||
this->setBinding(GL_FRAMEBUFFER, 0);
|
||||
this->bind();
|
||||
this->configure();
|
||||
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, boundNameDraw);
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, boundNameRead);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual void doDestroy(Context * ctx, GLuint name)
|
||||
{
|
||||
(void)ctx;
|
||||
if (name == 0) return;
|
||||
glDeleteFramebuffers(1, &name);
|
||||
this->m_config.clear();
|
||||
}
|
||||
|
||||
virtual void doBind(void)
|
||||
{
|
||||
glBindFramebuffer(this->m_target, this->m_name);
|
||||
}
|
||||
|
||||
virtual void doUnbind(void)
|
||||
{
|
||||
glBindFramebuffer(this->m_target, 0);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
FramebufferArguments m_config;
|
||||
|
||||
void configure(void)
|
||||
{
|
||||
for (RenderTargetMapping::Iterator it=this->m_config.colorTargets.bindings.begin(); it!=this->m_config.colorTargets.bindings.end(); ++it)
|
||||
{
|
||||
this->attachTarget(GL_COLOR_ATTACHMENT0 + it->first, it->second);
|
||||
}
|
||||
|
||||
if (this->m_config.depthStencilTarget.target)
|
||||
{
|
||||
this->attachTarget(GL_DEPTH_ATTACHMENT, this->m_config.depthStencilTarget);
|
||||
this->attachTarget(GL_STENCIL_ATTACHMENT, this->m_config.depthStencilTarget);
|
||||
}
|
||||
else
|
||||
{
|
||||
this->attachTarget(GL_DEPTH_ATTACHMENT, this->m_config.depthTarget );
|
||||
this->attachTarget(GL_STENCIL_ATTACHMENT, this->m_config.stencilTarget);
|
||||
}
|
||||
|
||||
if (this->m_config.colorTargets.bindings.empty())
|
||||
{
|
||||
glDrawBuffer(GL_NONE);
|
||||
glReadBuffer(GL_NONE);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::vector<GLenum> drawBuffers;
|
||||
drawBuffers.reserve(this->m_config.targetInputs.bindings.size());
|
||||
for (RenderTargetBinding::Iterator it=this->m_config.targetInputs.bindings.begin(); it!=this->m_config.targetInputs.bindings.end(); ++it)
|
||||
{
|
||||
const GLuint fragOutput = it->second;
|
||||
const GLuint attachmentIndex = GL_COLOR_ATTACHMENT0 + it->first;
|
||||
if (drawBuffers.size() <= size_t(fragOutput))
|
||||
{
|
||||
drawBuffers.resize(size_t(fragOutput + 1), GL_NONE);
|
||||
}
|
||||
drawBuffers[fragOutput] = attachmentIndex;
|
||||
}
|
||||
glDrawBuffers(GLsizei(drawBuffers.size()), &(drawBuffers[0]));
|
||||
glReadBuffer(drawBuffers[0]);
|
||||
}
|
||||
}
|
||||
|
||||
bool attachTarget(GLenum attachment, RenderTarget & target)
|
||||
{
|
||||
RenderableHandle & handle = target.target;
|
||||
|
||||
if (!handle)
|
||||
{
|
||||
glFramebufferRenderbuffer(this->m_target, attachment, GL_RENDERBUFFER, 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (handle->type())
|
||||
{
|
||||
case RenderbufferType : glFramebufferRenderbuffer (this->m_target, attachment, GL_RENDERBUFFER, handle->name() ); break;
|
||||
case Texture2DType : glFramebufferTexture2D (this->m_target, attachment, GL_TEXTURE_2D, handle->name(), target.level); break;
|
||||
default : GLW_ASSERT(0); break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
typedef detail::SafeHandle <Framebuffer> FramebufferHandle;
|
||||
typedef detail::UnsafeHandle <Framebuffer> BoundFramebuffer;
|
||||
|
||||
};
|
||||
|
||||
#endif // GLW_FRAMEBUFFER_H
|
|
@ -0,0 +1,87 @@
|
|||
#ifndef GLW_GEOMETRYSHADER_H
|
||||
#define GLW_GEOMETRYSHADER_H
|
||||
|
||||
#include "./shader.h"
|
||||
|
||||
namespace glw
|
||||
{
|
||||
|
||||
class GeometryShaderArguments : public ShaderArguments
|
||||
{
|
||||
public:
|
||||
|
||||
typedef ShaderArguments BaseType;
|
||||
typedef GeometryShaderArguments ThisType;
|
||||
|
||||
GeometryShaderArguments(void)
|
||||
{
|
||||
this->clear();
|
||||
}
|
||||
|
||||
void clear(void)
|
||||
{
|
||||
BaseType::clear();
|
||||
}
|
||||
};
|
||||
|
||||
class SafeGeometryShader : public virtual SafeShader
|
||||
{
|
||||
public:
|
||||
|
||||
typedef SafeShader BaseType;
|
||||
typedef SafeGeometryShader ThisType;
|
||||
|
||||
protected:
|
||||
|
||||
SafeGeometryShader(Context * ctx)
|
||||
: SafeObject (ctx)
|
||||
, BaseType (ctx)
|
||||
{
|
||||
;
|
||||
}
|
||||
};
|
||||
|
||||
class GeometryShader : public Shader, public SafeGeometryShader
|
||||
{
|
||||
friend class Context;
|
||||
friend class detail::SharedObjectBinding<GeometryShader>;
|
||||
|
||||
public:
|
||||
|
||||
typedef Shader BaseType;
|
||||
typedef SafeGeometryShader SafeType;
|
||||
typedef GeometryShader ThisType;
|
||||
|
||||
virtual Type type(void) const
|
||||
{
|
||||
return GeometryShaderType;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
GeometryShader(Context * ctx)
|
||||
: SafeObject (ctx)
|
||||
, SafeShader (ctx)
|
||||
, SafeType (ctx)
|
||||
, BaseType (ctx)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
virtual GLenum shaderType(void) const
|
||||
{
|
||||
return GL_GEOMETRY_SHADER;
|
||||
}
|
||||
|
||||
bool create(const GeometryShaderArguments & args)
|
||||
{
|
||||
return BaseType::create(args);
|
||||
}
|
||||
};
|
||||
|
||||
typedef detail::SafeHandle <GeometryShader> GeometryShaderHandle;
|
||||
typedef detail::UnsafeHandle <GeometryShader> BoundGeometryShader;
|
||||
|
||||
};
|
||||
|
||||
#endif // GLW_GEOMETRYSHADER_H
|
|
@ -0,0 +1,6 @@
|
|||
#ifndef GLW_GLHEADERS_H
|
||||
#define GLW_GLHEADERS_H
|
||||
|
||||
#include <GL/glew.h>
|
||||
|
||||
#endif // GLW_GLHEADERS_H
|
|
@ -0,0 +1,7 @@
|
|||
#ifndef GLW_GLW_H
|
||||
#define GLW_GLW_H
|
||||
|
||||
#include "./context.h"
|
||||
#include "./utility.h"
|
||||
|
||||
#endif // GLW_GLW_H
|
|
@ -0,0 +1,42 @@
|
|||
#ifndef GLW_NONCOPYABLE_H
|
||||
#define GLW_NONCOPYABLE_H
|
||||
|
||||
#include "./common.h"
|
||||
|
||||
namespace glw
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
class NonCopyable
|
||||
{
|
||||
public:
|
||||
|
||||
typedef void BaseType;
|
||||
typedef NonCopyable ThisType;
|
||||
|
||||
NonCopyable(void)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
NonCopyable(const ThisType & that)
|
||||
{
|
||||
(void)that;
|
||||
}
|
||||
|
||||
ThisType & operator = (const ThisType & that)
|
||||
{
|
||||
(void)that;
|
||||
return (*this);
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
#endif // GLW_NONCOPYABLE_H
|
|
@ -0,0 +1,143 @@
|
|||
#ifndef GLW_OBJECT_H
|
||||
#define GLW_OBJECT_H
|
||||
|
||||
#include "./bookkeeping.h"
|
||||
#include "./noncopyable.h"
|
||||
#include "./type.h"
|
||||
#include "./glheaders.h"
|
||||
|
||||
namespace glw
|
||||
{
|
||||
|
||||
class Context;
|
||||
|
||||
class ObjectArguments
|
||||
{
|
||||
public:
|
||||
|
||||
typedef void BaseType;
|
||||
typedef ObjectArguments ThisType;
|
||||
|
||||
ObjectArguments(void)
|
||||
{
|
||||
this->clear();
|
||||
}
|
||||
|
||||
void clear(void)
|
||||
{
|
||||
;
|
||||
}
|
||||
};
|
||||
|
||||
class SafeObject
|
||||
{
|
||||
friend class Object;
|
||||
|
||||
public:
|
||||
|
||||
typedef void BaseType;
|
||||
typedef SafeObject ThisType;
|
||||
|
||||
bool isValid(void) const
|
||||
{
|
||||
return (this->m_name != 0);
|
||||
}
|
||||
|
||||
Context * context(void)
|
||||
{
|
||||
return this->m_context;
|
||||
}
|
||||
|
||||
const Context * context(void) const
|
||||
{
|
||||
return this->m_context;
|
||||
}
|
||||
|
||||
GLuint name(void) const
|
||||
{
|
||||
return this->m_name;
|
||||
}
|
||||
|
||||
virtual Type type(void) const = 0;
|
||||
|
||||
protected:
|
||||
|
||||
Context * m_context;
|
||||
GLuint m_name;
|
||||
|
||||
SafeObject(Context * ctx)
|
||||
: m_context (ctx)
|
||||
, m_name (0)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
virtual ~SafeObject(void)
|
||||
{
|
||||
;
|
||||
}
|
||||
};
|
||||
|
||||
class Object : public detail::NonCopyable, public virtual SafeObject
|
||||
{
|
||||
friend class Context;
|
||||
|
||||
public:
|
||||
|
||||
typedef void BaseType;
|
||||
typedef SafeObject SafeType;
|
||||
typedef Object ThisType;
|
||||
|
||||
protected:
|
||||
|
||||
GLenum m_target;
|
||||
GLint m_unit;
|
||||
|
||||
Object(Context * ctx)
|
||||
: SafeType (ctx)
|
||||
, m_target (GL_NONE)
|
||||
, m_unit (0)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
void destroy(void)
|
||||
{
|
||||
if (!this->isValid()) return;
|
||||
|
||||
this->doDestroy(this->m_context, this->m_name);
|
||||
|
||||
this->m_context = 0;
|
||||
this->m_name = 0;
|
||||
}
|
||||
|
||||
void setBinding(GLenum target, GLint unit) const
|
||||
{
|
||||
ThisType * that = const_cast<ThisType *>(this);
|
||||
that->m_target = target;
|
||||
that->m_unit = unit;
|
||||
}
|
||||
|
||||
void bind(void)
|
||||
{
|
||||
GLW_ASSERT(this->isValid());
|
||||
this->doBind();
|
||||
}
|
||||
|
||||
void unbind(void)
|
||||
{
|
||||
GLW_ASSERT(this->isValid());
|
||||
this->doUnbind();
|
||||
}
|
||||
|
||||
virtual void doDestroy (Context * ctx, GLuint name) = 0;
|
||||
virtual void doBind (void) = 0;
|
||||
virtual void doUnbind (void) = 0;
|
||||
};
|
||||
|
||||
typedef detail::SafeHandle <Object> ObjectHandle;
|
||||
typedef detail::UnsafeHandle <Object> BoundObject;
|
||||
|
||||
};
|
||||
|
||||
#endif // GLW_OBJECT_H
|
|
@ -0,0 +1,504 @@
|
|||
#ifndef GLW_PROGRAM_H
|
||||
#define GLW_PROGRAM_H
|
||||
|
||||
#include <memory.h>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
#include "./vertexshader.h"
|
||||
#include "./geometryshader.h"
|
||||
#include "./fragmentshader.h"
|
||||
|
||||
namespace glw
|
||||
{
|
||||
|
||||
typedef std::vector<ShaderHandle> ShaderHandleVector;
|
||||
|
||||
class VertexAttributeBinding
|
||||
{
|
||||
public:
|
||||
|
||||
typedef void BaseType;
|
||||
typedef VertexAttributeBinding ThisType;
|
||||
|
||||
typedef std::map<std::string, GLuint> Map;
|
||||
typedef Map::const_iterator ConstIterator;
|
||||
typedef Map::iterator Iterator;
|
||||
typedef Map::value_type Value;
|
||||
|
||||
Map bindings;
|
||||
|
||||
VertexAttributeBinding(void)
|
||||
{
|
||||
this->clear();
|
||||
}
|
||||
|
||||
void clear(void)
|
||||
{
|
||||
this->bindings.clear();
|
||||
}
|
||||
|
||||
GLuint operator [] (const std::string & attributeName) const
|
||||
{
|
||||
return this->bindings.find(attributeName)->second;
|
||||
}
|
||||
|
||||
GLuint & operator [] (const std::string & attributeName)
|
||||
{
|
||||
return this->bindings[attributeName];
|
||||
}
|
||||
};
|
||||
|
||||
class GeometryStage
|
||||
{
|
||||
public:
|
||||
|
||||
typedef void BaseType;
|
||||
typedef GeometryStage ThisType;
|
||||
|
||||
/*
|
||||
GLenum inputPrimitiveType;
|
||||
GLenum outputPrimitiveType;
|
||||
GLint maxOutputVertices;
|
||||
*/
|
||||
|
||||
GeometryStage(void)
|
||||
{
|
||||
this->clear();
|
||||
}
|
||||
|
||||
void clear(void)
|
||||
{
|
||||
/*
|
||||
this->inputPrimitiveType = GLW_DONT_CARE;
|
||||
this->outputPrimitiveType = GLW_DONT_CARE;
|
||||
this->maxOutputVertices = GLW_DONT_CARE;
|
||||
*/
|
||||
}
|
||||
};
|
||||
|
||||
class TransformFeedbackStream
|
||||
{
|
||||
public:
|
||||
|
||||
typedef void BaseType;
|
||||
typedef TransformFeedbackStream ThisType;
|
||||
|
||||
typedef std::vector<std::string> VaryingVector;
|
||||
|
||||
VaryingVector varyings;
|
||||
GLenum bufferMode;
|
||||
|
||||
TransformFeedbackStream(void)
|
||||
{
|
||||
this->clear();
|
||||
}
|
||||
|
||||
void clear(void)
|
||||
{
|
||||
this->varyings.clear();
|
||||
this->bufferMode = GL_INTERLEAVED_ATTRIBS;
|
||||
}
|
||||
};
|
||||
|
||||
class RasterizerSettings
|
||||
{
|
||||
public:
|
||||
|
||||
typedef void BaseType;
|
||||
typedef RasterizerSettings ThisType;
|
||||
|
||||
enum RasterizerExecution
|
||||
{
|
||||
DontCare = 0,
|
||||
Autodetect,
|
||||
ForceEnabled,
|
||||
ForceDisabled
|
||||
};
|
||||
|
||||
// TODO
|
||||
//RasterizerExecution execution;
|
||||
|
||||
RasterizerSettings(void)
|
||||
{
|
||||
this->clear();
|
||||
}
|
||||
|
||||
void clear(void)
|
||||
{
|
||||
//this->execution = ThisType::Autodetect;
|
||||
}
|
||||
};
|
||||
|
||||
class FragmentOutputBinding
|
||||
{
|
||||
public:
|
||||
|
||||
typedef void BaseType;
|
||||
typedef FragmentOutputBinding ThisType;
|
||||
|
||||
typedef std::map<std::string, GLuint> Map;
|
||||
typedef Map::const_iterator ConstIterator;
|
||||
typedef Map::iterator Iterator;
|
||||
typedef Map::value_type Value;
|
||||
|
||||
Map bindings;
|
||||
|
||||
FragmentOutputBinding(void)
|
||||
{
|
||||
this->clear();
|
||||
}
|
||||
|
||||
void clear(void)
|
||||
{
|
||||
this->bindings.clear();
|
||||
}
|
||||
|
||||
GLuint operator [] (const std::string & outName) const
|
||||
{
|
||||
return this->bindings.find(outName)->second;
|
||||
}
|
||||
|
||||
GLuint & operator [] (const std::string & outName)
|
||||
{
|
||||
return this->bindings[outName];
|
||||
}
|
||||
};
|
||||
|
||||
class ProgramArguments : public ObjectArguments
|
||||
{
|
||||
public:
|
||||
|
||||
typedef ObjectArguments BaseType;
|
||||
typedef ProgramArguments ThisType;
|
||||
|
||||
ShaderHandleVector shaders;
|
||||
VertexAttributeBinding vertexInputs;
|
||||
GeometryStage geometryStage;
|
||||
TransformFeedbackStream feedbackStream;
|
||||
RasterizerSettings rasterSettings;
|
||||
FragmentOutputBinding fragmentOutputs;
|
||||
|
||||
ProgramArguments(void)
|
||||
{
|
||||
this->clear();
|
||||
}
|
||||
|
||||
void clear(void)
|
||||
{
|
||||
BaseType::clear();
|
||||
this->shaders .clear();
|
||||
this->vertexInputs .clear();
|
||||
this->geometryStage .clear();
|
||||
this->feedbackStream .clear();
|
||||
this->rasterSettings .clear();
|
||||
this->fragmentOutputs .clear();
|
||||
}
|
||||
};
|
||||
|
||||
class SafeProgram : public virtual SafeObject
|
||||
{
|
||||
public:
|
||||
|
||||
typedef SafeObject BaseType;
|
||||
typedef SafeProgram ThisType;
|
||||
|
||||
const ProgramArguments & arguments(void) const
|
||||
{
|
||||
return this->m_arguments;
|
||||
}
|
||||
|
||||
const std::string & log(void) const
|
||||
{
|
||||
return this->m_log;
|
||||
}
|
||||
|
||||
bool isLinked(void) const
|
||||
{
|
||||
return this->m_linked;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
ProgramArguments m_arguments;
|
||||
std::string m_log;
|
||||
bool m_linked;
|
||||
|
||||
SafeProgram(Context * ctx)
|
||||
: BaseType (ctx)
|
||||
, m_linked (false)
|
||||
{
|
||||
;
|
||||
}
|
||||
};
|
||||
|
||||
class Program : public Object, public SafeProgram
|
||||
{
|
||||
friend class Context;
|
||||
friend class detail::SharedObjectBinding<Program>;
|
||||
|
||||
public:
|
||||
|
||||
typedef Object BaseType;
|
||||
typedef SafeProgram SafeType;
|
||||
typedef Program ThisType;
|
||||
|
||||
virtual Type type(void) const
|
||||
{
|
||||
return ProgramType;
|
||||
}
|
||||
|
||||
GLint getUniformLocation(const std::string & name) const
|
||||
{
|
||||
GLW_ASSERT(this->m_uniforms.count(name) > 0);
|
||||
return this->m_uniforms.find(name)->second.location;
|
||||
}
|
||||
|
||||
#define _GLW_IMPLEMENT_SCALAR_UNIFORM_(TYPE, FUNCION_SUFFIX) \
|
||||
void setUniform (const std::string & name, TYPE x ) { glUniform1 ## FUNCION_SUFFIX (this->getUniformLocation(name), x ); } \
|
||||
void setUniform (const std::string & name, TYPE x, TYPE y ) { glUniform2 ## FUNCION_SUFFIX (this->getUniformLocation(name), x, y ); } \
|
||||
void setUniform (const std::string & name, TYPE x, TYPE y, TYPE z ) { glUniform3 ## FUNCION_SUFFIX (this->getUniformLocation(name), x, y, z ); } \
|
||||
void setUniform (const std::string & name, TYPE x, TYPE y, TYPE z, TYPE w ) { glUniform4 ## FUNCION_SUFFIX (this->getUniformLocation(name), x, y, z, w); }
|
||||
|
||||
#define _GLW_IMPLEMENT_VECTOR_UNIFORM_(TYPE, FUNCION_SUFFIX) \
|
||||
void setUniform1 (const std::string & name, const TYPE * v, int count = 1) { glUniform1 ## FUNCION_SUFFIX ## v (this->getUniformLocation(name), GLsizei(count), v ); } \
|
||||
void setUniform2 (const std::string & name, const TYPE * v, int count = 1) { glUniform2 ## FUNCION_SUFFIX ## v (this->getUniformLocation(name), GLsizei(count), v ); } \
|
||||
void setUniform3 (const std::string & name, const TYPE * v, int count = 1) { glUniform3 ## FUNCION_SUFFIX ## v (this->getUniformLocation(name), GLsizei(count), v ); } \
|
||||
void setUniform4 (const std::string & name, const TYPE * v, int count = 1) { glUniform4 ## FUNCION_SUFFIX ## v (this->getUniformLocation(name), GLsizei(count), v ); }
|
||||
|
||||
#define _GLW_IMPLEMENT_MATRIX_UNIFORM_(TYPE, FUNCION_SUFFIX) \
|
||||
void setUniform2x2 (const std::string & name, const TYPE * m, bool transpose, int count = 1) { glUniformMatrix2 ## FUNCION_SUFFIX ## v (this->getUniformLocation(name), GLsizei(count), GLboolean(transpose), m ); } \
|
||||
void setUniform2x3 (const std::string & name, const TYPE * m, bool transpose, int count = 1) { glUniformMatrix2x3 ## FUNCION_SUFFIX ## v (this->getUniformLocation(name), GLsizei(count), GLboolean(transpose), m ); } \
|
||||
void setUniform2x4 (const std::string & name, const TYPE * m, bool transpose, int count = 1) { glUniformMatrix2x4 ## FUNCION_SUFFIX ## v (this->getUniformLocation(name), GLsizei(count), GLboolean(transpose), m ); } \
|
||||
void setUniform3x2 (const std::string & name, const TYPE * m, bool transpose, int count = 1) { glUniformMatrix3x2 ## FUNCION_SUFFIX ## v (this->getUniformLocation(name), GLsizei(count), GLboolean(transpose), m ); } \
|
||||
void setUniform3x3 (const std::string & name, const TYPE * m, bool transpose, int count = 1) { glUniformMatrix3 ## FUNCION_SUFFIX ## v (this->getUniformLocation(name), GLsizei(count), GLboolean(transpose), m ); } \
|
||||
void setUniform3x4 (const std::string & name, const TYPE * m, bool transpose, int count = 1) { glUniformMatrix3x4 ## FUNCION_SUFFIX ## v (this->getUniformLocation(name), GLsizei(count), GLboolean(transpose), m ); } \
|
||||
void setUniform4x2 (const std::string & name, const TYPE * m, bool transpose, int count = 1) { glUniformMatrix4x2 ## FUNCION_SUFFIX ## v (this->getUniformLocation(name), GLsizei(count), GLboolean(transpose), m ); } \
|
||||
void setUniform4x3 (const std::string & name, const TYPE * m, bool transpose, int count = 1) { glUniformMatrix4x3 ## FUNCION_SUFFIX ## v (this->getUniformLocation(name), GLsizei(count), GLboolean(transpose), m ); } \
|
||||
void setUniform4x4 (const std::string & name, const TYPE * m, bool transpose, int count = 1) { glUniformMatrix4 ## FUNCION_SUFFIX ## v (this->getUniformLocation(name), GLsizei(count), GLboolean(transpose), m ); }
|
||||
|
||||
_GLW_IMPLEMENT_SCALAR_UNIFORM_(int, i )
|
||||
_GLW_IMPLEMENT_SCALAR_UNIFORM_(unsigned int, ui)
|
||||
_GLW_IMPLEMENT_SCALAR_UNIFORM_(float, f )
|
||||
_GLW_IMPLEMENT_VECTOR_UNIFORM_(int, i )
|
||||
_GLW_IMPLEMENT_VECTOR_UNIFORM_(unsigned int, ui)
|
||||
_GLW_IMPLEMENT_VECTOR_UNIFORM_(float, f )
|
||||
_GLW_IMPLEMENT_MATRIX_UNIFORM_(float, f )
|
||||
|
||||
GLW_IMPLEMENT_CUSTOM_UNIFORMS;
|
||||
|
||||
#undef _GLW_IMPLEMENT_SCALAR_UNIFORM_
|
||||
#undef _GLW_IMPLEMENT_VECTOR_UNIFORM_
|
||||
#undef _GLW_IMPLEMENT_MATRIX_UNIFORM_
|
||||
|
||||
protected:
|
||||
|
||||
Program(Context * ctx)
|
||||
: SafeObject (ctx)
|
||||
, SafeType (ctx)
|
||||
, BaseType (ctx)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
virtual ~Program(void)
|
||||
{
|
||||
this->destroy();
|
||||
}
|
||||
|
||||
bool create(const ProgramArguments & args)
|
||||
{
|
||||
this->destroy();
|
||||
|
||||
this->m_arguments = args;
|
||||
|
||||
GLint boundName = 0;
|
||||
glGetIntegerv(GL_CURRENT_PROGRAM, &boundName);
|
||||
|
||||
this->m_name = glCreateProgram();
|
||||
|
||||
// shaders
|
||||
{
|
||||
for (size_t i=0; i<this->m_arguments.shaders.size(); ++i)
|
||||
{
|
||||
const ShaderHandle & shader = this->m_arguments.shaders[i];
|
||||
if (!shader) continue;
|
||||
if (!shader->isCompiled()) continue;
|
||||
glAttachShader(this->m_name, shader->name());
|
||||
}
|
||||
}
|
||||
|
||||
// vertex
|
||||
{
|
||||
for (VertexAttributeBinding::ConstIterator it=this->m_arguments.vertexInputs.bindings.begin(); it!=this->m_arguments.vertexInputs.bindings.end(); ++it)
|
||||
{
|
||||
glBindAttribLocation(this->m_name, it->second, it->first.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
// geometry
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
// transform feedback
|
||||
{
|
||||
const size_t count = this->m_arguments.feedbackStream.varyings.size();
|
||||
if (count > 0)
|
||||
{
|
||||
const char ** varyings = new const char * [count];
|
||||
for (size_t i=0; i<count; ++i)
|
||||
{
|
||||
varyings[i] = this->m_arguments.feedbackStream.varyings[i].c_str();
|
||||
}
|
||||
glTransformFeedbackVaryings(this->m_name, GLsizei(count), varyings, this->m_arguments.feedbackStream.bufferMode);
|
||||
delete [] varyings;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO
|
||||
// rasterizer
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
// fragment
|
||||
{
|
||||
for (FragmentOutputBinding::ConstIterator it=this->m_arguments.fragmentOutputs.bindings.begin(); it!=this->m_arguments.fragmentOutputs.bindings.end(); ++it)
|
||||
{
|
||||
glBindFragDataLocation(this->m_name, it->second, it->first.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
glLinkProgram(this->m_name);
|
||||
|
||||
GLint linkStatus = 0;
|
||||
glGetProgramiv(this->m_name, GL_LINK_STATUS, &linkStatus);
|
||||
|
||||
this->m_log = ThisType::getInfoLog(this->m_name);
|
||||
this->m_linked = (linkStatus != GL_FALSE);
|
||||
|
||||
if (this->m_linked)
|
||||
{
|
||||
this->postLink();
|
||||
}
|
||||
|
||||
this->setBinding(GL_CURRENT_PROGRAM, 0);
|
||||
this->bind();
|
||||
// TODO
|
||||
// ... nothing to do ...
|
||||
|
||||
glUseProgram(boundName);
|
||||
|
||||
return this->m_linked;
|
||||
}
|
||||
|
||||
virtual void doDestroy(Context * ctx, GLuint name)
|
||||
{
|
||||
(void)ctx;
|
||||
if (name == 0) return;
|
||||
glDeleteProgram(name);
|
||||
}
|
||||
|
||||
virtual void doBind(void)
|
||||
{
|
||||
glUseProgram(this->m_name);
|
||||
}
|
||||
|
||||
virtual void doUnbind(void)
|
||||
{
|
||||
glUseProgram(0);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
class UniformInfo
|
||||
{
|
||||
public:
|
||||
|
||||
typedef void BaseType;
|
||||
typedef UniformInfo ThisType;
|
||||
|
||||
std::string name;
|
||||
GLint location;
|
||||
GLenum type;
|
||||
GLint size;
|
||||
|
||||
UniformInfo(void)
|
||||
: location (-1)
|
||||
, type (GL_NONE)
|
||||
, size (0)
|
||||
{
|
||||
;
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::map<std::string, UniformInfo> UniformMap;
|
||||
typedef UniformMap::const_iterator UniformMapConstIterator;
|
||||
typedef UniformMap::iterator UniformMapIterator;
|
||||
typedef UniformMap::value_type UniformMapValue;
|
||||
|
||||
UniformMap m_uniforms;
|
||||
|
||||
static std::string getInfoLog(GLuint Program)
|
||||
{
|
||||
std::string log;
|
||||
GLint logLen = 0;
|
||||
glGetProgramiv(Program, GL_INFO_LOG_LENGTH, &logLen);
|
||||
if (logLen > 0)
|
||||
{
|
||||
char * sLog = new char[logLen + 1];
|
||||
glGetProgramInfoLog(Program, logLen, &logLen, sLog);
|
||||
if (logLen > 0)
|
||||
{
|
||||
if (sLog[0] != '\0')
|
||||
{
|
||||
sLog[logLen - 1] = '\0';
|
||||
log = sLog;
|
||||
}
|
||||
}
|
||||
delete [] sLog;
|
||||
}
|
||||
return log;
|
||||
}
|
||||
|
||||
void setupUniforms(void)
|
||||
{
|
||||
this->m_uniforms.clear();
|
||||
|
||||
GLint ucount = 0;
|
||||
glGetProgramiv(this->m_name, GL_ACTIVE_UNIFORMS, &ucount);
|
||||
if (ucount <= 0) return;
|
||||
|
||||
GLint ulen = 0;
|
||||
glGetProgramiv(this->m_name, GL_ACTIVE_UNIFORM_MAX_LENGTH, &ulen);
|
||||
ulen++; // according to specs, +1 (for null) is already accounted, but some implementations are broken.
|
||||
if (ulen <= 0) return;
|
||||
|
||||
UniformInfo info;
|
||||
GLchar * uname = new GLchar [ulen + 1];
|
||||
for (int i=0; i<int(ucount); ++i)
|
||||
{
|
||||
GLsizei length = 0;
|
||||
glGetActiveUniform(this->m_name, GLuint(i), GLsizei(ulen), &length, &(info.size), &(info.type), uname);
|
||||
info.name = uname;
|
||||
info.location = glGetUniformLocation(this->m_name, uname);
|
||||
this->m_uniforms.insert(UniformMapValue(info.name, info));
|
||||
}
|
||||
delete [] uname;
|
||||
}
|
||||
|
||||
void postLink(void)
|
||||
{
|
||||
this->setupUniforms();
|
||||
}
|
||||
};
|
||||
|
||||
typedef detail::SafeHandle <Program> ProgramHandle;
|
||||
typedef detail::UnsafeHandle <Program> BoundProgram;
|
||||
|
||||
};
|
||||
|
||||
#endif // GLW_PROGRAM_H
|
|
@ -0,0 +1,83 @@
|
|||
#ifndef GLW_RENDERABLE_H
|
||||
#define GLW_RENDERABLE_H
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "./object.h"
|
||||
|
||||
namespace glw
|
||||
{
|
||||
|
||||
class RenderableArguments : public ObjectArguments
|
||||
{
|
||||
public:
|
||||
|
||||
typedef ObjectArguments BaseType;
|
||||
typedef RenderableArguments ThisType;
|
||||
|
||||
GLenum format;
|
||||
|
||||
RenderableArguments(void)
|
||||
{
|
||||
this->clear();
|
||||
}
|
||||
|
||||
void clear(void)
|
||||
{
|
||||
BaseType::clear();
|
||||
this->format = GL_NONE;
|
||||
}
|
||||
};
|
||||
|
||||
class SafeRenderable : public virtual SafeObject
|
||||
{
|
||||
public:
|
||||
|
||||
typedef SafeObject BaseType;
|
||||
typedef SafeRenderable ThisType;
|
||||
|
||||
GLenum format(void) const
|
||||
{
|
||||
return this->m_format;
|
||||
}
|
||||
|
||||
virtual int imageDimensions (void) const = 0;
|
||||
virtual bool isArray (void) const = 0;
|
||||
|
||||
protected:
|
||||
|
||||
GLenum m_format;
|
||||
|
||||
SafeRenderable(Context * ctx)
|
||||
: BaseType (ctx)
|
||||
, m_format (GL_NONE)
|
||||
{
|
||||
;
|
||||
}
|
||||
};
|
||||
|
||||
class Renderable : public Object, public virtual SafeRenderable
|
||||
{
|
||||
public:
|
||||
|
||||
typedef Object BaseType;
|
||||
typedef SafeRenderable SafeType;
|
||||
typedef Renderable ThisType;
|
||||
|
||||
protected:
|
||||
|
||||
Renderable(Context * ctx)
|
||||
: SafeObject (ctx)
|
||||
, SafeType (ctx)
|
||||
, BaseType (ctx)
|
||||
{
|
||||
;
|
||||
}
|
||||
};
|
||||
|
||||
typedef detail::SafeHandle <Renderable> RenderableHandle;
|
||||
typedef detail::UnsafeHandle <Renderable> BoundRenderable;
|
||||
|
||||
};
|
||||
|
||||
#endif // GLW_RENDERABLE_H
|
|
@ -0,0 +1,158 @@
|
|||
#ifndef GLW_RENDERBUFFER_H
|
||||
#define GLW_RENDERBUFFER_H
|
||||
|
||||
#include "./renderable.h"
|
||||
|
||||
namespace glw
|
||||
{
|
||||
|
||||
class RenderbufferArguments : public RenderableArguments
|
||||
{
|
||||
public:
|
||||
|
||||
typedef RenderableArguments BaseType;
|
||||
typedef RenderbufferArguments ThisType;
|
||||
|
||||
GLsizei width;
|
||||
GLsizei height;
|
||||
|
||||
RenderbufferArguments(void)
|
||||
{
|
||||
this->clear();
|
||||
}
|
||||
|
||||
void clear(void)
|
||||
{
|
||||
BaseType::clear();
|
||||
this->width = 0;
|
||||
this->height = 0;
|
||||
}
|
||||
};
|
||||
|
||||
class SafeRenderbuffer : public virtual SafeRenderable
|
||||
{
|
||||
public:
|
||||
|
||||
typedef SafeRenderable BaseType;
|
||||
typedef SafeRenderbuffer ThisType;
|
||||
|
||||
GLsizei width(void) const
|
||||
{
|
||||
return this->m_width;
|
||||
}
|
||||
|
||||
GLsizei height(void) const
|
||||
{
|
||||
return this->m_height;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
GLsizei m_width;
|
||||
GLsizei m_height;
|
||||
|
||||
SafeRenderbuffer(Context * ctx)
|
||||
: SafeObject (ctx)
|
||||
, BaseType (ctx)
|
||||
, m_width (0)
|
||||
, m_height (0)
|
||||
{
|
||||
;
|
||||
}
|
||||
};
|
||||
|
||||
class Renderbuffer : public Renderable, public SafeRenderbuffer
|
||||
{
|
||||
friend class Context;
|
||||
friend class detail::SharedObjectBinding<Renderbuffer>;
|
||||
|
||||
public:
|
||||
|
||||
typedef Renderable BaseType;
|
||||
typedef SafeRenderbuffer SafeType;
|
||||
typedef Renderbuffer ThisType;
|
||||
|
||||
virtual Type type(void) const
|
||||
{
|
||||
return RenderbufferType;
|
||||
}
|
||||
|
||||
virtual int imageDimensions(void) const
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
virtual bool isArray(void) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
Renderbuffer(Context * ctx)
|
||||
: SafeObject (ctx)
|
||||
, SafeRenderable (ctx)
|
||||
, SafeType (ctx)
|
||||
, BaseType (ctx)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
virtual ~Renderbuffer(void)
|
||||
{
|
||||
this->destroy();
|
||||
}
|
||||
|
||||
bool create(const RenderbufferArguments & args)
|
||||
{
|
||||
this->destroy();
|
||||
|
||||
GLint boundName = 0;
|
||||
glGetIntegerv(GL_RENDERBUFFER_BINDING, &boundName);
|
||||
|
||||
glGenRenderbuffers(1, &(this->m_name));
|
||||
this->setBinding(GL_RENDERBUFFER_BINDING, 0);
|
||||
this->bind();
|
||||
this->allocate(args.format, args.width, args.height);
|
||||
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, boundName);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual void doDestroy(Context * ctx, GLuint name)
|
||||
{
|
||||
(void)ctx;
|
||||
if (name == 0) return;
|
||||
this->m_format = GL_NONE;
|
||||
this->m_width = 0;
|
||||
this->m_height = 0;
|
||||
glDeleteRenderbuffers(1, &name);
|
||||
}
|
||||
|
||||
virtual void doBind(void)
|
||||
{
|
||||
glBindRenderbuffer(this->m_target, this->m_name);
|
||||
}
|
||||
|
||||
virtual void doUnbind(void)
|
||||
{
|
||||
glBindRenderbuffer(this->m_target, 0);
|
||||
}
|
||||
|
||||
void allocate(GLenum format, GLsizei width, GLsizei height)
|
||||
{
|
||||
GLW_ASSERT(this->isValid());
|
||||
glRenderbufferStorage(this->m_target, format, width, height);
|
||||
this->m_format = format;
|
||||
this->m_width = width;
|
||||
this->m_height = height;
|
||||
}
|
||||
};
|
||||
|
||||
typedef detail::SafeHandle <Renderbuffer> RenderbufferHandle;
|
||||
typedef detail::UnsafeHandle <Renderbuffer> BoundRenderbuffer;
|
||||
|
||||
};
|
||||
|
||||
#endif // GLW_RENDERBUFFER_H
|
|
@ -0,0 +1,174 @@
|
|||
#ifndef GLW_SHADER_H
|
||||
#define GLW_SHADER_H
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "./object.h"
|
||||
|
||||
namespace glw
|
||||
{
|
||||
|
||||
class ShaderArguments : public ObjectArguments
|
||||
{
|
||||
public:
|
||||
|
||||
typedef ObjectArguments BaseType;
|
||||
typedef ShaderArguments ThisType;
|
||||
|
||||
std::string source;
|
||||
|
||||
ShaderArguments(void)
|
||||
{
|
||||
this->clear();
|
||||
}
|
||||
|
||||
void clear(void)
|
||||
{
|
||||
BaseType::clear();
|
||||
this->source.clear();
|
||||
}
|
||||
};
|
||||
|
||||
class SafeShader : public virtual SafeObject
|
||||
{
|
||||
public:
|
||||
|
||||
typedef SafeObject BaseType;
|
||||
typedef SafeShader ThisType;
|
||||
|
||||
const std::string & source(void) const
|
||||
{
|
||||
return this->m_source;
|
||||
}
|
||||
|
||||
const std::string & log(void) const
|
||||
{
|
||||
return this->m_log;
|
||||
}
|
||||
|
||||
bool isCompiled(void) const
|
||||
{
|
||||
return this->m_compiled;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
std::string m_source;
|
||||
std::string m_log;
|
||||
bool m_compiled;
|
||||
|
||||
SafeShader(Context * ctx)
|
||||
: BaseType (ctx)
|
||||
, m_compiled (false)
|
||||
{
|
||||
;
|
||||
}
|
||||
};
|
||||
|
||||
class Shader : public Object, public virtual SafeShader
|
||||
{
|
||||
public:
|
||||
|
||||
typedef Object BaseType;
|
||||
typedef SafeShader SafeType;
|
||||
typedef Shader ThisType;
|
||||
|
||||
protected:
|
||||
|
||||
Shader(Context * ctx)
|
||||
: SafeObject (ctx)
|
||||
, BaseType (ctx)
|
||||
, SafeType (ctx)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
virtual ~Shader(void)
|
||||
{
|
||||
this->destroy();
|
||||
}
|
||||
|
||||
virtual GLenum shaderType(void) const = 0;
|
||||
|
||||
bool create(const ShaderArguments & args)
|
||||
{
|
||||
this->destroy();
|
||||
|
||||
const GLenum shType = this->shaderType();
|
||||
|
||||
this->m_name = glCreateShader(shType);
|
||||
this->setBinding(shType, 0);
|
||||
this->bind();
|
||||
this->compile(args.source);
|
||||
|
||||
return this->m_compiled;
|
||||
}
|
||||
|
||||
virtual void doDestroy(Context * ctx, GLuint name)
|
||||
{
|
||||
(void)ctx;
|
||||
if (name == 0) return;
|
||||
this->m_source.clear();
|
||||
this->m_log.clear();
|
||||
this->m_compiled = false;
|
||||
glDeleteShader(name);
|
||||
}
|
||||
|
||||
virtual void doBind(void)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
virtual void doUnbind(void)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
void compile(const std::string & source)
|
||||
{
|
||||
GLW_ASSERT(this->isValid());
|
||||
|
||||
const char * src = source.c_str();
|
||||
glShaderSource(this->m_name, 1, &src, 0);
|
||||
glCompileShader(this->m_name);
|
||||
|
||||
GLint compileStatus = 0;
|
||||
glGetShaderiv(this->m_name, GL_COMPILE_STATUS, &compileStatus);
|
||||
|
||||
this->m_source = source;
|
||||
this->m_log = ThisType::getInfoLog(this->m_name);
|
||||
this->m_compiled = (compileStatus != GL_FALSE);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
static std::string getInfoLog(GLuint Shader)
|
||||
{
|
||||
std::string log;
|
||||
|
||||
GLint logLen = 0;
|
||||
glGetShaderiv(Shader, GL_INFO_LOG_LENGTH, &logLen);
|
||||
if (logLen > 0)
|
||||
{
|
||||
char * sLog = new char[logLen + 1];
|
||||
glGetShaderInfoLog(Shader, logLen, &logLen, sLog);
|
||||
if (logLen > 0)
|
||||
{
|
||||
if (sLog[0] != '\0')
|
||||
{
|
||||
sLog[logLen - 1] = '\0';
|
||||
log = sLog;
|
||||
}
|
||||
}
|
||||
delete [] sLog;
|
||||
}
|
||||
return log;
|
||||
}
|
||||
};
|
||||
|
||||
typedef detail::SafeHandle <Shader> ShaderHandle;
|
||||
typedef detail::UnsafeHandle <Shader> BoundShader;
|
||||
|
||||
};
|
||||
|
||||
#endif // GLW_SHADER_H
|
|
@ -0,0 +1,136 @@
|
|||
#ifndef GLW_TEXTURE_H
|
||||
#define GLW_TEXTURE_H
|
||||
|
||||
#include "./renderable.h"
|
||||
|
||||
namespace glw
|
||||
{
|
||||
|
||||
class TextureSampleMode
|
||||
{
|
||||
public:
|
||||
|
||||
typedef void BaseType;
|
||||
typedef TextureSampleMode ThisType;
|
||||
|
||||
GLenum minFilter;
|
||||
GLenum magFilter;
|
||||
GLenum wrapS;
|
||||
GLenum wrapT;
|
||||
GLenum wrapR;
|
||||
|
||||
TextureSampleMode(void)
|
||||
{
|
||||
this->clear();
|
||||
}
|
||||
|
||||
TextureSampleMode(GLenum rMinFilter, GLenum rMagFilter, GLenum rWrapS, GLenum rWrapT, GLenum rWrapR)
|
||||
: minFilter (rMinFilter)
|
||||
, magFilter (rMagFilter)
|
||||
, wrapS (rWrapS)
|
||||
, wrapT (rWrapT)
|
||||
, wrapR (rWrapR)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
void clear(void)
|
||||
{
|
||||
this->minFilter = GLW_DONT_CARE;
|
||||
this->magFilter = GLW_DONT_CARE;
|
||||
this->wrapS = GLW_DONT_CARE;
|
||||
this->wrapT = GLW_DONT_CARE;
|
||||
this->wrapR = GLW_DONT_CARE;
|
||||
}
|
||||
};
|
||||
|
||||
inline TextureSampleMode texSampleMode(GLenum minFilter = GLW_DONT_CARE, GLenum magFilter = GLW_DONT_CARE, GLenum wrapS = GLW_DONT_CARE, GLenum wrapT = GLW_DONT_CARE, GLenum wrapR = GLW_DONT_CARE)
|
||||
{
|
||||
return TextureSampleMode(minFilter, magFilter, wrapS, wrapT, wrapR);
|
||||
}
|
||||
|
||||
class TextureArguments : public RenderableArguments
|
||||
{
|
||||
public:
|
||||
|
||||
typedef RenderableArguments BaseType;
|
||||
typedef TextureArguments ThisType;
|
||||
|
||||
TextureArguments(void)
|
||||
{
|
||||
this->clear();
|
||||
}
|
||||
|
||||
void clear(void)
|
||||
{
|
||||
BaseType::clear();
|
||||
}
|
||||
};
|
||||
|
||||
class SafeTexture : public virtual SafeRenderable
|
||||
{
|
||||
public:
|
||||
|
||||
typedef SafeRenderable BaseType;
|
||||
typedef SafeTexture ThisType;
|
||||
|
||||
protected:
|
||||
|
||||
SafeTexture(Context * ctx)
|
||||
: SafeObject (ctx)
|
||||
, BaseType (ctx)
|
||||
{
|
||||
;
|
||||
}
|
||||
};
|
||||
|
||||
class Texture : public Renderable, public virtual SafeTexture
|
||||
{
|
||||
public:
|
||||
|
||||
typedef Renderable BaseType;
|
||||
typedef SafeTexture SafeType;
|
||||
typedef Texture ThisType;
|
||||
|
||||
protected:
|
||||
|
||||
Texture(Context * ctx)
|
||||
: SafeObject (ctx)
|
||||
, SafeRenderable (ctx)
|
||||
, SafeType (ctx)
|
||||
, BaseType (ctx)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
virtual ~Texture(void)
|
||||
{
|
||||
this->destroy();
|
||||
}
|
||||
|
||||
virtual void doDestroy(Context * ctx, GLuint name)
|
||||
{
|
||||
(void)ctx;
|
||||
if (name == 0) return;
|
||||
glDeleteTextures(1, &name);
|
||||
}
|
||||
|
||||
virtual void doBind(void)
|
||||
{
|
||||
glActiveTexture(GL_TEXTURE0 + this->m_unit);
|
||||
glBindTexture(this->m_target, this->m_name);
|
||||
}
|
||||
|
||||
virtual void doUnbind(void)
|
||||
{
|
||||
glActiveTexture(GL_TEXTURE0 + this->m_unit);
|
||||
glBindTexture(this->m_target, 0);
|
||||
}
|
||||
};
|
||||
|
||||
typedef detail::SafeHandle <Texture> TextureHandle;
|
||||
typedef detail::UnsafeHandle <Texture> BoundTexture;
|
||||
|
||||
};
|
||||
|
||||
#endif // GLW_TEXTURE_H
|
|
@ -0,0 +1,175 @@
|
|||
#ifndef GLW_TEXTURE2D_H
|
||||
#define GLW_TEXTURE2D_H
|
||||
|
||||
#include "./texture.h"
|
||||
|
||||
namespace glw
|
||||
{
|
||||
|
||||
class Texture2DArguments : public TextureArguments
|
||||
{
|
||||
public:
|
||||
|
||||
typedef TextureArguments BaseType;
|
||||
typedef Texture2DArguments ThisType;
|
||||
|
||||
GLsizei width;
|
||||
GLsizei height;
|
||||
GLenum dataFormat;
|
||||
GLenum dataType;
|
||||
const void * data;
|
||||
TextureSampleMode sampler;
|
||||
|
||||
Texture2DArguments(void)
|
||||
{
|
||||
this->clear();
|
||||
}
|
||||
|
||||
void clear(void)
|
||||
{
|
||||
BaseType::clear();
|
||||
this->width = 0;
|
||||
this->height = 0;
|
||||
this->dataFormat = GL_NONE;
|
||||
this->dataType = GL_NONE;
|
||||
this->data = 0;
|
||||
this->sampler.clear();
|
||||
}
|
||||
};
|
||||
|
||||
class SafeTexture2D : public virtual SafeTexture
|
||||
{
|
||||
public:
|
||||
|
||||
typedef SafeTexture BaseType;
|
||||
typedef SafeTexture2D ThisType;
|
||||
|
||||
GLsizei width(void) const
|
||||
{
|
||||
return this->m_width;
|
||||
}
|
||||
|
||||
GLsizei height(void) const
|
||||
{
|
||||
return this->m_height;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
GLsizei m_width;
|
||||
GLsizei m_height;
|
||||
|
||||
SafeTexture2D(Context * ctx)
|
||||
: SafeObject (ctx)
|
||||
, SafeRenderable (ctx)
|
||||
, BaseType (ctx)
|
||||
, m_width (0)
|
||||
, m_height (0)
|
||||
{
|
||||
;
|
||||
}
|
||||
};
|
||||
|
||||
class Texture2D : public Texture, public SafeTexture2D
|
||||
{
|
||||
friend class Context;
|
||||
friend class detail::SharedObjectBinding<Texture2D>;
|
||||
|
||||
public:
|
||||
|
||||
typedef Texture BaseType;
|
||||
typedef SafeTexture2D SafeType;
|
||||
typedef Texture ThisType;
|
||||
|
||||
virtual Type type(void) const
|
||||
{
|
||||
return Texture2DType;
|
||||
}
|
||||
|
||||
virtual int imageDimensions(void) const
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
virtual bool isArray(void) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void allocateLevel(GLint level, GLsizei width, GLsizei height, GLenum dataFormat, GLenum dataType, const void * data)
|
||||
{
|
||||
GLW_ASSERT(this->isValid());
|
||||
glTexImage2D(this->m_target, level, this->m_format, width, height, 0, dataFormat, dataType, data);
|
||||
}
|
||||
|
||||
void setSubImage(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum dataFormat, GLenum dataType, const void * data)
|
||||
{
|
||||
GLW_ASSERT(this->isValid());
|
||||
glTexSubImage2D(this->m_target, level, xoffset, yoffset, width, height, dataFormat, dataType, data);
|
||||
}
|
||||
|
||||
void generateMipmap(void)
|
||||
{
|
||||
GLW_ASSERT(this->isValid());
|
||||
glGenerateMipmap(this->m_target);
|
||||
}
|
||||
|
||||
void setSampleMode(const TextureSampleMode & sampler)
|
||||
{
|
||||
GLW_ASSERT(this->isValid());
|
||||
if (GLW_CARE_OF(sampler.minFilter)) glTexParameteri(this->m_target, GL_TEXTURE_MIN_FILTER, sampler.minFilter);
|
||||
if (GLW_CARE_OF(sampler.magFilter)) glTexParameteri(this->m_target, GL_TEXTURE_MAG_FILTER, sampler.magFilter);
|
||||
if (GLW_CARE_OF(sampler.wrapS )) glTexParameteri(this->m_target, GL_TEXTURE_WRAP_S, sampler.wrapS );
|
||||
if (GLW_CARE_OF(sampler.wrapT )) glTexParameteri(this->m_target, GL_TEXTURE_WRAP_T, sampler.wrapT );
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
Texture2D(Context * ctx)
|
||||
: SafeObject (ctx)
|
||||
, SafeRenderable (ctx)
|
||||
, SafeTexture (ctx)
|
||||
, SafeType (ctx)
|
||||
, BaseType (ctx)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
bool create(const Texture2DArguments & args)
|
||||
{
|
||||
this->destroy();
|
||||
|
||||
GLint activeUnit = 0;
|
||||
glGetIntegerv(GL_ACTIVE_TEXTURE, &activeUnit);
|
||||
|
||||
GLint boundName = 0;
|
||||
glGetIntegerv(GL_TEXTURE_BINDING_2D, &boundName);
|
||||
|
||||
glGenRenderbuffers(1, &(this->m_name));
|
||||
this->setBinding(GL_TEXTURE_2D, 0);
|
||||
this->bind();
|
||||
this->allocate(args.format, args.width, args.height, args.dataFormat, args.dataType, args.data);
|
||||
this->setSampleMode(args.sampler);
|
||||
|
||||
glActiveTexture(activeUnit);
|
||||
glBindTexture(GL_TEXTURE_2D, boundName);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void allocate(GLenum format, GLsizei width, GLsizei height, GLenum dataFormat, GLenum dataType, const void * data)
|
||||
{
|
||||
GLW_ASSERT(this->isValid());
|
||||
glTexImage2D(this->m_target, 0, format, width, height, 0, dataFormat, dataType, data);
|
||||
this->m_format = format;
|
||||
this->m_width = width;
|
||||
this->m_height = height;
|
||||
}
|
||||
};
|
||||
|
||||
typedef detail::SafeHandle <Texture2D> Texture2DHandle;
|
||||
typedef detail::UnsafeHandle <Texture2D> BoundTexture2D;
|
||||
|
||||
};
|
||||
|
||||
#endif // GLW_TEXTURE2D_H
|
|
@ -0,0 +1,24 @@
|
|||
#ifndef GLW_TYPE_H
|
||||
#define GLW_TYPE_H
|
||||
|
||||
#include "./common.h"
|
||||
|
||||
namespace glw
|
||||
{
|
||||
|
||||
enum Type
|
||||
{
|
||||
NoType = 0,
|
||||
BufferType,
|
||||
RenderbufferType,
|
||||
VertexShaderType,
|
||||
GeometryShaderType,
|
||||
FragmentShaderType,
|
||||
ProgramType,
|
||||
Texture2DType,
|
||||
FramebufferType
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
#endif // GLW_TYPE_H
|
|
@ -0,0 +1,288 @@
|
|||
#ifndef GLW_UTILITY_H
|
||||
#define GLW_UTILITY_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#include "./context.h"
|
||||
|
||||
#define GLW_STRINGFY(S) #S
|
||||
#define GLW_OFFSET_OF(TYPE, MEMBER) ((const void *)(offsetof(TYPE, MEMBER)))
|
||||
|
||||
namespace glw
|
||||
{
|
||||
|
||||
class ShaderHeaderBuilder
|
||||
{
|
||||
public:
|
||||
|
||||
typedef void BaseType;
|
||||
typedef ShaderHeaderBuilder ThisType;
|
||||
|
||||
void clear(void)
|
||||
{
|
||||
this->m_version .clear();
|
||||
this->m_extensions .clear();
|
||||
this->m_defines .clear();
|
||||
this->m_texts .clear();
|
||||
}
|
||||
|
||||
ThisType & version(const std::string & v)
|
||||
{
|
||||
this->m_version = v;
|
||||
return (*this);
|
||||
}
|
||||
|
||||
ThisType & enableExtension(const std::string & ext)
|
||||
{
|
||||
this->m_extensions[ext] = ThisType::Enable;
|
||||
return (*this);
|
||||
}
|
||||
|
||||
ThisType & disableExtension(const std::string & ext)
|
||||
{
|
||||
this->m_extensions[ext] = ThisType::Disable;
|
||||
return (*this);
|
||||
}
|
||||
|
||||
ThisType & requireExtension(const std::string & ext)
|
||||
{
|
||||
this->m_extensions[ext] = ThisType::Require;
|
||||
return (*this);
|
||||
}
|
||||
|
||||
ThisType & define(const std::string & name, const std::string & value)
|
||||
{
|
||||
this->m_defines[name] = value;
|
||||
return (*this);
|
||||
}
|
||||
|
||||
ThisType & text(const std::string & txt)
|
||||
{
|
||||
this->m_texts.push_back(txt);
|
||||
return (*this);
|
||||
}
|
||||
|
||||
std::string toString(void) const
|
||||
{
|
||||
const char * extModeMap[] =
|
||||
{
|
||||
"",
|
||||
"enable",
|
||||
"disable",
|
||||
"require"
|
||||
};
|
||||
|
||||
std::ostringstream res;
|
||||
|
||||
if (!this->m_version.empty())
|
||||
{
|
||||
res << "#version " << this->m_version << std::endl;
|
||||
res << std::endl;
|
||||
}
|
||||
|
||||
if (!this->m_extensions.empty())
|
||||
{
|
||||
for (ExtensionMapConstIterator it=this->m_extensions.begin(); it!=this->m_extensions.end(); ++it)
|
||||
{
|
||||
if (it->second == ThisType::DontCare) continue;
|
||||
res << "#extension " << it->first << " : " << extModeMap[it->second] << std::endl;
|
||||
}
|
||||
res << std::endl;
|
||||
}
|
||||
|
||||
if (!this->m_defines.empty())
|
||||
{
|
||||
for (DefineMapConstIterator it=this->m_defines.begin(); it!=this->m_defines.end(); ++it)
|
||||
{
|
||||
res << "#define " << it->first << " " << it->second << std::endl;
|
||||
}
|
||||
res << std::endl;
|
||||
}
|
||||
|
||||
if (!this->m_texts.empty())
|
||||
{
|
||||
for (size_t i=0; i<this->m_texts.size(); ++i)
|
||||
{
|
||||
res << this->m_texts[i] << std::endl;
|
||||
}
|
||||
res << std::endl;
|
||||
}
|
||||
|
||||
return res.str();
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
enum ExtensionMode
|
||||
{
|
||||
DontCare = 0,
|
||||
Enable,
|
||||
Disable,
|
||||
Require
|
||||
};
|
||||
|
||||
typedef std::map<std::string, ExtensionMode> ExtensionMap;
|
||||
typedef ExtensionMap::const_iterator ExtensionMapConstIterator;
|
||||
typedef ExtensionMap::iterator ExtensionMapIterator;
|
||||
typedef ExtensionMap::value_type ExtensionMapValue;
|
||||
|
||||
typedef std::map<std::string, std::string> DefineMap;
|
||||
typedef DefineMap::const_iterator DefineMapConstIterator;
|
||||
typedef DefineMap::iterator DefineMapIterator;
|
||||
typedef DefineMap::value_type DefineMapValue;
|
||||
|
||||
typedef std::vector<std::string> TextVector;
|
||||
|
||||
std::string m_version;
|
||||
ExtensionMap m_extensions;
|
||||
DefineMap m_defines;
|
||||
TextVector m_texts;
|
||||
};
|
||||
|
||||
inline std::string readTextFile(const char * fileName)
|
||||
{
|
||||
std::string r;
|
||||
if (fileName == 0) return r;
|
||||
|
||||
FILE * f = fopen(fileName, "rb");
|
||||
if (f == 0) return r;
|
||||
|
||||
fseek(f, 0, SEEK_END);
|
||||
const size_t sz = size_t(ftell(f));
|
||||
rewind(f);
|
||||
|
||||
char * str = new char [sz + 1];
|
||||
fread(str, sizeof(char), sz / sizeof(char), f);
|
||||
fclose(f);
|
||||
|
||||
str[sz] = '\0';
|
||||
r = str;
|
||||
delete [] str;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
inline std::string readTextFile(const std::string & fileName)
|
||||
{
|
||||
return readTextFile(fileName.c_str());
|
||||
}
|
||||
|
||||
inline BufferHandle createBuffer(Context & ctx, GLsizeiptr size, const void * data = 0, GLenum usage = GL_STATIC_DRAW)
|
||||
{
|
||||
BufferArguments args;
|
||||
args.size = size;
|
||||
args.usage = usage;
|
||||
args.data = data;
|
||||
return ctx.createBuffer(args);
|
||||
}
|
||||
|
||||
template <typename TValue, typename TAllocator>
|
||||
inline BufferHandle createBuffer(Context & ctx, const std::vector<TValue, TAllocator> & data, GLenum usage = GL_STATIC_DRAW)
|
||||
{
|
||||
return createBuffer(ctx, GLsizeiptr(sizeof(TValue) * data.size()), ((!data.empty()) ? (&(data[0])) : (0)), usage);
|
||||
}
|
||||
|
||||
inline RenderbufferHandle createRenderbuffer(Context & ctx, GLenum format, GLsizei width, GLsizei height)
|
||||
{
|
||||
RenderbufferArguments args;
|
||||
args.format = format;
|
||||
args.width = width;
|
||||
args.height = height;
|
||||
return ctx.createRenderbuffer(args);
|
||||
}
|
||||
|
||||
inline Texture2DHandle createTexture2D(Context & ctx, GLenum format, GLsizei width, GLsizei height, GLenum dataFormat, GLenum dataType, const void * data = 0, const TextureSampleMode & sampler = TextureSampleMode())
|
||||
{
|
||||
Texture2DArguments args;
|
||||
args.format = format;
|
||||
args.width = width;
|
||||
args.height = height;
|
||||
args.dataFormat = dataFormat;
|
||||
args.dataType = dataType;
|
||||
args.data = data;
|
||||
args.sampler = sampler;
|
||||
return ctx.createTexture2D(args);
|
||||
}
|
||||
|
||||
inline FramebufferHandle createFramebuffer
|
||||
(
|
||||
Context & ctx,
|
||||
RenderTarget & depthTarget ,
|
||||
RenderTarget & colorTarget0 = RenderTarget(),
|
||||
RenderTarget & colorTarget1 = RenderTarget(),
|
||||
RenderTarget & colorTarget2 = RenderTarget(),
|
||||
RenderTarget & colorTarget3 = RenderTarget(),
|
||||
RenderTarget & colorTarget4 = RenderTarget(),
|
||||
RenderTarget & colorTarget5 = RenderTarget(),
|
||||
RenderTarget & colorTarget6 = RenderTarget(),
|
||||
RenderTarget & colorTarget7 = RenderTarget()
|
||||
)
|
||||
{
|
||||
FramebufferArguments args;
|
||||
|
||||
args.depthTarget = depthTarget;
|
||||
|
||||
if (colorTarget0.target) { args.colorTargets[0] = colorTarget0; args.targetInputs[0] = 0; }
|
||||
if (colorTarget1.target) { args.colorTargets[1] = colorTarget1; args.targetInputs[1] = 1; }
|
||||
if (colorTarget2.target) { args.colorTargets[2] = colorTarget2; args.targetInputs[2] = 2; }
|
||||
if (colorTarget3.target) { args.colorTargets[3] = colorTarget3; args.targetInputs[3] = 3; }
|
||||
if (colorTarget4.target) { args.colorTargets[4] = colorTarget4; args.targetInputs[4] = 4; }
|
||||
if (colorTarget5.target) { args.colorTargets[5] = colorTarget5; args.targetInputs[5] = 5; }
|
||||
if (colorTarget6.target) { args.colorTargets[6] = colorTarget6; args.targetInputs[6] = 6; }
|
||||
if (colorTarget7.target) { args.colorTargets[7] = colorTarget7; args.targetInputs[7] = 7; }
|
||||
|
||||
return ctx.createFramebuffer(args);
|
||||
}
|
||||
|
||||
inline ProgramHandle createProgram(Context & ctx, const std::string & srcPrefix, const std::string & vertexSrc, const std::string & geometrySrc, const std::string & fragmentSrc, const ProgramArguments & args = ProgramArguments())
|
||||
{
|
||||
ProgramArguments pArgs = args;
|
||||
|
||||
if (!vertexSrc.empty())
|
||||
{
|
||||
VertexShaderArguments args;
|
||||
args.source = srcPrefix + vertexSrc;
|
||||
pArgs.shaders.push_back(ctx.createVertexShader(args));
|
||||
}
|
||||
|
||||
if (!geometrySrc.empty())
|
||||
{
|
||||
GeometryShaderArguments args;
|
||||
args.source = srcPrefix + geometrySrc;
|
||||
pArgs.shaders.push_back(ctx.createGeometryShader(args));
|
||||
}
|
||||
|
||||
if (!fragmentSrc.empty())
|
||||
{
|
||||
FragmentShaderArguments args;
|
||||
args.source = srcPrefix + fragmentSrc;
|
||||
pArgs.shaders.push_back(ctx.createFragmentShader(args));
|
||||
}
|
||||
|
||||
return ctx.createProgram(pArgs);
|
||||
}
|
||||
|
||||
inline ProgramHandle createProgram(Context & ctx, const std::string & srcPrefix, const std::string & vertexSrc, const std::string & fragmentSrc, const ProgramArguments & args = ProgramArguments())
|
||||
{
|
||||
return createProgram(ctx, srcPrefix, vertexSrc, "", fragmentSrc, args);
|
||||
}
|
||||
|
||||
inline ProgramHandle loadProgram(Context & ctx, const std::string & srcPrefix, const std::string & vertexFile, const std::string & geometryFile, const std::string & fragmentFile, const ProgramArguments & args = ProgramArguments())
|
||||
{
|
||||
return createProgram(ctx, srcPrefix, readTextFile(vertexFile), readTextFile(geometryFile), readTextFile(fragmentFile), args);
|
||||
}
|
||||
|
||||
inline ProgramHandle loadProgram(Context & ctx, const std::string & srcPrefix, const std::string & vertexFile, const std::string & fragmentFile, const ProgramArguments & args = ProgramArguments())
|
||||
{
|
||||
return loadProgram(ctx, srcPrefix, vertexFile, "", fragmentFile.c_str(), args);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif // GLW_UTILITY_H
|
|
@ -0,0 +1,87 @@
|
|||
#ifndef GLW_VERTEXSHADER_H
|
||||
#define GLW_VERTEXSHADER_H
|
||||
|
||||
#include "./shader.h"
|
||||
|
||||
namespace glw
|
||||
{
|
||||
|
||||
class VertexShaderArguments : public ShaderArguments
|
||||
{
|
||||
public:
|
||||
|
||||
typedef ShaderArguments BaseType;
|
||||
typedef VertexShaderArguments ThisType;
|
||||
|
||||
VertexShaderArguments(void)
|
||||
{
|
||||
this->clear();
|
||||
}
|
||||
|
||||
void clear(void)
|
||||
{
|
||||
BaseType::clear();
|
||||
}
|
||||
};
|
||||
|
||||
class SafeVertexShader : public virtual SafeShader
|
||||
{
|
||||
public:
|
||||
|
||||
typedef SafeShader BaseType;
|
||||
typedef SafeVertexShader ThisType;
|
||||
|
||||
protected:
|
||||
|
||||
SafeVertexShader(Context * ctx)
|
||||
: SafeObject (ctx)
|
||||
, BaseType (ctx)
|
||||
{
|
||||
;
|
||||
}
|
||||
};
|
||||
|
||||
class VertexShader : public Shader, public SafeVertexShader
|
||||
{
|
||||
friend class Context;
|
||||
friend class detail::SharedObjectBinding<VertexShader>;
|
||||
|
||||
public:
|
||||
|
||||
typedef Shader BaseType;
|
||||
typedef SafeVertexShader SafeType;
|
||||
typedef VertexShader ThisType;
|
||||
|
||||
virtual Type type(void) const
|
||||
{
|
||||
return VertexShaderType;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
VertexShader(Context * ctx)
|
||||
: SafeObject (ctx)
|
||||
, SafeShader (ctx)
|
||||
, SafeType (ctx)
|
||||
, BaseType (ctx)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
virtual GLenum shaderType(void) const
|
||||
{
|
||||
return GL_VERTEX_SHADER;
|
||||
}
|
||||
|
||||
bool create(const VertexShaderArguments & args)
|
||||
{
|
||||
return BaseType::create(args);
|
||||
}
|
||||
};
|
||||
|
||||
typedef detail::SafeHandle <VertexShader> VertexShaderHandle;
|
||||
typedef detail::UnsafeHandle <VertexShader> BoundVertexShader;
|
||||
|
||||
};
|
||||
|
||||
#endif // GLW_VERTEXSHADER_H
|
Loading…
Reference in New Issue