• <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 戰魂小筑 閱讀(2544) 評論(0)  編輯 收藏 引用 所屬分類: 游戲開發技術 、C++/ 編程語言 、渲染 Shader 引擎
            无码任你躁久久久久久久| 99久久综合狠狠综合久久| 亚洲另类欧美综合久久图片区| 欧美午夜精品久久久久久浪潮| 久久成人小视频| 久久久精品免费国产四虎| 亚洲人成电影网站久久| jizzjizz国产精品久久| 欧美亚洲日本久久精品| 91精品国产综合久久香蕉 | 99热成人精品免费久久| 久久免费看黄a级毛片| 91亚洲国产成人久久精品网址 | 亚洲国产另类久久久精品| 久久电影网| 久久久精品午夜免费不卡| 久久人人爽人人爽人人片AV不 | 看全色黄大色大片免费久久久| 久久永久免费人妻精品下载| 欧美久久亚洲精品| 狠狠久久综合| 久久久久久免费一区二区三区| 久久无码中文字幕东京热| 一本一本久久a久久精品综合麻豆| 久久99国产精品久久99果冻传媒| 久久久亚洲欧洲日产国码是AV| 亚洲精品第一综合99久久 | 久久久久女教师免费一区| 久久精品国产亚洲77777| 久久久国产精华液| 久久精品国产欧美日韩99热| 久久无码精品一区二区三区| 久久国产成人| 欧美亚洲国产精品久久久久| 久久中文精品无码中文字幕| 伊人热热久久原色播放www| 久久久久黑人强伦姧人妻| 欧美激情精品久久久久久久| 久久免费大片| 中文字幕无码精品亚洲资源网久久| 久久精品国产日本波多野结衣|