Pergunta

Estou trabalhando em um jogo para o iPhone que tem um mecânico de desenho/pintura envolvido e estou tendo problemas para tentar criar uma ferramenta que apagarem as coisas já pintadas.

O principal problema é que o fundo está pintado não é uma cor sólida, mas uma imagem ou animação estática. Tentei usar diferentes opções de mistura e operações lógicas no desenho, mas nada parecia funcionar. Eu sou novo no OpenGL, então devo estar perdendo alguma coisa.

Alguma dica?

EDIT: Para fornecer um pouco mais de informação, estou usando texturas para meus pincéis e usando o glvertexPointer () e Gldrawarrays () para renderizá -los. Por exemplo:

glBindTexture(GL_TEXTURE_2D, circleBrush);
glVertexPointer(3, GL_FLOAT, 0, verts);
glTexCoordPointer(2, GL_FLOAT, 0, coords);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

EDIT 2: Infelizmente, os buffers de estêncil não estão disponíveis no iPhone. : (

EDIT 3: Os objetos de estrutura estão disponíveis no iPhone e essa é a estrada que eu segui. Ainda não o implementei totalmente, mas até agora parece que funciona da maneira que eu queria. Obrigado a todos!

Foi útil?

Solução

Desenhe um quadro texturizado em tela cheia sobre sua cena. Quando o usuário desenhar uma pincelada, use glTexSubImage2D Para atualizar a sua textura.

GlReadpixels/GlDrawPixels é lento.

O uso do quadroBufferObjects é ainda melhor, mas duvido que essa extensão esteja disponível no iPhone (então, novamente, não sei ao certo, então talvez tente). O FBO permite que você desenhe diretamente em uma textura como se fosse outro contexto de renderização.

Outras dicas

O buffer de estêncil é a melhor maneira de abordar isso com certeza ... você economizará tempo, CPU e problemas em potencial. .

        //Turn off writing to the Color Buffer and Depth Buffer
        //We want to draw to the Stencil Buffer only
        glColorMask(false, false, false, false);
        glDepthMask(false);

        //Enable the Stencil Buffer
        glEnable(GL_STENCIL_TEST);

        //Set 1 into the stencil buffer
        glStencilFunc(GL_ALWAYS, 1, 0xFFFFFFFF);
        glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);

        //CALL YOUR DRAWING METHOD HERE


        //Turn on Color Buffer and Depth Buffer
        glColorMask(true, true, true, true);
        glDepthMask(true);

        //Only write to the Stencil Buffer where 1 is set
        glStencilFunc(GL_EQUAL, 1, 0xFFFFFFFF);
        //Keep the content of the Stencil Buffer
        glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);

        //CALL OUR DRAWING METHOD AGAIN

Procure este exemplo:http://www.opengl.org/resources/code/samples/glut_examples/examples/stenciltst.c

Aqui está o resultado visual:http://www.opengl.org/resources/code/samples/glut_examples/examples/stenciltst.jpg

Eu impliquei o mesmo tipo de ferramenta de borracha com isso, no Android e no iPhone e funciona como um charme!

Boa sorte !

Felicidades !

Você não dá muita informação, mas suponho que você o armazenasse o que quer que eles "pintem" em um buffer e depois desenhem na tela como esta:

 glWindowPos2i(X, Y);
 glDrawPixels(drawing->Width, drawing->Height, drawing->Format, 
              GL_UNSIGNED_BYTE, drawing->ImageData);

Com o desenho-> imagedata sendo o buffer. O que você poderia fazer é ter um buffer de fundo separado e desenhá -lo primeiro. Em seguida, a ferramenta de apagamento simplesmente será interrompida no buffer de desenho (girando todos os valores, incluindo alfa, todo o caminho).

Para que esta solução funcione, você teria que ativar a mistura e Desligue o teste de profundidade.

 glEnable(GL_BLEND);
 glDisable(GL_DEPTH_TEST);
 glWindowPos2i(X, Y);
 //background never changes
 glDrawPixels(background->Width, background->Height, background->Format, 
              GL_UNSIGNED_BYTE, background->ImageData);
 glWindowPos2i(X, Y);
 glDrawPixels(drawing->Width, drawing->Height, drawing->Format, 
              GL_UNSIGNED_BYTE, drawing->ImageData);
 glEnable(GL_DEPTH_TEST);
 glDisable(GL_BLEND);

É isso que você está procurando?

Você pode usar o buffer de estêncil para esta operação. O buffer de estêncil é um buffer especial que mantém informações para cada pixel, semelhante ao buffer de profundidade. Ao contrário do buffer de profundidade, você decide como o buffer de estêncil é alterado durante o desenho e como ele influencia a decisão de atrair ou não o buffer de cores. Para fazer isso, você pode definir os estados específicos antes de qualquer operação de desenho. Aqui está o que você faz:

  • Na época em que os usuários apagam, desenhe a região "apagada" para o buffer de estêncil (usando o Stencilop, veja abaixo). Você pode usar qualquer função de desenho GL para isso.

  • Em cada passe de renderização, primeiro desenhe o plano de fundo (se você quiser, você pode usar um teste de estêncil negativo aqui para desenhar apenas a parte "apagada" do plano de fundo - pode aumentar o desempenho).

  • Em seguida, ative o teste de estêncil para todas as outras operações de desenho. O OpenGL apenas atrairá apenas as regiões "não-emeradas".

A função para definir como o buffer de estêncil deve influenciar o desenho (ou não): glstarkfunc ()

A função para definir como o próprio buffer de estêncil é influenciado pelo desenho: GlStopyChyop ()

Explicações adicionais, também com os argumentos para estes:http://www.opengl.org/resources/code/samples/sig99/advanced99/notes/node117.html

Usando o modo GLBLENDFUNC (GL_ONE, GL_ZERO) pode earse.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top