• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            戰魂小筑

            討論群:309800774 知乎關注:http://zhihu.com/people/sunicdavy 開源項目:https://github.com/davyxu

               :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
              257 隨筆 :: 0 文章 :: 506 評論 :: 0 Trackbacks
             

            最近在寫D3D9模擬D3D10接口的渲染系統中碰到大量的渲染狀態對象,不僅成員多,枚舉也多的要命。

             

                struct CORE_API RasterizerState : ResourceHandle            
                {
                    eFillMode            mFillMode;        
                    eCullMode            mCullMode;
                    bool                mFrontFaceCCW;
                    float                mDepthBias;
                    float                mSlopeScaledDepthBias;
                    bool                mDepthClipEnable;
                    bool                mScissorEnable;
                    bool                mMultisampleEnable;
            
                    RasterizerState();
                };
            

            而要從配置文件中讀取數據并填充到這個結構體,對于C++來說完全就是吃力不討好的,寫出來的代碼也是極為過程,修改和擴展極為麻煩的。

            因此決定使用反射的方法來填充數據,先總結一下我的C++反射系統

            class RTTIObject // 動態類型識別對象基類,對象通過一些宏后可以很方便的通過字符串創建出類實例,并且可以查詢注冊時的類型和其他綁定信息
            class NameRef  // 名字表,類似于虛幻中的FName,可以定義Const和普通Name,比較和拷貝只是一個dword耗費的時間
            value_parse,value_tostring,value_typename // 一系列類型模板函數,提供對類型的ToString,Parse及類型名查詢

             

            首先需要處理的是枚舉查詢,這里將枚舉通過宏做成一個個枚舉對象,并可以通過名字創建實例

            #define DECLARE_ENUMOBJECT( TEnum ) \
                struct EnumObject_##TEnum : EnumObject\
                {\
                DECLARE_RTTIOBJECT( EnumObject_##TEnum );\
                EnumObject_##TEnum( );\
                };
            
            
            #define IMPLEMENT_ENUMOBJECT_BEGIN( TEnum, TEnum_prefixoffset, TMember_prefixoffset ) \
                IMPLEMENT_RTTIOBJECT_STRING( EnumObject_##TEnum, #TEnum + TEnum_prefixoffset, #TEnum + TEnum_prefixoffset, "EnumObject" )\
                EnumObject_##TEnum::EnumObject_##TEnum(){ const int member_prefixoffset = TMember_prefixoffset;
            
            #define ENUMOBJECT_ADD( enumkey ) AddMember( #enumkey + member_prefixoffset, (dword)enumkey );
            
            #define IMPLEMENT_ENUMOBJECT_END }
            
            #define ENUMOBJECT_STATICINIT( TEnum ) EnumObject_##TEnum::StaticInit();
            

            EnumObject 中通過宏將枚舉的名稱和值保存在這個對象中

            IMPLEMENT_ENUMOBJECT_BEGIN( eFillMode, 1, 3 )  // 這里的1,3是將eFillMode及FM_Point轉成字符串后去掉前綴
                ENUMOBJECT_ADD( FM_Point )
                ENUMOBJECT_ADD( FM_Line )
                ENUMOBJECT_ADD( FM_Fill )
            IMPLEMENT_ENUMOBJECT_END
            
            // 注冊到RTTIObject系統
            
            ENUMOBJECT_STATICINIT( eFillMode )
            

             

            // 通過枚舉對象可以查找到字符串對應的值
            dword v;
            EnumObject::GetEnumValue( "FillMode", "Point", v )
            
            
            
            

            下一步是將結構體成員信息記錄

                void SettingObject::BindMember( const NameRef& objname, void* instancePtr, void* dataPtr, SettingProxy* proxy )
                {
                    proxy->mOffset = dword(dataPtr) - dword(instancePtr);
            
                    MemberList& memberlist = mSettingMap[ objname ];
                    memberlist[ proxy->mName ] = proxy;
                }

            這里記錄的是結構體成員的內存偏移

            使用大量的宏,可以讓結構體綁定變得漂亮

            #define BIND_SETTINGOBJECT_BEGIN( TClass ) \
                { const NameRef& soname = TClass::StaticGetClassInfo()->mClassName;TClass soobj;
            
            #define BIND_SO_MEMBER( TMemberType, TMember ) \
                so.BindMember( soname, &soobj, &soobj.TMember, new TSettingElement<TMemberType>(#TMember + 1 ) );
            
            #define BIND_SO_MEMBER_NAME( TMemberType, TMember, TName ) \
                so.BindMember( soname, &soobj, &soobj.TMember, new TSettingElement<TMemberType>(TName) );
            
            #define BIND_SO_ENUM( TEnumType, TMember ) \
                so.BindMember( soname, &soobj, &soobj.TMember, new TSettingEnum(#TMember + 1, #TEnumType + 1) );
            
            #define BIND_SO_ENUM_NAME( TEnumType, TMember, TName ) \
                so.BindMember( soname, &soobj, &soobj.TMember, new TSettingEnum(TName, #TEnumType + 1) );
            
            #define BIND_SETTINGOBJECT_END }

            綁定代碼如下

                    BIND_SETTINGOBJECT_BEGIN( RasterizerState )
                        BIND_SO_ENUM    ( eFillMode    , mFillMode )
                        BIND_SO_ENUM    ( eCullMode    , mCullMode )
                        BIND_SO_MEMBER    ( bool        , mFrontFaceCCW )
                        BIND_SO_MEMBER    ( float        , mDepthBias )
                        BIND_SO_MEMBER    ( float        , mSlopeScaledDepthBias)
                        BIND_SO_MEMBER    ( bool        , mDepthClipEnable)
                        BIND_SO_MEMBER    ( bool        , mScissorEnable)
                        BIND_SO_MEMBER    ( bool        , mMultisampleEnable)
                    BIND_SETTINGOBJECT_END

             

            所有結構體的信息被記錄在SettingObject中,讀取配置文件填充結構體的任務就變得異常的簡單了

                SettingObject settings;
            // 將所有的結構體信息記錄
                InitRenderStateObjectSetting( settings );
            
                const NameRef& rzname = DepthStencilState::StaticGetClassInfo()->mClassName;
            
                DepthStencilState a;
             // 這里就是將配置文件的信息填充到結構體
                settings.SetMember( rzname, &a, "BackFace.StencilFunc", "Equal" );
             
            posted on 2010-02-26 17:58 戰魂小筑 閱讀(2534) 評論(0)  編輯 收藏 引用 所屬分類: 游戲開發技術C++/ 編程語言渲染 Shader 引擎
            人人狠狠综合88综合久久| 久久久一本精品99久久精品66 | 99久久免费国产特黄| 99久久国产热无码精品免费| 人人狠狠综合久久亚洲婷婷| 久久人人爽人人精品视频| 四虎国产精品成人免费久久| 久久精品aⅴ无码中文字字幕不卡| 久久精品这里热有精品| 无码人妻久久一区二区三区蜜桃| 亚洲色欲久久久综合网| 伊人久久大香线焦综合四虎| 亚洲国产天堂久久综合| 久久久久久久久久久久中文字幕 | 亚洲欧美久久久久9999| 久久婷婷成人综合色综合| 精品久久久久中文字| 国产69精品久久久久久人妻精品| 色综合久久久久| 日韩av无码久久精品免费| 久久精品国产一区二区三区不卡 | 久久天堂AV综合合色蜜桃网| 精品久久久久久无码国产| 亚洲伊人久久精品影院| 久久中文字幕视频、最近更新| 久久久久AV综合网成人| 综合久久久久久中文字幕亚洲国产国产综合一区首| 97香蕉久久夜色精品国产| 国产精品99久久不卡| 欧美va久久久噜噜噜久久| 亚洲AV伊人久久青青草原| 伊人久久大香线焦综合四虎| 久久香蕉国产线看观看精品yw| 亚洲人成无码www久久久| 国产精品亚洲美女久久久| 狠狠干狠狠久久| 丰满少妇人妻久久久久久| 色综合久久综合中文综合网| 亚洲国产成人乱码精品女人久久久不卡 | 久久久久国色AV免费观看 | 中文精品久久久久人妻不卡|