Как маска влияет на стоимость трафарета в соответствии с операцией трафарета?
Документация в pdf справочного OpenGL (спецификации OpenGL 3.3 и 4.5) не очень ясна о том, что происходит с сохраненным значением трафарета, когда применяется маска.
В примере Если у меня есть следующая маска:
glStencilMask( 0x06);
и хранится в буфере трафарета уже есть это значение:
0x06
Если трафаретная операция GL_INCR_WRAP
что должно произойти, если StencilOp правильно вызван на этом пикселе?
В основном у меня есть маска:
00000110
и значение
00000110
и я пытаюсь увеличить его, это завернутый?
00000010
или это просто обнулено? (00000110 + 1) & mask
00000000
1 ответ
Раздел 17.4.2 "Точный контроль обновлений буфера" спецификации ядра OpenGL 4.5 гласит:
Команды
void StencilMask( uint mask );
void StencilMaskSeparate( enum face, uint mask );
контролировать запись определенных битов в трафаретной плоскости. Наименее значимые битыmask
где s - количество битов в буфере трафарета, укажите целочисленную маску. Если в этой маске появляется 1, соответствующий бит в буфере трафарета записывается; где появляется 0, бит не записывается.
glStencilMask()
Параметр контролирует, какие битовые плоскости записываются в буфер трафарета. Это не контролирует то, что читается, или как glStencilOp
работает.
Раздел 17.3.5 "Тест трафарета" гласит (мой акцент):
В целях увеличения и уменьшения биты трафарета рассматриваются как целое число без знака. Увеличение или уменьшение с насыщением ограничивает значение трафарета в 0 и максимальное представимое значение. Увеличение или уменьшение без насыщения будет перенесено так , что при увеличении максимального представимого значения будет получено 0, а при уменьшении 0 получится максимальное представимое значение.
Маска трафарета сама по себе не имеет отношения к этой стадии конвейера. Он применяется только тогда, когда фрагмент, наконец, записывается в кадровый буфер, как и все gl*Mask()
функции.
Таким образом, имея значение 0110
в буфере и применяя GL_INCR_WRAP
приводит к 0111
и когда это записывается в буфер, маска применяется, так что вы в конечном итоге в конечном итоге 0110
снова (а не 0).
Также обратите внимание, что есть также mask
параметр в glStencilFunc()
определение битовой маски, которая будет применена перед проверкой трафарета. Еще раз процитирую раздел 17.3.5: (мой акцент):
StencilFunc
а такжеStencilFuncSeparate
возьмите три аргумента, которые контролируют, пройден ли тест трафарета или нет.ref
является целочисленным ссылочным значением, которое используется в сравнении трафарета без знака. Операции сравнения трафарета и запросыref
Зафиксируйте его значение в диапазоне [0; 2^s - 1], где s - количество битов в буфере трафарета, присоединенном к буферу кадров рисования. Наименее значимые битыmask
побитовое И с и ссылкой, и сохраненным значением трафарета, и получающиеся маскированные значения являются теми, которые участвуют в сравнении, управляемомfunc
,
Поэтому, если вы хотите обернуть вокруг некоторого значения 2^n-1, вы можете просто проигнорировать дополнительные биты в буфере трафарета и просто проверить эти биты в тесте трафарета.