Question

Je travaille sur un jeu pour iPhone qui implique un mécanicien en dessin et peinture et je ne parviens pas à créer un outil qui effacerait les éléments déjà peints.

Le problème principal est que l’arrière-plan sur lequel vous souhaitez peindre n’est pas une couleur unie, mais une image ou une animation statique. J'ai essayé d'utiliser différentes options de fusion et opérations logiques dans le dessin, mais rien ne semblait fonctionner. Je suis nouveau sur OpenGL, donc il me manque quelque chose.

Des conseils?

EDIT: Pour donner un peu plus d’informations, j’utilise des textures pour mes pinceaux et j’utilise glVertexPointer () et glDrawArrays () pour les rendre. Par exemple:

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: Malheureusement, les tampons de stencil ne sont pas disponibles sur l'iPhone. : (

EDIT 3: les objets Framebuffer sont disponibles sur l’iPhone et c’est la route que j’ai empruntée. Je ne l'ai pas encore complètement mis en œuvre, mais jusqu'à présent, il semble que cela fonctionne comme je le voulais. Merci à tous!

Était-ce utile?

La solution

Dessinez un quad texturé en plein écran sur votre scène. Lorsque l'utilisateur dessine un trait, utilisez glTexSubImage2D pour mettre à jour la texture.

glReadPixels / glDrawPixels est lent.

Utiliser FrameBufferObjects est encore mieux, mais je doute que cette extension soit disponible sur l'iPhone (là encore, je ne sais pas vraiment, alors essayez-le peut-être). Les FBO vous permettent de dessiner directement dans une texture comme s'il s'agissait d'un autre contexte de rendu.

Autres conseils

Stencil Buffer est la meilleure façon d’aborder cela à coup sûr ... Vous gagnerez du temps, de l’unité centrale de traitement et des problèmes potentiels .., Ils sont disponibles sur Iphone, il vous suffit de créer une surface OpenGlES 2.0 (et non gles 1.0). ou 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

Recherchez cet exemple: http://www.opengl.org/resources/code/samples /glut_examples/examples/stenciltst.c

Voici le résultat visuel: http://www.opengl.org/resources/code/samples /glut_examples/examples/stenciltst.jpg

J'ai implémenté le même type d'outil gomme, sur Android et sur iPhone, et il fonctionne à merveille!

Bonne chance!

Salut!

Vous ne donnez pas beaucoup d’informations, mais je suppose que vous stockez tout ce qu’ils "peignent". dans un tampon, puis dessinez-le à l'écran comme ceci:

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

Avec dessin- > ImageData comme tampon. Ce que vous pouvez faire est d’avoir un tampon d’arrière-plan séparé et de le dessiner en premier. Ensuite, l’outil d’effacement effacera simplement le tampon de dessin (en tournant toutes les valeurs, y compris alpha, au maximum).

Pour que cette solution fonctionne, vous devez activer le mélange et désactiver les tests de profondeur .

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

Est-ce ce que vous cherchez?

Vous pouvez utiliser le tampon de gabarit pour cette opération. Le tampon de gabarit est un tampon spécial qui contient des informations pour chaque pixel, de la même manière que le tampon de profondeur. Contrairement au tampon de profondeur, vous décidez comment le tampon de gabarit est modifié pendant le dessin et comment il influence la décision de dessiner ou non dans le tampon de couleur. Pour ce faire, vous pouvez définir les états spécifiques avant toute opération de dessin. Voici ce que vous faites:

  • Au moment où les utilisateurs effacent, tracez le symbole "effacé". région dans le tampon de stencil (en utilisant StencilOp, voir ci-dessous). Vous pouvez utiliser n'importe quel dessin GL fonctionner pour cela.

  • Dans chaque passe de rendu, commencez par dessiner l'arrière-plan (si vous voulez, vous pouvez utiliser un test de pochoir négatif ici pour dessiner uniquement le texte "effacé" partie de la fond - peut augmenter performances).

  • Activez ensuite le test du pochoir pour tous autres opérations de dessin. OpenGL sera alors seulement attirer à la "non effacé" régions.

La fonction permettant de définir comment le tampon de gabarit doit influencer le dessin (ou non): glStencilFunc ()

La fonction permettant de définir comment le tampon de gabarit est influencé par le dessin: glStencilOp ()

Explications supplémentaires, y compris les arguments de ceux-ci: http://www.opengl.org/resources/ code / samples / sig99 / advanced99 / notes / node117.html

Vous pouvez utiliser le mode glBlendFunc (GL_ONE, GL_ZERO).

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top