2010-10-29 6 views
8

Dans le cadre de la modification du GLPaint, j'essaie d'ajouter une fonctionnalité d'effacement où l'utilisateur pourrait sélectionner un bouton effaceur et effacer la zone peinte tout comme la peinture.Effacer avec un pinceau dans GLPaint

J'essaie d'avoir une instruction conditionnelle dans la méthode "renderLineFromPoint:(CGPoint)start toPoint:(CGPoint)end" afin que je puisse vérifier si le trait est à peindre ou à effacer. Pour effacer, je ne sais pas utiliser les paramètres "start" et "end" pour l'effacement. Y at-il un appel de méthode dans OpenGL comme glClear() qui accepte ces deux paramètres et efface-t-il?

Tout pointeur sera très utile. Je vous remercie.

+0

Est-ce faisable? – blacky

+0

oui c'est, la réponse donnée par zlog fonctionne dans mon application de peinture – thgc

Répondre

9

Dans la même veine que Erase using brush in GLPaint, vous pouvez réutiliser la méthode

- (void)renderLineFromPoint:(CGPoint)start toPoint:(CGPoint)end 

en ayant la condition:

if (isEraserBrushType) { 
    glBlendFunc(GL_ONE, GL_ZERO); 
    glColor4f(0, 0, 0, 0.0); 
} else { 
    glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); 
    [self setBrushColorWithRed:brushColourRed green:brushColourGreen blue:brushColourBlue]; 
} 

au-dessus du code:

// Render the vertex array 
glVertexPointer(2, GL_FLOAT, 0, eraseBuffer); 
glDrawArrays(GL_POINTS, 0, vertexCount); 

note, vous ll doit implémenter isEraserBrushType, et stocker brushColourRed, brushColourGreen et brushColourBl ue en quelque sorte.

+1

il efface avec un pinceau rectangle (je pense que la taille de l'image de brosse - 64/64), pas avec l'image actuelle de la brosse. des idées pourquoi est-ce? –

+0

Je suppose que c'est pourquoi cette réponse n'est pas acceptée. @ zlog J'aimerais bien le savoir aussi. Une idée comment effacer avec l'image de la brosse, pas la boîte de délimitation de la brosse? – taber

+4

vient de trouver ce post: http: // stackoverflow.com/questions/4074955/blending-a-texture-à-effacer-alpha-values-softly-with-opengl en utilisant 'glBlendFunc (GL_ZERO, GL_ONE_MINUS_SRC_ALPHA)' semble faire l'affaire. – taber

4

Je pense que je peux résoudre ce problème, mais pas très bon.

Vous pouvez créer une nouvelle copie de fonction de "renderLineFromPoint", comme ceci;

- (void) drawErase:(CGPoint)start toPoint:(CGPoint)end 
{ 
    static GLfloat*  eraseBuffer = NULL; 
    static NSUInteger eraseMax = 64; 

    NSUInteger   vertexCount = 0, 
    count, 
    i; 

    [EAGLContext setCurrentContext:context]; 
    glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer); 

    // Convert locations from Points to Pixels 
    CGFloat scale = 1.0;//self.contentScaleFactor; 
    start.x *= scale; 
    start.y *= scale; 
    end.x *= scale; 
    end.y *= scale; 

    // Allocate vertex array buffer 
    if(eraseBuffer == NULL) 
     eraseBuffer = malloc(eraseMax * 2 * sizeof(GLfloat)); 

    // Add points to the buffer so there are drawing points every X pixels  
    count = MAX(ceilf(sqrtf((end.x - start.x) * (end.x - start.x) + (end.y - start.y) * (end.y - start.y))/kBrushPixelStep), 1); 

    for(i = 0; i < count; ++i) { 
     if(vertexCount == eraseMax) { 
      eraseMax = 2 * eraseMax; 
      eraseBuffer = realloc(eraseBuffer, eraseMax * 2 * sizeof(GLfloat)); 
     } 

     eraseBuffer[2 * vertexCount + 0] = start.x + (end.x - start.x) * ((GLfloat)i/(GLfloat)count); 
     eraseBuffer[2 * vertexCount + 1] = start.y + (end.y - start.y) * ((GLfloat)i/(GLfloat)count); 
     vertexCount += 1; 
    } 
    //} 
    //glEnable(GL_BLEND); // 打开混合 
     //glDisable(GL_DEPTH_TEST); // 关闭深度测试 
     //glBlendFunc(GL_SRC_ALPHA, GL_ONE); // 基于源象素alpha通道值的半透明混合函数 

     //You need set the mixed-mode 
    glBlendFunc(GL_ONE, GL_ZERO); 
     //the erase brush color is transparent. 
    glColor4f(0, 0, 0, 0.0); 

    // Render the vertex array 
    glVertexPointer(2, GL_FLOAT, 0, eraseBuffer); 
    glDrawArrays(GL_POINTS, 0, vertexCount); 

    // Display the buffer 
    glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer); 
    [context presentRenderbuffer:GL_RENDERBUFFER_OES]; 

     // at last restore the mixed-mode 
    glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); 
} 

Mon anglais est pauvre. Pouvez-vous comprendre ce que j'ai dit? J'espère que cela peut vous aider.

+0

Ceci est la réponse parfaite ... travaillé pour moi .. – Heena

-2

Une autre idée, si supposons est noir pur arrière plan de votre vue, vous pouvez simplement appeler [self setBrushColorWithRed:0.0 green:0.0 blue:0.0] puis appelez renderPoint: ToPint: - Cela attirera en noir (et l'utilisateur peut penser qu'il est en train d'effacer réellement

0
.

je tenté d'utiliser la réponse acceptée, mais il effacerait en carré, alors que je voulais effacer en utilisant mon pinceau. au lieu de cela je une fonction de mélange différent.

if (self.isErasing) { 
    glBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_ALPHA); 
    [self setBrushColorWithRed:0 green:0 blue:0]; 
} else { 
    glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); 
} 

la façon dont cela fonctionne est que la la couleur entrante (source) est multipliée par zéro à c disparaissent complètement, ce qui signifie que vous ne peignez rien de nouveau. La couleur de destination est alors définie sur (1 - Source Alpha). Donc, partout où la brosse a couleur la destination a pas couleur.

Questions connexes