Visualizzazione dei risultati da 1 a 10 su 10
  1. #1
    Utente di HTML.it
    Registrato dal
    Jun 2003
    Messaggi
    4,826

    Struttura dati definizioni e arrai void*

    Ciao.
    Ho un vector di strutture di tipo data cosi:
    codice:
    Struct data{
    byte mdata;
    int sizedata;
    }
    Dove mdata sono i dati e sizedata e' il numero di byte
    Per tipo di dato: float= 4,double=8 ecc....
    Vorrei riuscire a creare un vector<void*> storage
    Dove ci siano tutti i dati del vettore di strutture
    Con l' allineamento dato da:sizedata.
    In modo che se poi richiamo questo codice:
    codice:
    Void* pdata= storage.data();
    In pdata ci sono tutti i dati delle strutture
    Allineati correttamente.
    Mi serve per opengl dove la libreria vuole un void* con tutti i dati allineati per creare un buffer.
    La parte difficile per me e stato giostrarmi tra puntatori e dati

    Grazie.

  2. #2
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    Quel campo byte mdata è corretto o dovrebbe essere bytes* mdata?
    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.

  3. #3
    Utente di HTML.it
    Registrato dal
    Jun 2003
    Messaggi
    4,826
    Quote Originariamente inviata da shodan Visualizza il messaggio
    Quel campo byte mdata è corretto o dovrebbe essere bytes* mdata?
    scusa hai ragione ho scritto male deve essere byte*

  4. #4
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    Visto che non hai detto che API di opengl vuole i dati, suppongo che li voglia formattati così:
    4byte per la dimensione, n bytes per i dati.
    codice:
        int max_size = size_of(int) + sizedata +1;
        void* buff = ::operator_new(max_size); // o malloc.
        memcpy(buff,&sizedata,sizeof(int)); // imposta i primi 4 byte
        chiamata_api(buff);
    tuttavia senza conoscere l'API in questione si può solo tirare a indovinare.
    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.

  5. #5
    Utente di HTML.it
    Registrato dal
    Jun 2003
    Messaggi
    4,826
    Quote Originariamente inviata da shodan Visualizza il messaggio
    Visto che non hai detto che API di opengl vuole i dati, suppongo che li voglia formattati cos�:
    4byte per la dimensione, n bytes per i dati.
    codice:
        int max_size = size_of(int) + sizedata +1;
        void* buff = ::operator_new(max_size); // o malloc.
        memcpy(buff,&sizedata,sizeof(int)); // imposta i primi 4 byte
        chiamata_api(buff);
    tuttavia senza conoscere l'API in questione si pu� solo tirare a indovinare.
    Hai ragione Shodan , allora scusa se mi sono espresso male.
    le api opengl o vulkan su cui sono adesso accettano i dati come array di strutture ad es:
    codice:
    struct data
    {
       float[3] pos;
       float[3] col;
       float[2] uv
    }
    ecco...
    std::vector<data> Vdata;
    
    data* pDataStruct= new data();
    pDataStruct->pos={1.0,0.0,0.0} //per semplificare posizione vertice 1 3 float
    pDataStruct->col={1.0,0.0,0.0} //per semplificare rosso 3 float
    pDataStruct->uv={1.0,0.0} //per semplificare coordinate texture 2 float
    Vdata.push_back(pDataStruct);
    
    data* pDataStruct= new data();
    pDataStruct->pos={0.0,1.0,0.0} //per semplificare posizione vertice 1 3 float
    pDataStruct->col={1.0,0.0,0.0} //per semplificare rosso 3 float
    pDataStruct->uv={1.0,0.0} //per semplificare coordinate texture 2 float
    Vdata.push_back(pDataStruct);
    
    data* pDataStruct= new data();
    pDataStruct->pos={1.0,1.0,0.0} //per semplificare posizione vertice 1 3 float
    pDataStruct->col={1.0,0.0,0.0} //per semplificare rosso 3 float
    pDataStruct->uv={1.0,0.0} //per semplificare coordinate texture 2 float
    Vdata.push_back(pDataStruct);
    e passano i dati allineati come la struttura del tipo apivulkan(...,Vdata.data());


    io ho creato un semplice sistema template dove pero ho i dati non allineati del tipo un vector con tutti i pos , un vector con tutti i col e un vector con tutte le uv.
    io ho gia fatto la funzione per allineare i dati prendendo un float3 dal vettore all indice 0 pos e mettendolo in un array di puntatori a void, prendendo poi un float3 dal vector colori all indice 0 e mettendolo sempre nel vettore e cosi via con gli indici fino alla fine.
    Il problema � che uso i byte per creare qualsiasi tipo di dato possibile per questo il mio sistema template mi salva anche in una mappa il size dei vari elementi e crea la struttura,il blocchetto di dati e size dei dati in modo che se ho un uv con float2 salva il dato in byte* e nel size ci mette 8 o se ho un pos con float 3 salva il dato col dato in dato in byte* e nel size ci mette 12 e cosi via.
    a questo punto dai blocchetti vorrei creare un vector come se fosse un vector di strutture.
    chiedo se sia possibile in questo caso procedere cosi unendo tutti i blocchetti in un vector di puntatori void allineati.
    Il problema su cui sono e di cui ti chiedo � perch� se inserisco tutti i puntatori e faccio
    codice:
    byte*(byte)*vector.data();
    o
    byte*(byte)vector.data();
    i primi 3 float di pos sono corretti , ma poi gli altri dati non lo sono. quindi non posso passare a vulkan un vector.data() mentre se esamino la memoria del vettore cosi
    codice:
     byte* vector.data()[0] // pos corretto
    byte* vector.data()[1] // col corretto
    byte* vector.data()[2] // uv corretto
    non riesco cio� ad avere una zona di memoria contigua corretta con il vector.data();

    grazie ciao.

  6. #6
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    Scusa, ma ho l'impressione che tu ti stia complicando la vita. Non è più semplice creare un vettore di puntatori a data, fare delle funzioni che riversino i dati dai vettori_pos, vettori_col, vettori_uv nei rispettivi campi data_pos, data_col, data_uv e poi passare il tutto all'API, come il codice che hai mostrato (tra l'altro leggermente errato)?
    In uscita avresti i dati formattati direttamente nei campi di ogni singola struttura data.

    Non che non si possa fare in modo alternativo, ma in tal caso devi considerare che, mettiamo, per 5 strutture data devi allocare
    sizeof(data) * 5 = 160 bytes. I singoli pacchetti da 32 bytes ( ossia sizeof(data) ) sono la struttura simulata, di cui i primi 3*sizeof(float) sono il campo pos, i successivi 3 * sizeof(float) sono il campo col, e gli ultimi 2 * sizeof(float) sono il campo uv. E questo solo per la prima struttura simulata. In pratica accollandoti il lavoro che fa il compilatore.

    Non credo che l'API in questione sia così poco furba da fare una parserizzazione del genere. Più probabile faccia qualcosa del genere:
    codice:
         apivulkan(..., void* buffer, size_t num_bytes) {
             
             size_t num_struct = num_bytes / sizeof(data);
             struct data **tante_data = (struct data**) buffer;
             tante_data[0]->pos[0] = 0.1;
             tante_data[0]->pos[1] = 0.2;
             etc...
         }
    E poi non capisco
    Il problema � che uso i byte per creare qualsiasi tipo di dato possibile
    I dati sono vincolati dalla struttura data. Di che parliamo?
    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.

  7. #7
    Utente di HTML.it
    Registrato dal
    Jun 2003
    Messaggi
    4,826
    Quote Originariamente inviata da shodan Visualizza il messaggio
    Scusa, ma ho l'impressione che tu ti stia complicando la vita. Non � pi� semplice creare un vettore di puntatori a data, fare delle funzioni che riversino i dati dai vettori_pos, vettori_col, vettori_uv nei rispettivi campi data_pos, data_col, data_uv e poi passare il tutto all'API, come il codice che hai mostrato (tra l'altro leggermente errato)?
    In uscita avresti i dati formattati direttamente nei campi di ogni singola struttura data.

    Non che non si possa fare in modo alternativo, ma in tal caso devi considerare che, mettiamo, per 5 strutture data devi allocare
    sizeof(data) * 5 = 160 bytes. I singoli pacchetti da 32 bytes ( ossia sizeof(data) ) sono la struttura simulata, di cui i primi 3*sizeof(float) sono il campo pos, i successivi 3 * sizeof(float) sono il campo col, e gli ultimi 2 * sizeof(float) sono il campo uv. E questo solo per la prima struttura simulata. In pratica accollandoti il lavoro che fa il compilatore.

    Non credo che l'API in questione sia cos� poco furba da fare una parserizzazione del genere. Pi� probabile faccia qualcosa del genere:
    codice:
         apivulkan(..., void* buffer, size_t num_bytes) {
             
             size_t num_struct = num_bytes / sizeof(data);
             struct data **tante_data = (struct data**) buffer;
             tante_data[0]->pos[0] = 0.1;
             tante_data[0]->pos[1] = 0.2;
             etc...
         }
    E poi non capisco

    I dati sono vincolati dalla struttura data. Di che parliamo?
    si hai ragione , scusa avevo poco tempo e ho buttato giu velocemente dicendo delle cavolate.
    1.Cosa Voglio fare?
    vorrei creare una libreria template che mi assista e mi aiuti a configurare vulkan (il nuovo opengl)
    Come hai intuito e mi hai detto che mi sto complicando la vita � che serve una struttura vertex dl genere:
    codice:
    struct vertex
    {
       glm::vec3 pos;
       glm::vec2 UV
    }
    ecc....
    
    io vorrei aggiungere un wrapper attorno ai tipi che mi consenta di poter inserire altri dati che servono per la configurazione. una cosa cosi:
    struct vertex
    {
       wrapper<glm::vec3> pos;
       wrapper<glm::vec2> UV
    }
    e poi passare il vertex come argomento template ad un altra classe manager.
    cosi :
    codice:
    template <class V>
    class CManager{
    typedef typename V dati
    
    }
    in modo che possa fare una cosa del genere :
    CManager<Vertex> manager;
    manager.dati.pos.setBinding(.....
    manager.dati.UV.setBinding....
    manager.dati.pos.setvalue(glm::vec3(1.0f,1.0f,1.0f,1.0f)
    cosi che estendendo il wrapper posso inserire tutte le propriet� che voglio.
    Il mio problema � "portarle a casa" il wrapper � indipendente all interno della struttura e non ho accesso ai suoi risultati senza complicarmi appunto la vita.
    � una cosa che faccio nel tempo libero per imparare un po i template e ho visto che esistono le typelist posso fare qualcosa di meglio con le typelist secondo te?
    HO scelto i template in vulkan perch� ha un ampia fase di configurazione a design time e praticamente la parte dinamica � piccolissima.
    In pratica per velocizzare l'api si configura tutto in anticipo e poi si richiama la funzione draw per intenderci e minimizzare.

    Ora se per te le typelist non sono la soluzione dimmelo subito altrimenti senza loky con il c++ 11 si possono utilizzare?
    Ho visto in modern c++ programming che spiega come creare oggetti da una typelist e accederci tranquillamente con un indice.
    ciao.
    ps.non ho obblighi di tempo o consegne � solo una cosa che faccio io per imparare quindi non c'� fretta
    Grazie e scusa shodan

  8. #8
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    Se la tua API si aspetta una struttura siffatta:
    codice:
    struct vertex
    {
       glm::vec3 pos;
       glm::vec2 UV
    }
    dovrebbe essere sufficiente:
    codice:
    struct vertex
    {
       glm::vec3 pos;
       glm::vec2 UV
    }
    
    template <class T>
    struct wrapper {
        ... // varie cose
        T get_data() { return data; }
    }
    
    struct MyVertex {
        vertex vtype;
    
        wrapper< glm::vec3 > pos;
        wrapper< glm::vec2 > UV;  
    
        vertex* get_api_vertex() {
            vtype.pos = pos.get_data();
            vtype.UV = UV.get_data();
            return &vtype; 
        }
    }
    e dove hai il const void* passi: myVertex.get_api_vertex()
    Non vedo a cosa ti serva il CManager ne le typelist (o variadic template in C++)
    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.

  9. #9
    Utente di HTML.it
    Registrato dal
    Jun 2003
    Messaggi
    4,826
    Si, solo che sto creando una piccola libreria che mi permetta di definire una struttura di wrapper e semplicemente passarla al cmanager.a questo punto dal cmanager accedo ai wrapper ma :
    Non so quanti sono i campi nella struttura, in pratica la struttura mi e sconosciuta e ce ne possono essere molte.non c � poi molto da preoccuparsi per la memoria perch� presi i dati e creato un buffer vulkan rilascio tutta la memoria.
    Grazie.

  10. #10
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    Aggiornamento:
    HO scelto i template in vulkan perch� ha un ampia fase di configurazione a design time e praticamente la parte dinamica � piccolissima. eccetera...
    Qualcosa si può fare, ma dipende da quante singole strutture parliamo.
    Qui ho prodotto un test case, con tre strutture aventi campi diversi, dimensioni dei campi diversi ma tutti di tipo float. la funzione apivulkan() dovrebbe simulare il comportamento dell'API che vuoi usare (che spero prima o poi che tu la dica, in modo che possa leggerne la documentazione).
    Da quello che ho visto ogni funzione che accetta un const void*, accetta anche un parametro di tipo VKStructureType (o qualcosa del genere) che immagino serva all'API a capire cosa le sta arrivando.
    Continua a non esserci il CManager e onestamente non so come infilarcelo.
    Qui sia a livello template extreme per cui dovresti cercare variadic template su google per maggiori info.
    Spero sia quello che volevi fare o perlomeno che ci assomigli un po', in ogni caso buon divertimento.
    codice:
    #include "stdafx.h"
    #include <string>
    #include <iostream>
    #include <tuple>
    #include <vector>
    #include <algorithm>
    
    using namespace std;
    
    
    struct Type1 {
        float a[3];
    };
    
    struct Type2 {
        float a[3];
        float b[2];
    };
    
    struct Type3 {
        float a[3];
        float b[2];
        float c[4];
    };
    
    
    template <typename T>
    struct wrapper {
        T data;
        void set_data(const T& d) { 
            data = d; 
        }
        T get_data() { return data; }
    };
    
    
    template <std::size_t> struct Splat;
    
    template <> struct Splat<1> {
        static const int t = 0;
        Type1 t1;
        template <typename C>
        Type1* to_bytes(C& c) {
            // azzero Type1
            memset(&t1,0,sizeof(Type1));
            vector<float> tmp = get<0>(c).get_data();
            // aspetto 3 valori
            size_t maxcpy = std::min<size_t>(3,tmp.size());
            copy_n(tmp.begin(),maxcpy,t1.a);
            return &t1;
        }
    };
    
    template <> struct Splat<2> {
        static const int t = 1;
        
        Type2 t2;
        template <typename C>
        Type2* to_bytes(C& c) {
            memset(&t2, 0, sizeof(Type2));
            vector<float> tmp = get<0>(c).get_data();
            // aspetto 3 valori
            size_t maxcpy = std::min<size_t>(3, tmp.size());
            copy_n(tmp.begin(), maxcpy, t2.a);
    
            vector<float> tmp1 = get<1>(c).get_data();
            // aspetto 2 valori
            maxcpy = std::min<size_t>(2, tmp1.size());
            copy_n(tmp1.begin(), maxcpy, t2.b);
            return &t2;
        }
    };
    
    template <> struct Splat<3> {
        static const int t = 2;
        Type3 t3;
        template <typename C>
        Type3* to_bytes(C& c) {
            memset(&t3, 0, sizeof(Type3));
            vector<float> tmp = get<0>(c).get_data();
            // aspetto 3 valori
            size_t maxcpy = std::min<size_t>(3, tmp.size());
            copy_n(tmp.begin(), maxcpy, t3.a);
    
            vector<float> tmp1 = get<1>(c).get_data();
            // aspetto 2 valori
            maxcpy = std::min<size_t>(2, tmp1.size());
            copy_n(tmp1.begin(), maxcpy, t3.b);
    
            vector<float> tmp2 = get<2>(c).get_data();
            // aspetto 4 valori
            maxcpy = std::min<size_t>(4, tmp2.size());
            copy_n(tmp2.begin(), maxcpy, t3.c);
    
            return &t3;
        }
    };
    
    
    template <typename... T> struct Vertex;
    
    template <typename First, typename... Types>
    struct Vertex<First,Types...> : Vertex <Types...> {
        typedef std::tuple<wrapper<First>,wrapper<Types>...> Tupla;
        static const size_t ID = std::tuple_size<Tupla>::value;
        Tupla tup;
        Splat<ID> splat;
        const void* test() { 
            return splat.to_bytes(tup);
        } 
    };
    
    template <typename First>
    struct Vertex<First> {
        typedef std::tuple<wrapper<First>> Tupla;
        static const size_t ID = std::tuple_size<Tupla>::value;
        Tupla tup;
        Splat<ID> splat;
        const void* test() { 
            return splat.to_bytes(tup);
        }
    };
    
    
    void apivulkan(size_t type, const void* data) {
        if (type == 1) {
            const Type1* t1 = static_cast<const Type1*>(data);
            for (auto n : t1->a ) {
                cout << n << " ";
            }
            cout << endl;
        }
    
        if(type == 2) {
            const Type2* t2 = static_cast<const Type2*>(data);
            for(auto n : t2->a) {
                cout << n << " ";
            }
            cout << endl;
                
            for(auto n : t2->b) {
                cout << n << " ";
            }
            cout << endl;
    
        }
    
        if(type == 3) {
            const Type3* t3 = static_cast<const Type3*>(data);
            for(auto n : t3->a) {
                cout << n << " ";
            }
            cout << endl;
    
            for(auto n : t3->b) {
                cout << n << " ";
            }
            cout << endl;
    
            for(auto n : t3->c) {
                cout << n << " ";
            }
            cout << endl;
        }
    }
    
    
    int main() {
    
        Vertex<vector<float>> d;
        Vertex<vector<float>, vector<float>> d1;
        Vertex<vector<float>, vector<float>, vector<float>> d2;
    
        std::vector<float> v0{1.1f,2.1f,3.1f};
        get<0>(d.tup).set_data(v0);
    
        std::vector<float> v1a{ 4.1f,5.1f,6.1f };
        std::vector<float> v1b{ 7.1f,8.1f,9.1f };
    
        get<0>(d1.tup).set_data(v1a);
        get<1>(d1.tup).set_data(v1b);
    
        std::vector<float> v2a{ 10.1f,20.1f,30.1f };
        std::vector<float> v2b{ 40.1f,50.1f,60.1f };
        std::vector<float> v2c{ 70.1f,80.1f,90.1f,100.1f,200.1f };
    
        get<0>(d2.tup).set_data(v2a);
        get<1>(d2.tup).set_data(v2b);
        get<2>(d2.tup).set_data(v2c);
    
        apivulkan(d.ID, d.test());
        apivulkan(d1.ID, d1.test());
        apivulkan(d2.ID, d2.test());
    
    
    }
    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.

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.