31e3d15ab1
Starting the setup for builtin types for rendering. This will allow the engine to be easier to use for beginners while still offering great modularity and functionality. The builtin namespace is intended to simplify mesh loading and rendering. It should eventually offer pre-made shaders to simplify the rendering of the builtin types. Possibly in the future, it could have partially setup scenes/application to simplify scene/application building
380 lines
11 KiB
C++
380 lines
11 KiB
C++
#pragma once
|
|
|
|
#include <vector>
|
|
|
|
#include "DrawMode.h"
|
|
|
|
#include "Exception.h"
|
|
|
|
#include "Mesh.h"
|
|
|
|
namespace charcoal
|
|
{
|
|
template <typename VertexType, typename IndexType>
|
|
class MeshFactory
|
|
{
|
|
public:
|
|
typedef Mesh<VertexType, IndexType> 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<VertexType>& vertices, const std::vector<IndexType>& 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));
|
|
}
|
|
}
|
|
|
|
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<MeshType*> m_meshes;
|
|
};
|
|
|
|
template <typename VertexType, typename IndexType>
|
|
std::vector<Mesh<VertexType, IndexType>*> MeshFactory<VertexType, IndexType>::m_meshes = std::vector<Mesh<VertexType, IndexType>*>();
|
|
} |