何时删除缓冲区对象?
Posted
技术标签:
【中文标题】何时删除缓冲区对象?【英文标题】:When to delete buffer object? 【发布时间】:2013-03-08 00:25:35 【问题描述】:我从this question 了解到,一旦程序链接,着色器对象就可以被分离和删除。
缓冲区对象的行为是否与 VAO 相似?我可以在 VAO 初始化后删除它们(在下面Scene::Scene()
的末尾)还是应该保留我的代码,每次我想使用它们时绑定它们?
场景.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;
【问题讨论】:
【参考方案1】:VAO 不存储数据。它们存储缓冲区对象绑定和顶点格式。缓冲区对象仍然是数据存储的持有者。
所以不,不要那样做。
【讨论】:
所以,我不能在那里删除它们,但我不必绑定/取消绑定每一帧(因为 VAO 持有绑定)? 正确。这首先是 VAO 背后的基本原理,用一个来替换潜在的大量绑定调用。以上是关于何时删除缓冲区对象?的主要内容,如果未能解决你的问题,请参考以下文章