OpenGL, выбор имен всех единых блоков в вашей программе

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

0 Camera
1 Model
2 Material
3 Lights

В настоящий момент я связываюсь вручную, нахожу индекс именованного блока с glGetUniformBlockIndex, а затем привязывая его к glUniformBlockBinding. Я хотел бы сделать выбор из всех имен блоков в моей шейдерной программе. Когда я повторяю с glGetActiveUniformsiv, я получаю список всех униформ, который исключает имена блоков.

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

5 голосов | спросил Robinson 7 FebruaryEurope/MoscowbThu, 07 Feb 2013 18:46:36 +0400000000pmThu, 07 Feb 2013 18:46:36 +040013 2013, 18:46:36

1 ответ


5

Это довольно легко; просто API интроспекции программ для получения индексов. Сначала спросите, сколько равномерных блоков есть:

GLint numBlocks;
glGetProgramiv(prog, GL_ACTIVE_UNIFORM_BLOCKS, &numBlocks);​

Все ваши индексы единичного блока находятся в полуоткрытом диапазоне [0, numBlocks). Итак, идите через них и получите их имена.

std::vector<std::string> nameList;
nameList.reserve(numBlocks);
for(int blockIx = 0; blockIx < numBlocks; ++blockIx)
{
    GLint nameLen;
    glGetActiveUniformBlockiv​(prog, blockIx, GL_UNIFORM_BLOCK_NAME_LENGTH, &nameLen);

    std::vector<GLchar> name; //Yes, not std::string. There's a reason for that.
    name.resize(nameLen);
    glGetActiveUniformBlockName​(prog, blockIx, nameLen, NULL, &name[0]);

    nameList.push_back(std::string());
    nameList.back().assign(name.begin(), name.end() - 1); //Remove the null terminator.
}

Кстати, если вы делаете это, потому что считаете, что это быстрее, остановитесь. Во-первых, производительность не имеет значения, поскольку это одноразовый код настройки. Во-вторых, вы делаете это, возможно, не более 4-8 блоков. Это никак не повлияет на фактическую производительность. Так что, действительно, нет причин не просто получать индексы по имени, если это то, что вы в конечном итоге делаете. API интроспекции предназначен, когда вы не знаете , что там есть.

ответил Nicol Bolas 7 FebruaryEurope/MoscowbThu, 07 Feb 2013 22:40:49 +0400000000pmThu, 07 Feb 2013 22:40:49 +040013 2013, 22:40:49

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132