Войти
ПрограммированиеФорумГрафика

Функционал OpenGL 3.2 core

Страницы: 1 2 Следующая »
#0
15:55, 2 дек. 2018

Привет всем!

Я заметил, что на этом форуме есть сильные и опытные разработчики, хорошо знающие функционал OpenGL. Ребята, надеюсь я не слишком злоупотреблю вашим вниманием - у меня есть два вопроса, скорее теоретических, но явно в спецификациях по OpenGL я не нашел на них ответов, помогите разобраться.

Чтобы получить максимальный FPS загружаем данные VBO в память GPU - используя функции glBufferData и glBufferSubData. Все объекты грузим в один общий VBO и рисуем за один вызов glDrawElements. Все круто, FPS высокий, но вот возникла необходимость что-то нарисовать дополнительным вызовом glDrawElements.

Первый вопрос по функции glDrawElements/glDrawRangeElements - в них последний параметр это указатель на местоположение (начало блока), в котором хранятся данные/индексы. Я почему-то не нашел, как указать кусок (фрагмент) данных из памяти GPU НЕ от начала. Если индексы и данные расположены в GPU, то они обрабатываются фрагментом ВСЕГДА ТОЛЬКО ОТ НАЧАЛА области и до указанной границы. Собственно вопрос: можно ли рисовать объекты несколькими вызовами glDrawElements из одного VBO указывая разные блоки, или для каждого объекта надо либо заводить отдельный VBO, либо адресовать пользовательский массив данных в памяти приложения? Как правильно делать в таких случаях?

Второй вопрос. Из-за него, собственно, и возник первый - использование glStencilFunc для идентификации объектов:

 for(int i = 0; i < obj_count; i++) {
    glStencilFunc(GL_ALWAYS, i + 1, -1);
    draw_object(i);
  }

- если рисовать типовой террайн в виде меш-сетки, то чтобы использовать glStencilFunc для адресации отдельных ячеек, надо каждую ячейку рисовать отдельным вызовом чередуя с glStencilFunc или я чего-то упустил? Ведь если каждую ячейку меша рисовать отдельным вызовом - это же какие будут "тормоза"!


#1
16:06, 2 дек. 2018

bigov
> Первый вопрос

http://docs.gl/gl3/glDrawElementsBaseVertex

> если рисовать типовой террайн в виде меш-сетки, то чтобы использовать
> glStencilFunc для адресации отдельных ячеек,

тебе нужно найти треугольник в который попал курсор ? можно PrimitiveID писать в unsigned target или аналитически считать

стенсил же не резиновый :)

#2
18:38, 2 дек. 2018

bigov
можно через массив индексов указывать какие вертексы обрабатывать. Их придется каждый кадр обновлять и прокачивать по шине, но это не слишком большая нагрузка.

#3
1:21, 3 дек. 2018

>Ведь если каждую ячейку меша рисовать отдельным вызовом

в OpenGL3.2? Это мобильные игры/браузерные, там пара сотен(несколько тысяч максимум) полигонов на сцену максимум, нагрузка менее 5%(на все) будет даже на мобилках

про ID выше сказали, там тоже просто

#4
4:14, 3 дек. 2018

g-cont
> можно через массив индексов указывать ...

Если не трудно, "набросай" пару строчек для примера. Я не понял.

innuendo
> http://docs.gl/gl3/glDrawElementsBaseVertex

мимо. Все равно выводится один объект (или непрерывная группа) от начала буфера. Нельзя вывести вторым и последующими вызовами другие объекты - не с начала буфера.

innuendo
> стенсил же не резиновый :)

В каком смысле? Он соответствует числу пикселей на экране, можно хоть всю сцену на него завязать - все равно останутся попиксельные записи только ID видимых объектов. Все остальные будут просто перезаписаны или не попадут в него (если объект за пределами видимости).

#5
4:19, 3 дек. 2018

bigov
> В каком смысле?

8 битов

#6
4:23, 3 дек. 2018

innuendo
я понял - это про максимальное значение ID. Да -

The buffer is per pixel, and works on integer values, usually with a depth of one byte per pixel.
#7
4:34, 3 дек. 2018

bigov
> Все объекты грузим в один общий VBO и рисуем за один вызов glDrawElements. Все
> круто,

на самом деле не очень правильно всё в одном большом буфере … лучше тогда уже несколько

#8
4:48, 3 дек. 2018

innuendo
Да, теперь я вижу что сложную сцену в один буфер пихать получается "геморно" - проще будет дробить на несколько. Спасибо.

#9
8:41, 3 дек. 2018

bigov
> > http://docs.gl/gl3/glDrawElementsBaseVertex
>
> мимо. Все равно выводится один объект (или непрерывная группа) от начала буфера. Нельзя вывести вторым и последующими вызовами другие объекты - не с начала буфера.
Все там работает, glDrawElementsBaseVertex для этого и придумали что-бы была возможность выводить часть буфера не сначала.
Поробуй сделать квадрат и побей его на 2 треугольника. Выведи второй, указав смещение с 4 вершины, он как раз и будет не сначала буфера.

#10
13:11, 3 дек. 2018

Andrey
> Все там работает...

Действительно, я неверно понял описание

glDrawElementsBaseVertex behaves identically to glDrawElements except that the ith element transferred by the corresponding draw call will be taken from element indices + basevertex of each enabled array. ...

Посчитав,что речь идет только об индексном массиве. Да, работает.

#11
13:42, 3 дек. 2018

Danilw
>... там пара сотен(несколько тысяч максимум) полигонов ...

Ну да, у меня сцена из 6 тысяч полигонов, если все рисовать за один проход:

glDrawElements(GL_TRIANGLES, render_points, GL_UNSIGNED_INT, nullptr);

рендерится с FPS=1800. А если рендерить пошагово:

GLsizei max = (render_points / indices_per_quad) * vertices_per_quad;
for (GLsizei i = 0; i < max; i += vertices_per_quad)
{
    glDrawElementsBaseVertex(GL_TRIANGLES, indices_per_quad, GL_UNSIGNED_INT, nullptr, i);
}

то  FPS падает всего до 1400 - не так уж и много. Отличная новость, всем спасибо!

#12
14:12, 3 дек. 2018

однако :)

#13
15:47, 3 дек. 2018

bigov
> то  FPS падает всего до 1400 - не так уж и много
28 % ? на другой геометрии будет все 40 и более

#14
16:39, 3 дек. 2018

Andrey
С какого перепугу? Это тебе не неубогое апи.

Кстати, кто тебя просадки учил в процентах измерять?
Страницы: 1 2 Следующая »
ПрограммированиеФорумГрафика

Тема в архиве.