【问题标题】:How to create Stencil buffer with texture (Image) in OpenGL-ES 2.0如何在 OpenGL-ES 2.0 中使用纹理(图像)创建模板缓冲区
【发布时间】:2011-11-26 03:08:10
【问题描述】:

我可以在 OpenGL 2.0 中使用纹理(图像)准备 Stencil 这样图像的某些部分将是透明的,因此它将按原样传输
到模板缓冲区,然后将使用此模板缓冲区进行进一步绘图。


由 datenwolf 编辑以在答案中说明 OP 问题更新:

@InfiniteLoop:

@datenwolf 非常感谢您的回复,但没有成功:(这是我的代码

- (void)render 
{
    [EAGLContext setCurrentContext:context];
    glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebuffer);
    glUseProgram(program);
    glClearColor(0, 104.0/255.0, 55.0/255.0, 1.0);
    glViewport(0, 0, backingWidth, backingHeight);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
    // Set the stencil clear value
    glClearStencil ( 0x1 );

    // Set the depth clear value
    glClearDepthf( 0.75f );



    ////////
    ////
    GLfloat threshold = 0.5f;//half transparency
    /* the order in which orthogonal OpenGL state is set doesn't matter */
    glEnable(GL_STENCIL_TEST);
    glEnable(GL_ALPHA_TEST);

    /* don't write to color or depth buffer */
    glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
    glDepthMask(GL_FALSE);

    glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);

    /* first set alpha test so that fragments greater than the threshold
     will pass thus will set nonzero bits masked by 1 in stencil */
    glStencilFunc(GL_ALWAYS, 1, 1);//set one
    glAlphaFunc(GL_GREATER, threshold);//greater than half transparency

    glVertexAttribPointer(positionLoc, 3, GL_FLOAT, GL_FALSE, 0, fullVertices);
    glVertexAttribPointer(colorLoc, 4, GL_FLOAT, GL_FALSE, 0, colorVertices);
    glVertexAttribPointer(textureLoc, 2, GL_FLOAT, GL_FALSE, 0, textureVertices);
    [self drawTexture:texture2DMaskImage];
    /* second pass of the fragments less or equal than the threshold
     will pass thus will set zero bits masked by 1 in stencil */
    glStencilFunc(GL_ALWAYS, 0, 1);//set zero
    glAlphaFunc(GL_LEQUAL, threshold);//Less than Half transparency
    glVertexAttribPointer(positionLoc, 3, GL_FLOAT, GL_FALSE, 0, fullVertices);
    glVertexAttribPointer(colorLoc, 4, GL_FLOAT, GL_FALSE, 0, colorVertices);
    glVertexAttribPointer(textureLoc, 2, GL_FLOAT, GL_FALSE, 0, textureVertices);
    [self drawTexture:texture2DMaskImage];


// till here as suggested by u after this I have added to draw
// the next Image which will use the created Stencil
    glDepthMask(GL_TRUE);
    glDisable(GL_ALPHA_TEST);
    glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
    //
    glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);//stop further write to stencil buffer
    glStencilFunc(GL_EQUAL, 0, 1);//pass if 0
    glVertexAttribPointer(positionLoc, 3, GL_FLOAT, GL_FALSE, 0, fullVertices);
    glVertexAttribPointer(colorLoc, 4, GL_FLOAT, GL_FALSE, 0, colorVertices);
    glVertexAttribPointer(textureLoc, 2, GL_FLOAT, GL_FALSE, 0, textureVertices);
    [self drawTexture:texture2D];
    ////
    ///////



    // Validate program before drawing. This is a good check, 
    // but only really necessary in a debug build.
    // DEBUG macro must be defined in your debug configurations
    //  if that's not already the case.
#if defined(DEBUG)
    if (![self validateProgram:program])
    {
        NSLog(@"Failed to validate program: %d", program);
        return;
    }
#endif
    // draw
    [context presentRenderbuffer:GL_RENDERBUFFER];//Present
}

- (void) drawTexture:(Texture2D*)texture
{
    // handle viewing matrices
    GLfloat proj[16], modelview[16], modelviewProj[16];
    // setup projection matrix (orthographic)
    mat4f_LoadOrtho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0f, 1.0f, proj);
    //   glUniformMatrix4fv(uniforms[UNIFORM_PROJECTION], 1, 0, proj);
    // setup modelview matrix (rotate around z)
    mat4f_LoadIdentity(modelview);
    mat4f_LoadZRotation(0.0, modelview);
    mat4f_LoadTranslation3D(0.0, 0.0, 0.0, modelview);
    // projection matrix * modelview matrix
    mat4f_MultiplyMat4f(proj, modelview, modelviewProj);
    glUniformMatrix4fv(_modelViewUniform, 1, 0, modelviewProj);
    // update uniform values
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, texture.name);
    glUniform1i(_textureUniform, 0);
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, cubeIndices);
}

请说明我急需:(再次感谢。

【问题讨论】:

    标签: textures opengl-es-2.0 stencil-buffer


    【解决方案1】:

    是的,您可以使用 alpha 测试 (glEnable(GL_ALPHA_TEST); glAlphaFunc(COMPARISION, VALUE);) 来丢弃片段;丢弃的片段不会进行模板测试,因此您可以使用传递的片段来构建模板掩码。

    编辑代码示例

    /* the order in which orthogonal OpenGL state is set doesn't matter */
    glEnable(GL_STENCIL_TEST);
    glEnable(GL_ALPHA_TEST);
    
    /* don't write to color or depth buffer */
    glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
    glDepshMask(GL_FALSE);
    
    glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
    
    /* first set alpha test so that fragments greater than the threshold
       will pass thus will set nonzero bits masked by 1 in stencil */
    glStencilFunc(GL_ALWAYS, 1, 1);
    glAlphaFunc(GL_GREATER, threshold);
    draw_textured_primitive();
    
    
    /* second pass of the fragments less or equal than the threshold
       will pass thus will set zero bits masked by 1 in stencil */
    glStencilFunc(GL_ALWAYS, 0, 1);
    glAlphaFunc(GL_LEQUAL, threshold);
    draw_textured_primitive();
    

    之后不要忘记恢复 OpenGL 状态以进行绘图。

    编辑以说明更新的问题:

    由于您实际使用的是 iOS,因此 OpenGL-ES 2.0 的情况会有所不同。 OpenGL-ES2 中没有 alpha 测试。相反,如果片段着色器低于/高于所选阈值,您应该使用 discard 关键字/语句丢弃片段。

    【讨论】:

    • 感谢您的回复,是的,我试过了,但对流程感到困惑 喜欢 1. 禁用深度 2. 启用 Alpha 测试 3. 设置 Alpha 测试功能 4. 设置模板测试功能 5. 设置模板 OP (手术)。 6.绘制纹理。正确的???????但这并没有像预期的那样给出结果。StencilOp 应该是什么?和 stencilFunc 值??因此,如果 alpha 测试通过,则将“1”或“0”写入模板缓冲区,其余部分将与之前设置的一样清除模板缓冲区。请帮助再次感谢。
    • @infiniteLoop:查看我的代码编辑,它应该可以工作(我没有测试它)。
    • 没有从 ES 2.0 中删除 alpha 测试吗?所以你需要在片段着色器中使用你自己的比较和discard关键字来做。
    • @ChristianRau:问题标题谈到了 OpenGL 2.0(无 ES)。然而,由于必须在 OpenGL-ES2 中提供片段着色器,因此更改变得微不足道。
    • @datenwolf 哦,是的,Brad Larson 似乎已将问题完全更改为 OpenGL ES 并添加了代码示例。如果他不是同一个人或不与 OP 保持联系,那么这将是严重的滥用。
    【解决方案2】:

    最后,我设法在着色器中使用 discard 关键字有条件地传递颜色。 我还在同一个着色器中使用了 2 个纹理并相应地组合它们。

    谢谢大家。

    【讨论】:

    • 拜托,你能补充一些关于你如何组合这两种纹理的细节吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-01-07
    • 1970-01-01
    • 2014-12-18
    • 1970-01-01
    • 2013-01-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多