首页 > 代码库 > 《OpenGL游戏编程》第9章-PlanarShadow关键代码注释

《OpenGL游戏编程》第9章-PlanarShadow关键代码注释

阴影这块确实是难点。说到阴影就必须提到投影矩阵、模板值为1和2时分别渲染。说来话长,仅仅放上代码,供日后查阅。

 1 /** 渲染墙面和阴影 */ 2 void  CPlanarShadow::Render() 3 { 4   glClear(GL_STENCIL_BUFFER_BIT);                /**< 清除模版缓存 */ 5   glEnable(GL_STENCIL_TEST);                     /**< 启用模版测试 */ 6  7   /** 循环处理每个墙面 */ 8   for(int i = 0; i < (int)walls.size(); i++) 9   {10     glStencilFunc(GL_ALWAYS, 1, 1);           /**< 规定了模板测试的一种约定:RenderWall方法里所渲染的图形的模版值为1*/11     glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);      12 13     /** 绘制当前墙面 */14     glDisable(GL_LIGHT0);             15     RenderWall(walls[i]);                 /**< 渲染墙i,涉及到的像素对应的模板值为1*/16     glEnable(GL_LIGHT0);              17 18     glDisable(GL_DEPTH_TEST);             /**< 关闭深度测试,忽略深度测试,模板测试如果通过(代码行376)就算通过*/19     20     glStencilFunc(GL_EQUAL, 1, 1);               /**< 规定了模板测试的一种约定,这里ref和mask都等于1,就被认为是通过模板测试,绘制模版值为1的象素 */21     glStencilOp(GL_KEEP, GL_KEEP, GL_INCR);      /**< stencil test and the depth test pass,模版缓冲区的值加1 */22 23     glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);/**< 禁止颜色缓存写,就是为了储存模板缓冲区的值 */24     /** 开始投射阴影 根据模板测试的约定,PushMatrix里的涉及的顶点的模板值都要进行一次加1操作*/25     glPushMatrix(); 26       /** 创建投射矩阵 */27       float m[16] = {0};                28       CreateShadowMatrix(m, walls[i].vVerts[0], walls[i].vNormal, lightPos);/**< 计算当前墙面i的投影矩阵m*/29       glMultMatrixf(m); //投影矩阵与当前矩阵的一次叠加30 31 /** 这次是在新的矩阵空间中进行绘制物体,可以得到所谓的"阴影",这个阴影就是一个茶壶对象,实际上是RenderObjects方法中物体进行的投影变换,就像矩阵的平移变换 */32       glPushMatrix();33           RenderObjects();34       glPopMatrix();35 36     glPopMatrix();37 38     glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);                          /**< 恢复颜色缓存写 */39     RenderWall(walls[i]);                                                     /**< 绘制除阴影外的部分 */40     glEnable(GL_DEPTH_TEST);                                                  /**< 启用深度测试 */41   }42 43   glDisable(GL_STENCIL_TEST);       44 45 }

 

《OpenGL游戏编程》第9章-PlanarShadow关键代码注释