真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

C++教程:DirectX11Frame

C++教程:DirectX11Frame

創(chuàng)新互聯(lián)是一家集網(wǎng)站建設(shè),金臺(tái)企業(yè)網(wǎng)站建設(shè),金臺(tái)品牌網(wǎng)站建設(shè),網(wǎng)站定制,金臺(tái)網(wǎng)站建設(shè)報(bào)價(jià),網(wǎng)絡(luò)營(yíng)銷,網(wǎng)絡(luò)優(yōu)化,金臺(tái)網(wǎng)站推廣為一體的創(chuàng)新建站企業(yè),幫助傳統(tǒng)企業(yè)提升企業(yè)形象加強(qiáng)企業(yè)競(jìng)爭(zhēng)力??沙浞譂M足這一群體相比中小企業(yè)更為豐富、高端、多元的互聯(lián)網(wǎng)需求。同時(shí)我們時(shí)刻保持專業(yè)、時(shí)尚、前沿,時(shí)刻以成就客戶成長(zhǎng)自我,堅(jiān)持不斷學(xué)習(xí)、思考、沉淀、凈化自己,讓我們?yōu)楦嗟钠髽I(yè)打造出實(shí)用型網(wǎng)站。

前面幾講的內(nèi)容過(guò)于難了一些,當(dāng)然看不懂沒(méi)關(guān)系,因?yàn)樵谡麄€(gè)框架里面他們只是作為底層應(yīng)用來(lái)使用,而最終暴露的接口都相當(dāng)?shù)囊子谑褂?,那么,?duì)于拿來(lái)主義這就足夠了,因?yàn)榻酉聛?lái)的內(nèi)容都注定會(huì)是一馬平川。

回顧我們前面說(shuō)過(guò)的內(nèi)容:一套反射機(jī)制(對(duì)于這種非主流的GUI庫(kù)來(lái)說(shuō)沒(méi)有反射靠硬編碼來(lái)實(shí)現(xiàn)界面配置的話那么結(jié)果會(huì)是有些吃力不討好),一套事件系統(tǒng)(新的事件機(jī)制沒(méi)有推送,以前我們使用的事件響應(yīng)是依賴于boost的signal,不過(guò)boost的signal后來(lái)被我廢棄了,所以現(xiàn)在的事件響應(yīng)是一套全新的方案,當(dāng)然也不算是全新的了,因?yàn)榇笾陆Y(jié)構(gòu)是模仿C#的事件),一套完備的屬性系統(tǒng)(微信里面推送的是當(dāng)初設(shè)計(jì)這個(gè)屬性的一個(gè)版本,它的缺點(diǎn)我們已經(jīng)說(shuō)過(guò),至于第二個(gè)版本沒(méi)有在微信里進(jìn)行推送,第二個(gè)版本不但支持多槽函數(shù)進(jìn)行綁定還支持同步和異步兩種連接方式,當(dāng)然最重要的還實(shí)現(xiàn)了對(duì)象有效性的追蹤),一個(gè)基礎(chǔ)對(duì)象MObject(該對(duì)象繼承至屬性和反射,所以凡是MObject的子類都可以實(shí)現(xiàn)動(dòng)態(tài)創(chuàng)建對(duì)象以及除了使用新的事件機(jī)制向外部發(fā)送事件外還能夠使用屬性的操作方式和一些需要接收事件的槽函數(shù)進(jìn)行同步)。

好吧,簡(jiǎn)單的總結(jié)了一些我們前面說(shuō)過(guò)的一些東西后下面我們繼續(xù)向前,如同前面我們說(shuō)過(guò),DirectX本身并沒(méi)有窗口的概念,他需要依附在特定的窗口上面才能夠進(jìn)行可視化的繪制,而標(biāo)識(shí)這個(gè)窗口的東西就是HWND。雖然當(dāng)初這個(gè)Frame使用win32來(lái)實(shí)現(xiàn)的,但后來(lái)被應(yīng)用在Qt里面(公司使用的是Qt)進(jìn)行項(xiàng)目開(kāi)發(fā),所以該Frame的設(shè)計(jì)就是支持跨平臺(tái)的(不是指操作系統(tǒng),而是指在Windows下面的開(kāi)發(fā)平臺(tái)),只要能夠獲取到HWND就能夠使用這套Frame。

為了達(dá)到上面的效果,我們有必要來(lái)設(shè)計(jì)一個(gè)基礎(chǔ)窗口類,它提供了一些必須的接口以及一些共有的實(shí)現(xiàn),這個(gè)類就是MAppWindow.

//===============================

#pragma once

#include "MDx11Comm.h"

#include "MObject.h"

class MAppWindow : public MObject

{

public:

//

// 鼠標(biāo)消息函數(shù)

// 鼠標(biāo)按鍵,鼠標(biāo)動(dòng)作,x,y,是否為全局坐標(biāo)

//

//

typedef std::function MouseFunType;

typedef std::function ADD_INIT; // 附加初始化函數(shù)

typedef std::function RECALL_INIT; // 初始化函數(shù)

typedef std::function RECALL_DRAW; // 繪圖函數(shù)

typedef std::function RECALL_CLEAR; // 清理資源函數(shù)

typedef std::function RECALL_RESHAPE; // 更改尺寸處理函數(shù)

typedef std::function RECALL_WNDPROC; // 底層消息回調(diào)處理函數(shù)

typedef std::function RECALL_IDLE; // 空閑處理函數(shù)

typedef std::function RECALL_UPDATA; // 動(dòng)畫(huà)更新函數(shù)

typedef std::function InputFunType; // 輸入回掉函數(shù)

typedef std::function KeyEventFunType; // 鍵盤(pán)狀態(tài)回調(diào)函數(shù)

typedef std::function KeyInputCharFunType;// 處理輸入字符函數(shù)

public:

MAppWindow();

virtual ~MAppWindow();

//

// 獲取窗口句柄

//

virtual HWND WindHwnd(){ return nullptr; }

//

// 移除窗口邊框

//

virtual void RemoveBorder(){}

//

// 注冊(cè)函數(shù)

//

void RegisterFunInitD3D(RECALL_INIT initGLfun);

void RegisterDrawScreen(RECALL_DRAW drawFun); // 注冊(cè)顯示函數(shù),很重要,沒(méi)他,就顯示不出3D畫(huà)面

void RegisterReShape(RECALL_RESHAPE reshapeFun); // 移動(dòng)窗口會(huì)被調(diào)用

void RegisterWndProc(RECALL_WNDPROC WndProc); // 注冊(cè)事件回調(diào)函數(shù),該函數(shù)將會(huì)相應(yīng)窗口消息

void RegisterAddProcFun(RECALL_WNDPROC WndProc);

void RegisterOnIdleFun(RECALL_IDLE idlefun); // 注冊(cè)系統(tǒng)閑時(shí)處理函數(shù)

void RegisterClearFun(RECALL_CLEAR clearFun); // 注冊(cè)清除資源函數(shù)

void RegisterUpdataFun(RECALL_UPDATA updatafun) // 注冊(cè)更新界面函數(shù)

void RegisterMouseEnventFun(MouseFunType fun); // 注冊(cè)鼠標(biāo)事件函數(shù)

protected:

MouseFunType mMouseEventFun{ nullptr };

RECALL_INIT mInitD3d;

RECALL_DRAW mDrawScreen;

RECALL_RESHAPE mReshape;

RECALL_CLEAR mClearFun;

RECALL_IDLE mIdleFun;

RECALL_UPDATA mUpdateFun;

};

//==========================================

注冊(cè)系列函數(shù)我們已經(jīng)實(shí)現(xiàn),唯一需要用戶自行實(shí)現(xiàn)的就只有WindHwnd和RemoveBorder這兩個(gè)函數(shù),對(duì)于使用Win32或者M(jìn)FC的同學(xué)來(lái)說(shuō)獲取這個(gè)HWND實(shí)在是太簡(jiǎn)單了,對(duì)于使用Qt的同學(xué)來(lái)說(shuō)這兩個(gè)函數(shù)的實(shí)現(xiàn)依然很簡(jiǎn)單,對(duì)了,為什么我們要實(shí)現(xiàn)RemoveBorder呢?看看我們文章開(kāi)頭的圖片,整個(gè)窗口全都是使用DirectX繪制出來(lái)的,包括標(biāo)題欄和邊框,這樣我們就可以實(shí)現(xiàn)我們想要的任意風(fēng)格了,否則就算你把Client區(qū)域做得多華麗但是一看窗口邊框和標(biāo)題欄就會(huì)不自覺(jué)的認(rèn)為這不是一個(gè)風(fēng)格的。

由于我們現(xiàn)在是在win32下,所以這里我們可以使用MAppWindow來(lái)作為我們真正的窗口基類。真正的win32窗口類MWindow:

//==================================

#pragma once

#include "MDx11String.h"

#include

#include "MNoCopy.h"

#include

#include "MAppWindow.h"

using namespace MDx11;

class MWindow;

class MEventFun;

//

// 消息回調(diào)函數(shù)

//

HRESULT __stdcall WndProc(HWND, UINT, WPARAM, LPARAM);

class MWindow : public MAppWindow, public MNoCopy

{

DECLARE_CLASS(MWindow)

public:

explicit MWindow(MWindow* parent = nullptr);

virtual ~MWindow();

public:

unsigned Width() const{ return mWidth; }

unsigned Height() const{ return mHeight; }

void SetTitle(const MDx11String& Title);

//

// 重寫(xiě)繼承而來(lái)的兩個(gè)虛函數(shù)

//

void RemoveBorder();

virtual HWND WindHwnd(){ return mHwnd; }

//

// 開(kāi)啟消息循環(huán)

//

int Run() const;

//

// 顯示窗口

//

void Show();

virtual void SetExStyle(DWORD dwExStyle);

virtual void SetStyle(DWORD dwStyle);

virtual void SetIsFullScreen(bool fullscreen);

virtual void Update(){ InvalidateRect(*this, nullptr, false); }

virtual operator HWND() const{ return mHwnd; }

virtual LRESULT __stdcall MemWndProc(HWND, UINT, WPARAM, LPARAM);

bool IsFullScreen(){ return bIsFullscreen; }

bool IsActive(){ return bIsActive; }

void CalculateFrameStats();

//

// 事件

//

public:

friend LRESULT __stdcall WndProc(HWND, UINT, WPARAM, LPARAM); // 窗口回調(diào)函數(shù)

//

// 定義幾個(gè)事件屬性

//

static MDx11String MouseClickedEvent;

static MDx11String MouseMoveEvent;

static MDx11String MouseEnterEvent;

static MDx11String MouseLeverEvent;

static MDx11String ContentChangedEvent;

static MDx11String SelectedChangedEvent;

void RegisterEventFun(const MDx11String& EventDesc, MEventFun* SlotFun);

protected:

virtual bool InitWindow();

bool RegisterWndClass(); // 注冊(cè)窗口類

bool GenWindow(); // 創(chuàng)建窗口

virtual int Msgloop() const; // 消息循環(huán)

virtual void MouseEnterWindow();

virtual void MouseLeavesWindow();

//

// 窗口消息經(jīng)回調(diào)函數(shù)轉(zhuǎn)而進(jìn)相關(guān)的成員函數(shù),方便操作成員數(shù)據(jù)

//

LRESULT __stdcall BaseWndProc(HWND, UINT, WPARAM, LPARAM);

RECALL_WNDPROC mAddFun; // 消息回調(diào)附加函數(shù)

private:

MDx11String mTitle;

HWND mHwnd;

unsigned mWidth;

unsigned mHeight;

DWORD mDwExStyle; // 窗口風(fēng)格

DWORD mDwStyle; // 窗口風(fēng)格

bool* bIsKeys; //監(jiān)控鍵狀態(tài)

bool bIsInited;

volatile bool bIsDone;

bool bIsFullscreen;

bool bIsActive;

bool bIsAppPaused;

bool bIsMinimized;

bool bIsMaximized;

bool bIsResizing;

WNDCLASS mWndclass;

MDx11String mWndClassName;

//

// 一個(gè)計(jì)時(shí)器,凡是以I開(kāi)頭的東西都是從com組件中導(dǎo)出來(lái)的

//

ITimer* pTimer{ nullptr };

//

// 記錄鼠標(biāo)是否進(jìn)入窗口

//

bool bIsEnter{ false };

//

// 保存消息響應(yīng)函數(shù)

//

std::unordered_map mEventFunMap;

};

//=====================================

這個(gè)類沒(méi)啥多說(shuō)的,唯一的技巧性操作是將回調(diào)函數(shù)過(guò)程轉(zhuǎn)發(fā)指成員函數(shù)身上,要解決這個(gè)問(wèn)題很簡(jiǎn)單,正cpp文件中創(chuàng)建一個(gè)全局窗口對(duì)象,在類的構(gòu)造函數(shù)中將this直接賦給該全局指針,然后在回掉函數(shù)中根據(jù)HWND來(lái)檢查出對(duì)應(yīng)的窗口,從而將事件轉(zhuǎn)發(fā)指相應(yīng)的成員函數(shù)身上(其實(shí)如果只是簡(jiǎn)單的實(shí)現(xiàn)一個(gè)窗口大不必要這么麻煩,之所以這么干是考慮到以后該窗口類的擴(kuò)展性)。

現(xiàn)在只需要下面的代碼窗口就出來(lái)了:

//=====================================

MWindow w; //創(chuàng)建一個(gè)對(duì)象

w.SetTitle("Hello World"); // 設(shè)置窗口標(biāo)題

w.Show(); // 顯示窗口

w.Run(); // 開(kāi)啟消息循環(huán)

//=======================================

ok,今天的就到這里吧,具體實(shí)現(xiàn)因?yàn)楸容^簡(jiǎn)單就比貼出來(lái)了,只需要知道這些類有這些接口以及相關(guān)成員就足夠了,接下來(lái)我們開(kāi)始真正的進(jìn)入DirectX,下一講我們來(lái)說(shuō)說(shuō)該類的渲染核心——DirectX11的初始化。


網(wǎng)站名稱:C++教程:DirectX11Frame
當(dāng)前地址:http://weahome.cn/article/gsseid.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部