zoukankan      html  css  js  c++  java
  • OpenGL第23-26小结

      到后面代码相对而言比较复杂了,因为没有系统的看红宝书(就跟字典一样,兴趣缺缺),很多操作的步骤比较迷糊。

      23讲讲解了如何将环境纹理贴在球体、圆柱体等非矩形物体表面,从而达到一个反射周围景色的效果(恩,就像热水瓶内胆那样反射的效果)。我的理解就是一个自动贴纹理的函数的调用,初始化时,

      

      在绘制物体时,

      

      绘制完毕记得关掉,

       

      24讲是从TGA文件中得到字体纹理,避免了调用系统字体,跟之前的一个教程很像,但这个教程又多了一个获取GL扩展模块名的功能,暂时用不到,略过。

      25讲是从文本文件中读取点坐标(400多个点)来进行物体的创建,并通过改变每一个点的位置来实现物体间的变换,将点位移的距离进行等分,以达到平滑变化的效果。

      26讲,恩,教程里是蒙板缓存,有的地方又叫模板缓存,函数一样。该小节重点应该是通过构建一个模板缓存,来限制镜面中的物体的运动范围(超出范围不予显示),就像通过车窗看外面的风景那样。镜子中的物体仍然需要绘制的,并且其活动范围就是当前视角所看到的镜面中。(程序镜子中的物体是真实存在的,非生活中镜子那样只反射光)。

      蒙板补充:启用蒙版测试之后,将地板全部通过测试并将蒙板缓存替换为地板,

      

    glStencilFunc(GL_ALWAYS, 1, 1);                        // Always Passes, 1 Bit Plane, 1 As Mask
        glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);            // We Set The Stencil Buffer To 1 Where We Draw Any Polygon

      之后设置作为反射的球体与蒙板的交互:

      

    glStencilFunc(GL_EQUAL, 1, 1);                        // We Draw Only Where The Stencil Is 1
                                                            // (I.E. Where The Floor Was Drawn)
        glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);                // Don't Change The Stencil Buffer

      之后通过测试的才显示。

      第七版红宝书的蒙板缓存示例代码跟nehe一样都出问题了,诶,还找不到问题在哪。

      然而我纠结的地方确实半透明的实现。。。首先是alpha通道测试函数:

      

    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

      我看了看书上的说法,是说这个混合函数是通过RGB通量与alpha或者指定的值进行相乘,相加,之后缩放到规定RGB值范围得到混合(变换)后的RGB值。我数学不是很好,看的云里雾里的。

      多的就不说了,我只说我想到的东西,因看到本节示例程序汇总球体表面的灯光反射效果时由一个相同大小的球体贴上相应的贴图实现的:

       透明球体我修改ALPHA值怎么一点反应都没有呢?后来多番测试,得到这么点结论:平时使用我用就这两个就好了:

      

    glBlendFunc(GL_SRC_ALPHA, GL_ONE);                    
    glBlendFunc(GL_SRC_ALPHA,GL_ZERO);

      GL_ONE全透明,GL_ZERO不透明(黑色)(理论上可以0-1之间自定义),用的时候别忘了开启混合,用完关掉(或者用按键控制整个场景的混合开关。用按键控制的时候要注意,有一些物体灯光+半透明可能不是想要的效果,我测试了一个正方体,在关灯的情况下6个面全是半透明的,是我想要的,然而开灯之后,旋转正方体会发现有些面不是半透明的,原因我不清楚)至于想通过ALPHA值调整透明度的,就用这个吧:

    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    不过在使用之前一定要先禁掉灯光,用完之后再恢复,不然修改ALPHA值无变化:

    就像这样

     

    glEnable(GL_BLEND);                                    // Enable Blending (Otherwise The Reflected Object Wont Show)
        glDisable(GL_LIGHTING);                                // Since We Use Blending, We Disable Lighting
        glColor4f(1.0f, 1.0f, 1.0f, 0.8f);                    // Set Color To White With 80% Alpha
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);    // Blending Based On Source Alpha And 1 Minus Dest Alpha
        DrawFloor();                                        // Draw The Floor To The Screen
        glEnable(GL_LIGHTING);                                // Enable Lighting
        glDisable(GL_BLEND);                                // Disable Blending

     恩,理论知识缺缺,我也只能通过不断尝试的方式去探索这些开关、函数的使用方法。21讲的小游戏蛮厉害的,22讲的凹凸纹理没看,为什么不看?因为好多啊。。而且数学算法一阵头大,要用的时候套过来用好了。

      

  • 相关阅读:
    手动创建DataSet数据集
    Ado.Net 参数化操作
    序列化和反序列化
    封装多个集合在一个类中
    窗体之间的传递
    C程序设计语言练习题1-12
    C程序设计语言练习题1-11
    C程序设计语言练习题1-10
    C程序设计语言练习题1-9
    C程序设计语言练习题1-8
  • 原文地址:https://www.cnblogs.com/ForRickHuan/p/5761968.html
Copyright © 2011-2022 走看看