Программирование игр, создание игрового движка, OpenGL, DirectX, физика, форум
GameDev.ru / Программирование / Форум / glDeleteBuffers() и glDeleteTextures() не освобождают память (upd.: освобождают; опечатка - два одинаковых индекса, дважды создавался VAO, а удалялся только один) (3 стр)

glDeleteBuffers() и glDeleteTextures() не освобождают память (upd.: освобождают; опечатка - два одинаковых индекса, дважды создавался VAO, а удалялся только один) (3 стр)

Страницы: 1 2 3 4 Следующая »
DampireУчастникwww20 мар. 201818:31#30
foxes
GL_ARRAY_BUFFER - vbo (vertex buffer object), GL_ELEMENT_ARRAY_BUFFER - ebo/ibo (element/index buffer object), Vertex Array Object aka VAO - это совершенно иной объект.
Роман ШуваловУчастникwww20 мар. 201818:32#31
Dampire
> Сделай один
Ну не совсем один, а по одному на каждый шейдер и на каждую конфигурацию атрибутов вершин. Наверное, так и надо делать. Хочется услышать подтверждение кого-то, кто знает наверняка.

foxes
Я не понял, что ты имеешь в виду.
Массив с геометрией - в GL_ARRAY_BUFFER
Массив с индексами вершин - в GL_ELEMENT_ARRAY_BUFFER_ARB
Ни то, ни другое к VAO это не имеет отношения.

А вот набор из glEnableVertexAttribArray/glVertexAttribPointer как раз-таки хранится в VAO. (Без, вроде бы, привязки к VBO/IBO)

foxesПостоялецwww20 мар. 201818:33#32
Dampire
Роман Шувалов
Казалось бы.
Интерфейсы у буферов и массива вершин разные, а настраиваются и работают одинаково.

Правка: 20 мар. 2018 18:36

DampireУчастникwww20 мар. 201818:37#33
Роман Шувалов
> а по одному на каждый шейдер и на каждую конфигурацию атрибутов вершин
Что это тебе даст? Ты все равно после каждой привязки vbo будешь перенастраивать атрибуты. Я года 4 назад тоже думал, что vao это волшебный объект, хранящий лейаут. Хрен там плавал. Он грубо говоря хранит указатели на участки памяти, которые задаются в момент glEnableVertexAttribArray/glVertexAttribPointer. И если ты привязывешь другой vbo - ничего не меняется, надо снова настраивать атрибуты. Потому что vbo хранится в глобальном стейте, а не внутри vao. VAO только читает его из глобального стейта в момент настройки.

Правка: 20 мар. 2018 18:38

Роман ШуваловУчастникwww20 мар. 201819:07#34
Dampire
Угу, уже попробовал и понял, что все именно так, как ты написал.

И чё делать? Как удалить VAO? Он жрёт память. (Эмулировать старый вариант - крайняя мера, теряю производительность же. Ну и непорядок, так ведь не должно быть.)

MrShoorУчастникwww20 мар. 201819:12#35
Роман Шувалов
> Ничего нового не узнал. CodeXL даже не показал то, что показывал valgrind:
Но CodeXL он же другие лики показывает.

> P.S. На мысль о том, что VAO вообще удалять не нужно, навело вот вот это:
Удалять точно нужно, и они корректно удаляются. У меня в рантайме десятки тысяч этих VAO может создаваться, и все корректно удаляется.
Возможно перед вызовом glDeleteVertexArrays у тебя не забинжен контекст. Возможно VAO был создан в другом контексте (например во временном).
Так что ищи, но совершенно точно, что проблема в твоем коде.

Правка: 20 мар. 2018 19:12

Vlad2001_MFSПостоялецwww20 мар. 201819:13#36
Роман Шувалов
VAO объединяет VBO и VertexLayout. Есть расширение которое разделяет VBO и VertexLayout путем добавления binding points - ARB_vertex_attrib_binding. Правда это расширение для OpenGL 4.3.
foxesПостоялецwww20 мар. 201819:18#37
Походу у тебя последовательность удаления не верная, ты с начало VAO удалял, а потом уже VBO и тд, может наоборот?
Надо из каждого VAO  свой VBO удалить.
По этому на glGenVertexArrays ругается, поскольку не может корректно удалить VAO без обнуления VBO в нем.

Правка: 20 мар. 2018 19:30

Роман ШуваловУчастникwww20 мар. 201819:44#38
MrShoor
> Но CodeXL он же другие лики показывает.
CodeXL работал в режиме дебага, а не анализатора кадра, и должен был показать всё.

Vlad2001_MFS
> VAO объединяет VBO и VertexLayout.
Ясно, в данном вопросе поставили точку. Один VAO на каждый VBO. Спасибо.

foxes
> Походу у тебя последовательность удаления не верная, ты с начало VAO удалял, а потом уже VBO и тд, может наоборот?
Да я и так, и сяк пробовал. Но не исключаю, что забыл что-нибудь отбиндить. Сейчас перепроверю.

MrShoorУчастникwww20 мар. 201819:49#39
Роман Шувалов
> и должен был показать всё.
Но он же показывает в первую очередь лики OpenGL объектов.

> Один VAO на каждый VBO. Спасибо.
Нет такого правила. У меня на один VBO может быть несколько VAO под каждый шейдер, ибо в каждом шейдере может быть лейаут разный (+сталкивался с багами в OpenGL драйверах, когда даже при одинаковом лейауте оно не работало).

Роман ШуваловУчастникwww20 мар. 201820:09#40
MrShoor
> Нет такого правила.
Ну, я не так сказал, нельзя один VAO на несколько VBO. А наоборот - да, у меня тоже так, в каждом VBO-объекте массив из нескольких VAO, по одному на каждый шейдер, использующий данный VBO.

Итак.

- пробегаемся по всем VAO
- биндим
- glBindBuffer(GL_ARRAY_BUFFER, 0)
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
- для кучи glDisableVertexAttribArray() для каждого атрибута
- glBindVertexArray(0);
- glDeleteVertexArrays(1, &(vaoid[ i ]));

И... фиг, все равно память жрётся.

Как правильно удалить VAO?

Правка: 20 мар. 2018 20:20

foxesПостоялецwww20 мар. 201820:31#41
Роман Шувалов
А в glGetError тоже чисто?

Правка: 20 мар. 2018 20:31

Роман ШуваловУчастникwww20 мар. 201820:43#42
foxes
> glGetError
Чисто.
Vlad2001_MFSПостоялецwww20 мар. 201821:10#43
Роман Шувалов
> Один VAO на каждый VBO
Опять-таки нет. VAO может объединять несколько VBO.
Например:
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vboVerts);
glVertexAttribPointer(0, 3, GL_FLOAT, false, 20, (char*)nullptr + 0);
glVertexAttribDivisor(0, 0);
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, vboTexCoords);
glVertexAttribPointer(1, 2, GL_FLOAT, false, 20, (char*)nullptr + 12);
glVertexAttribDivisor(1, 0);

// Где-то при отрисовке
glBindVertexArray(vao);

А вот как это все выглядело бы при использовании расширения ARB_vertex_attrib_binding:

glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glEnableVertexAttribArray(0);
glVertexAttribFormat(0, 3, GL_FLOAT, false, 0);
glVertexAttribBinding(0, 0);
glVertexBindingDivisor(0, 0);
glEnableVertexAttribArray(1);
glVertexAttribFormat(1, 2, GL_FLOAT, false, 12);
glVertexAttribBinding(1, 1);
glVertexBindingDivisor(1, 0);

// Где-то при отрисовке
glBindVertexArray(vao);
glBindVertexBuffer(0, vboVerts, 0, 20);
glBindVertexBuffer(1, vboTexCoords, 0, 20);

glVertexAttribFormat
glVertexAttribBinding
glVertexBindingDivisor
glBindVertexBuffer

MrShoorУчастникwww20 мар. 201821:14#44
Роман Шувалов
> - пробегаемся по всем VAO
> - биндим
> - glBindBuffer(GL_ARRAY_BUFFER, 0)
> - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
> - для кучи glDisableVertexAttribArray() для каждого атрибута
> - glBindVertexArray(0);
> - glDeleteVertexArrays(1, &(vaoid[ i ]));
Я этого ничего не делаю. Просто зову glDeleteVertexArrays. Единственно, что у меня объект, инкапуслирующий VAO удерживает ссылки на VBO, а это значит, что glDeleteVertexArrays у меня вызовется гарантированно раньше чем glDeleteBuffers (хотя насколько я знаю можно даже наоборот делать, и ничего страшного не произойдет).

Роман Шувалов
> Как правильно удалить VAO?
Убедись, что код с glDeleteVertexArrays вообще вызывается, добавив например вывод в консоль.
Еще не красиво выглядит, что у тебя не зануляются дескрипторы:

for (int i = 0; i < RS_MAX_SHADERS; i++) {
    if ( vaoid[i] ) {
        glDeleteVertexArrays(1, &(vaoid[i]));
        vaoid[i] = 0; //лучше добавить это, чтобы логика дальше не была нигде поломана
    };
};
Ну и наконец включен ли Break On OpenGL Errors и Break On Detected Errors в CodeXL?
Страницы: 1 2 3 4 Следующая »

/ Форум / Программирование игр / Графика

2001—2018 © GameDev.ru — Разработка игр