2012-07-08 8 views
5

Ich versuche, den "Stencil Buffer" zu verwenden, um einen Teil meines Renderings von einer Textur anzuzeigen, aber mein Render wird ohne jeden Maskierungseffekt angezeigt.Verwenden Sie Stencil Buffer mit iOS

Es ist für ein 2D-iOS-Projekt, mit OpenGL ES 2.0 Dies ist der betreffende Teil meines Code:

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); 
glEnable(GL_STENCIL_TEST); 


// mask rendering 
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); 
glStencilFunc(GL_ALWAYS, 1, 1); 
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); 

glBindTexture(GL_TEXTURE_2D, _maskTexture); 
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); 


// scene rendering 
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); 
glStencilFunc(GL_EQUAL, 1, 1); 
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); 

glBindTexture(GL_TEXTURE_2D, _viewTexture); 
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); 

Jede Hilfe wäre sehr dankbar!

(wie üblich für einen Französisch-Entwickler, sorry für mein Englisch!)

Präzision: "_maskTexture" ist ein schwarzes & Weiß-Bild.


Lösung:


Ich löste finnaly mein Problem mit den Indikationen rotoglub und tim. Danke euch beiden.

1/Der Stencil Buffer wurde nicht korrekt erstellt. Es soll wie folgt initialisiert werden:

glBindRenderbufferOES(GL_RENDERBUFFER_OES, depthStencilRenderbuffer); 
glRenderbufferStorageOES(GL_RENDERBUFFER_OES, 
          GL_DEPTH24_STENCIL8_OES, 
          backingWidth, 
          backingHeight); 

Es ist der Hauptgrund, warum mein Rendering nicht durch meine Maske betroffen war.

2/Um eine Textur als Maske verwenden zu können, ersetzte ich die schwarze Farbe durch einen Alpha-Kanal und ermöglichte das Mischen in meinem Rendering.

Meine letzte Rendering-Code sieht wie folgt aus:

glEnableClientState(GL_VERTEX_ARRAY); 
glEnableClientState(GL_TEXTURE_COORD_ARRAY); 

glVertexPointer(2, GL_FLOAT, 0, vertices); 
glTexCoordPointer(2, GL_FLOAT, 0, texcoords); 

glClearStencil(0); 
glClearColor (0.0,0.0,0.0,1); 
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); 


// mask rendering 
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); 
glEnable(GL_STENCIL_TEST); 
glEnable(GL_ALPHA_TEST); 
glBlendFunc(GL_ONE, GL_ONE); 
glAlphaFunc(GL_NOTEQUAL, 0.0); 
glStencilFunc(GL_ALWAYS, 1, 1); 
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); 

glBindTexture(GL_TEXTURE_2D, _mask); 
glDrawArrays(GL_TRIANGLE_STRIP, 4, 4); 

// scene rendering 
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); 
glStencilFunc(GL_EQUAL, 1, 1); 
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); 

glDisable(GL_STENCIL_TEST); 
glDisable(GL_ALPHA_TEST); 
glBindTexture(GL_TEXTURE_2D, _texture); 
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); 
+1

Gerade beschreiben Sie Ihr Problem so * nicht funktionieren * ist nicht wirklich hilfreich getan. Aber ich nehme an, dein Problem ist das Problem, das in dieser anderen Frage gelöst wurde: http://stackoverflow.com/questions/7571075/how-to-create-stencil-buffer-with-texture-image-in-opengl-es-2- 0 – rotoglup

+0

Vielen Dank für Ihren Kommentar. Mit "nicht arbeiten", ich meine, dass "_viewTexture" ohne Maske Effekt von "_maskTexture" angezeigt wurde. Ich werde versuchen, in Zukunft genauer zu sein. In Bezug auf den Beitrag, den Sie erwähnt haben, habe ich es bereits gelesen, aber wenn ich mich nicht irre, löste er sein Problem mit einem Shader und hat den Stencil Buffer aufgegeben. – EricD

+1

Beim Lesen Ihres Lösungsbeitrags denke ich, dass Sie immer noch Probleme haben (vielleicht vorerst ausgeblendet): Ihr Schablonentest ist für Ihren zweiten Rendering-Durchlauf deaktiviert, sodass die von Ihnen beobachtete Maskierung durch diesen Test nicht hervorgerufen werden kann. Außerdem sollte das Mischen nicht für den Schablonentest, sondern nur für den Alphatest nützlich sein. Ich denke, dass Sie die Maskierung beobachten, die Sie wollten, aber wahrscheinlich aus einem anderen Grund, dass das Schablonieren. – rotoglup

Antwort

1

einfach, das Problem ist, dass Sie nur eine Textur der Szene zeichnen, ohne eine Prüfung zu tun, was in der Textur ist. Der Schablonenpuffer nicht über die Farben in der Textur schert, überprüft er nur:

Did you draw a fragment ? (Update stencil buffer) : (Don't update stencil buffer);

Sie ein Fragment für jedes Pixel Ihrer Textur zeichnen, so dass jeder Maske Wirkung in der Textur ist nutzlos.

Wenn Sie mit einer Textur maskieren möchten, müssen Sie alle Fragmente, die Sie nicht im Stencil-Puffer aktualisiert werden wollen, verwerfen.

Dies geschieht entweder mit discard Schlüsselwort in Shader oder glAlphaTest/glAlphaFunc in OpenGLES 1.1