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;
        }
    };

  • 相关阅读:
    【Uvalive4960】 Sensor network (苗条树,进化版)
    【UVA 1151】 Buy or Build (有某些特别的东东的最小生成树)
    【UVA 1395】 Slim Span (苗条树)
    【UVA 10600】 ACM Contest and Blackout(最小生成树和次小生成树)
    【UVA 10369】 Arctic Network (最小生成树)
    【UVA 10816】 Travel in Desert (最小瓶颈树+最短路)
    【UVA 11183】 Teen Girl Squad (定根MDST)
    【UVA 11865】 Stream My Contest (二分+MDST最小树形图)
    【UVA 11354】 Bond (最小瓶颈生成树、树上倍增)
    【LA 5713 】 Qin Shi Huang's National Road System (MST)
  • 原文地址:https://www.cnblogs.com/mazhenyu/p/3806654.html
Copyright © 2011-2022 走看看