zoukankan      html  css  js  c++  java
  • osg轮廓特效 【转】

    // -*-c++-*-

    /*
     * OpenSceneGraph - Copyright (C) 1998-2003 Robert Osfield
     *
     * This library is open source and may be redistributed and/or modified under
     * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
     * (at your option) any later version.  The full license is in LICENSE file
     * included with this distribution, and on the openscenegraph.org website.
     *
     * This library is distributed in the hope that it will be useful,
     * but WITHOUT ANY WARRANTY; without even the implied warranty of
     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     * OpenSceneGraph Public License for more details.
     */

    /*
     * osgFX::Outline - Copyright (C) 2004,2009 Ulrich Hertlein
     */

    #ifndef OSGFX_OUTLINE_
    #define OSGFX_OUTLINE_

    #include <osgFX/Export>
    #include <osgFX/Effect>

    namespace osgFX
    {
        /**
         * Outline effect.
         */
        class Outline : public Effect
        {
        public:
            /// Constructor.
            Outline();
            Outline(const Outline& copy,
                    const osg::CopyOp& op = osg::CopyOp::SHALLOW_COPY)
                : Effect(copy, op) {
                _width = copy._width;
                _color = copy._color;
            }

            // Effect class info
            META_Effect(osgFX, Outline, "Outline",
                        "Stencil buffer based object outlining.",
                        "Ulrich Hertlein <u.hertlein@sandbox.de>");

            /// Set outline width.
            void setWidth(float w) {
                _width = w;
            }

            /// Get outline width.
            float getWidth() const {
                return _width;
            }

            /// Set outline color.
            void setColor(const osg::Vec4& col) {
                _color = col;
            }

            /// Get outline color.
            const osg::Vec4& getColor() const {
                return _color;
            }

        protected:
            /// Destructor.
            virtual ~Outline() {
            }

            /// Define available techniques.
            bool define_techniques();

        private:
            /// Outline width.
            float _width;

            /// Outline color.
            osg::Vec4 _color;
        };
    };

    #endif

    // -*-c++-*-

    /*
     * OpenSceneGraph - Copyright (C) 1998-2009 Robert Osfield
     *
     * This library is open source and may be redistributed and/or modified under
     * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
     * (at your option) any later version.  The full license is in LICENSE file
     * included with this distribution, and on the openscenegraph.org website.
     *
     * This library is distributed in the hope that it will be useful,
     * but WITHOUT ANY WARRANTY; without even the implied warranty of
     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     * OpenSceneGraph Public License for more details.
     */

    /*
     * osgFX::Outline - Copyright (C) 2004,2009 Ulrich Hertlein
     */

    #include <osgFX/Outline>
    #include <osgFX/Registry>

    #include <osg/Group>
    #include <osg/Stencil>
    #include <osg/CullFace>
    #include <osg/PolygonMode>
    #include <osg/LineWidth>
    #include <osg/Material>

    #include <osg/NodeCallback>
    #include <osgUtil/CullVisitor>

    #include <iostream>


    const unsigned int Override_On = osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE;
    const unsigned int Override_Off = osg::StateAttribute::OFF|osg::StateAttribute::OVERRIDE;


    namespace osgFX
    {
        /// Register prototype.
        Registry::Proxy proxy(new Outline);

        /**
         * Outline technique.
         */
        class OutlineTechnique : public Technique
        {
        public:
            /// Constructor.
            OutlineTechnique(const Outline& outline) : Technique() {
                _outline = &outline;
            }

            /// Validate.
            bool validate(osg::State&) const {
                return true;
            }

        protected:
            /// Define render passes.
            void define_passes() {

                /*
                 * draw
                 * - set stencil buffer to ref=1 where draw occurs
                 * - clear stencil buffer to 0 where test fails
                 */
                {
                    osg::StateSet* state = new osg::StateSet;

                    // stencil op
                    osg::Stencil* stencil  = new osg::Stencil;
                    stencil->setFunction(osg::Stencil::ALWAYS, 1, ~0);
                    stencil->setOperation(osg::Stencil::KEEP,
                                          osg::Stencil::KEEP,
                                          osg::Stencil::REPLACE);
                    state->setAttributeAndModes(stencil, Override_On);

                    addPass(state);
                }

                /*
                 * post-draw
                 * - only draw where draw didn't set the stencil buffer
                 * - draw only back-facing polygons
                 * - draw back-facing polys as lines
                 * - disable depth-test, lighting & texture
                 */
                {
                    osg::StateSet* state = new osg::StateSet;

                    // stencil op
                    osg::Stencil* stencil  = new osg::Stencil;
                    stencil->setFunction(osg::Stencil::NOTEQUAL, 1, ~0);
                    stencil->setOperation(osg::Stencil::KEEP,
                                          osg::Stencil::KEEP,
                                          osg::Stencil::REPLACE);
                    state->setAttributeAndModes(stencil, Override_On);

                    // cull front-facing polys
                    osg::CullFace* cf = new osg::CullFace;
                    cf->setMode(osg::CullFace::FRONT);
                    state->setAttributeAndModes(cf, Override_On);

                    // poly mode for back-facing polys
                    osg::PolygonMode* pm = new osg::PolygonMode;
                    pm->setMode(osg::PolygonMode::BACK, osg::PolygonMode::LINE);
                    state->setAttributeAndModes(pm, Override_On);

                    // outline width
                    osg::LineWidth* lw = new osg::LineWidth;
                    lw->setWidth(_outline->getWidth());
                    state->setAttributeAndModes(lw, Override_On);

                    // outline color/material
                    const osg::Material::Face face = osg::Material::FRONT_AND_BACK;
                    osg::Material* mtl = new osg::Material;
                    mtl->setColorMode(osg::Material::AMBIENT_AND_DIFFUSE);
                    mtl->setAmbient(face, _outline->getColor());
                    mtl->setDiffuse(face, _outline->getColor());
                    mtl->setEmission(face, _outline->getColor());
                    state->setAttributeAndModes(mtl, Override_On);

                    // disable modes
                    state->setMode(GL_BLEND, Override_Off);
                    state->setMode(GL_DEPTH_TEST, Override_Off);
                    state->setTextureMode(0, GL_TEXTURE_1D, Override_Off);
                    state->setTextureMode(0, GL_TEXTURE_2D, Override_Off);
                    state->setTextureMode(0, GL_TEXTURE_3D, Override_Off);

                    addPass(state);
                }
            }

        private:
            /// Outline effect.
            osg::ref_ptr<const Outline> _outline;
        };

        /**
         * Enable stencil clear callback.
         */
        class EnableStencilCallback : public osg::NodeCallback
        {
        public:
            EnableStencilCallback() {}

            virtual void operator()(osg::Node* node, osg::NodeVisitor* nv) {

                osgUtil::CullVisitor* cv = dynamic_cast<osgUtil::CullVisitor*>(nv);
                if (cv) {
                    // enable stencil clear on render stage
                    osgUtil::RenderStage* render = cv->getRenderStage();
                    unsigned int mask = render->getClearMask();
                    if ((mask & GL_STENCIL_BUFFER_BIT) == 0) {
                        render->setClearMask(mask | GL_STENCIL_BUFFER_BIT);
                        render->setClearStencil(0);
                        //std::cerr << "osgFX::Outline activated stencil/n";
                    }
                }

                traverse(node, nv);
            }

        private:
        };

        /// Constructor.
        Outline::Outline() : Effect()
        {
            _width = 3.0f;
            _color.set(1.0f,1.0f,1.0f,1.0f);
            addCullCallback(new EnableStencilCallback);
        }

        /// Define available techniques.
        bool Outline::define_techniques()
        {
            addTechnique(new OutlineTechnique(*this));
            return true;
        }
    };

  • 相关阅读:
    石头剪刀布技巧+个人经验总结
    能让你聪明的工作DEAL四法则,来自《每周工作四小时》书籍
    开发软件名称简写定义表
    罗永浩简历(自荐新东方的简历)
    感人微电影 《健康树》金赫及作品简介
    陈寅恪
    中国朝代顺序表
    Loading...加载图收集
    KeyBoardUtils.java——android键盘工具类
    LogUtils.java
  • 原文地址:https://www.cnblogs.com/mazhenyu/p/3806654.html
Copyright © 2011-2022 走看看