Partage
  • Partager sur Facebook
  • Partager sur Twitter

Remplissage VBO

    12 février 2024 à 13:02:14

    Bonjour à tous,
    Tout d'abord merci à ceux qui prendront le temps de m'aider.

    Faisons simple pour commencer :D : Dans un projet C++ utilisant OpenGL sur Qt (Linux), je reçois des données que je dois mettre en forme (c'est à dire que je dois afficher). Je dois réaliser une vue radar, pour cela je reçois 2240 cellules * 4096azimuts toutes les 1s (autrement dit, j'ai un cercle composé de 4096 azimuts/radiales contenant tous 2240 carrés représentants une cellule radar). Mon but est donc d'afficher ce cercle :-°.

    Pour le moment j'ai réalisé l'affichage de mon cercle 2D en plaçant les coordonnées initiales de chaque cellule. Les coordonnées des cellules sont contenus dans VBO_GRID.
    Maintenant j'essaye de remplir VBO_COLORS qui "en gros" est censé récupéré dans l'ordre croissant des azimuts (de 0 à 359) la couleur de chaque cellule.

    J'ai 2 threads à prendre en compte :
    - helloglwidget => classe dans laquelle je m'occupe de l'affichage OpenGL
    - vertexConversion => classe dans laquelle j'effectue des traitements pour récupérer tous mes niveaux de couleurs de chaque cellule toutes les secondes

    J'aimerai simplement que vertexConversion remplissent VBO_COLORS des couleurs reçues, et lorsque VBO_COLORS est MAJ provoqué le changement de couleurs des cellules du cercle sans pour autant avoir à redessiner tout le cercle qui provoque des problèmes de transfert :'(.

    Voici les problèmes que pour le moment j'ai :
    - Chute de performance lorsque VBO_COLORS MAJ
    - Fonction d'update du VBO_COLORS appelé uniquement lorsque je réalise des déplacements du dessin/zoom qui provoque un "update" forcé
    - Grille polaire redessiner entièrement à chaque changement

    Voici le code que j'ai en espérant que vous pouvez m'aider, merci !

    #include "vertexconversion.h"
    #include <QMutex>
    #include <QDebug>
    #include <omp.h>
    #include <QOpenGLFunctions>
    #include "packetprocess.h"
    #include "packet_struc.h"
    #include "shareddefinitions.h"
    
    vertexConversion::vertexConversion(QObject* parent) : QThread(parent)
    {
    }
    
    void vertexConversion::run()
    {
        QVector<RadarCell> cells;
    
    //Paire azimut_start et signalLevel
        std::vector<float> signalLevels;
        signalLevels.reserve(2240*4096); //2240 cellules + 1 Azimut_Start
        int cpt=0;
        firstAzimuthReceived = false;
    
        while (!stopFlag)
        {
            while (packetprocess::cellQueue.try_dequeue(cells)) {
                for (const auto& cell : cells)
                {
                    /*Si on reçoit pour la première fois le 1er Azimut*/
                    if (!firstAzimuthReceived && cell.azimuth_start <=0)
                    { firstAzimuthReceived=true; signalLevels.clear(); cpt=0; qDebug()<<"Premier reçu";}
    
                    /*Si on a déjà reçu le premier Azimut*/
                    if (firstAzimuthReceived)
                    {
                        float colorIntensity = convertSignalToColorIntensity(cell.signalLevel);
                        signalLevels.push_back(colorIntensity);
                        cpt++;
                    }
    
                    /*Si on a traité un tour complet : Càd si on a stack les 2240*4096 cellules*/
                    if (cpt>= 2240*4096)
                    {
                        qDebug()<<"Tour complet";
                        if(!dataReady.load(std::memory_order_acquire))
                        {
                            /*Màj du VBO couleurs*/
                            couleurs.enqueue(signalLevels);
                            dataReady.store(true, std::memory_order_release);
                            qDebug()<<"Transmission";
                        }else {
                            qDebug()<<"Pas de transmission";
                        }
                        /*Réinitialisation*/
                        signalLevels.clear();
                        cpt=0;
                    }
                }
    
            }
    
    }
    
    }
    
    float vertexConversion::convertSignalToColorIntensity(float signalLevel)
    {
        return std::min(std::max(signalLevel, 0.0f), 1.0f); 
    }
    
    #include "helloglwidget.h"
    
    HelloGLWidget::HelloGLWidget(QWidget *parent) :
        QOpenGLWidget(parent)
    {
    //    QTimer* timer = new QTimer(this);
    //    connect(timer, &QTimer::timeout, this, &HelloGLWidget::update);
    //    timer->start(16);
    }
    
    HelloGLWidget::~HelloGLWidget()
    {
        glDeleteBuffers(1,&VBO_GRID);
    }
    
    QSize HelloGLWidget::sizeHint() const
    {
        return QSize(640, 480);
    }
    
    void HelloGLWidget::calculateRadarData()
    {
        radarData.resize(AZIMUTS, std::vector<QVector3D>(CELLS_PER_AZIMUTS));
        for (int azimut = 0; azimut < AZIMUTS; azimut++)
        {
            double theta = (azimut*2*M_PI)/AZIMUTS; //Conversion azimut en radians
            for(int cell = 0; cell<CELLS_PER_AZIMUTS; ++cell)
            {
                double D = CELL_DUR * (START_RG+cell) * c/2.0;
                double x = D*cos(theta);
                double y = D*sin(theta);
                radarData[azimut][cell] = QVector3D(x,y,-2);
            }
        }
        //qDebug()<<"Taille radarGrid :"<<radarData.size();
    }
    
    void HelloGLWidget::updateVBOcouleurs()
    {
            std::vector<float> signalLvlsUpdate;
            while(couleurs.try_dequeue(signalLvlsUpdate))
            {
                qDebug()<<"Update VBO_COLORS";
                glBindBuffer(GL_ARRAY_BUFFER, VBO_COLORS);
    
                if(glMapBuffer)
                {
                    void* ptr = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
                    if(ptr)
                    {
                        /*Copie des données dans VBO*/
                        memcpy(ptr, signalLvlsUpdate.data(), signalLvlsUpdate.size()*sizeof (float));
                        glUnmapBuffer(GL_ARRAY_BUFFER); //Valide les modifications
                    }
                } else {
                    qDebug()<<"glMapBuffer pas dispo";
                        //glBufferData(GL_ARRAY_BUFFER, signalLvlsUpdate.size()*sizeof (float),signalLvlsUpdate.data(), GL_DYNAMIC_DRAW);
                        }
    
            }
            dataReady.store(false, std::memory_order_release);
    }
    
    void HelloGLWidget::initializeGL()
    {
        initializeOpenGLFunctions();
        //initializeGLFunctions();
    
        /*Implémentation de glMapBuffer()*/
        glMapBuffer = (PFNGLMAPBUFFERPROC) QOpenGLContext::currentContext();
        if(!glMapBuffer)
        {
            qWarning("Could not resolve glMapBuffer");
        }
    
        glEnable(GL_DEPTH_TEST);
        //glEnable(GL_CULL_FACE);
    
        glClearColor(0.0f,0.0f,0.0f,1.0f);
        //qglClearColor(QColor(Qt::black));
    
        shaderProgram.addShaderFromSourceFile(QGLShader::Vertex, ":/vertexShader.vsh");
        shaderProgram.addShaderFromSourceFile(QGLShader::Fragment, ":/fragmentShader.fsh");
        shaderProgram.link();
    
        glEnable(GL_MULTISAMPLE);
        glEnable(GL_LINE_SMOOTH);
        glHint(GL_LINE_SMOOTH_HINT,GL_NICEST);
    
        calculateRadarData();
    
        /*Création et liaison du VBO*/
        glGenBuffers(1,&VBO_GRID);
        glBindBuffer(GL_ARRAY_BUFFER,VBO_GRID);
    
        /*Préparation des données de vertex pour la grille polaire*/
        std::vector<GLfloat> vertexData;
        for(const auto& azimut : radarData)
        {
            for(const auto& point : azimut)
            {
                vertexData.push_back(point.x());
                vertexData.push_back(point.y());
                vertexData.push_back(point.z());
            }
        }
        glBufferData(GL_ARRAY_BUFFER, vertexData.size()*sizeof (GLfloat), vertexData.data(), GL_STATIC_DRAW);
    
    }
    
    void HelloGLWidget::resizeGL(int width, int height)
    {
        if (height == 0)
        {
            height = 1;
        }
        GLfloat aspect = GLfloat(width) / GLfloat(height);
        pMatrix.setToIdentity();
        pMatrix.ortho(-5643*aspect, 5643*aspect, -5643, 5643, -10000,10000);
        glViewport(0,0,width,height);
    }
    
    void HelloGLWidget::paintGL()
    {
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
        QMatrix4x4 mMatrix;
        QMatrix4x4 vMatrix;
    
        shaderProgram.bind();
        shaderProgram.setUniformValue("mvpMatrix", pMatrix * vMatrix * mMatrix);
        shaderProgram.setUniformValue("color", QColor(Qt::blue));
    
        if(dataReady.load(std::memory_order_acquire))
        {
           updateVBOcouleurs();
        }else{
        qDebug()<<"Not Updated";
             }
    
        glBindBuffer(GL_ARRAY_BUFFER,VBO_GRID);
        int vertexLocation = shaderProgram.attributeLocation("vertex");
        shaderProgram.enableAttributeArray(vertexLocation);
        glVertexAttribPointer(vertexLocation,3,GL_FLOAT, GL_FALSE,0,0);
    
        //glDrawArrays(GL_POINTS,0,AZIMUTS*CELLS_PER_AZIMUTS);
        glLineWidth(0.01f);
        glDrawArrays(GL_LINE_LOOP,0,AZIMUTS*CELLS_PER_AZIMUTS);
    
        shaderProgram.disableAttributeArray(vertexLocation);
    
        //glDrawArrays(GL_TRIANGLES, 0, vertices.size());
        //shaderProgram.disableAttributeArray(shaderProgram.attributeLocation("vertex"));
    
        shaderProgram.release();
    
    
    }
    
    void HelloGLWidget::wheelEvent(QWheelEvent *event)
    {
        if(event->delta()>0)
        {
            zoomFactor *= 0.9;
        } else {
            zoomFactor *=1.1;
        }
        GLfloat aspect = GLfloat(width()) / GLfloat(height());
    
        GLfloat left = -5643 * aspect * zoomFactor;
        GLfloat right = 5643 * aspect * zoomFactor;
        GLfloat bottom = -5643 * zoomFactor;
        GLfloat top = 5643 * zoomFactor;
    
        pMatrix.setToIdentity();
        pMatrix.ortho(left,right,bottom,top,-10000,10000);
    
        update();
        //event->accept();
    }
    
    void HelloGLWidget::mousePressEvent(QMouseEvent *event)
    {
        if (event->button() == Qt::LeftButton)
        {
            lastMousePosition = event->pos();
        }
    }
    
    void HelloGLWidget::mouseMoveEvent(QMouseEvent *event)
    {
        if(event->buttons() & Qt::LeftButton)
        {
            QPoint delta = event->pos() - lastMousePosition;
            lastMousePosition = event->pos();
            float aspect = float(width()) / float(height());
    
            float dx = (delta.x()/float(width())) * 11286 * zoomFactor * aspect;
            float dy = (-delta.y()/float(height())) * 11286 * zoomFactor;
            pMatrix.translate(dx,dy,0);
            update();
        }
    }
    




    • Partager sur Facebook
    • Partager sur Twitter

    Remplissage VBO

    × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
    • Editeur
    • Markdown