c++ - 何时删除缓冲区对象?

标签 c++ opengl vbo

我从this question了解到一旦程序链接,着色器对象就可以分离和删除。

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

场景.h:

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

场景.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;
        }
    }
}

最佳答案

VAO 不存储数据。它们存储缓冲区对象绑定(bind)和顶点格式。缓冲区对象仍然是数据存储的持有者。

所以不,不要这样做。

关于c++ - 何时删除缓冲区对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15284561/

相关文章:

java - 带纹理的 VBO,没有弃用的功能

c++ - 我的 getNumber() 函数有什么问题?

OPENGL ARB_occlusion_query 遮挡剔除

c++ - + 头文件,在定义 block 中包含文件或仅在文件顶部

windows - 如何从Mesa3D隐式获取opengl 4.2

c++ - 简单的彩色 3D 棱镜

opengl - JOGL VBO,glDrawElements 的替代品

c++ - 什么是 glVertexPointer 中的步幅,VBO 中的 glTexCoordPointer

c++ - OpenCV 通过子矩阵改变矩阵

c++ - 避免编译 ISO C++