#pragma once #include #include "DrawMode.h" #include "Exception.h" #include "Mesh.h" template class MeshFactory { public: typedef Mesh MeshType; private: MeshFactory() {} // Prevent instanciation of this static class public: typedef unsigned int SizeType; virtual ~MeshFactory() { for (SizeType i = 0; i < m_meshes.size(); ++i) { delete[] m_meshes[i]->vertices; m_meshes[i]->vertices = nullptr; delete[] m_meshes[i]->indices; m_meshes[i]->indices = nullptr; delete m_meshes[i]; m_meshes[i] = nullptr; } } static MeshType* gen(const DrawMode& draw_mode, const VertexType& a) { MeshType* mesh; switch (draw_mode) { case DrawMode::DRAW_POINTS: mesh = create_mesh(1, 1); mesh->vertices[0] = a; mesh->indices[0] = 0; return mesh; case DrawMode::DRAW_LINE_STRIP: case DrawMode::DRAW_LINE_LOOP: case DrawMode::DRAW_LINES: case DrawMode::DRAW_TRIANGLE_STRIP: case DrawMode::DRAW_TRIANGLE_FAN: case DrawMode::DRAW_TRIANGLES: case DrawMode::DRAW_LINE_STRIP_ADJACENCY: case DrawMode::DRAW_LINES_ADJACENCY: case DrawMode::DRAW_TRIANGLE_STRIP_ADJACENCY: case DrawMode::DRAW_TRIANGLES_ADJACENCY: case DrawMode::DRAW_PATCHES: default: throw EXCEPTION("Unable to gen for current draw mode: " + std::to_string(draw_mode)); } } static MeshType* gen(const DrawMode& draw_mode, const VertexType& a, const VertexType& b) { MeshType* mesh; switch (draw_mode) { case DrawMode::DRAW_POINTS: case DrawMode::DRAW_LINE_STRIP: case DrawMode::DRAW_LINE_LOOP: case DrawMode::DRAW_LINES: mesh = create_mesh(2, 2); mesh->vertices[0] = a; mesh->vertices[1] = b; mesh->indices[0] = 0; mesh->indices[1] = 1; return mesh; case DrawMode::DRAW_TRIANGLE_STRIP: case DrawMode::DRAW_TRIANGLE_FAN: case DrawMode::DRAW_TRIANGLES: case DrawMode::DRAW_LINE_STRIP_ADJACENCY: case DrawMode::DRAW_LINES_ADJACENCY: case DrawMode::DRAW_TRIANGLE_STRIP_ADJACENCY: case DrawMode::DRAW_TRIANGLES_ADJACENCY: case DrawMode::DRAW_PATCHES: default: throw EXCEPTION("Unable to gen for current draw mode: " + std::to_string(draw_mode)); } } static MeshType* gen(const DrawMode& draw_mode, const VertexType& a, const VertexType& b, const VertexType& c) { MeshType* mesh; switch (draw_mode) { case DrawMode::DRAW_POINTS: case DrawMode::DRAW_LINE_STRIP: case DrawMode::DRAW_LINE_LOOP: case DrawMode::DRAW_TRIANGLE_STRIP: case DrawMode::DRAW_TRIANGLE_FAN: case DrawMode::DRAW_TRIANGLES: mesh = create_mesh(3, 3); mesh->vertices[0] = a; mesh->vertices[1] = b; mesh->vertices[2] = c; mesh->indices[0] = 0; mesh->indices[1] = 1; mesh->indices[2] = 2; return mesh; case DrawMode::DRAW_LINES: mesh = create_mesh(3, 6); mesh->vertices[0] = a; mesh->vertices[1] = b; mesh->vertices[2] = c; mesh->indices[0] = 0; mesh->indices[1] = 1; mesh->indices[2] = 1; mesh->indices[3] = 2; mesh->indices[4] = 2; mesh->indices[5] = 0; return mesh; case DrawMode::DRAW_LINE_STRIP_ADJACENCY: case DrawMode::DRAW_LINES_ADJACENCY: case DrawMode::DRAW_TRIANGLE_STRIP_ADJACENCY: case DrawMode::DRAW_TRIANGLES_ADJACENCY: case DrawMode::DRAW_PATCHES: default: throw EXCEPTION("Unable to gen for current draw mode: " + std::to_string(draw_mode)); } } static MeshType* gen(const DrawMode& draw_mode, const VertexType& a, const VertexType& b, const VertexType& c, const VertexType& d) { MeshType* mesh; switch (draw_mode) { case DrawMode::DRAW_POINTS: case DrawMode::DRAW_LINE_STRIP: case DrawMode::DRAW_LINE_LOOP: case DrawMode::DRAW_TRIANGLE_STRIP: case DrawMode::DRAW_TRIANGLE_FAN: mesh = create_mesh(4, 4); mesh->vertices[0] = a; mesh->vertices[1] = b; mesh->vertices[2] = c; mesh->vertices[3] = d; mesh->indices[0] = 0; mesh->indices[1] = 1; mesh->indices[2] = 2; mesh->indices[3] = 3; return mesh; case DrawMode::DRAW_LINES: // Implementation similar to LINE_LOOP mesh = create_mesh(4, 8); mesh->vertices[0] = a; mesh->vertices[1] = b; mesh->vertices[2] = c; mesh->vertices[3] = d; mesh->indices[0] = 0; mesh->indices[1] = 1; mesh->indices[2] = 1; mesh->indices[3] = 2; mesh->indices[4] = 2; mesh->indices[5] = 3; mesh->indices[6] = 3; mesh->indices[7] = 0; return mesh; case DrawMode::DRAW_TRIANGLES: mesh = create_mesh(4, 6); mesh->vertices[0] = a; mesh->vertices[1] = b; mesh->vertices[2] = c; mesh->vertices[3] = d; mesh->indices[0] = 0; mesh->indices[1] = 1; mesh->indices[2] = 2; mesh->indices[3] = 2; mesh->indices[4] = 1; mesh->indices[5] = 3; return mesh; case DrawMode::DRAW_LINE_STRIP_ADJACENCY: case DrawMode::DRAW_LINES_ADJACENCY: case DrawMode::DRAW_TRIANGLE_STRIP_ADJACENCY: case DrawMode::DRAW_TRIANGLES_ADJACENCY: case DrawMode::DRAW_PATCHES: default: throw EXCEPTION("Unable to gen for current draw mode: " + std::to_string(draw_mode)); } } static MeshType* gen(const DrawMode& draw_mode, const std::vector& vertices, const std::vector& indices) { MeshType* mesh; switch (draw_mode) { case DrawMode::DRAW_POINTS: case DrawMode::DRAW_LINE_STRIP: case DrawMode::DRAW_LINE_LOOP: case DrawMode::DRAW_LINES: case DrawMode::DRAW_TRIANGLE_STRIP: case DrawMode::DRAW_TRIANGLE_FAN: case DrawMode::DRAW_TRIANGLES: int n = vertices.size(); mesh = create_mesh(n, n); for (SizeType i = 0; i < vertices.size(); ++i) { mesh->vertices[i] = vertices[i]; mesh->indices[i] = i; } return mesh; case DrawMode::DRAW_LINE_STRIP_ADJACENCY: case DrawMode::DRAW_LINES_ADJACENCY: case DrawMode::DRAW_TRIANGLE_STRIP_ADJACENCY: case DrawMode::DRAW_TRIANGLES_ADJACENCY: case DrawMode::DRAW_PATCHES: default: throw EXCEPTION("Unable to gen for current draw mode: " + std::to_string(draw_mode)); } } // Generates a "cube" (8-vert shape) with 8 vertices. This function should probably not be used // if the vertices are expected to have normals. static MeshType* gen_cube( const DrawMode& draw_mode, const VertexType& top_left_front, const VertexType& bottom_left_front, const VertexType& top_right_front, const VertexType& bottom_right_front, const VertexType& top_left_back, const VertexType& bottom_left_back, const VertexType& top_right_back, const VertexType& bottom_right_back ) { MeshType* mesh; switch (draw_mode) { case DrawMode::DRAW_POINTS: mesh = create_mesh(8, 8); mesh->vertices[0] = top_left_front; mesh->vertices[1] = bottom_left_front; mesh->vertices[2] = top_right_front; mesh->vertices[3] = bottom_right_front; mesh->vertices[4] = top_left_back; mesh->vertices[5] = bottom_left_back; mesh->vertices[6] = top_right_back; mesh->vertices[7] = bottom_right_back; mesh->indices[0] = 0; mesh->indices[1] = 1; mesh->indices[2] = 3; mesh->indices[3] = 3; mesh->indices[4] = 4; mesh->indices[5] = 5; mesh->indices[6] = 6; mesh->indices[7] = 7; return mesh; case DrawMode::DRAW_LINES: mesh = create_mesh(8, 24); mesh->vertices[0] = top_left_front; mesh->vertices[1] = bottom_left_front; mesh->vertices[2] = top_right_front; mesh->vertices[3] = bottom_right_front; mesh->vertices[4] = top_left_back; mesh->vertices[5] = bottom_left_back; mesh->vertices[6] = top_right_back; mesh->vertices[7] = bottom_right_back; // Front mesh->indices[0] = 0; mesh->indices[1] = 1; mesh->indices[2] = 1; mesh->indices[3] = 2; mesh->indices[4] = 2; mesh->indices[5] = 3; mesh->indices[6] = 3; mesh->indices[7] = 0; // Back mesh->indices[8] = 4; mesh->indices[9] = 5; mesh->indices[10] = 5; mesh->indices[11] = 6; mesh->indices[12] = 6; mesh->indices[13] = 7; mesh->indices[14] = 7; mesh->indices[15] = 4; // Connecting mesh->indices[16] = 0; mesh->indices[17] = 4; mesh->indices[18] = 1; mesh->indices[19] = 5; mesh->indices[20] = 2; mesh->indices[21] = 6; mesh->indices[22] = 3; mesh->indices[23] = 7; return mesh; case DrawMode::DRAW_TRIANGLES: mesh = create_mesh(8, 36); mesh->vertices[0] = top_left_front; mesh->vertices[1] = bottom_left_front; mesh->vertices[2] = top_right_front; mesh->vertices[3] = bottom_right_front; mesh->vertices[4] = top_left_back; mesh->vertices[5] = bottom_left_back; mesh->vertices[6] = top_right_back; mesh->vertices[7] = bottom_right_back; // Counter Clockwise // Front mesh->indices[0] = 1; mesh->indices[1] = 3; mesh->indices[2] = 0; mesh->indices[3] = 0; mesh->indices[4] = 3; mesh->indices[5] = 2; // Right mesh->indices[6] = 3; mesh->indices[7] = 7; mesh->indices[8] = 2; mesh->indices[9] = 2; mesh->indices[10] = 7; mesh->indices[11] = 6; // Back mesh->indices[12] = 7; mesh->indices[13] = 5; mesh->indices[14] = 6; mesh->indices[15] = 6; mesh->indices[16] = 5; mesh->indices[17] = 4; // Left mesh->indices[18] = 5; mesh->indices[19] = 1; mesh->indices[20] = 4; mesh->indices[21] = 4; mesh->indices[22] = 1; mesh->indices[23] = 0; // Top mesh->indices[24] = 0; mesh->indices[25] = 2; mesh->indices[26] = 4; mesh->indices[27] = 4; mesh->indices[28] = 2; mesh->indices[29] = 6; // Bottom mesh->indices[30] = 5; mesh->indices[31] = 7; mesh->indices[32] = 1; mesh->indices[33] = 1; mesh->indices[34] = 7; mesh->indices[35] = 3; return mesh; case DrawMode::DRAW_LINE_STRIP: case DrawMode::DRAW_LINE_LOOP: case DrawMode::DRAW_TRIANGLE_STRIP: // Could probably implement this one in some way in the future case DrawMode::DRAW_TRIANGLE_FAN: case DrawMode::DRAW_LINE_STRIP_ADJACENCY: case DrawMode::DRAW_LINES_ADJACENCY: case DrawMode::DRAW_TRIANGLE_STRIP_ADJACENCY: case DrawMode::DRAW_TRIANGLES_ADJACENCY: case DrawMode::DRAW_PATCHES: default: throw EXCEPTION("Unable to gen_cube for current draw mode: " + std::to_string(draw_mode)); } } protected: static MeshType* create_mesh(unsigned int vertex_count, unsigned int index_count) { MeshType* mesh = new MeshType(); mesh->vertices = new VertexType[vertex_count]; mesh->vertex_count = vertex_count; mesh->indices = new IndexType[index_count]; mesh->index_count = index_count; m_meshes.push_back(mesh); return mesh; } private: static std::vector m_meshes; }; template std::vector*> MeshFactory::m_meshes = std::vector*>();