Использование масок в OpenGL ES 2.0 для приложений iOS - PullRequest
2 голосов
/ 15 октября 2011

У меня есть приложение, в котором я хочу, чтобы пользователь рисовал в одной определенной области экрана. Для этого я использую рисунок маски, который является черным в области рисования и прозрачным в области без рисования. Таким образом, пользователь может рисовать только в области экрана внутри маски и внутри черной области маски.

Я попытался реализовать его через буфер трафарета и изменил некоторый код из примера проекта GLPaint: http://pastebin.com/94MBr1Su

Однако я до сих пор не понимаю, как использовать трафаретные буферы. Может ли кто-нибудь помочь мне с примерами кода буфера трафарета для моей проблемы? Кроме того, есть ли способ реализовать это без трафаретных буферов?

1 Ответ

1 голос
/ 17 апреля 2013

Поскольку ваша маска является текстурой, буфер трафарета не очень хорошая идея.

  • во время рендеринга маски вы должны использовать "discard;" для прозрачных пикселей в вашем фрагментном шейдере
  • приветствуем проблемы сглаживания

Для вашего любопытства приведем код для настройки маски с буфером трафарета:

const bool invert_mask = false; // allow to draw inside or outside mask
unsigned mask_id = 1; // you can use this code multiple time without clearing stencil, just increment mask_id

glEnable(GL_STENCIL_TEST);
// write on stencil_mask
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
glStencilFunc(GL_ALWAYS, mask_id, 0);

// remove depth test and color writing
glDepthMask(GL_FALSE);
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);


// TODO: draw geometry of mask here. (if you use a texture, dont forget to use discard in the shader 


// enabled depth & color writing
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glDepthMask(GL_TRUE);

// no stencil write
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
// test stencil value
glStencilFunc(invert_mask ? GL_NOTEQUAL : GL_EQUAL, mask_id, 0xff);


// TODO: draw  "clipped" geometry here


// finally, remove stencil test
glDisable(GL_STENCIL_TEST);

Самый простой способ - НЕ ИСПОЛЬЗОВАТЬ ТРАДИЦИЮ. Создайте текстуру в натуральную величину, напишите свою маску внутри. Затем свяжите его в свой фрагментный шейдер:

uniform LOW_P sampler2D u_diffuse_sampler;
uniform LOW_P sampler2D u_mask_sampler;
varying mediump vec2 v_texcoord;

void main(void) {
    gl_FragColor = texture2D(u_diffuse_sampler, v_texcoord) * texture2D(u_mask_sampler, v_texcoord).r;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...