C 教程 DirectX11Frame屬性

2021-07-22 23:55:12 字數 3215 閱讀 7390

原本打算先和大家說怎麼在c++裡面操作的lua的,畢竟這個frame的主要功能便是靠lua實現的,但是想想可能有些朋友對lua不甚了解所以在說怎麼和lua通訊之前那麼大家可以先了解lua是個什麼鬼,哦,對了,我用的是5.3版本的,雖然這個版本沒什麼第三方庫,但是現在很多常用的東西我自己已經新增好,所以順手了也就無所謂了。

那麼今天我們從什麼地方入手呢?嗯,好吧,就從「屬性」這玩意而已開始吧,屬性這個東西可能不是大家想想的屬性,我取名字這事已經被同事吐槽了不下10次了,總覺得我名字莫名其妙,好吧,不說這些,先來認識下我所謂的屬性到底是個什麼鬼吧。

假設物件a表示乙個矩形,那麼他將有長和寬的概念,另乙個物件b表示乙個橢圓,當物件a的尺寸發生變化時而物件b能夠知道a的尺寸發生變化而做出相應的改變,這就是我所謂的屬性的概念,長和寬是矩形的屬性,屬性改變將會通知關心他屬性的物件所作相應的動作,現在我用**模擬這種情況出來:

//***********************************

class a

private:

mstring mvalue;

};class b

private:

mstring mvalue;

};void testfun(const mstring& value)

int main()

//***********************************===

現在我們要做的事就是當a類的setvalue被呼叫時b類的setvalue也相應的被呼叫,也就是a的mvalue的值被修改時那麼b也應當修改自己的mvalue值,現在我們要解決的就是該問題。

解決該問題的方法可能有很多,如果在qt裡面我們可以考慮使用訊號槽來解決,在mfc中可以考慮使用事件通知來完成,在c#裡面使用事件委託來完成,嗯不過好像不論是哪一種方式感覺都不是最理想的,因為如果使用訊號槽那麼如果我們需要觀察多個屬性的話可能會要定義好多個訊號,同樣如果使用事件的話那麼我們同樣需要定義很多事件型別,所以這些都不是乙個一勞永逸的方法,這都是我所認為最理想的方法。

大家可能想起了前面我們所說的boost裡面的訊號槽,不錯的主意,但是這個qt的訊號槽本身是差不多的東西,所以一樣不滿意,當然最重要的一點,如果我們通過obja呼叫setvalue的時候會觸發objb的setvalue,而objb在呼叫setvalue的時候就會觸發testfun,那麼無論是qt的訊號槽還是boost的訊號槽都沒法做到,那麼好吧,這樣一來似乎沒有什麼選擇的餘地了,要麼是函式物件要麼就是函式指標。

接下來要說的東西可能以我之口舌沒法很好的說清楚,重要的還是大家多理解**,我覺得一碼勝千言。要讓obja和objb聯絡起來那麼必然通過一種介質,假如這個函式為connect,那麼我們先將設會是下面這種形式:

connect(siganl(obja,***x),slot(objb,***x));

這個形式模仿的是qt的connect,這就不說了,我們現在來看看如果實現這個connect函式,而他的引數又應該是什麼?想一下,當我們操作obja到時候objb會得到相應的響應,那麼這個函式裡面我們至少要知道obja和objb關聯的到底是那個函式,所以此處應該需要將函式傳遞到connnect裡面。ok,現在我們來看乙個原型:

template

void connect(

const mstring& funname,

void(t::*fun1)(args...),

t* obj1,

std::function eventfun

)從這個原型我們幾乎可以肯定這就是我們所需要的了,funname是函式的名字fun1就是obja要呼叫的函式,obj1就是obja,eventfun即為我們被觸發的函式,從這個函式原型來看他是支援無限引數的,所以他所完成的事是qt的訊號槽亦或是boost的訊號都做不到的,大家也許會像何以見得呢?當然更多的可能是怎麼來呼叫這個函式?和上面一樣我們可以再進一步封裝然後如下呼叫:

connect(msignal(testa, setvalue, &obja),mslot(&b::setvalue,&objb));

這樣一來是不是很清晰了呢?msignal包裝的是類的名字,函式,物件的指標,mslot的引數為成員函式的位址以及物件指標,好吧,這就作為我們的呼叫約定,那麼問題來了,msignal和mslot是如何實現的呢?為什麼兩個引數呼叫方式差距還如此之大呢?為了滿足我們上面connect的原型,signal必須能夠生成乙個和函式名等同的字串以及該函式的函式指標和乙個物件指標,而mslot將會通過成員函式的位址以及物件指標生成乙個函式物件出來。

看到這裡大家是不是覺得開始有些懵了呢?好吧,我們正在c++的路上越走越深,因為這些如果不是出於構建庫的目的話正常使用過程中幾乎可能肯定不會使用得到。

msignal和mslot的呼叫差別如此之大正是因為兩者的實現方式天差地別,因為msignal的現實相當簡單,其實他就是乙個巨集定義:

#ifndef msignal

#define msignal(classname,memfun,obj) #memfun,&classname::memfun,obj

#endif

但是mslot的實現卻相當複雜,要說清楚真心不是那麼容易,**雖然不多,但是想要理清還是需要好好琢磨一下:

//***********************************

//// 下面只是一些輔助函式,不需要看懂,只需要知道怎麼使用mslot即可

//template

struct mpropertyfunhelp

};template<>

struct mpropertyfunhelp<0>

};template

struct tofun

};template

struct tofun

};//

// 包裝成員函式,我們需要用的就是下面的函式

//template

std::function mslot(r(t::*fun)(args...),t* obj)

//// 包裝自由函式

//template

std::function mslot(r(*fun)(args...))

//******************************==

到此下面的函式便可被正確呼叫了:

connect(msignal(testa, setvalue, &obja),mslot(&b::setvalue,&objb));

該呼叫模式適用於任何型別包括自由函式而且不受引數個數限制都是同樣的呼叫方式,也就是說無論setvalue和setvalue的引數有多少個上面的函式呼叫依舊不變。

Directx11教程37 紋理對映 7

本章是在教程35 36的基礎上來實現乙個光照紋理結合的程式,就是把場景中旋轉的cube加上紋理。lighttex.vs中頂點的結構現在為 struct vertexinputtype 紋理座標 output.tex input.tex 紋理座標不做任何變化,只是單純的從vs輸出到ps中。lightt...

Directx11教程38 紋理對映 8

上篇日誌中,我們用紋理和光照顏色調製的方式得到最終顏色,本章我們嘗試用紋理取樣的顏色,直接做為材質的漫反射係數kd,並用它來做光照計算,最後再做個gamma校正,如果不做的話,效果會偏亮。lighttex.ps主要改動 float4 texturecolor shadertexture.sample...

Directx11教程39 紋理對映 9

在mytutoriald3d11 32中,我們在planemodelclass中增加乙個紋理textureclass m texture 讀入乙個grass的紋理,程式執行後的效果如下 完整的 請參考 工程檔案mytutoriald3d11 32 在mytutoriald3d11 33中,我們移去了...