grazie shodan, provo a buttare giu un esempio reale di quello che vorrei fare e poi posto.
cosi gli errori di pensiero se ci sono(e ci saranno)vengono subito all occhio.
ciao
grazie shodan, provo a buttare giu un esempio reale di quello che vorrei fare e poi posto.
cosi gli errori di pensiero se ci sono(e ci saranno)vengono subito all occhio.
ciao
ciao Shodan , ho provato a buttare giu un esempietto:
quello che vorrei fare è creare una gestione dei vbo(sono alla fine buffer per opengl) con i template per sperimentare quello che ho letto.codice:#include "stdafx.h" #include <iostream> using namespace std; template< class T > class CDataVbo; template < class T > class Creator{ public: template < class U > static void Create(CDataVbo<U> item) { cout << item.tipo; cout << item.getData()[0]; cout << item.getData()[1]; cout << item.getData()[2]; cout << item.getData()[3]; } }; class CEmpty { }; //specializzo il creator per lavorare con le stringhe , in //modo che posso avere la possibilità di lavorare diversamente a seconda del tipo template <> class Creator<string> { public: template < class U > static void Create(CDataVbo<U> item) { cout << item.tipo; cout << item.getData()[0].c_str(); cout << item.getData()[1].c_str(); cout << item.getData()[2].c_str(); cout << item.getData()[3].c_str(); } }; //specializzazione per CEmpty template <> class Creator<CEmpty> { public: template < class U > static void Create(CDataVbo<U> item) { //non faccio niente , la classe è CEmpty } }; //policy Class, assemblo il vbo template< class Data , class Creator > class CVboCreator { public: CVboCreator(CDataVbo<Data> DataItem) { m_DataItem = DataItem; } void Create() { Creator::Create<Data>(m_DataItem); } CDataVbo< Data > m_DataItem; }; //creo una classe di dati generica potrei anche utilizzare un Vector o un List template <typename T> class CData { T* m_data; public: typedef T type; T* getData() { return m_data; } void setData( T* data) { m_data = data; } //per semplificare creo un m_data di dimensione fisso CData(){ m_data = new T[200]; } }; //creo un senplice enum per una proprietà enum eType{ STATIC, DYNAMIC }; //estendo la classe di dati generica per aggiungere qualche proprietà //e soprattutto creo il metodo che crea la policy class che creerà il vbo template< class T > class CDataVbo : public CData<T> { public: void CreateVbo() { //utilizzo la classe data come se fosse una policy, solo che contiene dati e la passo alla classe policy class CVboCreator<T, Creator<T> > policy(*this); policy.Create(); } eType tipo; int size; }; //creo la classe manager principale, nel caso i vari item devono lavorare insieme //per questo ho creato queesta classe template < //metto di default la classe CEmpty per il caso in cui non utilizzo il parametro //piu avanti specializzo il Creator che creerà il vbo in modo che se ho una classe //CEmpty non farà niente(che è quello che deve fare) class Type1 = CEmpty, class Type2 = CEmpty, class Type3 = CEmpty, class Type4 = CEmpty > class CVboManager{ public: CVboManager(){}; CDataVbo<Type1> m_Item1; CDataVbo<Type2> m_Item2; CDataVbo<Type3> m_Item3; CDataVbo<Type4> m_Item4; inline void CreateAll() { m_Item1.CreateVbo(); m_Item2.CreateVbo(); m_Item3.CreateVbo(); m_Item4.CreateVbo(); } }; int _tmain(int argc, _TCHAR* argv[]) { //creo un CVboManager con due tipi : double e string per semplificare //nell implementazione che voglio fare qui ci andranno i tipi opengl per i buffer item CVboManager<double, string> VboManager; VboManager.m_Item1.tipo = STATIC; VboManager.m_Item2.tipo = DYNAMIC; double* ddata = new double[4]; ddata[0] = 0.0; ddata[1] = 1.0; ddata[2] = 2.0; ddata[3] = 3.0; VboManager.m_Item1.setData(ddata); string* strdata = new string[4]; strdata[0] = "A"; strdata[1] = "B"; strdata[2] = "C"; strdata[3] = "D"; VboManager.m_Item2.setData(strdata); //creo e assemblo il tutto VboManager.CreateAll(); return 0; }
sono pero' davvero alle prime armi coi template quindi avro fatto sicuramente degli errori (infatti ho un po paura di coprirmi di ridicolo e che cio che ho scritto non possa servire a nessuno).
Quello che cercavo di dirti è se magari è una buona idea l'utilizzare una policy che contiene dei dati invece che delle funzioni di trasformazione in modo da dividere la funzione pura dai dati e magari fare si che la funzione che trasforma i dati e basta erediti da una classe task di tbb(in tbb una classe che eredita da task è gestita in modo parallelo da un tasksheduler , dovrebbe fare tutto tbb , ma bisogna vedere in pratica) e utilizzare un task sheduler.
Infatti in opengl avro una scenegraph che non è altro che un grafo a cui sono agganciati dei dati(vbo e texture o altro, oggetti grafici per intenderci)e delle funzioni di trasformazione (ad esempio una funzione che ruota tutti i punti del vbo o altro)indipendenti l'una dalle altre, quindi pensavo che potrei parallelizzare, adesso nell esempio è una funzione di creazione , quindi non ha bisogno di essere performante , ma magari in una funzione che è richiamata 60 volte al secondo puo far comodo.
grazie.
ciao.
Il codice compila senza problemi quindi errori nella stesura dei template non ne hai fatti.Originariamente inviato da giuseppe500
quello che vorrei fare è creare una gestione dei vbo(sono alla fine buffer per opengl) con i template per sperimentare quello che ho letto.
sono pero' davvero alle prime armi coi template quindi avro fatto sicuramente degli errori (infatti ho un po paura di coprirmi di ridicolo e che cio che ho scritto non possa servire a nessuno).
Però nella classe CData fai un grossimo errore: sovrascrivi il puntatore m_data perdendo la memoria precedente. Inoltre quando fai:
stai copiando bit a bit il puntatore m_data. Se il codice attuale non crea problemi è perché non esiste nessuna delete, ma appena ne metti una vedi i fuochi d'artificio.codice:CVboCreator<T, Creator<T> > policy(*this);
Un vector<T> può risolvere la questione a patto che CData::getData() ne restituisca il reference (del resto già adesso restituisci un puntatore). Se dovesse essere troppo pesante puoi sempre crearti una classe buffer personalizzata, oppure aggiungere il costruttore di copia (ed eventualemente di trasferimento) alla classe CData. Al di la della tecnica che vuoi usare, attualmente CData è un petardo acceso in mano.
L'unico modo per saperlo è mettere alla prova questa idea: se regge è una buona idea.Quello che cercavo di dirti è se magari è una buona idea l'utilizzare una policy che contiene dei dati invece che delle funzioni di trasformazione in modo da dividere la funzione pura dai dati![]()
Non c'è modo di saperlo finché non la completi. Inoltre non è detto che parallelizzando il tutto diventi più veloce. Fa delle prove sia usando tbb sia senza e vedi cosa ti soddisfa di più.Infatti in opengl avro una scenegraph che non è altro che un grafo a cui sono agganciati dei dati(vbo e texture o altro, oggetti grafici per intenderci)e delle funzioni di trasformazione (ad esempio una funzione che ruota tutti i punti del vbo o altro)indipendenti l'una dalle altre, quindi pensavo che potrei parallelizzare, adesso nell esempio è una funzione di creazione , quindi non ha bisogno di essere performante , ma magari in una funzione che è richiamata 60 volte al secondo puo far comodo.
This code and information is provided "as is" without warranty of any kind, either expressed
or implied, including but not limited to the implied warranties of merchantability and/or
fitness for a particular purpose.
hai ragione .Non c'è modo di saperlo finché non la completi. Inoltre non è detto che parallelizzando il tutto diventi più veloce. Fa delle prove sia usando tbb sia senza e vedi cosa ti soddisfa di più.
adesso vado avanti.
grazie comunque![]()
ciao .
adesso che sto implementando le cose e ho un po di tempo vorrei chiedere un altra cosa:
1)I vertex buffer in opengl hanno una diversa semanica per indicare che fanno diverse cose ad es
Position : è un buffer di posizione dei vari vertici
Normal : è un buffer delle diverse normali per faccia dei triangoli
Texture : è un buffer delle coordinate texture
Sarebbe molto comodo , se non quasi indispensabile fare si che l'utente quando inserisce i dati possa essere aiutato dalla scrittura del codice , ad es quando sta immettendo dei vertici il nome Position , per es :
invece di
VboManager.m_Item1.setData(....)
mi piacerebbe molto un :
VboManager.Position.setData(...)
per fare questo sono indispensabili le variabili template nella classe vbomanager, dovrei pero' rispettare un dato ordine(Position è al primo posto, normal è al secondo , texture è al terzo) , e questo è un problema perchè potrei avere dei parametri mancanti qualora il VboManager non implementi la normale o la texture ecc... quindi non posso neanche utilizzare il default perchè non rispetterei un ordine.
forse potrei utilizzare un std::function con un bind a una funzione che ritorna l'oggetto item ma che si chiama position.
Insomma è un po che ci penso ma non ci salto fuori![]()
spero di essermi spiegato bene, se no riscrivo.
ciao.
l'ordine lo hai definito tu:per fare questo sono indispensabili le variabili template nella classe vbomanager, dovrei pero' rispettare un dato ordine(Position è al primo posto, normal è al secondo , texture è al terzo) , e questo è un problema perchè potrei avere dei parametri mancanti qualora il VboManager non implementi la normale o la texture ecc... quindi non posso neanche utilizzare il default perchè non rispetterei un ordine.
e tale deve restare. Se uno di questi non è previsto, devi esplicitare il suo tipo a CEmpty seguendo le regole dei default parameters delle funzioni normali (solo il tipo più a destra può essere default, altrimenti va esplicitato).Position è al primo posto, normal è al secondo , texture è al terzo
Detto questo, basta rinominare le variabili m_Itemx con i nomi rappresentativi (Position, Normal, Texture) e hai risolto il problema.
This code and information is provided "as is" without warranty of any kind, either expressed
or implied, including but not limited to the implied warranties of merchantability and/or
fitness for a particular purpose.