Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/sql-server-2008/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Opengl glBufferData不删除现有数据存储_Opengl - Fatal编程技术网

Opengl glBufferData不删除现有数据存储

Opengl glBufferData不删除现有数据存储,opengl,Opengl,美国 glBufferData为当前缓冲区对象创建新的数据存储 一定要瞄准目标。任何预先存在的数据存储都将被删除。新数据 使用指定的大小(以字节为单位)和用法创建存储 所以我编码 // allocate storage in GPU and copy data glBufferData( GL_ARRAY_BUFFER, myData.VertexCount()*sizeof(GL_FLOAT), myData.Vertex(),

美国

glBufferData为当前缓冲区对象创建新的数据存储
一定要瞄准目标。任何预先存在的数据存储都将被删除。新数据 使用指定的大小(以字节为单位)和用法创建存储

所以我编码

    // allocate storage in GPU and copy data
    glBufferData(
      GL_ARRAY_BUFFER,
      myData.VertexCount()*sizeof(GL_FLOAT),
      myData.Vertex(),
      GL_STREAM_DRAW);
    ...
    glDrawArrays(
      GL_TRIANGLES,
      0,
      myData.VertexCount() );
每次我需要刷新场景时都会执行

顶点的数量有时会发生很大的变化。当顶点数减少时,旧数据似乎仍然存在,并且旧数据的渲染出现混乱

我可以通过在每次刷新开始时创建缓冲区索引,然后删除它来解决这个问题

    // construct buffer index
    GLuint vertexbuffer;
    glGenBuffers(1, &vertexbuffer);

   ...

   glDeleteBuffers(1,&vertexbuffer);
目前这还可以,但我想稍后再进行优化,包括重用缓冲区中的一些顶点,而无需在每次刷新时创建新的副本

这个问题并没有出现在我所有的机器上。看起来拥有更好图形卡的机器没有问题

以下是完整的渲染代码供参考:

    void Render()
    {
        // Background color
        glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
        glEnable(GL_DEPTH_TEST);
        glDepthFunc(GL_LESS);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT );

        glUseProgram( myShaderID );

        // Send our transformation to the currently bound shader,
        // in the "MVP" uniform
        glUniformMatrix4fv(myMatrixID, 1, GL_FALSE, &MVP[0][0]);

        // enable vertices attribute buffer
        glEnableVertexAttribArray(0);

        // make current
        glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);

        // allocate storage in GPU and copy data
        glBufferData(GL_ARRAY_BUFFER, myData.VertexCount()*sizeof(GL_FLOAT),
                     myData.Vertex(), GL_STREAM_DRAW);

        // let shaders access buffer
        glVertexAttribPointer(
            0,                  // attribute. No particular reason for 0, but must match the layout in the shader.
            3,                  // size
            GL_FLOAT,           // type
            GL_FALSE,           // normalized?
            0,                  // stride
            (void*)0            // array buffer offset
        );

        // 2nd attribute buffer : colors
        glEnableVertexAttribArray(1);
        glBindBuffer(GL_ARRAY_BUFFER, colorbuffer);
        glBufferData(GL_ARRAY_BUFFER, myData.VertexCount()*sizeof(GL_FLOAT),
                     myData.Color(), GL_STREAM_DRAW);
        glVertexAttribPointer(
            1,                                // attribute. No particular reason for 1, but must match the layout in the shader.
            3,                                // size
            GL_FLOAT,                         // type
            GL_FALSE,                         // normalized?
            0,                                // stride
            (void*)0                          // array buffer offset
        );

        glDrawArrays(GL_TRIANGLES, 0, myData.VertexCount() );

        glDisableVertexAttribArray(0);
        glDisableVertexAttribArray(1);

        glFlush();
        myCanvas->SwapBuffers();
}
这是最终的、固定的生产代码。VertexCount()现在返回顶点的实际计数,而不仅仅是顶点向量中的浮点数

/** Update GL display */
void Render()
{
    // Background color
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LESS);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT );

    glUseProgram( myShaderID );

    // Send our transformation to the currently bound shader,
    // in the "MVP" uniform
    glUniformMatrix4fv(
        myMatrixID,
        1,
        GL_FALSE,
        myCamera.ModelViewProjection() );

    // enable vertices attribute buffer
    glEnableVertexAttribArray(0);

    // make current
    glBindBuffer(GL_ARRAY_BUFFER, myVertexBufferID);

    // allocate storage in GPU and copy data
    glBufferData(
        GL_ARRAY_BUFFER,
        3 * myData.VertexCount()*sizeof(GL_FLOAT),
        myData.Vertex(),
        GL_STREAM_DRAW);

    // let shaders access buffer
    glVertexAttribPointer(
        0,                  // attribute. No particular reason for 0, but must match the layout in the shader.
        3,                  // size
        GL_FLOAT,           // type
        GL_FALSE,           // normalized?
        0,                  // stride
        (void*)0            // array buffer offset
    );

    // 2nd attribute buffer : colors
    glEnableVertexAttribArray(1);
    glBindBuffer(GL_ARRAY_BUFFER, myColorBufferID);
    glBufferData(
        GL_ARRAY_BUFFER,
        3 * myData.VertexCount()*sizeof(GL_FLOAT),
        myData.Color(),
        GL_STREAM_DRAW);
    glVertexAttribPointer(
        1,                                // attribute. No particular reason for 1, but must match the layout in the shader.
        3,                                // size
        GL_FLOAT,                         // type
        GL_FALSE,                         // normalized?
        0,                                // stride
        (void*)0                          // array buffer offset
    );

    glDrawArrays(GL_TRIANGLES, 0, myData.VertexCount() );

    glDisableVertexAttribArray(0);
    glDisableVertexAttribArray(1);

    glFlush();
    myCanvas->SwapBuffers();

}

发生的情况是,当您调用
glBufferData
时,GL驱动程序会在其内存中为您提供一个可能与上一个位置相同的位置。您认为可以使用
glBufferData
更新整个过程的一部分,但事实并非如此。其余数据可能与旧数据一致,也可能不一致。 我认为您最好使用
glBufferSubData
而不是
glBufferData
来更新新数据(或其中的一部分),而无需删除和重新创建数据存储。
当newSize>oldSize时,您需要删除并重新创建。

发生的情况是,当您调用
glBufferData
时,GL驱动程序会在其内存中为您提供一个可能与上一个位置相同的位置。您认为可以使用
glBufferData
更新整个过程的一部分,但事实并非如此。其余数据可能与旧数据一致,也可能不一致。 我认为您最好使用
glBufferSubData
而不是
glBufferData
来更新新数据(或其中的一部分),而无需删除和重新创建数据存储。
当newSize>oldSize时,您需要删除并重新创建。

您的代码不正确。将顶点属性指针设置为每个顶点读取3
GLfloat
s,并使用
myData.VertexCount()
作为绘图调用中的顶点数,但仅将
myData.VertexCount()*sizeof(GL\u FLOAT)
字节上载到VBO。因此,您将读取超过缓冲区末尾的内容,结果只是未定义的行为


.

您的代码就是不正确。将顶点属性指针设置为每个顶点读取3
GLfloat
s,并使用
myData.VertexCount()
作为绘图调用中的顶点数,但仅将
myData.VertexCount()*sizeof(GL\u FLOAT)
字节上载到VBO。因此,您将读取超过缓冲区末尾的内容,结果只是未定义的行为


.

“已删除现有数据存储”而不是“已存储数据”如何呈现旧数据?刷新时不更新它吗?是否对glDrawXXX使用了与glBufferData使用的计数不匹配的计数?您希望如何重用以前声明为已删除的数据?请解释一下,考虑一个像C++指针一样的缓冲区(即“数据存储”)。您可以删除指针,而无需清除指向的数据。仅再次将内存标记为可用。glBufferData是缓冲区副本,而不是缓冲区映射——您应该认为该存储是新的,未初始化。如果在渲染中看到旧数据,则可能是在上载旧数据,或者以某种方式触发未定义的行为(例如渲染过多的顶点)。“已删除现有数据存储”而不是“已存储数据”如何渲染旧数据?刷新时不更新它吗?是否对glDrawXXX使用了与glBufferData使用的计数不匹配的计数?您希望如何重用以前声明为已删除的数据?请解释一下,考虑一个像C++指针一样的缓冲区(即“数据存储”)。您可以删除指针,而无需清除指向的数据。仅再次将内存标记为可用。glBufferData是缓冲区副本,而不是缓冲区映射——您应该认为该存储是新的,未初始化。如果在渲染中看到旧数据,则可能是在上载旧数据,也可能是在以某种方式触发未定义的行为(例如渲染过多的顶点)。这一解释是有道理的。它没有解释为什么要绘制旧数据。我使用正确的、减少的顶点计数调用glDrawArrays,但它会继续进行,并渲染超过该计数的顶点。是否在
glBufferData
之前再次调用
glBufferData
?不确定“再次”是什么意思。我确实在GLBUFFERDATA之前调用了glBindBuffer这个解释就其本身而言是有意义的。它没有解释为什么要绘制旧数据。我使用正确的、减少的顶点计数调用glDrawArrays,但它会继续进行,并渲染超过该计数的顶点。是否在
glBufferData
之前再次调用
glBufferData
?不确定“再次”是什么意思。我确实在GLBUFFERDATA出现之前调用了glBindBuffer。我需要编写gldrawArray(GL_三角形,0,myData.VertexCount()/3);你可以这么做,但我建议你打电话给VertexCount,因为这不是名字所暗示的。这是一个快速修复方法,可以测试我对你答案的理解。在生产代码中,我保持glDrawArrays调用不变,并编写了传递给GLBUFFERDATA的字节数,并将其增加了三倍。我需要编写gldrawArray(GL_三角形,0,myData.VertexCount()/3);你可以这样做,但是我建议你调用
VertexCount
其他的东西,因为它不是这个名字所暗示的