E' una domanda a cui non si può ripondere bene su un forum.
Generalmente i template servono per risolvere alcune problematiche di programmazione che un approccio polimorfico renderebbe complicate.
Pensa alle classe std::vector. Se non fosse basata su template, occorrerebbe che tutti i dati derivassero
da una classe base comune per poi fare cast a go go per avere il dato corretto.
O a una funzione compare().
Senza template saresti costretto a creare N funzioni in overloading ognuna per il tipo di dato che puoi passare.
Con il template astrai i dato e scrivi una sola funzione.
E' meglio:
codice:
bool compare(int a,int b) { return a == b; }
bool compare(char a,char b) { return a == b; }
bool compare(char* a,char* b) { return !strcmp(a,b); }
bool compare(MioTipo a,MioTipo b) { return a == b; }
etc...
o:
codice:
template <typename X>
bool compare(X a,X b) { return a == b; }
lasciando che sia il compilatore a scriversi la funzione?
Specializzandolo per char* diventa:
codice:
template <>
bool compare<char*>(char* a,char* b) { return !strcmp(a,b); }
la specializzazione serve in caso un tipo ( o più ) di dato su N dati deve avere un comportamento speciale appunto.
Ti consiglio questo articolo:
http://www.eptacom.net/pubblicazioni/pub_it/oopgen.html
Per quanto riguarda il resto.
A quanto ho capito hai una situazione del genere:
codice:
class VertexBase {
public:
virtual ~VertexBase() {}
virtual void paint() {}
};
class CBase {
virtual ~Cbase() {}
virtual VertexBase* getVertex(int i) { return vb_[i]; }
virtual void addVertex(VertexBase* vb, int pos) { vb_[pos] = vb;}
protected:
VertexBase vb_[100];
};
class SimpleVertex : public VertexBase {
public:
SimpleVertex(D3DXVECTOR3 a, D3DXVECTOR2 b) { ... setta i membri privati ... }
virtual void paint() {
... fa qualcosa con i dati interni Pos, Tex ...
... e disegna il Vertex ...
}
private:
D3DXVECTOR3 Pos; // Position
D3DXVECTOR2 Tex; // Texture Coordinate
};
class SkinnedVertex : public VertexBase {
public:
SimpleVertex(
D3DXVECTOR3 a,
D3DXVECTOR2 b,
D3DXVECTOR3 c,
D3DXVECTOR2 d
) { ... setta i membri privati ... }
virtual void paint() {
... fa qualcosa con i dati interni Pos, Tex, Pos2, Tex2 ...
... e disegna il Vertex ...
}
private:
D3DXVECTOR3 Pos; // Position
D3DXVECTOR2 Tex; // Texture Coordinate
D3DXVECTOR3 Pos2; // Position
D3DXVECTOR2 Tex2; // Texture Coordinate
};
class CShader {
public:
virtual void rendering(CBase* cb) {}
private:
};
class CMesh: public Cbase {
public:
virtual void getVertex(int pos) {
... eventuali elaborazioni su membri privati di CMesh ...
return vb_[pos];
}
virtual void addVertex(VertexBase* vb, int pos) {
... eventuali elaborazioni su membri privati di CMesh ...
vb_[pos] = vb;
}
private:
};
class CSkinnedMesh: public Cbase {
public:
virtual void getVertex(int pos) {
... eventuali elaborazioni su membri privati di CSkinnedMesh ...
return vb_[pos];
}
virtual void addVertex(VertexBase* vb, int pos) {
... eventuali elaborazioni su membri privati di CSkinnedMesh ...
vb_[pos] = vb;
}
private:
};
class CSimpleShader : public CShader {
public:
virtual void rendering(CBase* cb) {
... eventuale codice specifico per CSimpleShader ...
... cicla su ogni Vertex di CBase ...
cb->getVertex(i)->paint();
}
private:
};
class CSkinnedShader : public CShader {
public:
virtual void rendering(CBase* cb) {
... eventuale codice specifico per CSkinnedShader ...
... cicla su ogni Vertex di CBase ...
cb->getVertex(i)->paint();
}
private:
};
template <typename T> class CImport;
template <>
class CImport<CMesh> {
public:
CBase* load() {
... seleziona i vertex adatti a CMesh ...
VertexBase* vb = new SimpleVertex(dato1, dato2);
CBase* cb = new CMesh;
cb->addVertex(vb);
return cb;
}
};
template <>
class CImport<CSkinnedMesh> {
public:
CBase* load() {
... seleziona i vertex adatti a CSkinnedMesh ...
VertexBase* vb = new SkinnedVertex(dato1, dato2, dato3, dato4);
CBase* cb = new CSkinnedMesh;
cb->addVertex(vb);
return cb;
}
};
CImport<CMesh> msh;
CImport<CSkinnedMesh> skmh;
CShader* ssh = new CSimpleShader;
CShader* sksh = new CSkinnedShader;
ssh->rendering(msh.load());
sksh->rendering(sksh.load());
E' un codice di massima. (E probabilmente non è quello che cercavi
)
Il concetto alla base è che non è lo Shader che "shaderizza" (perdona il neologismo
) ma è il Vertex nella sua specifica implementazione a sapere come "shaderizzarsi".
Lo Shader non fa altro che invocare la getVertex() che restituisce il giusto Vertex