90bac19849
Finally got a 3D cube to be rendered. While doing it, fixed a bug in MeshFactory that caused it to allocate the incorrect amount of memory for each mesh.
378 lines
10 KiB
C++
378 lines
10 KiB
C++
#pragma once
|
|
|
|
#include <vector>
|
|
|
|
#include "DrawMode.h"
|
|
|
|
#include "Exception.h"
|
|
|
|
#include "Mesh.h"
|
|
|
|
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));
|
|
}
|
|
}
|
|
|
|
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<MeshType*> m_meshes;
|
|
};
|
|
|
|
template <typename VertexType, typename IndexType>
|
|
std::vector<Mesh<VertexType, IndexType>*> MeshFactory<VertexType, IndexType>::m_meshes = std::vector<Mesh<VertexType, IndexType>*>(); |