让OpenGL模板缓冲区剪辑在glkit上运行

时间:2014-05-04 20:05:54

标签: ios opengl-es-2.0 glkit

我正在尝试在GLKViewController中重现this stencil buffer tutorial here中使用模板进行裁剪的效果。

在我的绘画方法中,我有:

- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect {


    [self.effect prepareToDraw];

    glEnableVertexAttribArray(GLKVertexAttribPosition);
    glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid *) offsetof(Vertex, Position));
    glEnableVertexAttribArray(GLKVertexAttribTexCoord0);
    glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid *) offsetof(Vertex, TexCoord));

    glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexBuffer);

    glClearColor(0.5, 0.5, 0.5, 1.0);
    glClear( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);



    glClear(GL_DEPTH_BUFFER_BIT);
    glEnable(GL_STENCIL_TEST);
    glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
    glDepthMask(GL_FALSE);
    glStencilFunc(GL_NEVER, 1, 0xFF);
    glStencilOp(GL_REPLACE, GL_KEEP, GL_KEEP);  // draw 1s on test fail (always)

    // draw stencil pattern
    glStencilMask(0xFF);
    glClear(GL_STENCIL_BUFFER_BIT);  // needs mask=0xFF




    glDrawElements(GL_TRIANGLES, 1*6, GL_UNSIGNED_SHORT, 0);

     glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
    glDepthMask(GL_TRUE);
    glStencilMask(0x00);


    // draw only where stencil's value is 1
    glStencilFunc(GL_EQUAL, 1, 0xFF);


    glDrawElements(GL_TRIANGLES, nLiveSquares*6, GL_UNSIGNED_SHORT, 0);


    glDisable(GL_STENCIL_TEST);

}

顶点缓冲区包含用于保存纹理的正方形的信息。

我想要得到的效果是让第一个方块用于定义模板形状,然后当我绘制场景时,任何位于第一个方块之外的东西都会被剪裁。因此,我使用了drawElements两次 - 首先绘制剪裁方块然后绘制所有正方形。

我还有另一种用于OpenGL设置的方法,在程序开始时调用一次。正如对this stackoverflow question的回答所建议的那样,其中包括:

GLuint depthStencilRenderbuffer;

glGenRenderbuffers(1, &depthStencilRenderbuffer);
glBindRenderbuffer(GL_RENDERBUFFER, depthStencilRenderbuffer);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthStencilRenderbuffer);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, depthStencilRenderbuffer);

除了包含灰色清晰颜色的屏幕外,运行此结果不会产生任何结果。似乎所有东西都被印刷出来(或者没有被绘制到屏幕上)。

1 个答案:

答案 0 :(得分:0)

解决方案:

i)我将初始化更改为:

GLuint depthStencilRenderbuffer;
glBindRenderbufferOES(GL_RENDERBUFFER_OES, depthStencilRenderbuffer);
glRenderbufferStorageOES(GL_RENDERBUFFER_OES,
                         GL_DEPTH24_STENCIL8_OES,
                         self.view.bounds.size.width,
                         self.view.bounds.size.height);

我不确定区别是什么,但这似乎有效。

ii)在设置中我使用:

GLKView *view = (GLKView *)self.view;
view.context = self.context;
view.drawableDepthFormat = GLKViewDrawableDepthFormat24;
view.drawableStencilFormat = GLKViewDrawableStencilFormat8;

感谢@rickster的建议。