Pregunta

Estoy trabajando en un juego para iPhone que tiene una mecánica de dibujo / pintura involucrada y estoy teniendo problemas para intentar crear una herramienta que borre las cosas ya pintadas.

El problema principal es que el fondo que se está pintando no es un color sólido sino una imagen estática o animación. Intenté usar diferentes opciones de fusión y operaciones lógicas en el dibujo, pero nada parecía funcionar. Soy nuevo en OpenGL, así que me falta algo.

¿Algún consejo?

EDITAR: para dar un poco más de información, estoy usando texturas para mis pinceles y usando glVertexPointer () y glDrawArrays () para representarlos. Por ejemplo:

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: Desafortunadamente, los buffers de plantilla no están disponibles en el iPhone. : (

EDIT 3: los objetos Framebuffer están disponibles en el iPhone y ese es el camino que tomé. Todavía no lo he implementado por completo, pero hasta ahora parece que funciona de la manera que quería. ¡Gracias a todos!

¿Fue útil?

Solución

Dibuja un quad con textura de pantalla completa sobre tu escena. Cuando el usuario dibuja un trazo de pincel, use glTexSubImage2D para actualizar su textura.

glReadPixels / glDrawPixels es lento.

Usar FrameBufferObjects es aún mejor, pero dudo que esta extensión esté disponible en el iPhone (por otra parte, no estoy seguro, así que quizás lo intente). Los FBO le permiten dibujar directamente en una textura como si fuera otro contexto de representación.

Otros consejos

Stencil Buffer es la mejor manera de abordar esto con seguridad ... Ahorrará tiempo, CPU y problemas potenciales ..., están disponibles en Iphone, solo tiene que crear una superficie OpenGlES 2.0 (no gles 1.0 o 1.1).

        //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

Busque este ejemplo: http://www.opengl.org/resources/code/samples /glut_examples/examples/stenciltst.c

Aquí está el resultado visual: http://www.opengl.org/resources/code/samples /glut_examples/examples/stenciltst.jpg

¡He implementado el mismo tipo de herramienta de borrador con esto, tanto en Android como en iPhone, y funciona de maravilla!

¡Buena suerte!

¡Salud!

No das mucha información, pero supongo que estás almacenando lo que sea que "pinten" en un búfer y luego dibujarlo en la pantalla de esta manera:

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

Con drawing- > ImageData siendo el búfer. Lo que podría hacer es tener un búfer de fondo separado y dibujarlo primero. Luego, la herramienta de borrado simplemente blanqueará el búfer de dibujo (girando todos los valores, incluido alfa, completamente).

Para que esta solución funcione, debe activar la mezcla y desactivar las pruebas de profundidad .

 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);

¿Es eso lo que estás buscando?

Puede usar el búfer de plantilla para esta operación. El búfer de plantilla es un búfer especial que contiene información para cada píxel, similar al búfer de profundidad. A diferencia del búfer de profundidad, usted decide cómo se altera el búfer de la plantilla al dibujar y cómo influye en la decisión de dibujar en el búfer de color o no. Para hacerlo, puede establecer los estados específicos antes de cualquier operación de dibujo. Esto es lo que haces:

  • En el momento en que los usuarios borran, dibuja el " borrado " región en el stencil buffer (usando StencilOp, ver abajo). Puedes usar cualquier dibujo GL función para eso.

  • En cada pasada de renderizado, primer sorteo el fondo (si quieres, puedes use una prueba de plantilla negativa aquí para solo dibuje el " borrado " parte de fondo - puede aumentar rendimiento).

  • Luego, habilite la prueba de plantilla para todos Otras operaciones de dibujo. OpenGL entonces solo atraerá a la " no borrado " regiones.

La función para establecer cómo el búfer de la plantilla debe influir en el dibujo (o no): glStencilFunc ()

La función para establecer cómo el búfer de stencil se ve influenciado por el dibujo: glStencilOp ()

Explicación adicional, también con los argumentos para estos: http://www.opengl.org/resources/ code / samples / sig99 / advanced99 / notes / node117.html

El uso del modo glBlendFunc (GL_ONE, GL_ZERO) puede ser útil.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top