• <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 戰魂小筑 閱讀(2539) 評論(0)  編輯 收藏 引用 所屬分類: 游戲開發技術C++/ 編程語言渲染 Shader 引擎
            AA级片免费看视频久久| 久久久久国产视频电影| 久久精品天天中文字幕人妻| 亚洲精品国精品久久99热一| 久久天天躁狠狠躁夜夜2020一| 久久人妻AV中文字幕| 久久婷婷激情综合色综合俺也去| 久久精品国产99久久久| 国内精品久久久久久久影视麻豆| 久久久精品国产免大香伊| 97久久精品无码一区二区| 久久久久久国产精品免费免费| 免费精品久久天干天干| 国产精品永久久久久久久久久 | 亚洲国产成人久久一区久久| 狠狠色狠狠色综合久久| 狠狠久久综合| 国内精品伊人久久久久av一坑| 久久久久亚洲AV成人网人人网站 | 99久久国产综合精品麻豆| 国内精品久久久久久不卡影院 | 久久国产高清字幕中文| 亚洲国产另类久久久精品黑人| 久久99国产精品成人欧美| 久久久久久久久久久久中文字幕| 久久久久人妻一区精品| 99久久国产综合精品网成人影院| 国内精品综合久久久40p| 久久人人爽人人爽人人片AV东京热| 久久国产精品77777| 亚洲午夜久久久影院| 女人高潮久久久叫人喷水| 热久久国产精品| 秋霞久久国产精品电影院| 久久99精品久久久久久久不卡| 色综合久久久久久久久五月| AAA级久久久精品无码片| 蜜臀久久99精品久久久久久小说 | 免费一级做a爰片久久毛片潮| 国内精品久久久久久久涩爱| 亚洲欧美精品伊人久久|