Opengl, DrawArrays без привязки VBO

Я визуализирую массив точек с помощью пользовательского вершинного шейдера. Шейдеры выглядят так:

void mainVP()
in varying int    in_vertex_id : VERTEXID
{
    foo(in_vertex_id);
}

Так что единственное, что мне нужно - это идентификатор вершины. Но мне нужно много вершин, и я не хочу хранить для них поддельные VBO (это занимает около 16 МБ памяти).

Я попытался запустить свой код без привязки к VBO. Оно работает. Итак, мой рендеринг выглядит так:

size_t num_vertices = ...
glDrawArrays(GL_POINTS, 0, num_vertices);

Но могу ли я быть уверен, что рендеринг без привязки VBO безопасен?


person Roman Silakov    schedule 07.11.2011    source источник


Ответы (1)


Но могу ли я быть уверен, что рендеринг без привязки VBO безопасен?

Вы не можете.

В основном профиле спецификации OpenGL (3.2 и выше) четко указано, что это должно быть разрешено, что вы можете отображать с отключенными всеми атрибутами. Профиль совместимости спецификации OpenGL или любых версий до 3.2 так же четко указывает, что вы не можете сделать это.

Конечно, это все равно не имеет значения. Драйверы NVIDIA позволяют сделать это на любой версии и профиле OpenGL. Драйверы ATI не позволяют вам делать это в любой версии или профиле OpenGL. Они оба являются ошибками драйверов, просто по-разному.

Вам просто нужно признать, что вам нужен фиктивный атрибут вершины. Однако:

Но мне нужно много вершин, и я не хочу хранить для них поддельные VBO (это занимает около 16 МБ памяти).

Пустой атрибут будет занимать 4 байта (одно число с плавающей запятой или 4-вектор нормализованных байтов. Помните: вам не нужны данные). Таким образом, вы можете уместить 4 миллиона из них в 16 МБ.

В качестве альтернативы вы можете использовать инстансный рендеринг через glDrawArraysInstanced. Там вы просто визуализируете одну вершину, но с num_vertices экземплярами. Конечно, ваш шейдер должен будет использовать идентификатор экземпляра.

person Nicol Bolas    schedule 07.11.2011
comment
glDrawArraysInstanced — отличный совет! Проверил сегодня. Оно работает. Для 4 миллионов вершин скорость такая же, как у glDrawArrays. Спасибо. - person Roman Silakov; 08.11.2011
comment
Эта информация устарела? Я только что попробовал программу, которая рендерит пустой VAO на Radeon, и она отлично работала, как и на графическом процессоре Nvidia. Ориентация на OpenGL 4.3/GLSL 430. - person Vandroiy; 26.03.2017
comment
@Vandroiy: Может быть. Прошло более 5 лет с тех пор, как я проверил. А как же Интел? - person Nicol Bolas; 26.03.2017
comment
Я только что запустил его на графическом процессоре Intel; там тоже проблем не увидел. Если я правильно понимаю, проблема возникнет, если я создам новый VAO, привяжу его, не вызову glEnableVertexAttribArray, а вызову glDrawArrays? Не уверен, что я что-то неправильно понимаю. Но было бы не слишком удивительно, если бы это просто работало; В последние годы поддержка OpenGL в целом улучшилась. - person Vandroiy; 26.03.2017