#pragma once class Shape { protected: GLuint buffers[2]; GLuint arrays[2]; GLuint count[2]; GLvoid* ioff[2]; struct vertex_t { glm::vec4 pos; glm::vec2 uvs; }; public: bool create_buffers(GLvoid* idx, GLvoid* vertices, int isize, int vsize); void draw_fill() const; void draw_stroke() const; }; class Plane : public Shape { void create_impl(float w, float h, int div, GLushort* idx, vertex_t* vertices); public: template bool create(float w, float h) { static GLushort idx[div * div * 6 + 8]; static vertex_t vertices[(div+1)*(div+1)]; create_impl(w, h, div, idx, vertices); return create_buffers(idx, vertices, sizeof(idx), sizeof(vertices)); } }; class Circle : public Shape { public: enum class kUVMapping: uint8_t { Planar, Tube }; template bool create(float radius) { static GLushort idx[div*3 + div*2]; static vertex_t vertices[div+1]; create_impl(radius, div, idx, vertices); return create_buffers(idx, vertices, sizeof(idx), sizeof(vertices)); } template bool create(float radius, kUVMapping map) { static GLushort idx[(div+1)*3 + (div+1)*4]; static vertex_t vertices[(div+1)*2]; create_impl(radius, 0.f, (div+1), idx, vertices, map); return create_buffers(idx, vertices, sizeof(idx), sizeof(vertices)); } template bool create(float radius_out, float radius_in, kUVMapping map) { static GLushort idx[(div+1)*6 + (div+1)*4]; static vertex_t vertices[(div+1) * 2]; create_impl(radius_out, radius_in, (div+1), idx, vertices, map); return create_buffers(idx, vertices, sizeof(idx), sizeof(vertices)); } private: void create_impl(float radius, int div, GLushort* idx, vertex_t* vertices); void create_impl(float radius_out, float radius_in, int div, GLushort* idx, vertex_t* vertices, kUVMapping map); }; class Rounded : public Shape { void create_impl(float w, float h, float r, int div, GLushort* idx, GLushort* idx_tmp, vertex_t* vertices); public: template bool create(float w, float h, float r) { static GLushort idx[(10 + div * 4) * 3 + (4 + div * 4) * 2]; static GLushort idx_tmp[div+1]; static vertex_t vertices[12 + (div-1) * 4]; create_impl(w, h, r, div, idx, idx_tmp, vertices); return create_buffers(idx, vertices, sizeof(idx), sizeof(vertices)); } }; class Slice9 : public Shape { void create_impl(float w, float h, float r, float tr, GLushort* idx, vertex_t* vertices); public: bool create(float w, float h, float r, float tr) { static GLushort idx[3 * 3 * 6 + 4 * 2]; static vertex_t vertices[4 * 4]; create_impl(w, h, r, tr, idx, vertices); return create_buffers(idx, vertices, sizeof(idx), sizeof(vertices)); } };