查看: 2085|回复: 0

RTTPICKEr分析

[复制链接]
  • TA的每日心情
    开心
    2020-3-20 17:50
  • 签到天数: 1 天

    [LV.1]初来乍到

    发表于 2020-4-14 10:43:59 | 显示全部楼层 |阅读模式
    本帖最后由 liyihongcug 于 2020-4-14 10:45 编辑

    RTTPICKEr 使用RTT 相机。
    Picks objects using an RTT camera and Vertex Attributes.

    说明如何操作
    /**
             * Starts a pick operation. When the operation completes, invokes the callback
             * with the results. You can use this method if you want to use the picker directly
             * WITHOUT installing it as an EventHandler. If you use it as an EventHandler, you
             * do NOT need to call this method directly; the Picker will call it upon handling
             * a pick event (i.e., when Callback::accept returns true).
             *
             * Returns true if the pick was succesfully queued; false if not.
             */

    着色器源码
    {
        // SHADERS for the RTT pick camera.

        const char* pickVertexEncode =
            "#version " GLSL_VERSION_STR "\n"

            "#pragma vp_entryPoint oe_pick_encodeObjectID\n"
            "#pragma vp_location   vertex_clip\n"
            
            "uint oe_index_objectid; \n"                        // Vertex stage global containing the Object ID; set in ObjectIndex shader.

            "flat out vec4 oe_pick_encoded_objectid; \n"        // output encoded oid to fragment shader
            "flat out int oe_pick_color_contains_objectid; \n"  // whether color already contains oid (written by another RTT camera)

            "void oe_pick_encodeObjectID(inout vec4 vertex) \n"
            "{ \n"
            "    oe_pick_color_contains_objectid = (oe_index_objectid == 1u) ? 1 : 0; \n"
            "    if ( oe_pick_color_contains_objectid == 0 ) \n"
            "    { \n"
            "        float b0 = float((oe_index_objectid & 0xff000000u) >> 24u); \n"
            "        float b1 = float((oe_index_objectid & 0x00ff0000u) >> 16u); \n"
            "        float b2 = float((oe_index_objectid & 0x0000ff00u) >> 8u ); \n"
            "        float b3 = float((oe_index_objectid & 0x000000ffu)       ); \n"
            "        oe_pick_encoded_objectid = vec4(b0, b1, b2, b3) / 255.0; \n"
            "    } \n"
            "} \n";

        const char* pickFragment =
            "#version " GLSL_VERSION_STR "\n"

            "#pragma vp_entryPoint oe_pick_renderEncodedObjectID\n"
            "#pragma vp_location   fragment_output\n"
            "#pragma vp_order      last\n"

            "flat in vec4 oe_pick_encoded_objectid; \n"
            "flat in int oe_pick_color_contains_objectid; \n"
            
            "out vec4 fragColor; \n"

            "void oe_pick_renderEncodedObjectID(inout vec4 color) \n"
            "{ \n"
            "    if ( oe_pick_color_contains_objectid == 1 ) \n"
            "        fragColor = color; \n"
            "    else \n"
            "        fragColor = oe_pick_encoded_objectid; \n"
            "} \n";
    }


    VirtualProgram*
    RTTPicker::createRTTProgram()
    {   
        VirtualProgram* vp = new VirtualProgram();
        vp->setName( "osgEarth::RTTPicker" );

        // Install RTT picker shaders:
        ShaderPackage pickShaders;
        pickShaders.add( "RTTPicker.vert.glsl", pickVertexEncode );
        pickShaders.add( "RTTPicker.frag.glsl", pickFragment );
        pickShaders.loadAll( vp );

        // Install shaders and bindings from the ObjectIndex:
        Registry:bjectIndex()->loadShaders( vp );

        return vp;
    }

    RTTPicker::RTTPicker(int cameraSize)
    {
        // group that will hold RTT children for all cameras
        _group = new osg::Group();

        // Size of the RTT camera image
        _rttSize = std::max(cameraSize, 4);   

        // pixels around the click to test
        _buffer = 2;
    }

    RTTPicker::~RTTPicker()
    {
        // remove the RTT camera from all views
        for(int i=0; i<_pickContexts.size(); ++i)
        {
            PickContext& pc = _pickContexts;
            while( pc._pickCamera->getNumParents() > 0 )
            {
                pc._pickCamera->getParent(0)->removeChild( pc._pickCamera.get() );
            }
        }
    }
    osgEarth::VirtualProgram在apply时用到了osg:rogram,也就是VirtualProgram最终是要通过osg::Program实现着色器功能,只不过VirtualProgram中还封装了一些其他内容(比如继承、抽象属性,着色器代码管理等),方便使用而已。
    您需要登录后才可以回帖 登录 | 注册

    本版积分规则

    OSG中国官方论坛-有您OSG在中国才更好

    网站简介:osgChina是国内首个三维相关技术开源社区,旨在为国内更多的技术开发人员提供最前沿的技术资讯,为更多的三维从业者提供一个学习、交流的技术平台。

    联系我们

    • 工作时间:09:00--18:00
    • 反馈邮箱:1315785073@qq.com
    快速回复 返回顶部 返回列表