Как работает трафаретный буфер в OpenGL

Я пытаюсь добиться следующего эффекта в OpenGL, как показано в данной ссылке http://commons.wikimedia.org/wiki/File:OpenGL_Tutorial_Stencil.png, ниже также приведен фрагмент кода, это официальное руководство по openGL wikipedia.

Несмотря на то, что он содержит код и комментирует объяснения, мне все еще трудно понять логику работы буфера трафарета в openGL. Напоминаю, что перед тем, как приступить к трафарету, я прочитал большинство инструкций из красной книги, так что я знаю и знаю, как работает glStencilFunc, glStencilOp, glStencilMask и т. Д., Но все еще есть некоторые неясные и неясные вещи в мой разум связан с трафаретом.

Вот мое пошаговое руководство по интерпретации кода:

  1. С glStencilFunc(GL_NEVER, 1, 0xFF); glStencilOp(GL_REPLACE, GL_KEEP, GL_KEEP); Я считаю, что тестирование по трафарету всегда будет проходить, и провал теста по трафарету приведет к заполнению 1 с в буфере трафарета из-за инструкций, установленных в glStencilOp

  2. Если предыдущие кодовые блоки (# 1) устанавливают все пиксели в буфере трафарета, чего мы достигаем glStencilMask(0xFF); вызов процедуры. Гарантируем ли мы, что все 1 успешно записаны в буфер трафарета или что на самом деле?

  3. Рисуем круг, затем включаем маски, но на этот раз glStencilMask(0x00)Вот одна из путаниц, я думаю, что это связано с предотвращением переопределения значений буфера трафарета новыми значениями, но комментарии кода говорят, что это просто заполняет буфер трафарета нулями.

  4. Наконец, если вы не измените какое-либо значение (из-за glStencilMask(0x00) ) в буфере трафарета, какой смысл иметь

    // fill 0s
    glStencilFunc(GL_EQUAL, 0, 0xFF);
    /* (nothing to draw) */
    // fill 1s
    glStencilFunc(GL_EQUAL, 1, 0xFF);

Основное тело программы:

 void onDisplay() {
glClearColor(0.1, 0.1, 0.1, 1.0);
glClear(GL_COLOR_BUFFER_BIT);

glClear(GL_DEPTH_BUFFER_BIT);
glEnable(GL_STENCIL_TEST);
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
glDepthMask(GL_FALSE);
glStencilFunc(GL_NEVER, 1, 0xFF);
glStencilOp(GL_REPLACE, GL_KEEP, GL_KEEP);  // draw 1s on test fail (always)

// draw stencil pattern
glStencilMask(0xFF);
glClear(GL_STENCIL_BUFFER_BIT);  // needs mask=0xFF
draw_circle();

glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glDepthMask(GL_TRUE);
glStencilMask(0x00);
// fill 0s
glStencilFunc(GL_EQUAL, 0, 0xFF);
/* (nothing to draw) */
// fill 1s
glStencilFunc(GL_EQUAL, 1, 0xFF);

draw_scene();

glDisable(GL_STENCIL_TEST);

glutSwapBuffers();
}

1

Решение

glStencilMask(0xFF) аналогично glColorMask(true, true, true, true) или же glDepthMask(true) functions — 0xFF — это маска, которая побитовая И применяется к любым трафаретным данным перед их записью в буфер трафарета. Поэтому через glStencilMask(0xFF)мы гарантируем, что любое значение, которое OpenGL пытается записать в буфер трафарета, будет успешно записано.

glStencilMask(0x00): когда 0x00 побитовое И с любым байтом, выход всегда будет равен 0. Таким образом, каждый раз, когда будут пытаться записать байты в буфер трафарета, записанный байт будет равен 0. По сути, на этом этапе он просто гарантирует, что в буфере трафарета НЕ записаны новые данные.

Согласно моей интерпретации, раздел с /* (nothing to draw) */ комментарий, где вы будете рисовать материалы, предназначенные для вне трафарета проверен круг. 0 — это значение по умолчанию в буфере трафарета; поэтому, поскольку область в круге помечена как 1, пиксели, которые находятся за пределами круга, пройдут, а пиксели внутри будут отброшены. Это просто заполнитель.

Я считаю, что когда в комментариях говорится // fill 0s, что они имеют в виду, что «все, что нарисовано здесь, заполнит часть буфера трафарета это установлено в 0. Учитывая призыв к glStencilFunc с GL_EQUAL а также 0 в качестве аргументов, это то, что произойдет. Я также уверен, что когда в комментариях говорится // fill 1s они означают то же самое, но с частью буфера трафарета, установленной в 1 (то есть область, где круг был нарисован в буфере трафарета).

1

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

Других решений пока нет …

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