PDA

Visualizza la versione completa : [c++]tempalte template parameters?


giuseppe500
20-10-2012, 16:52
ciao.
Ho implementato un gestore di bufferobject opengl, funziona coi template e si usa cosi:


CVboManager<
CVboCreator ,
3,
glm::vec3[3],
GL_FLOAT,
CEmpty,
0,
glm::vec3[3],
GL_FLOAT
> VBO("VertexPosition", "", "VertexColor");

VBO.Position[0].x = -0.5f;
VBO.Position[0].y = -0.5f;
VBO.Position[0].z = 0.5f;
ecc.....

il primo parametro il Creator , ce ne possono essere vari e l'ho pensato in un futuro in cui volessi cambiare o implementare per es la versione directx ,il secondo il numero di elementi
il terzo il tipo di elemento(glm una libreria matematica studiata per opengl, in questo caso uso un array di tre vettori float.
il 4 il tipo del elemento base per opengl. passo il problema e non mi dilungo: in questo caso
devo per forza sapere in anticipo il numero di elementi che avra' quel vertex buffer e mi piacerebbe aggiungere quanti voglio elementi senza starli a contare e fare si che sia il c++ a calcolare il tutto.

per questo ho pensato ad un mio personale buffer tipo questobasandomi su di un vector(pseudocodice)


#pragma once
#include <vector>
template< class T >
class CSizeVaringData
{
public:
CSizeVaringData();
~CSizeVaringData();
std::vector<T> m_data;
typedef T Type;
void AddData(T element)
{
m_data.push_back(element);
}

T* getAllData(){
return m_data[];
}

};


in modo da fare cosi:


CVboManager<
CVboCreator ,
3,
CSizeVaringData<glm::vec3>,
GL_FLOAT,
CEmpty,
0,
glm::vec3[3],
GL_FLOAT
> VBO("VertexPosition", "", "VertexColor");


il problema che devo mantenere la compatibilit con i precedenti parametri.

e devo usare l'overloading per gestire diversamente il cariccamento nel creator del buffer


Creator:
template<class Data>
bool Create(GLuint& vertexArrayObject, GLuint& vertexBufferObject, std::string strSemantic, ptrBaseEffect ptrEff, GLenum type, Data* VBOData)
{
glGenBuffers(1, &vertexBufferObject);
glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObject);
glBufferData(GL_ARRAY_BUFFER, sizeof(*VBOData), glm::value_ptr(*VBOData[0]), GL_STATIC_DRAW);
glVertexAttribPointer(glGetAttribLocation(ptrEff->m_headerShader, strSemantic.c_str()), 3, GL_FLOAT, GL_FALSE, sizeof(*VBOData[0]), (void*)0/*nOffset*/);
glEnableVertexAttribArray(glGetAttribLocation(ptrE ff->m_headerShader, strSemantic.c_str()));
float* pF = glm::value_ptr(*VBOData[0]);
return true;
}
template<class Data>
bool Create(GLuint& vertexArrayObject, GLuint& vertexBufferObject, std::string strSemantic, ptrBaseEffect ptrEff, GLenum type, CEmpty* VBOData)
{
return true;
}
template<class Data>
bool Create(GLuint& vertexArrayObject, GLuint& vertexBufferObject, std::string strSemantic, ptrBaseEffect ptrEff, GLenum type, CSizeVaringData<glm::vec3>* VBOData)
{
}

//il problema attorno a questa funzione in overload:
//bool Create(GLuint& vertexArrayObject, GLuint& vertexBufferObject, std::string strSemantic, ptrBaseEffect ptrEff, GLenum type, CSizeVaringData<glm::vec3>* VBOData)
//{
//}

il problema questo:
CSizeVaringData<glm::vec3>* VBOData
se uso un overloading cosi va, ma io non so che tipo ho specificato nel template CVboManager potrei aver specificato un int3 ,
e devo specificare per forza un tipo nel parametro con CSizeVaringData.
quello che posso fare utilizzare due parametri template , uno per il contenitore e uno per il tipo contenuto nel contenitore.
poi gestire in overloading i diversi contenitori , quando ce ne ho 2 o 3 abbastanza per quello che devo fare .
non vedo altra soluzione.
possibile utilizzare i template template parameter ? come si usano? possono tornare utili in questo caso
io non ci sono riuscito.
grazie.

clynamen
20-10-2012, 22:27
Se ho capito bene il problema, aggiungere l' enum GLenum come template argument a CSizeVaringData dovrebbe risolvere il problema.

giuseppe500
21-10-2012, 11:48
Originariamente inviato da clynamen
Se ho capito bene il problema, aggiungere l' enum GLenum come template argument a CSizeVaringData dovrebbe risolvere il problema.
grazie clynamen , ma non ho ben capito :l'enum GLenum un enum per il tipo opengl(per es. se il tipo del vbo che voglio creare un insieme di float o int o double ecc....), io devo lavorare con un tipo che mi permetta di passare dei dati come il vec3(che un tipo vettore con tre componenti x,y e z), non solo per entrare nella funzione che mi interessa in overload, devo utilizzare anche i dati.
c' qualcosa che mi sfugge?
dici che meglio usare un parametro per gestire l'overload(penso sia questo che intendi )?ma come aggiungerne uno?

il problema che se non specifico il parametro template di CSizeVaringData non ho una classe e se lo specifico nell'overload non so a priori che tipo mi arriva e non voglio usare 9999999 funzioni con tutti i tipi possibili, anzi , proprio quello che non voglio , per questo che ho pensato che un soluzione sarebbe passare CSizeVaringData come parametro template e il tipo come un altro parametro template ,cosi : template < template <class W> class Container, class Type> ma mi complica un po la vita.

ciao.

clynamen
21-10-2012, 17:54
Non avevo capito ci che volevi fare.

Per accedere al tipo contenuto in CSizeVaringData potresti usare un typedef per poi riottenere il tipo dentro il metodo create. Ho fatto un piccolo esempio:


#include <iostream>

template<typename T> class Container {

public:
typedef T ContainerType;

T value;

};

template<class Cont> void create(const Cont& container) {
typename Cont::ContainerType foo; // <- Accedi al tipo contenuto in container.

std::cout << foo << std::endl;
}

int main() {
Container<int> intCont;
Container<float> floatCont;
Container<bool> boolCont;

create(intCont);
create(floatCont);
create(boolCont);
}

Loading