koxter 发表于 2019-1-29 17:21:08

outline 与 天空盒 同时使用 outline 显示不全 求解

本帖最后由 koxter 于 2019-1-29 17:24 编辑

将例子 Examples osgvertexprogram 中的天空盒 与 OsgFx::outline 同时使用
随着相机旋转 outline不显示 或 变的显示不全
求解

koxter 发表于 2019-1-29 17:22:20

本帖最后由 koxter 于 2019-1-29 17:26 编辑

二楼是代码#include <osgViewer/Viewer>
#include <osg/Group>
#include <osg/Geode>
#include <osgGA/GUIEventHandler>
#include <osgFX/Outline>
#include <osg/ShapeDrawable>
#include <osg/Stencil>
#include <osg/CullFace>
#include <osg/PolygonMode>
#include <osg/LineWidth>
#include <osg/Material>
#include <osgFX/Outline>
#include <osgFX/BumpMapping>
#include <osg/Depth>
#include <osg/CullFace>
#include <osg/PolygonOffset>
#include <osg/PolygonMode>
#include <osg/Material>
#include <osgDB/ReadFile>
#include <osgGA/OrbitManipulator>
#include <osg/TexMat>
#include <osg/TexGen>
#include <osg/TexEnv>
#include <osg/TexEnvCombine>
#include <osg/TextureCubeMap>



osg::TextureCubeMap* readCubeMap()
{
        osg::TextureCubeMap* cubemap = new osg::TextureCubeMap;
        //#define CUBEMAP_FILENAME(face) "nvlobby_" #face ".png"
        //#define CUBEMAP_FILENAME(face) "Cubemap_axis/" #face ".png"
#define CUBEMAP_FILENAME(face) "Cubemap_snow/" #face ".jpg"

        osg::Image* imagePosX = osgDB::readImageFile(CUBEMAP_FILENAME(posx));
        osg::Image* imageNegX = osgDB::readImageFile(CUBEMAP_FILENAME(negx));
        osg::Image* imagePosY = osgDB::readImageFile(CUBEMAP_FILENAME(posy));
        osg::Image* imageNegY = osgDB::readImageFile(CUBEMAP_FILENAME(negy));
        osg::Image* imagePosZ = osgDB::readImageFile(CUBEMAP_FILENAME(posz));
        osg::Image* imageNegZ = osgDB::readImageFile(CUBEMAP_FILENAME(negz));

        if (imagePosX && imageNegX && imagePosY && imageNegY && imagePosZ && imageNegZ)
        {
                cubemap->setImage(osg::TextureCubeMap::POSITIVE_X, imagePosX);
                cubemap->setImage(osg::TextureCubeMap::NEGATIVE_X, imageNegX);
                cubemap->setImage(osg::TextureCubeMap::POSITIVE_Y, imagePosY);
                cubemap->setImage(osg::TextureCubeMap::NEGATIVE_Y, imageNegY);
                cubemap->setImage(osg::TextureCubeMap::POSITIVE_Z, imagePosZ);
                cubemap->setImage(osg::TextureCubeMap::NEGATIVE_Z, imageNegZ);

                cubemap->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_EDGE);
                cubemap->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_EDGE);
                cubemap->setWrap(osg::Texture::WRAP_R, osg::Texture::CLAMP_TO_EDGE);

                cubemap->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR_MIPMAP_LINEAR);
                cubemap->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR);
        }

        return cubemap;
}


// Update texture matrix for cubemaps
struct TexMatCallback : public osg::NodeCallback
{
public:

        TexMatCallback(osg::TexMat& tm) :
                _texMat(tm)
        {
        }

        virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
        {
                osgUtil::CullVisitor* cv = dynamic_cast<osgUtil::CullVisitor*>(nv);
                if (cv)
                {
                        const osg::Matrix& MV = *(cv->getModelViewMatrix());
                        const osg::Matrix R = osg::Matrix::rotate(osg::DegreesToRadians(112.0f), 0.0f, 0.0f, 1.0f)*
                                osg::Matrix::rotate(osg::DegreesToRadians(90.0f), 1.0f, 0.0f, 0.0f);

                        osg::Quat q = MV.getRotate();
                        const osg::Matrix C = osg::Matrix::rotate(q.inverse());

                        _texMat.setMatrix(C*R);
                }

                traverse(node, nv);
        }

        osg::TexMat& _texMat;
};


class MoveEarthySkyWithEyePointTransform : public osg::Transform
{
public:
        /** Get the transformation matrix which moves from local coords to world coords.*/
        virtual bool computeLocalToWorldMatrix(osg::Matrix& matrix, osg::NodeVisitor* nv) const
        {
                osgUtil::CullVisitor* cv = dynamic_cast<osgUtil::CullVisitor*>(nv);
                if (cv)
                {
                        osg::Vec3 eyePointLocal = cv->getEyeLocal();
                        matrix.preMultTranslate(eyePointLocal);
                }
                return true;
        }

        /** Get the transformation matrix which moves from world coords to local coords.*/
        virtual bool computeWorldToLocalMatrix(osg::Matrix& matrix, osg::NodeVisitor* nv) const
        {
                osgUtil::CullVisitor* cv = dynamic_cast<osgUtil::CullVisitor*>(nv);
                if (cv)
                {
                        osg::Vec3 eyePointLocal = cv->getEyeLocal();
                        matrix.postMultTranslate(-eyePointLocal);
                }
                return true;
        }
};


osg::Node* createSkyBox()
{

        osg::StateSet* stateset = new osg::StateSet();

        osg::TexEnv* te = new osg::TexEnv;
        te->setMode(osg::TexEnv::REPLACE);
        stateset->setTextureAttributeAndModes(0, te, osg::StateAttribute::ON);

        osg::TexGen *tg = new osg::TexGen;
        tg->setMode(osg::TexGen::NORMAL_MAP);
        stateset->setTextureAttributeAndModes(0, tg, osg::StateAttribute::ON);

        osg::TexMat *tm = new osg::TexMat;
        stateset->setTextureAttribute(0, tm);

        osg::TextureCubeMap* skymap = readCubeMap();
        stateset->setTextureAttributeAndModes(0, skymap, osg::StateAttribute::ON);

        stateset->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
        stateset->setMode(GL_CULL_FACE, osg::StateAttribute::OFF);

        // clear the depth to the far plane.
        osg::Depth* depth = new osg::Depth;
        depth->setFunction(osg::Depth::ALWAYS);
        depth->setRange(1.0, 1.0);
        stateset->setAttributeAndModes(depth, osg::StateAttribute::ON);

        stateset->setRenderBinDetails(-1, "RenderBin");

        osg::Drawable* drawable = new osg::ShapeDrawable(new osg::Sphere(osg::Vec3(0.0f, 0.0f, 0.0f), 1));

        osg::Geode* geode = new osg::Geode;
        geode->setCullingActive(false);
        geode->setStateSet(stateset);
        geode->addDrawable(drawable);


        osg::Transform* transform = new MoveEarthySkyWithEyePointTransform;
        transform->setCullingActive(false);
        transform->addChild(geode);

        osg::ClearNode* clearNode = new osg::ClearNode;
        //clearNode->setRequiresClear(false);
        clearNode->setCullCallback(new TexMatCallback(*tm));
        clearNode->addChild(transform);

        return clearNode;
}


int main(int argc, char **argv)
{

        // must have stencil buffer...
        osg::DisplaySettings::instance()->setMinimumNumStencilBits(1);

        // construct the viewer
        osgViewer::Viewer viewer;
        viewer.setUpViewInWindow(100, 100, 800, 600);


        osg::ref_ptr<osg::Group> root = new osg::Group;

        // read the scene from the list of file specified commandline args.
        osg::ref_ptr<osg::Node> loadedModel = osgDB::readNodeFile("cow.osgt");
        osgFX::Outline* pOutLine = new osgFX::Outline;
        pOutLine->setName("OutLineEffect");
        pOutLine->setColor(osg::Vec4(1.0, 0.0f, 0.0f, 1.0f));
        pOutLine->setWidth(10.0f);
        pOutLine->addChild(loadedModel);
        root->addChild(pOutLine);
        root->addChild(createSkyBox());

        //////////////////////////////////////////////////////////////////////////

        // construct the viewer
        viewer.setSceneData(root.get());

        // must clear stencil buffer...
        unsigned int clearMask = viewer.getCamera()->getClearMask();
        viewer.getCamera()->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
        return viewer.run();

}

koxter 发表于 2019-1-29 18:43:00

找到原因了, 是天空盒ClearNode节点的原因
页: [1]
查看完整版本: outline 与 天空盒 同时使用 outline 显示不全 求解