Reputation: 403
I'm trying to write a simple 3D soft engine, but I've got a little problem..
I have a class called Mesh
which contains vertex and edge data:
struct Vertex { float x, y, z; };
struct Edge { int from, to; };
template <int vs, int es>
class Mesh {
public:
Vertex vertices[vs];
int vSize = vs;
Edge edges[es];
int eSize = es;
};
then a derived class called Cube
which specifies the vertex and edge data for a cube (I will later on add more shapes of course):
class Cube : public Mesh<8, 12> {
public:
inline Cube() {
Vertex v[] = {
{ -1.0f, -1.0f, -1.0f },
{ 1.0f, -1.0f, -1.0f },
{ 1.0f, 1.0f, -1.0f },
{ -1.0f, 1.0f, -1.0f },
{ -1.0f, -1.0f, 1.0f },
{ 1.0f, -1.0f, 1.0f },
{ 1.0f, 1.0f, 1.0f },
{ -1.0f, 1.0f, 1.0f }
};
for (int i = 0; i < 8; i++)
this->vertices[i] = v[i];
Edge e[] = {
{ 0,1 },{ 1,2 },{ 2,3 },{ 3,0 },
{ 4,5 },{ 5,6 },{ 6,7 },{ 7,4 },
{ 0,4 },{ 1,5 },{ 2,6 },{ 3,7 }
};
for (int i = 0; i < 12; i++)
this->edges[i] = e[i];
}
};
And after that a class called Engine
, which has an array of Mesh
parent classes, which should be able to hold Cube
and later Triangle
etc..
template <int w, int h, int mSize>
class Engine {
private:
int width = w;
int height = h;
Mesh meshes[mSize]; <-- problem
int mCount = 0;
byte fBuffer[w][h];
byte bBuffer[w][h];
public:
inline Engine() {};
inline void addMesh(Mesh mesh) { this->meshes[this->mCount++] = mesh; }
};
which yields this error:
Engine.h: 19:3: error: invalid use of template-name 'Mesh' without an argument list
Mesh* meshes = new Mesh[m]
Engine.h: 25:23: error: 'Mesh' is not a type
inline void addMesh(Mesh mesh) { this->meshes[this->mCount++] = mesh; }
I know it's because the Mesh meshes[mSize];
should have Mesh<a, b>
values but of course I don't know that for every possible Mesh
.
What's a better way of storing these?
Upvotes: 0
Views: 48
Reputation: 66230
I suppose you could add a not-template base for Mesh
, say mBase
struct mBase { };
template <std::size_t vs, std::size_t es>
struct Mesh : public mBase
{ };
and define meshes
as an array of mBase
s
mBase meshes[mSize]; // <-- no more problem
void addMesh(mBase mesh) { this->meshes[this->mCount++] = mesh; }
Upvotes: 1
Reputation: 16
You don't have to use templates for what you're trying to achieve here. So why don't declare your Mesh.vertices and Mesh.edges as std::vectors
(for instance), and fill them as you construct your derived objects?
Like so:
#include <vector>
class Mesh {
public:
std::vector<Vertex> vertices;
std::vector<Edge> edges;
};
class Cube : public Mesh {
public:
Cube() {
// Following stuff is only allowed since c++11
// But there's other tricks for vector's initializations before c++11
this->vertices = {
{ -1.0f, -1.0f, -1.0f },
{ 1.0f, -1.0f, -1.0f },
{ 1.0f, 1.0f, -1.0f },
{ -1.0f, 1.0f, -1.0f },
{ -1.0f, -1.0f, 1.0f },
{ 1.0f, -1.0f, 1.0f },
{ 1.0f, 1.0f, 1.0f },
{ -1.0f, 1.0f, 1.0f }
};
this->edges = {
{ 0,1 },{ 1,2 },{ 2,3 },{ 3,0 },
{ 4,5 },{ 5,6 },{ 6,7 },{ 7,4 },
{ 0,4 },{ 1,5 },{ 2,6 },{ 3,7 }
};
}
};
Note that you don't need to store the size of these vectors, since you can get it with: std::vector<T>.size()
(Mesh.edges.size()
)
Make sure to be familiar with the templated objects from the STL before creating your own ;)
(In facts, here your classes should be structs... But that is out of scope of the problem I guess...)
Upvotes: 0