Nathan Prins
Nathan Prins

Reputation: 403

3D soft Engine: Array of objects without defining template argument list

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

Answers (2)

max66
max66

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 mBases

mBase meshes[mSize]; // <-- no more problem 

void addMesh(mBase mesh) { this->meshes[this->mCount++] = mesh; }

Upvotes: 1

DendyTheElephant
DendyTheElephant

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

Related Questions