2015-11-24 27 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