2011-09-26 11 views
8

Sto cercando di creare un visualizzatore di nuvole di punti dinamico. I punti vengono aggiornati ogni fotogramma con il sensore Kinect. Per afferrare i fotogrammi sto usando OpenCV e GLUT da mostrare. L'API OpenCV restituisce un 640 x 480 (float *), per la posizione dei punti xyz e un 640 x 480 (int *) per i dati del colore rgb. Per ottenere le massime prestazioni, sto cercando di utilizzare Vertex Buffer Object in modalità stream invece di una semplice Vertex Array. Sto riuscendo a renderlo con Vertex Array, ma nulla viene reso con la mia implementazione VBO. Ho provato un sacco di ordini diversi nelle dichiarazioni, ma non riesco a trovare quello che mi manca. Qualcuno può provare a indicarmi la giusta direzione? Ecco il codice simpflified: (Ive riscritto la versione sbagliata, come chiesto da Christian Rau, così voi ragazzi può capire i miei errori)Rendering nuvola di punti Kinect con VBO (Vertex Buffer Object)

int main() 
{ 
    //Delaring variables, inittiating glut, setting camera and checking the compatibility as http://www.songho.ca/opengl/gl_vbo.html 
    glutDisplayFunc(displayCB); 
    glutIdleFunc(displayCB); 
    ... 
    //Inittiating the vertex buffers 
    if(vboSupported) 
    { 
     glGenBuffers(1, &vertex_buffer); 
     glBindBuffer(GL_ARRAY_BUFFER_ARB, buffer); 
     glBufferData(GL_ARRAY_BUFFER_ARB, (sizeof(GLfloat) * 640 * 480 * 3), 0, GL_STREAM_DRAW_ARB); 
     glBufferSubData(GL_ARRAY_BUFFER_ARB, 0, (sizeof(float) * 640 * 480 * 3), point_cloud.points_position); 

     glGenBuffers(2, &color_buffer); 
     glBindBuffer(GL_ARRAY_BUFFER_ARB, buffer); 
     glBufferData(GL_ARRAY_BUFFER_ARB, (sizeof(GLbyte) * 640 * 480 * 3), 0, GL_STREAM_DRAW_ARB); 
     glBufferSubData(GL_ARRAY_BUFFER_ARB, 0, (sizeof(char) * 640 * 480 * 3), point_cloud.points_color); 
    } 
    //glutMainLoop(), cleaning memory, ending main 
    .. 
} 

//Updating the screen 
void displayCB() 
{ 
    point_cloud.update(); 

    // clear buffer 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); 

    // save the initial ModelView matrix before modifying ModelView matrix 
    glPushMatrix(); 

     glBindBuffer(GL_ARRAY_BUFFER_ARB, color_buffer); 
     glBufferSubData(GL_ARRAY_BUFFER_ARB, 0, (sizeof(char) * 640 * 480 * 3), point_cloud.points_color); 
     glColorPointer(3, GL_UNSIGNED_BYTE, 0, 0); 

     glBindBuffer(GL_ARRAY_BUFFER_ARB, vertex_buffer); 
     glBufferSubData(GL_ARRAY_BUFFER_ARB, 0, (sizeof(float) * 640 * 480 * 3), point_cloud.points_position); 
     glVertexPointer(3, GL_FLOAT, 0, 0)); 

     // enable vertex arrays 
     glEnableClientState(GL_VERTEX_ARRAY); 
     glEnableClientState(GL_COLOR_ARRAY); 

     glDrawArrays(GL_POINT, 0, 640*480); 

     glDisableClientState(GL_VERTEX_ARRAY); // disable vertex arrays 
     glDisableClientState(GL_COLOR_ARRAY); 

     glBindBuffer(GL_ARRAY_BUFFER_ARB, 0); 

    glPopMatrix(); 

    glutSwapBuffers(); 
} 
+1

commento abbastanza estranei: piuttosto usare 'glBufferData' (invece di' glBufferSubData') quando si aggiorna l'intero buffer. Questo potrebbe aiutare il guidatore a ottimizzare le cose, ma non approfondirò su questo ora. Almeno nel codice principale il 'glBufferSubData' che segue un' glBufferData' è completamente inutile. –

+1

Dovresti piuttosto ** aggiungere ** nuove versioni del tuo codice alla domanda, invece di cambiare completamente il codice della domanda dopo ogni risposta o commento, in quanto ciò invalida altre risposte e le persone che leggono la domanda e le risposte si confondono completamente. –

+0

Lo faccio da postint come una nuova risposta? –

risposta

0

PS: Il programma è installato e funzionante, ma non riesco a vedere qualsiasi miglioramento delle prestazioni medie rispetto alla versione di Vertex Array. Va bene? IL PROBLEMA E 'STATO RISOLTO. Ive fatto tre modifiche:

1 - I though that glGenBuffers first parameter was the number that 
would be associated to the buffer, instead, its the number of 
buffers that would be allocated. This doesn't matter anyway, because 
now I'm using a single buffer and adding all the data to it. Didn't 
solved the problem, but was going in the right way. 

2 - There are two ways of being able to use OpenGL VBO functions. 
First, you can bind the ARB version functions by yourself OR you 
can add glew.h and use glewInit() after starting an OpenGL context. 
The second option is a LOT cleaner and I changed my code so I don't 
use the ARB versions anymore. Still didn't solved the problem. 

3 - Christian Rau asked me for glErrors in the code, so, I wrote it 
after each OpenGL operation in displayCB. After glDrawArrays I got 
an 0x00500 error, that means there is an invalid enum, so I noticed 
I was using GL_POINT as parameter to glDrawArrays, instead of 
GL_POINTS, so silly that makes me want to kill myself. 

Il codice finale:

//EDIT: Added glew.h as a header and I´m not using the ARB version anymore 
#include <glew.h> 

    int main() 
    { 
     //Declaring variables, initiating glut, setting camera and checking the compatibility as http://www.songho.ca/opengl/gl_vbo.html 
     glutDisplayFunc(displayCB); 
     glutIdleFunc(displayCB); 
     ... 

     //EDIT: IS VERY IMPORTANT TO ADD IT AS SOON AS YOU START AN OPENGL CONTEXT. 
     initGlew(); 

     //Inittiating the vertex buffers 
     if(vboSupported) 
     { 
      //EDIT: I was using two buffers, one for color and another for the vertex. I changed the code so I use a single buffer now. 
      //EDIT: Notice that I'm not using the ARB version of the functions anymore. 
      glGenBuffers(1, &buffer); 
      glBindBuffer(GL_ARRAY_BUFFER_ARB, buffer); 
      glBufferData(GL_ARRAY_BUFFER_ARB, (sizeof(GLfloat) * 640 * 480 * 3) + (sizeof(GLbyte) * 640 * 480 * 3), 0, GL_STREAM_DRAW_ARB); 
     } 
     //glutMainLoop(), cleaning memory, ending main 
     .. 
    } 

    //Updating the screen 
    void displayCB() 
    { 
     point_cloud.update(); 

     // clear buffer 
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); 

     // save the initial ModelView matrix before modifying ModelView matrix 
     glPushMatrix(); 

      glBindBuffer(GL_ARRAY_BUFFER_ARB, buffer); 
      glBufferSubData(GL_ARRAY_BUFFER_ARB, 0, (sizeof(char) * 640 * 480 * 3), point_cloud.points_color); 
      glBufferSubData(GL_ARRAY_BUFFER_ARB, (sizeof(char) * 640 * 480 * 3), (sizeof(float) * 640 * 480 * 3), point_cloud.points_position); 

      // enable vertex arrays 
      glEnableClientState(GL_VERTEX_ARRAY); 
      glEnableClientState(GL_COLOR_ARRAY); 

      glColorPointer(3, GL_UNSIGNED_BYTE, 0, 0); 
      //EDIT: Added the right offset at the vertex pointer position 
      glVertexPointer(3, GL_FLOAT, 0, (void*)(sizeof(char) * 640 * 480 * 3)); 

      //EDIT: Was using GL_POINT instead of GL_POINTS 
      glDrawArrays(GL_POINTS, 0, 640*480); 

      glDisableClientState(GL_VERTEX_ARRAY); // disable vertex arrays 
      glDisableClientState(GL_COLOR_ARRAY); 

      glBindBuffer(GL_ARRAY_BUFFER_ARB, 0); 

     glPopMatrix(); 

     glutSwapBuffers(); 
    }