first commit of the glw library.

This commit is contained in:
Marco Di Benedetto 2012-04-30 18:23:53 +00:00
parent e532ec9751
commit c70bd419a7
21 changed files with 3584 additions and 0 deletions

582
wrap/glw/bookkeeping.h Normal file
View File

@ -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

210
wrap/glw/buffer.h Normal file
View File

@ -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

25
wrap/glw/common.h Normal file
View File

@ -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

12
wrap/glw/config.h Normal file
View File

@ -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

438
wrap/glw/context.h Normal file
View File

@ -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

87
wrap/glw/fragmentshader.h Normal file
View File

@ -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

316
wrap/glw/framebuffer.h Normal file
View File

@ -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

87
wrap/glw/geometryshader.h Normal file
View File

@ -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

6
wrap/glw/glheaders.h Normal file
View File

@ -0,0 +1,6 @@
#ifndef GLW_GLHEADERS_H
#define GLW_GLHEADERS_H
#include <GL/glew.h>
#endif // GLW_GLHEADERS_H

7
wrap/glw/glw.h Normal file
View File

@ -0,0 +1,7 @@
#ifndef GLW_GLW_H
#define GLW_GLW_H
#include "./context.h"
#include "./utility.h"
#endif // GLW_GLW_H

42
wrap/glw/noncopyable.h Normal file
View File

@ -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

143
wrap/glw/object.h Normal file
View File

@ -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

504
wrap/glw/program.h Normal file
View File

@ -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

83
wrap/glw/renderable.h Normal file
View File

@ -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

158
wrap/glw/renderbuffer.h Normal file
View File

@ -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

174
wrap/glw/shader.h Normal file
View File

@ -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

136
wrap/glw/texture.h Normal file
View File

@ -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

175
wrap/glw/texture2d.h Normal file
View File

@ -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

24
wrap/glw/type.h Normal file
View File

@ -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

288
wrap/glw/utility.h Normal file
View File

@ -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

87
wrap/glw/vertexshader.h Normal file
View File

@ -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