Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/opengl/4.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
C++ 何时删除缓冲区对象?_C++_Opengl_Vbo - Fatal编程技术网

C++ 何时删除缓冲区对象?

C++ 何时删除缓冲区对象?,c++,opengl,vbo,C++,Opengl,Vbo,我从中了解到,只要程序链接,着色器对象就可以分离和删除 缓冲区对象的行为是否与VAO类似?在VAO初始化后(在下面的Scene::Scene()末尾),我可以删除它们吗?还是应该让代码保持原样,每次使用它们时都绑定它们 场景h: class Scene { public: void render(); Scene(); ~Scene(); private: GLuint vertexArray; GLuint vertexBuffer; GLuin

我从中了解到,只要程序链接,着色器对象就可以分离和删除

缓冲区对象的行为是否与VAO类似?在VAO初始化后(在下面的
Scene::Scene()
末尾),我可以删除它们吗?还是应该让代码保持原样,每次使用它们时都绑定它们

场景h:

class Scene
{
public:
    void render();
    Scene();
    ~Scene();
private:
    GLuint vertexArray;
    GLuint vertexBuffer;
    GLuint indexBuffer;
    GLuint program;
};
Scene.cpp:

#include <GL/glew.h>
#include <stdio.h>

#include "Scene.h"

namespace
{
    void printProgramInfoLog(GLuint program);
    void printShaderInfoLog(GLuint shader);
}

void Scene::render()
{
    glBindVertexArray(vertexArray);
    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
    glUseProgram(program);

    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0);

    glUseProgram(0);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindVertexArray(0);
}

Scene::Scene()
{
    const float vertices[] =
    {
        -1.0f, -1.0f, 0.0f,
         1.0f, -1.0f, 0.0f,
         1.0f,  1.0f, 0.0f,
        -1.0f,  1.0f, 0.0f,
    };

    const unsigned short indices[] =
    {
        0,
        1,
        2,
        0,
        2,
        3,
    };

    const char* vertexShaderSource[] =
    {
        "#version 330\n",
        "\n",
        "in vec3 position;\n",
        "\n",
        "out vec2 fspos;",
        "\n",
        "void main()\n",
        "{\n",
        "    gl_Position = vec4(position, 1.0);\n",
            "fspos = vec2(position.x, position.y);\n",
        "}\n",
    };

    const char* fragmentShaderSource[] =
    {
        "#version 330\n",
        "\n",
        "precision highp float;\n",
        "\n",
        "in vec2 fspos;",
        "\n",
        "out vec4 color;\n",
        "\n",
        "void main()\n",
        "{\n",
        "    color = vec4(abs(fspos.x), abs(fspos.y), 0.0, 1.0);\n",
        "}\n",
    };

    //-------------------------------
    // Create and bind vertex array.
    //-------------------------------
    glGenVertexArrays(1, &vertexArray);
    glBindVertexArray(vertexArray);

    //--------------------------------------
    // Create, bind and fill vertex buffer.
    //--------------------------------------
    glGenBuffers(1, &vertexBuffer);
    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

    //-------------------------------------
    // Create, bind and fill index buffer.
    //-------------------------------------
    glGenBuffers(1, &indexBuffer);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

    //-----------------
    // Create program.
    //-----------------
    program = glCreateProgram();

    //----------------------------------
    // Create and attach vertex shader.
    //----------------------------------
    GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertexShader, sizeof(vertexShaderSource) / sizeof(vertexShaderSource[0]), vertexShaderSource, 0);
    glCompileShader(vertexShader);
    printShaderInfoLog(vertexShader);
    glAttachShader(program, vertexShader);

    //------------------------------------
    // Create and attach fragment shader.
    //------------------------------------
    GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragmentShader, sizeof(fragmentShaderSource) / sizeof(fragmentShaderSource[0]), fragmentShaderSource, 0);
    glCompileShader(fragmentShader);
    printShaderInfoLog(fragmentShader);
    glAttachShader(program, fragmentShader);

    //---------------
    // Link program.
    //---------------
    glLinkProgram(program);
    printProgramInfoLog(program);

    //-----------------------
    // Set up shader inputs.
    //-----------------------
    GLint position = glGetAttribLocation(program, "position");
    glEnableVertexAttribArray(position);
    glVertexAttribPointer(position, 3, GL_FLOAT, GL_FALSE, 0, 0);

    //------------------------------------
    // Detach and delete fragment shader.
    //------------------------------------
    glDetachShader(program, fragmentShader);
    glDeleteShader(fragmentShader);

    //----------------------------------
    // Detach and delete vertex shader.
    //----------------------------------
    glDetachShader(program, vertexShader);
    glDeleteShader(vertexShader);

    //----------------------
    // Unbind vertex array.
    //----------------------
    glBindVertexArray(0);

    //!!!!!!!!!!!!!!!!!!!
    // Unbinding and deleting the buffers here and only binding the VAO in
    // render() works just fine, but is it okay to do this or should I leave
    // it as is?
    //!!!!!!!!!!!!!!!!!!!
}

Scene::~Scene()
{
    glDeleteProgram(program);
    glDeleteBuffers(1, &indexBuffer);
    glDeleteBuffers(1, &vertexBuffer);
    glDeleteVertexArrays(1, &vertexArray);
}

namespace
{
    void printProgramInfoLog(GLuint program)
    {
        int logLength;
        glGetProgramiv(program, GL_INFO_LOG_LENGTH, &logLength);
        if (logLength > 0)
        {
            char* log = new char[logLength];
            glGetProgramInfoLog(program, logLength, 0, log);
            fprintf(stderr, "%s", log);
            delete[] log;
        }
    }

    void printShaderInfoLog(GLuint shader)
    {
        int logLength;
        glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &logLength);
        if (logLength > 0)
        {
            char* log = new char[logLength];
            glGetShaderInfoLog(shader, logLength, 0, log);
            fprintf(stderr, "%s", log);
            delete[] log;
        }
    }
}
#包括
#包括
#包括“Scene.h”
名称空间
{
作废打印程序信息日志(GLuint程序);
void printShaderInfoLog(GLuint着色器);
}
void场景::render()
{
glBindVertexArray(vertexArray);
glBindBuffer(GL_数组_BUFFER,vertexBuffer);
glBindBuffer(GL_元素数组缓冲区,indexBuffer);
glUseProgram(程序);
GLD元素(GL_三角形,6,GL_无符号_短,0);
glUseProgram(0);
glBindBuffer(GL_元素_数组_缓冲区,0);
glBindBuffer(GL_数组_BUFFER,0);
glBindVertexArray(0);
}
场景::场景()
{
常量浮点顶点[]=
{
-1.0f,-1.0f,0.0f,
1.0f,-1.0f,0.0f,
1.0f,1.0f,0.0f,
-1.0f,1.0f,0.0f,
};
常量无符号短索引[]=
{
0,
1.
2.
0,
2.
3.
};
常量字符*vertexShaderSource[]=
{
“#版本330\n”,
“\n”,
“处于vec3位置;\n”,
“\n”,
“out vec2 fspos;”,
“\n”,
“void main()\n”,
“{\n”,
“gl_Position=vec4(Position,1.0);\n”,
“fspos=vec2(位置.x,位置.y);\n”,
“}\n”,
};
常量字符*fragmentShaderSource[]=
{
“#版本330\n”,
“\n”,
“精度高浮点;\n”,
“\n”,
“在vec2 fspos中;”,
“\n”,
“输出vec4颜色;\n”,
“\n”,
“void main()\n”,
“{\n”,
“color=vec4(abs(fspos.x)、abs(fspos.y)、0.0、1.0);\n”,
“}\n”,
};
//-------------------------------
//创建并绑定顶点数组。
//-------------------------------
GLGEnVertexArray(1和vertexArray);
glBindVertexArray(vertexArray);
//--------------------------------------
//创建、绑定和填充顶点缓冲区。
//--------------------------------------
glGenBuffers(1和vertexBuffer);
glBindBuffer(GL_数组_BUFFER,vertexBuffer);
glBufferData(GLU数组缓冲区、大小(顶点)、顶点、GLU静态图);
//-------------------------------------
//创建、绑定和填充索引缓冲区。
//-------------------------------------
glGenBuffers(1和indexBuffer);
glBindBuffer(GL_元素数组缓冲区,indexBuffer);
glBufferData(GL元素\数组\缓冲区、sizeof(索引)、索引、GL静态\绘图);
//-----------------
//创建程序。
//-----------------
program=glCreateProgram();
//----------------------------------
//创建并附加顶点着色器。
//----------------------------------
GLuint vertexShader=glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader,sizeof(vertexShaderSource)/sizeof(vertexShaderSource[0]),vertexShaderSource,0);
glCompileShader(顶点着色器);
printShaderInfoLog(顶点着色器);
glAttachShader(程序,顶点着色器);
//------------------------------------
//创建并附加片段着色器。
//------------------------------------
GLuint fragmentShader=glCreateShader(GL\u fragmentShader);
glShaderSource(fragmentShader,sizeof(fragmentShaderSource)/sizeof(fragmentShaderSource[0]),fragmentShaderSource,0);
glCompileShader(fragmentShader);
printShaderInfoLog(fragmentShader);
glAttachShader(程序、碎片着色器);
//---------------
//链接程序。
//---------------
glLinkProgram(program);
打印程序信息日志(程序);
//-----------------------
//设置着色器输入。
//-----------------------
闪烁位置=GLGETARTIBLOCATION(程序,“位置”);
GlenableVertexAttributeArray(位置);
glvertexattributepointer(位置,3,GL\u浮点,GL\u假,0,0);
//------------------------------------
//分离并删除片段着色器。
//------------------------------------
glDetachShader(程序、碎片着色器);
glDeleteShader(fragmentShader);
//----------------------------------
//分离并删除顶点着色器。
//----------------------------------
glDetachShader(程序、顶点着色器);
glDeleteShader(顶点着色器);
//----------------------
//取消绑定顶点数组。
//----------------------
glBindVertexArray(0);
//!!!!!!!!!!!!!!!!!!!
//在此处解除绑定并删除缓冲区,并且仅在中绑定VAO
//render()工作正常,但这样做可以吗,还是应该离开
//是这样吗?
//!!!!!!!!!!!!!!!!!!!
}
场景::~Scene()
{
glDeleteProgram(program);
glDeleteBuffers(1和indexBuffer);
glDeleteBuffers(1和vertexBuffer);
GLDeleteVertexArray(1和vertexArray);
}
名称空间
{
作废打印程序信息日志(GLuint程序)
{
整数对数长度;
glGetProgramiv(程序、总账信息、日志长度和日志长度);
如果(对数长度>0)
{
char*log=新字符[logLength];
glGetProgramInfoLog(程序,日志长度,0,日志);
fprintf(标准,“%s”,日志);
删除[]日志;
}
}
void printShaderInfoLog(GLuint着色器)
{
整数对数长度;
glGetShaderiv(着色器、GL\u信息\u日志长度和日志长度);
如果(对数长度>0)
{
char*log=新字符[logLength];
glGetShaderInfoLog(着色器,logLength,0,log);
fprintf(标准,“%s”,日志);
删除[]日志;
}
}
}
VAO不存储数据。它们存储缓冲区对象绑定和顶点格式。缓冲区对象仍然是数据存储的持有者


因此,不,不要这样做。

因此,我不能在那里删除它们,但我不必绑定/取消绑定每个帧(因为VAO持有bi)