Hello

osgFX::Outline does not work in GL3 mode
I get the following warnings, and no outline rendered

Warning: PolygonMode::apply(State&) - only GL_FRONT_AND_BACK is supported.

Warning: Material::apply(State&) - not supported.


Attached is a simple fix.
I changed the line polygon mode from GL_BACK to GL_FRONT_AND_BACK.
I introduced a minimal shader program with material color uniform.

I surrounded changes with OSG_GL3_AVAILABLE preprocessor tests

now rendering works, and I don't get the warnings anymore.

please review

Cheers,
Rémi
// -*-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/GL>
#include <osg/Group>
#include <osg/Stencil>
#include <osg/CullFace>
#include <osg/PolygonMode>
#include <osg/LineWidth>
#ifdef OSG_GL3_AVAILABLE
#include <osg/Uniform>
#include <osg/Program>
#else
#include <osg/Material>
#endif
#include <osg/Texture1D>


namespace
{
    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 Outline::OutlineTechnique : public Technique
    {
    public:
        /// Constructor.
        OutlineTechnique() : Technique(),
            _lineWidth(), _width(2),
#ifdef OSG_GL3_AVAILABLE
            _matColorUnif(),
#else
            _material(),
#endif
            _color(1,1,1,1) {
        }

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

        /// Set outline width.
        void setWidth(float w) {
            _width = w;
            if (_lineWidth.valid()) {
                _lineWidth->setWidth(w);
            }
        }

        /// Set outline color.
        void setColor(const osg::Vec4& color) {
            _color = color;
#ifdef OSG_GL3_AVAILABLE
            if (_matColorUnif.valid()) {
                _matColorUnif->set(_color);
            }
#else
            if (_material.valid()) {
                const osg::Material::Face face = osg::Material::FRONT_AND_BACK;
                _material->setAmbient(face, osg::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
                _material->setDiffuse(face, osg::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
                _material->setSpecular(face, osg::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
                _material->setEmission(face, color);
            }
#endif
        }

    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, ~0u);
                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, ~0u);
                stencil->setOperation(osg::Stencil::KEEP,
                                      osg::Stencil::KEEP,
                                      osg::Stencil::REPLACE);
                state->setAttributeAndModes(stencil, Override_On);

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

                // draw back-facing polygon lines
                osg::PolygonMode* polyMode = new osg::PolygonMode;
#ifdef OSG_GL3_AVAILABLE
                polyMode->setMode(osg::PolygonMode::FRONT_AND_BACK, 
osg::PolygonMode::LINE);
#else
                polyMode->setMode(osg::PolygonMode::BACK, 
osg::PolygonMode::LINE);
#endif
                state->setAttributeAndModes(polyMode, Override_On);

                // outline width
                _lineWidth = new osg::LineWidth;
                setWidth(_width);
                state->setAttributeAndModes(_lineWidth.get(), Override_On);

#ifdef OSG_GL3_AVAILABLE
                // outline program
                const char *vertex_shader =
                        "#version 330\n"
                        "in vec4 osg_Vertex;\n"
                        "uniform mat4 osg_ModelViewProjectionMatrix;\n"

                        "void main(void)\n"
                        "{\n"
                        "    gl_Position = osg_ModelViewProjectionMatrix * 
osg_Vertex;\n"
                        "}\n";
                const char *fragment_shader =
                        "#version 330\n"
                        "uniform vec4 un_matColor;\n"
                        "out vec4 out_fragColor;\n"

                        "void main(void)\n"
                        "{\n"
                        "    out_fragColor = un_matColor;\n"
                        "}\n";
                osg::ref_ptr<osg::Program> prog = new osg::Program;
                osg::ref_ptr<osg::Shader> vs = new 
osg::Shader(osg::Shader::VERTEX, vertex_shader);
                osg::ref_ptr<osg::Shader> fs = new 
osg::Shader(osg::Shader::FRAGMENT, fragment_shader);
                prog->addShader(vs.get());
                prog->addShader(fs.get());
                state->setAttributeAndModes(prog.get(), Override_On);

                // outline color/material
                _matColorUnif = new osg::Uniform("un_matColor", _color);
                state->addUniform(_matColorUnif.get(), Override_On);
#else
                // outline color/material
                _material = new osg::Material;
                _material->setColorMode(osg::Material::OFF);
                setColor(_color);
                state->setAttributeAndModes(_material.get(), Override_On);
#endif

                // 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 width.
        osg::ref_ptr<osg::LineWidth> _lineWidth;
        float _width;

        /// Outline Material.
#ifdef OSG_GL3_AVAILABLE
        osg::ref_ptr<osg::Uniform> _matColorUnif;
#else
        osg::ref_ptr<osg::Material> _material;
#endif
        osg::Vec4 _color;
    };


    /**
     * Outline effect.
     */
    Outline::Outline() : Effect(), _width(2), _color(1,1,1,1), _technique(0)
    {
    }

    void Outline::setWidth(float w)
    {
        _width = w;
        if (_technique) {
            _technique->setWidth(w);
        }
    }

    void Outline::setColor(const osg::Vec4& color)
    {
        _color = color;
        if (_technique) {
            _technique->setColor(color);
        }
    }

    bool Outline::define_techniques()
    {
        _technique = new OutlineTechnique;
        addTechnique(_technique);

        setWidth(_width);
        setColor(_color);

        return true;
    }
}
23a24
> #include <osg/GL>
28a30,33
> #ifdef OSG_GL3_AVAILABLE
> #include <osg/Uniform>
> #include <osg/Program>
> #else
29a35
> #endif
54c60,65
<             _material(), _color(1,1,1,1) {
---
> #ifdef OSG_GL3_AVAILABLE
>             _matColorUnif(),
> #else
>             _material(),
> #endif
>             _color(1,1,1,1) {
72a84,88
> #ifdef OSG_GL3_AVAILABLE
>             if (_matColorUnif.valid()) {
>                 _matColorUnif->set(_color);
>             }
> #else
79a96
> #endif
129a147,149
> #ifdef OSG_GL3_AVAILABLE
>                 polyMode->setMode(osg::PolygonMode::FRONT_AND_BACK, 
> osg::PolygonMode::LINE);
> #else
130a151
> #endif
137a159,189
> #ifdef OSG_GL3_AVAILABLE
>                 // outline program
>                 const char *vertex_shader =
>                         "#version 330\n"
>                         "in vec4 osg_Vertex;\n"
>                         "uniform mat4 osg_ModelViewProjectionMatrix;\n"
> 
>                         "void main(void)\n"
>                         "{\n"
>                         "    gl_Position = osg_ModelViewProjectionMatrix * 
> osg_Vertex;\n"
>                         "}\n";
>                 const char *fragment_shader =
>                         "#version 330\n"
>                         "uniform vec4 un_matColor;\n"
>                         "out vec4 out_fragColor;\n"
> 
>                         "void main(void)\n"
>                         "{\n"
>                         "    out_fragColor = un_matColor;\n"
>                         "}\n";
>                 osg::ref_ptr<osg::Program> prog = new osg::Program;
>                 osg::ref_ptr<osg::Shader> vs = new 
> osg::Shader(osg::Shader::VERTEX, vertex_shader);
>                 osg::ref_ptr<osg::Shader> fs = new 
> osg::Shader(osg::Shader::FRAGMENT, fragment_shader);
>                 prog->addShader(vs.get());
>                 prog->addShader(fs.get());
>                 state->setAttributeAndModes(prog.get(), Override_On);
> 
>                 // outline color/material
>                 _matColorUnif = new osg::Uniform("un_matColor", _color);
>                 state->addUniform(_matColorUnif.get(), Override_On);
> #else
142a195
> #endif
160a214,216
> #ifdef OSG_GL3_AVAILABLE
>         osg::ref_ptr<osg::Uniform> _matColorUnif;
> #else
161a218
> #endif
_______________________________________________
osg-submissions mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-submissions-openscenegraph.org

Reply via email to