• <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 引擎
            狠狠色狠狠色综合久久 | 久久无码AV中文出轨人妻| 久久不射电影网| 久久久噜噜噜久久熟女AA片| 久久精品国产日本波多野结衣| 亚洲精品乱码久久久久久| 久久久久亚洲av无码专区喷水| 热99RE久久精品这里都是精品免费| 国内精品久久久久久不卡影院| 久久精品国产精品亚洲精品| 91精品国产高清91久久久久久| 久久人人爽人爽人人爽av| 麻豆精品久久久久久久99蜜桃| 亚洲欧洲精品成人久久曰影片 | 久久香综合精品久久伊人| 久久国产AVJUST麻豆| 亚洲精品美女久久久久99小说| 少妇熟女久久综合网色欲| 亚洲精品无码久久久影院相关影片| 婷婷久久久亚洲欧洲日产国码AV | 综合久久精品色| 18岁日韩内射颜射午夜久久成人| 精品久久久久中文字幕日本| 久久久久亚洲AV综合波多野结衣 | 久久天天躁狠狠躁夜夜2020老熟妇 | 国产免费久久精品99久久| 成人午夜精品无码区久久| 久久人爽人人爽人人片AV | 日日狠狠久久偷偷色综合0| 久久精品一区二区国产| 久久精品国产99久久久香蕉| 国产亚洲美女精品久久久久狼| 久久99精品久久久久久水蜜桃| 国产aⅴ激情无码久久| 久久99国产精品久久99| 欧美精品乱码99久久蜜桃| 99久久婷婷免费国产综合精品| 亚洲婷婷国产精品电影人久久| 久久精品国产亚洲av高清漫画| 欧美精品一区二区久久| 99精品久久精品一区二区|