Domanda

Sto lavorando a un gioco per iPhone in cui è coinvolto un meccanico di disegno / pittura e sto riscontrando problemi nel tentativo di creare uno strumento che cancellerebbe le cose già dipinte.

Il problema principale è che lo sfondo su cui si sta dipingendo non è un colore solido ma un'immagine statica o un'animazione. Ho provato a utilizzare diverse opzioni di fusione e operazioni logiche nel disegno, ma nulla sembrava funzionare. Sono nuovo di OpenGL, quindi mi manca qualcosa.

Qualche consiglio?

EDIT: per dare un po 'più di informazioni, sto usando le trame per i miei pennelli e usando glVertexPointer () e glDrawArrays () per renderle. Ad esempio:

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

MODIFICA 2: Sfortunatamente, i buffer di stencil non sono disponibili su iPhone. : (

EDIT 3: gli oggetti Framebuffer sono disponibili su iPhone e questa è la strada che ho preso. Non l'ho ancora completamente implementato, ma finora sembra che funzioni come volevo. Grazie a tutti!

È stato utile?

Soluzione

Disegna un quad strutturato a schermo intero sulla scena. Quando l'utente disegna una pennellata, utilizzare glTexSubImage2D per aggiornare la trama.

glReadPixels / glDrawPixels è lento.

L'uso di FrameBufferObjects è ancora meglio, ma dubito che questa estensione sia disponibile su iPhone (poi di nuovo, non lo so per certo, quindi forse provalo). Gli FBO ti consentono di disegnare direttamente in una trama come se fosse un altro contesto di rendering.

Altri suggerimenti

Stencil Buffer è il modo migliore per affrontarlo di sicuro ... Risparmierai tempo, CPU e potenziali problemi .., Sono disponibili su Iphone, devi solo creare una superficie OpenGlES 2.0 (non 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

Cerca questo esempio: http://www.opengl.org/resources/code/samples /glut_examples/examples/stenciltst.c

Ecco il risultato visivo: http://www.opengl.org/resources/code/samples /glut_examples/examples/stenciltst.jpg

Con questo ho impiantato lo stesso tipo di strumento per cancellare, sia su Android che su iPhone e funziona come un fascino!

Buona fortuna!

Saluti!

Non fornisci molte informazioni, ma presumo che tu stia conservando qualunque cosa "dipingano". in un buffer e quindi disegnandolo sullo schermo in questo modo:

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

Con drawing- > ImageData come buffer. Quello che potresti fare è avere un buffer di sfondo separato e disegnarlo prima. Quindi lo strumento di cancellazione semplicemente cancellerà il buffer del disegno (aumentando tutti i valori, incluso l'alfa, fino in alto).

Per far funzionare questa soluzione dovresti attivare la fusione e disattivare il test di profondità .

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

È quello che stai cercando?

È possibile utilizzare il buffer di stencil per questa operazione. Il buffer di stencil è un buffer speciale che contiene informazioni per ogni pixel, simile al buffer di profondità. A differenza del buffer di profondità, decidi come modificare il buffer di stencil durante il disegno e in che modo influenza la decisione di disegnare o meno nel buffer di colore. Per fare ciò, è possibile impostare gli stati specifici prima di qualsiasi operazione di disegno. Ecco cosa fai:

  • Nel momento in cui gli utenti cancellano, disegna il "cancellato" regione nel buffer di stencil (usando StencilOp, vedi sotto). Puoi usare qualsiasi disegno GL funzione per questo.

  • In ogni passaggio di rendering, prima disegna lo sfondo (se vuoi, puoi usa un test di stencil negativo qui per disegna solo il "cancellato" parte di sfondo - può aumentare prestazioni).

  • Quindi, abilitare il test dello stencil per tutti altre operazioni di disegno. OpenGL attingerà quindi solo a & Quot; non cancellata " regioni.

La funzione per impostare come il buffer dello stencil dovrebbe influenzare (o meno) il disegno: glStencilFunc ()

La funzione per impostare come il buffer dello stencil stesso viene influenzato dal disegno: glStencilOp ()

Ulteriore spiegazione, anche con gli argomenti per questi: http://www.opengl.org/resources/ codice / campioni / sig99 / advanced99 / note / node117.html

L'utilizzo della modalità glBlendFunc (GL_ONE, GL_ZERO) può essere effettuato.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top