OpenGL-maska z wieloma teksturami

Zaimplementowałem maskowanie w OpenGL zgodnie z następującą koncepcją:

    Maska składa się z czarno-białych kolorów.
  • Tekstura pierwszego planu powinna być widoczna tylko w białych częściach maski.
  • Tekstura tła powinna być widoczna tylko w czarnych częściach maski.

Mogę sprawić, że biała lub czarna część będzie działać tak, jak powinna, używając glBlendFunc (), ale nie obu jednocześnie, ponieważ warstwa pierwszoplanowa nie tylko się miesza na maskę, ale także na warstwę tła.

Czy jest ktoś, kto wie jak najlepiej to osiągnąć? Przeszukałem Sieć i przeczytałem coś o shaderach fragmentów. To jest droga?

Author: genpfault, 2011-02-24

1 answers

To powinno zadziałać:

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);
To jest dość trudne, więc powiedz mi, jeśli coś jest niejasne.

Nie zapomnij zażądać bufora alfa podczas tworzenia kontekstu GL. W przeciwnym razie możliwe jest uzyskanie kontekstu bez bufora Alfa.

Edit: tutaj zrobiłem ilustrację. ilustracja

Edit: od napisania tej odpowiedzi nauczyłem się, że są lepsze sposoby na to:

  • jeśli ograniczasz się do stałej funkcji OpenGL pipeline, użyj środowisk tekstur
  • jeśli możesz używać shaderów, użyj shadera fragmentów.

Sposób opisany w tej odpowiedzi działa i nie jest szczególnie gorszy pod względem wydajności niż te 2 lepsze opcje, ale jest mniej elegancki i mniej elastyczny.

 37
Author: Stefan Monov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-05 15:39:15