OpenGL: How to implement the eraser tool?

I am working on a game for the iPhone that uses the drawing / drawing mechanism, and I am having problems trying to create a tool that will erase already painted things.

The main problem is that the drawn background is not a solid color, but a static image or animation. I tried using different blending options and logical drawing operations, but nothing worked. I am new to OpenGL, so something is missing me.

Any tips?

EDIT. To give a little more information, I use textures for my brushes and using glVertexPointer () and glDrawArrays () to render them. For instance:

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: Unfortunately, stencil buffers on the iPhone are not available .:(

EDIT 3: Framebuffer objects are available on the iPhone, and that was the road I took. I have not fully implemented it yet, but so far it is similar to how I did it. Thanks everyone!

+4
source share
5 answers

Draw a full-screen textured square above your scene. When the user draws a brush stroke, use glTexSubImage2D to update the texture.

glReadPixels / glDrawPixels is slow.

Using FrameBufferObjects is even better, but I doubt this extension is available on the iPhone (again, I don’t know for sure, so maybe try it). FBO allows you to draw directly into the texture, as if it were a different rendering context.

+5
source

Stencil Buffer is the best way to approach this for sure ... You will save time, processor and potential problems .. They are available on Iphone, you just need to create an OpenGlES 2.0 surface (not gles 1.0 or 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 

Check out this example: http://www.opengl.org/resources/code/samples/glut_examples/examples/stenciltst.c

Here's the visual result: http://www.opengl.org/resources/code/samples/glut_examples/examples/stenciltst.jpg

I used the same tool for erasers on both Android and iPhone, and it works like a charm!

Good luck

Greetings!

+4
source

You do not give much information, but I assume that you store everything that they "draw" into the buffer, and then draw on the screen as follows:

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

With a drawing-> ImageData is a buffer. What you can do is have a separate background buffer and draw it first. Then the erase tool will simply cross out the drawing buffer (all values, including alpha, all up).

For this solution to work, you need to enable blending and disable depth testing .

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

Is this what you are looking for?

+2
source

You can use a stencil buffer for this operation. The stencil buffer is a special buffer that contains information for each pixel, similar to the depth buffer. Unlike the depth buffer, you decide how template traffic changes when drawing and how it affects the decision to draw colors in the buffer or not. To do this, you can set specific states before any drawing operation. Here is what you do:

  • While erasing users, draw an “erased” area in the stencil buffer (using StencilOp, see below). You can use any GL drawing for this.

  • In each rendering pass, a background is drawn first (if you want, you can use a negative screen test here to just draw the “erased” part of the background - performance may increase).

  • Then turn on the stencil test for all other drawing operations. OpenGL will then only have the “non-erased” regions.

The function of determining how the stencil buffer should affect the drawing (or not): glStencilFunc ()

The function of determining how the stencil buffer affects the drawing itself: glStencilOp ()

Further explanation as well as arguments for them: http://www.opengl.org/resources/code/samples/sig99/advanced99/notes/node117.html

+2
source

Using glBlendFunc mode (GL_ONE, GL_ZERO) may go away.

0
source

All Articles