c++ - 阴影卷 - 最后阶段

标签 c++ opengl shadow stencil-buffer

finishing with volume itself 之后,我继续在 OpenGL 中处理阴影体积,我需要使用模板缓冲区绘制阴影,这就是我卡住的地方 :) 我渲染了这个场景:http://prntscr.com/17lyr 如您所见,球体代表光源,一个蘑菇的体积直接绘制到屏幕上,而另一个没有(我希望看到阴影)。它们绝对相等,使一个模型在 X 轴上平移一些单位。这是我正在使用的代码:

 void Display(){
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
    glLoadIdentity();
    glLightfv(GL_LIGHT1,GL_POSITION,light_position[0]);

    cam.SetPrespective();

    DrawDebugObject(true);
    glTranslatef(15,0,0);
    DrawDebugObject(false);

    glFinish();
    glutSwapBuffers();
}

void DrawDebugObject(bool draw_sil){
    glPushMatrix();
    glTranslatef(light_position[1][0],light_position[1][1],light_position[1][2]);
    glColor3ub(255,255,0);
    gluSphere(gluNewQuadric(),0.5,10,10);
    glPopMatrix();

    glDisable(GL_LIGHTING);
    glBegin(GL_QUADS);
        glColor3f(1,1,1);
        glVertex3f(-100,0,-100);
        glVertex3f(-100,0,100);
        glVertex3f(100,0,100);
        glVertex3f(100,0,-100);
        glEnd();
    glEnable(GL_LIGHTING);
    pModel->draw();
    if(draw_sil)
        pModel->markSilouette(light_position[1]);
    castShadow(pModel,light_position[1]);   
}

void castShadow(Model* model,float* lp){
        glDisable(GL_LIGHTING);
        glDepthMask(GL_FALSE);
        glDepthFunc(GL_LEQUAL);

        pModel->markVisible(lp);

        glEnable(GL_STENCIL_TEST);
        glColorMask(0, 0, 0, 0);
        glStencilFunc(GL_ALWAYS, 1, 0xffffffff);

        // first pass, stencil operation decreases stencil value
        glFrontFace(GL_CCW);
        glStencilOp(GL_KEEP, GL_KEEP, GL_INCR);
        pModel->markSilouette(lp);

        // second pass, stencil operation increases stencil value
        glFrontFace(GL_CW);
        glStencilOp(GL_KEEP, GL_KEEP, GL_DECR);
        pModel->markSilouette(lp);

        glFrontFace(GL_CCW);
        glColorMask(1, 1, 1, 1);

        //draw a shadowing rectangle covering the entire screen
        glColor4f(1.0f, 0.0f, 0.0f, 0.4f);
        glEnable(GL_BLEND);
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
        glStencilFunc(GL_NOTEQUAL, 0, 0xffffffff);
        glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
        glPushMatrix();
        glLoadIdentity();
        glBegin(GL_QUADS);
        glVertex3f(-0.1f, 0.1f,-0.10f);
        glVertex3f(-0.1f,-0.1f,-0.10f);
        glVertex3f( 0.1f, 0.1f,-0.10f);
        glVertex3f( 0.1f,-0.1f,-0.10f);
        glEnd();
        glPopMatrix();
        glDisable(GL_BLEND);

        glDepthFunc(GL_LEQUAL);
        glDepthMask(GL_TRUE);
        glEnable(GL_LIGHTING);
        glDisable(GL_STENCIL_TEST);
}

这是我的 GL 初始化函数:

void InitGL(){
    glEnable(GL_NORMALIZE);
    glEnable(GL_LIGHTING);
    glEnable(GL_TEXTURE_2D);
    glShadeModel(GL_SMOOTH);
    glClearDepth(1.0f);                                 // Depth Buffer Setup
    glClearStencil(0);                                  // Stencil Buffer Setup
    glEnable(GL_DEPTH_TEST);                            // Enables Depth Testing
    glDepthFunc(GL_LEQUAL);                             // The Type Of Depth Testing To Do

    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);  // Really Nice Perspective Calculations
    glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
    glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST);
    glHint(GL_FOG_HINT, GL_NICEST);
...nothing important after that

在我的主要功能中:

glutInit(&argc,argv);
    glutInitDisplayMode(GLUT_RGB|GLUT_DEPTH|GLUT_DOUBLE|GLUT_STENCIL|GLUT_ACCUM);
    glutInitWindowSize(Width,Height);
    glutCreateWindow("Spheres");

    glutDisplayFunc(Display);
    glutReshapeFunc(Reshape);
    glutKeyboardFunc(Keyboard);
    glutKeyboardUpFunc(KeyboardUp);
    glutTimerFunc(TIMEOUT,Timer,TIMEOUT);
    glutPassiveMotionFunc(MouseMove);

我的代码一切正常吗?因为我看不到阴影,甚至不知道如何检查模板值是否设置正确。

最佳答案

据我所知,无法检查模板。我将假设您正在使用深度失败。我建议像这样使用 glStencilOpSeperate。

    glClear(GL_STENCIL_BUFFER_BIT);
    glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
    glEnable(GL_STENCIL_TEST);
    glEnable(GL_POLYGON_OFFSET_FILL);
    glDisable(GL_CULL_FACE);
    glStencilFunc(GL_ALWAYS, 0x00, 0xFF);
    glStencilOpSeparate(GL_FRONT, GL_KEEP, GL_INCR_WRAP, GL_KEEP);
    glStencilOpSeparate(GL_BACK, GL_KEEP, GL_DECR_WRAP, GL_KEEP);
    glPolygonOffset(0.0f, 5.0f);
    glDepthFunc(GL_LESS);

然后当您绘制实际几何体时,请确保您正在替换模板值,如下所示:

    glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
    glEnable(GL_CULL_FACE);
    glDisable(GL_POLYGON_OFFSET_FILL);
    glCullFace(GL_BACK);
    glDepthFunc(GL_GEQUAL);
    glStencilFunc(GL_EQUAL, 0x00, 0xFF);
    glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);

关于c++ - 阴影卷 - 最后阶段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4257153/

相关文章:

Android,在 RecyclerView 的每个项目下显示一个阴影(没有边距填充)

c++ - 使用 cuda 而不是 cudnn 测试 caffe 时的未知池方法

opengl - GLEW 链接错误

c++ - 为什么建议使用多个像素缓冲区对象。肯定是多余的?

android - 如何设置android按钮阴影而不是设置文本阴影

具有自定义阴影颜色的 Android CardView

c++ - 如何处理多重继承的资源管理?

c++ - 使用带有指针参数的函数从字符数组中删除空格

c++ - 如何减少 OpenGL CPU 使用率和/或如何正确使用 OpenGL

c++ - openGL 中的相似对象是否需要多个顶点缓冲区?