--- /dev/null
+#ifndef BLANK_GRAPHICS_VERTEXARRAY_HPP_
+#define BLANK_GRAPHICS_VERTEXARRAY_HPP_
+
+#include <vector>
+#include <GL/glew.h>
+
+
+namespace blank {
+
+template<std::size_t N>
+class VertexArray {
+
+public:
+ static constexpr std::size_t NUM_ATTRS = N;
+
+public:
+ VertexArray() noexcept;
+ ~VertexArray() noexcept;
+
+ VertexArray(const VertexArray<N> &) = delete;
+ VertexArray<N> &operator =(const VertexArray<N> &) = delete;
+
+ VertexArray(VertexArray<N> &&) noexcept;
+ VertexArray<N> &operator =(VertexArray<N> &&) noexcept;
+
+public:
+ void Bind() const noexcept;
+
+ template <class T>
+ void PushAttribute(std::size_t which, const std::vector<T> &data) noexcept;
+
+ template<class T>
+ void PushIndices(std::size_t which, const std::vector<T> &indices) noexcept;
+
+ void DrawLineElements() const noexcept;
+ void DrawTriangleElements() const noexcept;
+
+private:
+ void BindAttribute(std::size_t which) const noexcept;
+ void EnableAttribute(std::size_t which) noexcept;
+ template <class T>
+ void AttributeData(const std::vector<T> &) noexcept;
+ template <class T>
+ void AttributePointer(std::size_t which) noexcept;
+
+ void BindIndex(std::size_t which) const noexcept;
+ template <class T>
+ void IndexData(const std::vector<T> &) noexcept;
+
+private:
+ GLuint array_id;
+ GLuint attr_id[NUM_ATTRS];
+
+ std::size_t idx_count;
+ GLenum idx_type;
+
+};
+
+}
+
+#include "VertexArray.inl"
+
+#endif
--- /dev/null
+#include "../graphics/gl_traits.hpp"
+
+namespace blank {
+
+template<std::size_t N>
+VertexArray<N>::VertexArray() noexcept
+: idx_count(0)
+, idx_type(GL_UNSIGNED_INT) {
+ glGenVertexArrays(1, &array_id);
+ glGenBuffers(N, attr_id);
+}
+
+template<std::size_t N>
+VertexArray<N>::~VertexArray() noexcept {
+ if (array_id != 0) {
+ glDeleteBuffers(N, attr_id);
+ glDeleteVertexArrays(1, &array_id);
+ }
+}
+
+template<std::size_t N>
+VertexArray<N>::VertexArray(VertexArray<N> &&other) noexcept
+: array_id(other.array_id)
+, idx_count(other.idx_count)
+, idx_type(other.idx_type) {
+ other.array_id = 0;
+ for (std::size_t i = 0; i < N; ++i) {
+ attr_id[i] = other.attr_id[i];
+ other.attr_id[i] = 0;
+ }
+}
+
+template<std::size_t N>
+VertexArray<N> &VertexArray<N>::operator =(VertexArray<N> &&other) noexcept {
+ std::swap(array_id, other.array_id);
+ for (std::size_t i = 0; i < N; ++i) {
+ std::swap(attr_id[i], other.attr_id[i]);
+ }
+ idx_count = other.idx_count;
+ idx_type = other.idx_type;
+ return *this;
+}
+
+template<std::size_t N>
+void VertexArray<N>::Bind() const noexcept {
+ glBindVertexArray(array_id);
+}
+
+template<std::size_t N>
+template <class T>
+void VertexArray<N>::PushAttribute(std::size_t which, const std::vector<T> &data) noexcept {
+ BindAttribute(which);
+ AttributeData(data);
+ EnableAttribute(which);
+ AttributePointer<T>(which);
+}
+
+template<std::size_t N>
+void VertexArray<N>::BindAttribute(std::size_t i) const noexcept {
+ assert(i < NUM_ATTRS && "vertex attribute ID out of bounds");
+ glBindBuffer(GL_ARRAY_BUFFER, attr_id[i]);
+}
+
+template<std::size_t N>
+void VertexArray<N>::EnableAttribute(std::size_t i) noexcept {
+ assert(i < NUM_ATTRS && "vertex attribute ID out of bounds");
+ glEnableVertexAttribArray(i);
+}
+
+template<std::size_t N>
+template<class T>
+void VertexArray<N>::AttributeData(const std::vector<T> &buf) noexcept {
+ glBufferData(GL_ARRAY_BUFFER, buf.size() * sizeof(T), buf.data(), GL_STATIC_DRAW);
+}
+
+template<std::size_t N>
+template <class T>
+void VertexArray<N>::AttributePointer(std::size_t which) noexcept {
+ glVertexAttribPointer(
+ which, // program location
+ gl_traits<T>::size, // element size
+ gl_traits<T>::type, // element type
+ GL_FALSE, // normalize to [-1,1] or [0,1] for unsigned types
+ 0, // stride
+ nullptr // offset
+ );
+}
+
+template<std::size_t N>
+template <class T>
+void VertexArray<N>::PushIndices(std::size_t which, const std::vector<T> &indices) noexcept {
+ BindIndex(which);
+ IndexData(indices);
+}
+
+template<std::size_t N>
+void VertexArray<N>::BindIndex(std::size_t i) const noexcept {
+ assert(i < NUM_ATTRS && "element index ID out of bounds");
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, attr_id[i]);
+}
+
+template<std::size_t N>
+template<class T>
+void VertexArray<N>::IndexData(const std::vector<T> &buf) noexcept {
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, buf.size() * sizeof(T), buf.data(), GL_STATIC_DRAW);
+ idx_count = buf.size();
+ idx_type = gl_traits<T>::type;
+}
+
+
+template<std::size_t N>
+void VertexArray<N>::DrawLineElements() const noexcept {
+ Bind();
+ glDrawElements(
+ GL_LINES, // how
+ idx_count, // count
+ idx_type, // type
+ nullptr // offset
+ );
+}
+
+template<std::size_t N>
+void VertexArray<N>::DrawTriangleElements() const noexcept {
+ Bind();
+ glDrawElements(
+ GL_TRIANGLES, // how
+ idx_count, // count
+ idx_type, // type
+ nullptr // offset
+ );
+}
+
+}
--- /dev/null
+#include "gl_traits.hpp"
+
+
+namespace blank {
+
+constexpr GLint gl_traits<signed char>::size;
+constexpr GLenum gl_traits<signed char>::type;
+
+constexpr GLint gl_traits<unsigned char>::size;
+constexpr GLenum gl_traits<unsigned char>::type;
+
+constexpr GLint gl_traits<short>::size;
+constexpr GLenum gl_traits<short>::type;
+
+constexpr GLint gl_traits<unsigned short>::size;
+constexpr GLenum gl_traits<unsigned short>::type;
+
+constexpr GLint gl_traits<int>::size;
+constexpr GLenum gl_traits<int>::type;
+
+constexpr GLint gl_traits<unsigned int>::size;
+constexpr GLenum gl_traits<unsigned int>::type;
+
+constexpr GLint gl_traits<float>::size;
+constexpr GLenum gl_traits<float>::type;
+
+constexpr GLint gl_traits<double>::size;
+constexpr GLenum gl_traits<double>::type;
+
+}
--- /dev/null
+#ifndef BLANK_GRAPHICS_GL_TRAITS_HPP_
+#define BLANK_GRAPHICS_GL_TRAITS_HPP_
+
+#include <GL/glew.h>
+#include <glm/glm.hpp>
+
+
+namespace blank {
+
+template<class T>
+struct gl_traits {
+
+ /// number of components per generic attribute
+ /// must be 1, 2, 3, 4
+ // static constexpr GLint size;
+
+ /// component type
+ /// accepted values are:
+ /// GL_BYTE, GL_UNSIGNED_BYTE,
+ /// GL_SHORT, GL_UNSIGNED_SHORT,
+ /// GL_INT, GL_UNSIGNED_INT,
+ /// GL_HALF_FLOAT, GL_FLOAT, GL_DOUBLE,
+ /// GL_FIXED, GL_INT_2_10_10_10_REV, GL_UNSIGNED_INT_2_10_10_10_REV
+ // static constexpr GLenum type;
+
+};
+
+
+// basic types
+
+template<> struct gl_traits<signed char> {
+ static constexpr GLint size = 1;
+ static constexpr GLenum type = GL_BYTE;
+};
+
+template<> struct gl_traits<unsigned char> {
+ static constexpr GLint size = 1;
+ static constexpr GLenum type = GL_UNSIGNED_BYTE;
+};
+
+template<> struct gl_traits<short> {
+ static constexpr GLint size = 1;
+ static constexpr GLenum type = GL_SHORT;
+};
+
+template<> struct gl_traits<unsigned short> {
+ static constexpr GLint size = 1;
+ static constexpr GLenum type = GL_UNSIGNED_SHORT;
+};
+
+template<> struct gl_traits<int> {
+ static constexpr GLint size = 1;
+ static constexpr GLenum type = GL_INT;
+};
+
+template<> struct gl_traits<unsigned int> {
+ static constexpr GLint size = 1;
+ static constexpr GLenum type = GL_UNSIGNED_INT;
+};
+
+template<> struct gl_traits<float> {
+ static constexpr GLint size = 1;
+ static constexpr GLenum type = GL_FLOAT;
+};
+
+template<> struct gl_traits<double> {
+ static constexpr GLint size = 1;
+ static constexpr GLenum type = GL_DOUBLE;
+};
+
+// composite types
+
+template<>
+template<class T, glm::precision P>
+struct gl_traits<glm::tvec1<T, P>> {
+ static constexpr GLint size = 1;
+ static constexpr GLenum type = gl_traits<T>::type;
+};
+template<class T, glm::precision P>
+constexpr GLint gl_traits<glm::tvec1<T, P>>::size;
+template<class T, glm::precision P>
+constexpr GLenum gl_traits<glm::tvec1<T, P>>::type;
+
+template<>
+template<class T, glm::precision P>
+struct gl_traits<glm::tvec2<T, P>> {
+ static constexpr GLint size = 2;
+ static constexpr GLenum type = gl_traits<T>::type;
+};
+template<class T, glm::precision P>
+constexpr GLint gl_traits<glm::tvec2<T, P>>::size;
+template<class T, glm::precision P>
+constexpr GLenum gl_traits<glm::tvec2<T, P>>::type;
+
+template<>
+template<class T, glm::precision P>
+struct gl_traits<glm::tvec3<T, P>> {
+ static constexpr GLint size = 3;
+ static constexpr GLenum type = gl_traits<T>::type;
+};
+template<class T, glm::precision P>
+constexpr GLint gl_traits<glm::tvec3<T, P>>::size;
+template<class T, glm::precision P>
+constexpr GLenum gl_traits<glm::tvec3<T, P>>::type;
+
+template<>
+template<class T, glm::precision P>
+struct gl_traits<glm::tvec4<T, P>> {
+ static constexpr GLint size = 4;
+ static constexpr GLenum type = gl_traits<T>::type;
+};
+template<class T, glm::precision P>
+constexpr GLint gl_traits<glm::tvec4<T, P>>::size;
+template<class T, glm::precision P>
+constexpr GLenum gl_traits<glm::tvec4<T, P>>::type;
+
+}
+
+#endif
dirty = true;
}
+namespace {
+
+SpriteModel::Buffer sprite_buf;
+
+}
+
void Text::Update() {
- sprite.LoadRect(size.x, size.y, align(pivot, size));
+ sprite_buf.LoadRect(size.x, size.y, align(pivot, size));
+ sprite.Update(sprite_buf);
dirty = false;
}
#ifndef BLANK_MODEL_BLOCKMODEL_HPP_
#define BLANK_MODEL_BLOCKMODEL_HPP_
+#include "../graphics/VertexArray.hpp"
+
#include <vector>
#include <GL/glew.h>
#include <glm/glm.hpp>
using Lights = std::vector<Light>;
using Indices = std::vector<Index>;
-public:
+ enum Attribute {
+ ATTRIB_VERTEX,
+ ATTRIB_COLOR,
+ ATTRIB_LIGHT,
+ ATTRIB_INDEX,
+ ATTRIB_COUNT,
+ };
+
struct Buffer {
Positions vertices;
};
-public:
- BlockModel() noexcept;
- ~BlockModel() noexcept;
-
- BlockModel(const BlockModel &) = delete;
- BlockModel &operator =(const BlockModel &) = delete;
-
- BlockModel(BlockModel &&) noexcept;
- BlockModel &operator =(BlockModel &&) noexcept;
+ using VAO = VertexArray<ATTRIB_COUNT>;
+public:
void Update(const Buffer &) noexcept;
void Draw() const noexcept;
private:
- enum Attribute {
- ATTRIB_VERTEX,
- ATTRIB_COLOR,
- ATTRIB_LIGHT,
- ATTRIB_INDEX,
- ATTRIB_COUNT,
- };
-
- GLuint va;
- GLuint handle[ATTRIB_COUNT];
- size_t count;
+ VAO vao;
};
--- /dev/null
+#ifndef BLANK_MODEL_ENTITYMODEL_HPP_
+#define BLANK_MODEL_ENTITYMODEL_HPP_
+
+#include "../graphics/VertexArray.hpp"
+
+#include <vector>
+#include <GL/glew.h>
+#include <glm/glm.hpp>
+
+
+namespace blank {
+
+class EntityModel {
+
+public:
+ using Position = glm::vec3;
+ using Color = glm::vec3;
+ using Normal = glm::vec3;
+ using Index = unsigned int;
+
+ using Positions = std::vector<Position>;
+ using Colors = std::vector<Color>;
+ using Normals = std::vector<Normal>;
+ using Indices = std::vector<Index>;
+
+ enum Attribute {
+ ATTRIB_VERTEX,
+ ATTRIB_COLOR,
+ ATTRIB_NORMAL,
+ ATTRIB_INDEX,
+ ATTRIB_COUNT,
+ };
+
+ struct Buffer {
+
+ Positions vertices;
+ Colors colors;
+ Normals normals;
+ Indices indices;
+
+ void Clear() noexcept {
+ vertices.clear();
+ colors.clear();
+ normals.clear();
+ indices.clear();
+ }
+
+ void Reserve(size_t p, size_t i) {
+ vertices.reserve(p);
+ colors.reserve(p);
+ normals.reserve(p);
+ indices.reserve(i);
+ }
+
+ };
+
+ using VAO = VertexArray<ATTRIB_COUNT>;
+
+public:
+ void Update(const Buffer &) noexcept;
+
+ void Draw() const noexcept;
+
+private:
+ VAO vao;
+
+};
+
+}
+
+#endif
+++ /dev/null
-#ifndef BLANK_MODEL_MODEL_HPP_
-#define BLANK_MODEL_MODEL_HPP_
-
-#include <vector>
-#include <GL/glew.h>
-#include <glm/glm.hpp>
-
-
-namespace blank {
-
-class Model {
-
-public:
- using Position = glm::vec3;
- using Color = glm::vec3;
- using Normal = glm::vec3;
- using Index = unsigned int;
-
- using Positions = std::vector<Position>;
- using Colors = std::vector<Color>;
- using Normals = std::vector<Normal>;
- using Indices = std::vector<Index>;
-
-public:
- struct Buffer {
-
- Positions vertices;
- Colors colors;
- Normals normals;
- Indices indices;
-
- void Clear() noexcept {
- vertices.clear();
- colors.clear();
- normals.clear();
- indices.clear();
- }
-
- void Reserve(size_t p, size_t i) {
- vertices.reserve(p);
- colors.reserve(p);
- normals.reserve(p);
- indices.reserve(i);
- }
-
- };
-
-public:
- Model() noexcept;
- ~Model() noexcept;
-
- Model(const Model &) = delete;
- Model &operator =(const Model &) = delete;
-
- Model(Model &&) noexcept;
- Model &operator =(Model &&) noexcept;
-
- void Update(const Buffer &) noexcept;
-
- void Draw() const noexcept;
-
-private:
- enum Attribute {
- ATTRIB_VERTEX,
- ATTRIB_COLOR,
- ATTRIB_NORMAL,
- ATTRIB_INDEX,
- ATTRIB_COUNT,
- };
-
- GLuint va;
- GLuint handle[ATTRIB_COUNT];
- size_t count;
-
-};
-
-}
-
-#endif
#ifndef BLANK_MODEL_OUTLINEMODEL_HPP_
#define BLANK_MODEL_OUTLINEMODEL_HPP_
+#include "../graphics/VertexArray.hpp"
+
#include <vector>
#include <GL/glew.h>
#include <glm/glm.hpp>
using Colors = std::vector<Color>;
using Indices = std::vector<Index>;
-public:
- Positions vertices;
- Colors colors;
- Indices indices;
+ enum Attribute {
+ ATTRIB_VERTEX,
+ ATTRIB_COLOR,
+ ATTRIB_INDEX,
+ ATTRIB_COUNT,
+ };
-public:
- OutlineModel() noexcept;
- ~OutlineModel() noexcept;
+ struct Buffer {
- OutlineModel(const OutlineModel &) = delete;
- OutlineModel &operator =(const OutlineModel &) = delete;
+ Positions vertices;
+ Colors colors;
+ Indices indices;
- void Invalidate() noexcept { dirty = true; }
+ void Clear() noexcept {
+ vertices.clear();
+ colors.clear();
+ indices.clear();
+ }
- void Clear() noexcept;
- void Reserve(int vtx_count, int idx_count);
+ void Reserve(size_t p, size_t i) {
+ vertices.reserve(p);
+ colors.reserve(p);
+ indices.reserve(i);
+ }
- void Draw() noexcept;
+ };
-private:
- void Update() noexcept;
+ using VAO = VertexArray<ATTRIB_COUNT>;
-private:
- enum Attribute {
- ATTRIB_VERTEX,
- ATTRIB_COLOR,
- ATTRIB_INDEX,
- ATTRIB_COUNT,
- };
+public:
+ void Update(const Buffer &) noexcept;
- GLuint va;
- GLuint handle[ATTRIB_COUNT];
- bool dirty;
+ void Draw() noexcept;
+
+private:
+ VAO vao;
};
#define BLANK_MODEL_SHAPE_HPP_
#include "BlockModel.hpp"
-#include "Model.hpp"
+#include "EntityModel.hpp"
#include "OutlineModel.hpp"
#include <vector>
/// the number of vertex indices this shape has
size_t VertexIndexCount() const noexcept { return vtx_idx.size(); }
- const Model::Normal &VertexNormal(size_t idx) const noexcept { return vtx_nrm[idx]; }
- Model::Normal VertexNormal(
+ const EntityModel::Normal &VertexNormal(size_t idx) const noexcept { return vtx_nrm[idx]; }
+ EntityModel::Normal VertexNormal(
size_t idx, const glm::mat4 &transform
) const noexcept {
- return Model::Normal(transform * glm::vec4(vtx_nrm[idx], 0.0f));
+ return EntityModel::Normal(transform * glm::vec4(vtx_nrm[idx], 0.0f));
}
/// fill given buffers with this shape's elements with an
/// optional transform and offset
void Vertices(
- Model::Positions &vertex,
- Model::Normals &normal,
- Model::Indices &index
+ EntityModel::Positions &vertex,
+ EntityModel::Normals &normal,
+ EntityModel::Indices &index
) const;
void Vertices(
- Model::Positions &vertex,
- Model::Normals &normal,
- Model::Indices &index,
+ EntityModel::Positions &vertex,
+ EntityModel::Normals &normal,
+ EntityModel::Indices &index,
const glm::mat4 &transform,
- Model::Index idx_offset = 0
+ EntityModel::Index idx_offset = 0
) const;
void Vertices(
BlockModel::Positions &vertex,
) const noexcept = 0;
protected:
- void SetShape(const Model::Positions &pos, const Model::Normals &nrm, const Model::Indices &idx) {
+ void SetShape(const EntityModel::Positions &pos, const EntityModel::Normals &nrm, const EntityModel::Indices &idx) {
vtx_pos = pos;
vtx_nrm = nrm;
vtx_idx = idx;
}
private:
- Model::Positions vtx_pos;
- Model::Normals vtx_nrm;
- Model::Indices vtx_idx;
+ EntityModel::Positions vtx_pos;
+ EntityModel::Normals vtx_nrm;
+ EntityModel::Indices vtx_idx;
OutlineModel::Positions out_pos;
OutlineModel::Indices out_idx;
#ifndef BLANK_MODEL_SPRITEMODEL_HPP_
#define BLANK_MODEL_SPRITEMODEL_HPP_
+#include "../graphics/VertexArray.hpp"
+
#include <vector>
#include <GL/glew.h>
#include <glm/glm.hpp>
using TexCoords = std::vector<TexCoord>;
using Indices = std::vector<Index>;
-public:
- Positions vertices;
- TexCoords coords;
- Indices indices;
+ enum Attribute {
+ ATTRIB_VERTEX,
+ ATTRIB_TEXCOORD,
+ ATTRIB_INDEX,
+ ATTRIB_COUNT,
+ };
-public:
- SpriteModel() noexcept;
- ~SpriteModel() noexcept;
+ struct Buffer {
- SpriteModel(const SpriteModel &) = delete;
- SpriteModel &operator =(const SpriteModel &) = delete;
+ Positions vertices;
+ TexCoords coords;
+ Indices indices;
- void Invalidate() noexcept { dirty = true; }
+ void Clear() noexcept {
+ vertices.clear();
+ coords.clear();
+ indices.clear();
+ }
- void Clear() noexcept;
- void Reserve(int vtx_count, int idx_count);
+ void Reserve(size_t p, size_t i) {
+ vertices.reserve(p);
+ coords.reserve(p);
+ indices.reserve(i);
+ }
- void LoadRect(
- float w, float h,
- const glm::vec2 &pivot = glm::vec2(0.0f),
- const glm::vec2 &tex_begin = glm::vec2(0.0f),
- const glm::vec2 &tex_end = glm::vec2(1.0f, 1.0f)
- );
+ void LoadRect(
+ float w, float h,
+ const glm::vec2 &pivot = glm::vec2(0.0f),
+ const glm::vec2 &tex_begin = glm::vec2(0.0f),
+ const glm::vec2 &tex_end = glm::vec2(1.0f, 1.0f)
+ );
- void Draw() noexcept;
+ };
-private:
- void Update() noexcept;
+ using VAO = VertexArray<ATTRIB_COUNT>;
-private:
- enum Attribute {
- ATTRIB_VERTEX,
- ATTRIB_TEXCOORD,
- ATTRIB_INDEX,
- ATTRIB_COUNT,
- };
+public:
+ void Update(const Buffer &) noexcept;
- GLuint va;
- GLuint handle[ATTRIB_COUNT];
- bool dirty;
+ void Draw() noexcept;
+
+private:
+ VAO vao;
};
#include "BlockModel.hpp"
-#include "Model.hpp"
+#include "EntityModel.hpp"
#include "OutlineModel.hpp"
#include "SpriteModel.hpp"
+#include <algorithm>
#include <iostream>
namespace blank {
-Model::Model() noexcept
-: va(0)
-, handle{}
-, count(0) {
- glGenVertexArrays(1, &va);
- glGenBuffers(ATTRIB_COUNT, handle);
-}
-
-Model::~Model() noexcept {
- glDeleteBuffers(ATTRIB_COUNT, handle);
- glDeleteVertexArrays(1, &va);
-}
-
-Model::Model(Model &&other) noexcept
-: va(other.va)
-, count(other.count) {
- other.va = 0;
- for (int i = 0; i < ATTRIB_COUNT; ++i) {
- handle[i] = other.handle[i];
- other.handle[i] = 0;
- }
-}
-
-Model &Model::operator =(Model &&other) noexcept {
- std::swap(va, other.va);
- for (int i = 0; i < ATTRIB_COUNT; ++i) {
- std::swap(handle[i], other.handle[i]);
- }
- count = other.count;
- return *this;
-}
-
-void Model::Update(const Buffer &buf) noexcept {
- glBindVertexArray(va);
- glBindBuffer(GL_ARRAY_BUFFER, handle[ATTRIB_VERTEX]);
- glBufferData(GL_ARRAY_BUFFER, buf.vertices.size() * sizeof(glm::vec3), buf.vertices.data(), GL_STATIC_DRAW);
- glEnableVertexAttribArray(ATTRIB_VERTEX);
- glVertexAttribPointer(
- ATTRIB_VERTEX, // location (for shader)
- 3, // size
- GL_FLOAT, // type
- GL_FALSE, // normalized
- 0, // stride
- nullptr // offset
- );
-
+void EntityModel::Update(const Buffer &buf) noexcept {
#ifndef NDEBUG
if (buf.colors.size() < buf.vertices.size()) {
- std::cerr << "Model: not enough colors!" << std::endl;
+ std::cerr << "EntityModel: not enough colors!" << std::endl;
}
-#endif
- glBindBuffer(GL_ARRAY_BUFFER, handle[ATTRIB_COLOR]);
- glBufferData(GL_ARRAY_BUFFER, buf.colors.size() * sizeof(glm::vec3), buf.colors.data(), GL_STATIC_DRAW);
- glEnableVertexAttribArray(ATTRIB_COLOR);
- glVertexAttribPointer(
- ATTRIB_COLOR, // location (for shader)
- 3, // size
- GL_FLOAT, // type
- GL_FALSE, // normalized
- 0, // stride
- nullptr // offset
- );
-
-#ifndef NDEBUG
if (buf.normals.size() < buf.vertices.size()) {
- std::cerr << "Model: not enough normals!" << std::endl;
+ std::cerr << "EntityModel: not enough normals!" << std::endl;
}
#endif
- glBindBuffer(GL_ARRAY_BUFFER, handle[ATTRIB_NORMAL]);
- glBufferData(GL_ARRAY_BUFFER, buf.normals.size() * sizeof(glm::vec3), buf.normals.data(), GL_STATIC_DRAW);
- glEnableVertexAttribArray(ATTRIB_NORMAL);
- glVertexAttribPointer(
- ATTRIB_NORMAL, // location (for shader)
- 3, // size
- GL_FLOAT, // type
- GL_FALSE, // normalized
- 0, // stride
- nullptr // offset
- );
-
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, handle[ATTRIB_INDEX]);
- glBufferData(GL_ELEMENT_ARRAY_BUFFER, buf.indices.size() * sizeof(Index), buf.indices.data(), GL_STATIC_DRAW);
- count = buf.indices.size();
-}
-
-void Model::Draw() const noexcept {
- glBindVertexArray(va);
- glDrawElements(
- GL_TRIANGLES, // how
- count, // count
- GL_UNSIGNED_INT, // type
- nullptr // offset
- );
+ vao.Bind();
+ vao.PushAttribute(ATTRIB_VERTEX, buf.vertices);
+ vao.PushAttribute(ATTRIB_COLOR, buf.colors);
+ vao.PushAttribute(ATTRIB_NORMAL, buf.normals);
+ vao.PushIndices(ATTRIB_INDEX, buf.indices);
}
-BlockModel::BlockModel() noexcept
-: va(0)
-, handle{}
-, count(0) {
- glGenVertexArrays(1, &va);
- glGenBuffers(ATTRIB_COUNT, handle);
-}
-
-BlockModel::~BlockModel() noexcept {
- glDeleteBuffers(ATTRIB_COUNT, handle);
- glDeleteVertexArrays(1, &va);
+void EntityModel::Draw() const noexcept {
+ vao.DrawTriangleElements();
}
-BlockModel::BlockModel(BlockModel &&other) noexcept
-: va(other.va)
-, count(other.count) {
- other.va = 0;
- for (int i = 0; i < ATTRIB_COUNT; ++i) {
- handle[i] = other.handle[i];
- other.handle[i] = 0;
- }
-}
-
-BlockModel &BlockModel::operator =(BlockModel &&other) noexcept {
- std::swap(va, other.va);
- for (int i = 0; i < ATTRIB_COUNT; ++i) {
- std::swap(handle[i], other.handle[i]);
- }
- count = other.count;
- return *this;
-}
void BlockModel::Update(const Buffer &buf) noexcept {
- glBindVertexArray(va);
- glBindBuffer(GL_ARRAY_BUFFER, handle[ATTRIB_VERTEX]);
- glBufferData(GL_ARRAY_BUFFER, buf.vertices.size() * sizeof(glm::vec3), buf.vertices.data(), GL_STATIC_DRAW);
- glEnableVertexAttribArray(ATTRIB_VERTEX);
- glVertexAttribPointer(
- ATTRIB_VERTEX, // location (for shader)
- 3, // size
- GL_FLOAT, // type
- GL_FALSE, // normalized
- 0, // stride
- nullptr // offset
- );
-
#ifndef NDEBUG
if (buf.colors.size() < buf.vertices.size()) {
std::cerr << "BlockModel: not enough colors!" << std::endl;
}
-#endif
- glBindBuffer(GL_ARRAY_BUFFER, handle[ATTRIB_COLOR]);
- glBufferData(GL_ARRAY_BUFFER, buf.colors.size() * sizeof(glm::vec3), buf.colors.data(), GL_STATIC_DRAW);
- glEnableVertexAttribArray(ATTRIB_COLOR);
- glVertexAttribPointer(
- ATTRIB_COLOR, // location (for shader)
- 3, // size
- GL_FLOAT, // type
- GL_FALSE, // normalized
- 0, // stride
- nullptr // offset
- );
-
-#ifndef NDEBUG
if (buf.lights.size() < buf.vertices.size()) {
std::cerr << "BlockModel: not enough lights!" << std::endl;
}
#endif
- glBindBuffer(GL_ARRAY_BUFFER, handle[ATTRIB_LIGHT]);
- glBufferData(GL_ARRAY_BUFFER, buf.lights.size() * sizeof(float), buf.lights.data(), GL_STATIC_DRAW);
- glEnableVertexAttribArray(ATTRIB_LIGHT);
- glVertexAttribPointer(
- ATTRIB_LIGHT, // location (for shader)
- 1, // size
- GL_FLOAT, // type
- GL_FALSE, // normalized
- 0, // stride
- nullptr // offset
- );
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, handle[ATTRIB_INDEX]);
- glBufferData(GL_ELEMENT_ARRAY_BUFFER, buf.indices.size() * sizeof(Index), buf.indices.data(), GL_STATIC_DRAW);
- count = buf.indices.size();
+ vao.Bind();
+ vao.PushAttribute(ATTRIB_VERTEX, buf.vertices);
+ vao.PushAttribute(ATTRIB_COLOR, buf.colors);
+ vao.PushAttribute(ATTRIB_LIGHT, buf.lights);
+ vao.PushIndices(ATTRIB_INDEX, buf.indices);
}
void BlockModel::Draw() const noexcept {
- glBindVertexArray(va);
- glDrawElements(
- GL_TRIANGLES, // how
- count, // count
- GL_UNSIGNED_INT, // type
- nullptr // offset
- );
-}
-
-OutlineModel::OutlineModel() noexcept
-: vertices()
-, colors()
-, indices()
-, va(0)
-, handle{}
-, dirty(false) {
- glGenVertexArrays(1, &va);
- glGenBuffers(ATTRIB_COUNT, handle);
+ vao.DrawTriangleElements();
}
-OutlineModel::~OutlineModel() noexcept {
- glDeleteBuffers(ATTRIB_COUNT, handle);
- glDeleteVertexArrays(1, &va);
-}
-
-
-void OutlineModel::Clear() noexcept {
- vertices.clear();
- colors.clear();
- indices.clear();
- Invalidate();
-}
-
-void OutlineModel::Reserve(int v, int i) {
- vertices.reserve(v);
- colors.reserve(v);
- indices.reserve(i);
-}
-
-
-void OutlineModel::Update() noexcept {
- glBindBuffer(GL_ARRAY_BUFFER, handle[ATTRIB_VERTEX]);
- glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(glm::vec3), vertices.data(), GL_STATIC_DRAW);
- glEnableVertexAttribArray(ATTRIB_VERTEX);
- glVertexAttribPointer(
- ATTRIB_VERTEX, // location (for shader)
- 3, // size
- GL_FLOAT, // type
- GL_FALSE, // normalized
- 0, // stride
- nullptr // offset
- );
+void OutlineModel::Update(const Buffer &buf) noexcept {
#ifndef NDEBUG
- if (colors.size() < vertices.size()) {
+ if (buf.colors.size() < buf.vertices.size()) {
std::cerr << "OutlineModel: not enough colors!" << std::endl;
- colors.resize(vertices.size(), { 1, 0, 1 });
}
#endif
- glBindBuffer(GL_ARRAY_BUFFER, handle[ATTRIB_COLOR]);
- glBufferData(GL_ARRAY_BUFFER, colors.size() * sizeof(glm::vec3), colors.data(), GL_STATIC_DRAW);
- glEnableVertexAttribArray(ATTRIB_COLOR);
- glVertexAttribPointer(
- ATTRIB_COLOR, // location (for shader)
- 3, // size
- GL_FLOAT, // type
- GL_FALSE, // normalized
- 0, // stride
- nullptr // offset
- );
-
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, handle[ATTRIB_INDEX]);
- glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(Index), indices.data(), GL_STATIC_DRAW);
- dirty = false;
+ vao.Bind();
+ vao.PushAttribute(ATTRIB_VERTEX, buf.vertices);
+ vao.PushAttribute(ATTRIB_COLOR, buf.colors);
+ vao.PushIndices(ATTRIB_INDEX, buf.indices);
}
void OutlineModel::Draw() noexcept {
- glBindVertexArray(va);
-
- if (dirty) {
- Update();
- }
-
glEnable(GL_LINE_SMOOTH);
glLineWidth(2.0f);
-
- glDrawElements(
- GL_LINES, // how
- indices.size(), // count
- GL_UNSIGNED_SHORT, // type
- nullptr // offset
- );
-}
-
-
-SpriteModel::SpriteModel() noexcept
-: vertices()
-, coords()
-, indices()
-, va(0)
-, handle{}
-, dirty(false) {
- glGenVertexArrays(1, &va);
- glGenBuffers(ATTRIB_COUNT, handle);
-}
-
-SpriteModel::~SpriteModel() noexcept {
- glDeleteBuffers(ATTRIB_COUNT, handle);
- glDeleteVertexArrays(1, &va);
+ vao.DrawLineElements();
}
-void SpriteModel::Clear() noexcept {
- vertices.clear();
- coords.clear();
- indices.clear();
- Invalidate();
-}
-
-void SpriteModel::Reserve(int v, int i) {
- vertices.reserve(v);
- coords.reserve(v);
- indices.reserve(i);
-}
-
-
-void SpriteModel::LoadRect(
+void SpriteModel::Buffer::LoadRect(
float w, float h,
const glm::vec2 &pivot,
const glm::vec2 &tex_begin,
coords.emplace_back(tex_end.x, tex_end.y);
indices.assign({ 0, 2, 1, 1, 2, 3 });
-
- Invalidate();
}
-void SpriteModel::Update() noexcept {
- glBindBuffer(GL_ARRAY_BUFFER, handle[ATTRIB_VERTEX]);
- glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(Position), vertices.data(), GL_STATIC_DRAW);
- glEnableVertexAttribArray(ATTRIB_VERTEX);
- glVertexAttribPointer(
- ATTRIB_VERTEX, // location (for shader)
- 3, // size
- GL_FLOAT, // type
- GL_FALSE, // normalized
- 0, // stride
- nullptr // offset
- );
-
+void SpriteModel::Update(const Buffer &buf) noexcept {
#ifndef NDEBUG
- if (coords.size() < vertices.size()) {
+ if (buf.coords.size() < buf.vertices.size()) {
std::cerr << "SpriteModel: not enough coords!" << std::endl;
- coords.resize(vertices.size(), { 1, 1 });
}
#endif
- glBindBuffer(GL_ARRAY_BUFFER, handle[ATTRIB_TEXCOORD]);
- glBufferData(GL_ARRAY_BUFFER, coords.size() * sizeof(TexCoord), coords.data(), GL_STATIC_DRAW);
- glEnableVertexAttribArray(ATTRIB_TEXCOORD);
- glVertexAttribPointer(
- ATTRIB_TEXCOORD, // location (for shader)
- 2, // size
- GL_FLOAT, // type
- GL_FALSE, // normalized
- 0, // stride
- nullptr // offset
- );
-
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, handle[ATTRIB_INDEX]);
- glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(Index), indices.data(), GL_STATIC_DRAW);
- dirty = false;
+ vao.Bind();
+ vao.PushAttribute(ATTRIB_VERTEX, buf.vertices);
+ vao.PushAttribute(ATTRIB_TEXCOORD, buf.coords);
+ vao.PushIndices(ATTRIB_INDEX, buf.indices);
}
void SpriteModel::Draw() noexcept {
- glBindVertexArray(va);
-
- if (dirty) {
- Update();
- }
-
- glDrawElements(
- GL_TRIANGLES, // how
- indices.size(), // count
- GL_UNSIGNED_SHORT, // type
- nullptr // offset
- );
+ vao.DrawTriangleElements();
}
}
namespace blank {
void Shape::Vertices(
- Model::Positions &vertex,
- Model::Normals &normal,
- Model::Indices &index
+ EntityModel::Positions &vertex,
+ EntityModel::Normals &normal,
+ EntityModel::Indices &index
) const {
for (const auto &pos : vtx_pos) {
vertex.emplace_back(pos);
}
void Shape::Vertices(
- Model::Positions &vertex,
- Model::Normals &normal,
- Model::Indices &index,
+ EntityModel::Positions &vertex,
+ EntityModel::Normals &normal,
+ EntityModel::Indices &index,
const glm::mat4 &transform,
- Model::Index idx_offset
+ EntityModel::Index idx_offset
) const {
for (const auto &pos : vtx_pos) {
vertex.emplace_back(transform * glm::vec4(pos, 1.0f));
#define BLANK_UI_HUD_H_
#include "../graphics/FixedText.hpp"
-#include "../model/Model.hpp"
+#include "../model/EntityModel.hpp"
#include "../model/OutlineModel.hpp"
#include <glm/glm.hpp>
const BlockTypeRegistry &types;
const Font &font;
- Model block;
- Model::Buffer block_buf;
+ EntityModel block;
+ EntityModel::Buffer block_buf;
glm::mat4 block_transform;
FixedText block_label;
block_transform = glm::rotate(block_transform, 3.5f, glm::vec3(1.0f, 0.0f, 0.0f));
block_transform = glm::rotate(block_transform, 0.35f, glm::vec3(0.0f, 1.0f, 0.0f));
- crosshair.vertices = std::vector<glm::vec3>({
+ OutlineModel::Buffer buf;
+ buf.vertices = std::vector<glm::vec3>({
{ -10.0f, 0.0f, 0.0f }, { 10.0f, 0.0f, 0.0f },
{ 0.0f, -10.0f, 0.0f }, { 0.0f, 10.0f, 0.0f },
});
- crosshair.indices = std::vector<OutlineModel::Index>({
+ buf.indices = std::vector<OutlineModel::Index>({
0, 1, 2, 3
});
- crosshair.colors.resize(4, { 10.0f, 10.0f, 10.0f });
- crosshair.Invalidate();
+ buf.colors.resize(4, { 10.0f, 10.0f, 10.0f });
+ crosshair.Update(buf);
block_label.Position(
glm::vec3(50.0f, 85.0f, 0.0f),
const BlockType &type = types.Get(b.type);
block_buf.Clear();
- type.FillModel(block_buf, b.Transform());
+ type.FillEntityModel(block_buf, b.Transform());
block.Update(block_buf);
block_label.Set(font, type.label);
}
}
+namespace {
+
+OutlineModel::Buffer outl_buf;
+
+}
+
void Interface::CheckAim() {
float dist;
if (world.Intersection(aim, glm::mat4(1.0f), aim_chunk, aim_block, dist, aim_normal)) {
- outline.Clear();
- aim_chunk->Type(aim_chunk->BlockAt(aim_block)).FillOutlineModel(outline);
+ outl_buf.Clear();
+ aim_chunk->Type(aim_chunk->BlockAt(aim_block)).FillOutlineModel(outl_buf);
+ outline.Update(outl_buf);
outline_transform = glm::scale(glm::vec3(1.0002f));
outline_transform *= aim_chunk->Transform(world.Player().ChunkCoords());
outline_transform *= aim_chunk->ToTransform(Chunk::ToPos(aim_block), aim_block);
#include "Block.hpp"
#include "../model/BlockModel.hpp"
-#include "../model/Model.hpp"
+#include "../model/EntityModel.hpp"
#include "../model/OutlineModel.hpp"
#include "../model/shapes.hpp"
return fill[block.OrientedFace(face)];
}
- void FillModel(
- Model::Buffer &m,
+ void FillEntityModel(
+ EntityModel::Buffer &m,
const glm::mat4 &transform = glm::mat4(1.0f),
- Model::Index idx_offset = 0
+ EntityModel::Index idx_offset = 0
) const noexcept;
void FillBlockModel(
BlockModel::Buffer &m,
BlockModel::Index idx_offset = 0
) const noexcept;
void FillOutlineModel(
- OutlineModel &m,
+ OutlineModel::Buffer &m,
const glm::vec3 &pos_offset = { 0, 0, 0 },
OutlineModel::Index idx_offset = 0
) const noexcept;
int GetLight(const Pos &pos) const noexcept { return GetLight(ToIndex(pos)); }
int GetLight(const Block::Pos &pos) const noexcept { return GetLight(ToIndex(pos)); }
- float GetVertexLight(const Pos &, const BlockModel::Position &, const Model::Normal &) const noexcept;
+ float GetVertexLight(const Pos &, const BlockModel::Position &, const EntityModel::Normal &) const noexcept;
bool Intersection(
const Ray &ray,
namespace {
-blank::Model::Buffer model_buffer;
+blank::EntityModel::Buffer model_buffer;
}
#include "Block.hpp"
#include "Chunk.hpp"
#include "../model/geometry.hpp"
-#include "../model/Model.hpp"
+#include "../model/EntityModel.hpp"
#include <string>
#include <glm/glm.hpp>
private:
const Shape *shape;
- Model model;
+ EntityModel model;
std::string name;
}
-void BlockType::FillModel(
- Model::Buffer &buf,
+void BlockType::FillEntityModel(
+ EntityModel::Buffer &buf,
const glm::mat4 &transform,
- Model::Index idx_offset
+ EntityModel::Index idx_offset
) const noexcept {
shape->Vertices(buf.vertices, buf.normals, buf.indices, transform, idx_offset);
buf.colors.insert(buf.colors.end(), shape->VertexCount(), color);
}
void BlockType::FillOutlineModel(
- OutlineModel &model,
+ OutlineModel::Buffer &buf,
const glm::vec3 &pos_offset,
OutlineModel::Index idx_offset
) const noexcept {
- shape->Outline(model.vertices, model.indices, pos_offset, idx_offset);
- model.colors.insert(model.colors.end(), shape->OutlineCount(), outline_color);
+ shape->Outline(buf.vertices, buf.indices, pos_offset, idx_offset);
+ buf.colors.insert(buf.colors.end(), shape->OutlineCount(), outline_color);
}
return light[index];
}
-float Chunk::GetVertexLight(const Pos &pos, const BlockModel::Position &vtx, const Model::Normal &norm) const noexcept {
+float Chunk::GetVertexLight(const Pos &pos, const BlockModel::Position &vtx, const EntityModel::Normal &norm) const noexcept {
int index = ToIndex(pos);
float light = GetLight(index);
--- /dev/null
+#include "GLTraitsTest.hpp"
+
+#include "graphics/gl_traits.hpp"
+
+CPPUNIT_TEST_SUITE_REGISTRATION(blank::test::GLTraitsTest);
+
+
+namespace blank {
+namespace test {
+
+void GLTraitsTest::setUp() {
+
+}
+
+void GLTraitsTest::tearDown() {
+
+}
+
+
+void GLTraitsTest::testSize() {
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "bad number of components for byte",
+ 1, gl_traits<signed char>::size
+ );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "bad number of components for ubyte",
+ 1, gl_traits<unsigned char>::size
+ );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "bad number of components for short",
+ 1, gl_traits<short>::size
+ );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "bad number of components for ushort",
+ 1, gl_traits<unsigned short>::size
+ );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "bad number of components for int",
+ 1, gl_traits<int>::size
+ );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "bad number of components for uint",
+ 1, gl_traits<unsigned int>::size
+ );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "bad number of components for float",
+ 1, gl_traits<float>::size
+ );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "bad number of components for double",
+ 1, gl_traits<double>::size
+ );
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "bad number of components for vec2",
+ 2, gl_traits<glm::vec2>::size
+ );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "bad number of components for vec3",
+ 3, gl_traits<glm::vec3>::size
+ );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "bad number of components for vec4",
+ 4, gl_traits<glm::vec4>::size
+ );
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "bad number of components for vec2i",
+ 2, gl_traits<glm::tvec2<int>>::size
+ );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "bad number of components for vec3i",
+ 3, gl_traits<glm::tvec3<int>>::size
+ );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "bad number of components for vec4i",
+ 4, gl_traits<glm::tvec4<int>>::size
+ );
+}
+
+void GLTraitsTest::testType() {
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "bad component type for byte",
+ GLenum(GL_BYTE), gl_traits<signed char>::type
+ );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "bad component type for ubyte",
+ GLenum(GL_UNSIGNED_BYTE), gl_traits<unsigned char>::type
+ );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "bad component type for short",
+ GLenum(GL_SHORT), gl_traits<short>::type
+ );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "bad component type for ushort",
+ GLenum(GL_UNSIGNED_SHORT), gl_traits<unsigned short>::type
+ );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "bad component type for int",
+ GLenum(GL_INT), gl_traits<int>::type
+ );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "bad component type for uint",
+ GLenum(GL_UNSIGNED_INT), gl_traits<unsigned int>::type
+ );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "bad component type for float",
+ GLenum(GL_FLOAT), gl_traits<float>::type
+ );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "bad component type for double",
+ GLenum(GL_DOUBLE), gl_traits<double>::type
+ );
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "bad component type for vec2",
+ GLenum(GL_FLOAT), gl_traits<glm::vec2>::type
+ );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "bad component type for vec3",
+ GLenum(GL_FLOAT), gl_traits<glm::vec3>::type
+ );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "bad component type for vec4",
+ GLenum(GL_FLOAT), gl_traits<glm::vec4>::type
+ );
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "bad component type for vec2i",
+ GLenum(GL_INT), gl_traits<glm::tvec2<int>>::type
+ );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "bad component type for vec3i",
+ GLenum(GL_INT), gl_traits<glm::tvec3<int>>::type
+ );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "bad component type for vec4i",
+ GLenum(GL_INT), gl_traits<glm::tvec4<int>>::type
+ );
+}
+
+}
+}
--- /dev/null
+#ifndef BLANK_TEST_GRAPHICS_GLTRAITSTEST_HPP_
+#define BLANK_TEST_GRAPHICS_GLTRAITSTEST_HPP_
+
+#include <cppunit/extensions/HelperMacros.h>
+
+namespace blank {
+namespace test {
+
+class GLTraitsTest
+: public CppUnit::TestFixture {
+
+CPPUNIT_TEST_SUITE(GLTraitsTest);
+
+CPPUNIT_TEST(testSize);
+CPPUNIT_TEST(testType);
+
+CPPUNIT_TEST_SUITE_END();
+
+public:
+ void setUp();
+ void tearDown();
+
+ void testSize();
+ void testType();
+
+};
+
+}
+}
+
+#endif