2011-09-26 123 views
8

我正嘗試做一個動態的點雲可視化。使用Kinect傳感器每點更新點數。要抓住框架,我使用OpenCV和GLUT來顯示。 OpenCV API爲點xyz位置返回640 x 480(float *),併爲rgb顏色數據返回640 x 480(int *)。 爲了獲得最佳性能,我試圖在流模式下使用頂點緩衝對象而不是簡單的頂點數組。我可以使用頂點數組來渲染它,但是沒有任何東西正在渲染與我的VBO實現。我在聲明中嘗試了一堆不同的命令,但是我找不到我想要的東西。有人可以試圖指出我正確的方向嗎?這裏是simpflified代碼:(從來就rewrited錯誤的版本要求由基督教勞,所以你們能理解我的錯誤)渲染Kinect的點雲數據與頂點緩衝區對象(VBO)

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

相當無關的評論:更新整個緩衝區時,而使用'glBufferData'(而不是'glBufferSubData')。這可能有助於駕駛員優化事情,但我現在不會詳細討論。至少在主代碼中,'glBufferData'後面的'glBufferSubData'完全沒用。 –

+1

您應該**將**代碼的新版本追加到問題中,而不是在每次回答或評論後徹底更改問題代碼,因爲這會使其他答案無效,並且讀取問題和答案的人會完全混淆。 –

+0

我通過postint作爲一個新的答案嗎? –

回答

0

PS:程序運行起來,但我看不到與頂點陣列版本相比,平均性能有所提高。這樣好嗎? 問題解決了。從來就做了三個改變:

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. 

最終代碼:

//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(); 
    } 
相關問題