OpenGL связывает много текстур при рисовании одной сетки

Я хотел бы связать, например, 80 текстур на одну сетку и поместить его в мой VBO.
Как мне этого добиться?

Я читал, что glActiveTexture умеет это делать, однако позволяет использовать максимум 32 текстуры (зависит от графического процессора).

Мой код VBO:

//Generating VBO
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, vertices.size()*sizeof(Vector3d) + textureCoords.size()*sizeof(Vector2d), 0, GL_STATIC_DRAW);
glBufferSubData(GL_ARRAY_BUFFER, 0, vertices.size()*sizeof(Vector3d), vertices.data());
glBufferSubData(GL_ARRAY_BUFFER, vertices.size()*sizeof(Vector3d), textureCoords.size()*sizeof(Vector2d), textureCoords.data());

glGenBuffers(1, &IND);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IND);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size()*sizeof(unsigned int), &indices[0], GL_STATIC_DRAW);

//Drawing VBO:
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glBindBuffer(GL_ARRAY_BUFFER, VBO);

glVertexPointer(3, GL_DOUBLE, 0, 0);
glTexCoordPointer(2, GL_DOUBLE, 0, (void*)(vertices.size()*sizeof(Vector3d)));

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IND);
glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, (void*)0);

glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);

1

Решение

Связывание многих (100-х) текстур

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

Обновление: вы также можете использовать множество текстурных массивов для хранения текстурных атласов (см. Комментарии и @ Ответ Итана).


Применение нескольких текстур к сетке

Как я скажу VBO, какие лица будут иметь какую текстуру?

Я думаю, что более насущная проблема заключается в том, как вы применяете различные текстуры (или материалы) к одной и той же сетке. Есть несколько вещей, чтобы рассмотреть …

  1. Наиболее распространенным случаем применения нескольких текстур является ситуация, когда каждая хранит разные атрибуты материала, но все они используют одинаковые координаты текстуры / «UV». Например. диффузные, нормальные, зеркальные карты. Я предполагаю, что в крайнем случае, когда у вас есть сотни различных атрибутов, вам нужна текстура массива.
  2. Если каждая текстура должна отображаться по-разному, у вас будет отдельная координата текстуры для каждой вершины VBO для каждой текстуры. Затем вам придется решить, как текстуры взаимодействуют или смешиваются, когда они применяются.
  3. У вас есть полностью отдельные материалы / текстуры на лицо. Обычно на сетке есть только несколько материалов. То, как вы отображаете это в отдельных партиях, сгруппированы по материалам. Свяжите правильную текстуру, установите форму шейдера, нарисуйте треугольные индексы от A до B.
  4. Если почти у каждого лица есть другой материал. Я думаю, это может быть в том случае, если вы рисуете игру на основе тайлов с множеством разных тайлов.
    Проблема здесь в том, что количество вызовов отрисовки становится узким местом,
    так что вам придется объединять разные материалы в один и тот же колл-розыгрыш.
    Вы можете сделать это, сохранив материал по атрибутам вершин, например, добавив цвет вершин VBO.
    Вместо цвета вы можете сохранить идентификатор текстуры для каждой вершины, а если вы используете атлас текстуры, то область в атласе, где находится ваша текстура.
    Это начинает становиться неэффективным, потому что у вас будут одни и те же данные материала, которые хранятся несколько раз в каждой вершине ваших треугольников.
    Чтобы минимизировать накладные расходы, вы могли бы сохранить индекс материала для каждой вершины, который указывает на материал, определенный где-то в таблице (либо в небольшом однородном массиве, либо, если вам нужно больше материалов, другую текстуру).
    Затем добавьте идентификатор текстуры и область атласа к материалу в таблице.

    Надеюсь, этот последний пункт отвечает на ваш вопрос.

2

Другие решения

Если честно, если у вас более 32 текстур для одного меша, у вас, вероятно, гораздо большая проблема, чем проблемы связывания. Но если вы настаиваете на наличии такого количества текстур, у вас есть 2 варианта: Bindless или Texture array. Однако есть и недостатки: Bindless ограничит вашу аппаратную поддержку. Массив текстур требует, чтобы текстуры были одинакового размера и формата. Лично я думаю, что Texture Array — работоспособное решение. Вы можете попытаться изменить размеры текстур, если это возможно, а затем сгруппировать их с одинаковым размером. & форматировать в один массив. Теперь у вас есть 32 массива для работы, и этого должно быть более чем достаточно, например, один массив для всех текстур альбедо, один для всех карт нормалей и т. д. Что касается изменения размера, рассмотрите возможность масштабирования текстур до максимального размера, который у вас есть, или, возможно, разделение на категории, например. маленький Средний Большой. Избегайте произвольных размеров.

2

По вопросам рекламы [email protected]