OpenGL - маска с несколькими текстурами - PullRequest
15 голосов
/ 24 февраля 2011

Я реализовал маскирование в OpenGL в соответствии со следующей концепцией:

  • Маска состоит из черного и белого цветов.
  • Текстура переднего плана должна быть видна только в беломчасти маски.
  • Фоновая текстура должна быть видна только в черных частях маски.

Я могу заставить белую часть или черную часть работать, как предполагается, используяglBlendFunc (), но не два одновременно, потому что слой переднего плана не только смешивается с маской, но и с фоновым слоем.

Есть ли кто-нибудь, кто знает, как это сделать наилучшим образом??Я искал в сети и читал что-то о фрагментных шейдерах.Это путь?

1 Ответ

37 голосов
/ 24 февраля 2011

Это должно работать:

glEnable(GL_BLEND);
// Use a simple blendfunc for drawing the background
glBlendFunc(GL_ONE, GL_ZERO);
// Draw entire background without masking
drawQuad(backgroundTexture);
// Next, we want a blendfunc that doesn't change the color of any pixels,
// but rather replaces the framebuffer alpha values with values based
// on the whiteness of the mask. In other words, if a pixel is white in the mask,
// then the corresponding framebuffer pixel's alpha will be set to 1.
glBlendFuncSeparate(GL_ZERO, GL_ONE, GL_SRC_COLOR, GL_ZERO);
// Now "draw" the mask (again, this doesn't produce a visible result, it just
// changes the alpha values in the framebuffer)
drawQuad(maskTexture);
// Finally, we want a blendfunc that makes the foreground visible only in
// areas with high alpha.
glBlendFunc(GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA);
drawQuad(foregroundTexture);

Это довольно сложно, поэтому скажите мне, если что-то неясно.

Не забудьте запросить альфа-буфер при создании контекста GL.В противном случае можно получить контекст без альфа-буфера.

Редактировать: Здесь я сделал иллюстрацию.illustration

Редактировать: Со времени написания этого ответа я узнал, что есть лучшие способы сделать это:

  • Если вы ограниченыКонвейер с фиксированной функцией OpenGL, используйте текстурные среды
  • Если вы можете использовать шейдеры, используйте фрагментный шейдер.

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

...