2015-11-24 30 views
-2

放棄慢glBegin/glEnd技術後,我終於決定使用VBOs。經過幾個小時和幾個小時的挫折,我終於完成了編譯。但這並不意味着它有效。函數「CreateVBO」無誤地執行,但一旦調用glutMainLoop(),程序崩潰,它甚至不會調用Reshape()Render()函數。OpenGL崩潰之前,它可以渲染一幀 - VBOs

這裏是CreateVBO()功能: (注:「線條」變量等於400萬,整個程序只是一個壓力測試渲染多行之前,我可以做的事,其實是有道理的)

void CreateVBO() 
{ 
    glGenBuffers = (PFNGLGENBUFFERSPROC)wglGetProcAddress("glGenBuffers"); 
    glBindBuffer=(PFNGLBINDBUFFERPROC)wglGetProcAddress("glBindBuffer"); 
    glBufferData=(PFNGLBUFFERDATAPROC)wglGetProcAddress("glBufferData"); 
    glDeleteBuffers=(PFNGLDELETEBUFFERSPROC)wglGetProcAddress("glDeleteBuffers"); 
    glMapBuffer=(PFNGLMAPBUFFERPROC)wglGetProcAddress("glMapBuffer"); 


    for(float i=0; i<lines*2; i++) 
    { 

     t_vertices.push_back(i/9000); 
     t_vertices.push_back(5 * (((int)i%2)*2-1)); 
     t_vertices.push_back(20); 

     vert_cols.push_back(0); 
     vert_cols.push_back(255); 
     vert_cols.push_back(0); 


     t_indices.push_back((int)i); 
    } 

    glGenBuffers(1, &VertexVBOID); 
    glBindBuffer(GL_ARRAY_BUFFER, VertexVBOID); 
    glBufferData(GL_ARRAY_BUFFER, sizeof(float)*t_vertices.size(), &t_vertices[0], GL_STATIC_DRAW); 

    glGenBuffers(1, &IndexVBOID); 
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IndexVBOID); 
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(int)*t_indices.size(), NULL, GL_STATIC_DRAW); 

    GLvoid * buf = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY); 

    memcpy((void*)buf, &vert_cols[0], (size_t)(sizeof(float)*vert_cols.size())); 

    glBindBuffer(GL_ARRAY_BUFFER, 0); 
} 

這裏是Render()函數。我不知道它可能有什麼問題,因爲在調用該函數之前程序崩潰了。

void Display() 
{ 
    glRotatef(1, 0, 1, 0); 
    glClearColor(0, 0, 0, 0); 
    glClear(GL_COLOR_BUFFER_BIT); 

    glBindBuffer(GL_ARRAY_BUFFER, VertexVBOID); 
    glEnableClientState(GL_VERTEX_ARRAY); 
    glVertexPointer(t_vertices.size(), GL_FLOAT, 0, 0); //The starting point of the VBO, for the vertices 
    glEnableClientState(GL_COLOR_ARRAY); 
    glColorPointer(vert_cols.size(), GL_FLOAT, 0, 0); 

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IndexVBOID); 
    glDrawElements(GL_LINES, lines, GL_UNSIGNED_INT, 0); 
    glutSwapBuffers(); 
    //Sleep(16); 
    glutPostRedisplay(); 
} 
+0

顯示過量設置代碼 – BDL

+0

注意:我知道問題是使用GenerateVBO(),有一次它可以處理3行,但是當我將其更改爲30時,它崩潰了 – CrizerPL

回答

1

您的代碼沒有意義。

首先,你創建你的vertexVBOID大到足以容納你的t_vertices矢量,並填充它確切的數組。 然後,將VBO和的數據映射爲中的數據與vert_color向量的數據。對於繪圖,您可以指定頂點位置和顏色屬性來自內存中的相同位置 - 因此也有效地將顏色用作位置。

但這並不是墜機的原因。實際上有崩潰的原因主要有兩個:

  1. 創建IndexVBOID大到足以容納你的索引數組,但你永遠不initalize該緩衝區的一些數據。您改爲指定NULL作爲數據指針,因此存儲已創建,但保持未初始化狀態。所以你最終在該緩衝區中定義了一個未定義的內容,當繪圖時GL會訪問arbtrary的內存位置。

  2. 您的glVertexPointerglColorPointer呼叫是錯誤的。第一個參數size而不是數組的大小。它的大小是單個矢量,它可以是1,2,3或4.你的數組大小可能是其他的東西,所以這個調用最終會產生一個GL_INVALID_VALUE錯誤,並且根本不設置attrib指針。並且默認情況下,這些指針是NULL。

因此,最終你要求GL從相對於NULL指針的未定義數組索引中繪製。這很可能會崩潰。一般來說,這只是未定義的行爲,結果可能是任何事情。

此外,您還保留VertexVBOID緩衝區映射 - 你永遠不會取消映射它。只要它被映射(除非創建了一個持久映射,這是一個相對較新的特性,它並不真正屬於這裏),否則使用緩衝區作爲GL命令的源或目標是無效的。

+0

非常感謝,我真的不知道我在寫什麼,現在我意識到代碼是多麼愚蠢......顯然我的代碼現在是好的,但似乎有一個65535頂點限制,即使我使用32位整數索引。但是非常感謝你;) – CrizerPL