1. 程式人生 > >個人對DirectX3D做2D程式設計的理解

個人對DirectX3D做2D程式設計的理解

很多年前就知道DirectX是用來做遊戲的,從DOS時代直接操作視訊記憶體,到Windows時代只能通過驅動,並覺得DirectX的API太多,弄不清楚,感覺太麻煩,一直以來想寫個遊戲都是用GDI,但是GDI的效率很低,遊戲做不大,只好硬著頭皮去啃DirectX的SDK了,還好現在網路發達,資源很多,總是能學會不是。

在網上看了很多文章,感覺對初學者還是太難,做2D遊戲也不需要太多D3D知識,大概整理了一下可能對初學者有些幫忙吧。

以下是以DirectX9的SDK進行描述的,另外渲染跟繪製差不多意思。

1、初始化一個D3D的介面IDirect3D9,方法永遠是Direct3DCreate9( D3D_SDK_VERSION );

2、獲取裝置能力,GetDeviceCaps,Adapter取預設值D3DADAPTER_DEFAULT,DeviceType一般選硬體顯示卡,即D3DDEVTYPE_HAL

3、獲取顯示模式描述表 GetAdapterDisplayMode,在這個描述表裡可以修改高寬、顏色模式、緩衝區型別等一堆資訊

4、建立裝置IDirect3DDevice9,用CreateDevice來建立,裝置有一個就行了,裝置要與視窗控制代碼關聯

5、其它設定,什麼世界矩陣,渲染狀態

HRESULT InitDirect3D( HWND hWnd, BOOL bWindowed )
{
    g_pD3D = Direct3DCreate9( D3D_SDK_VERSION );

    D3DCAPS9 d3dCaps;
    g_pD3D->GetDeviceCaps( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &d3dCaps );

    D3DDISPLAYMODE d3ddm;
    g_pD3D->GetAdapterDisplayMode( D3DADAPTER_DEFAULT, &d3ddm );

    D3DPRESENT_PARAMETERS d3dpp;
    ZeroMemory( &d3dpp, sizeof(d3dpp) );

    if( bWindowed == TRUE )
    {
        d3dpp.Windowed         = TRUE;
        d3dpp.SwapEffect       = D3DSWAPEFFECT_DISCARD;
        d3dpp.BackBufferFormat = d3ddm.Format;
    }
    else
    {
        d3dpp.Windowed         = FALSE;
        d3dpp.SwapEffect       = D3DSWAPEFFECT_DISCARD;
        d3dpp.BackBufferWidth  = SCREEN_WIDTH;
        d3dpp.BackBufferHeight = SCREEN_HEIGHT;
        d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8;
    }

    d3dpp.EnableAutoDepthStencil = TRUE;
    d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
    d3dpp.PresentationInterval   = D3DPRESENT_INTERVAL_IMMEDIATE; // Do NOT sync to vertical retrace
    //d3dpp.PresentationInterval   = D3DPRESENT_INTERVAL_DEFAULT; // Sync to vertical retrace
    d3dpp.Flags                  = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;

    g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
                          D3DCREATE_SOFTWARE_VERTEXPROCESSING,
                          &d3dpp, &g_pd3dDevice );

    D3DXMATRIX matProj;
    D3DXMatrixPerspectiveFovLH( &matProj, D3DXToRadian( 45.0f ), 
                                SCREEN_WIDTH / SCREEN_HEIGHT, 0.1f, 100.0f );
    g_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj );

    g_pd3dDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
    g_pd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);

    return S_OK;
}


6、建立2D精靈,D3DXCreateSprite,一行就夠了,這個精靈建立一個就行,可以載入多個紋理進行批量渲染

7、建立紋理,我們這裡說的是載入2D圖片,可以從檔案載入,從記憶體載入,也可以建立一個空的,自己填資料

8、渲染,先Device.Clear,再開啟裝置渲染事務Device.BeginScene,然後可以進行精靈渲染,也可以通過獲取裝置後備緩衝直接寫,最後結束裝置渲染事務Device.EndScene

9、精靈渲染有很東西可以設定,很麻煩有興趣的自己學習,這裡只說一個一定要在精靈渲染事務里加允許透明渲染的標誌D3DXSPRITE_ALPHABLEND,事務中可以進行多項紋理繪製,所有的繪製都必須在事務中才會生效

10、精靈渲染可以渲染整個紋理,也可以只渲染其中一部分

11、精靈渲染的縮放、旋轉、位置的問題,在D3D裡使用3D的向量,我們搞2D程式設計所以Z座標永遠是1.0,縮放可以紋理的表面進行復制自動縮放,有的版本可以直接在Draw方法裡旋轉和縮放

終於有時間,而且對渲染這一塊又有了一些瞭解

12、渲染到紋理,一個紋理中可以有多個表面,不過通常只用一個,可以將這個表面設為當前渲染的表面,紋理建立時有要求

 a)建立可以用GDI、GDI+作圖的紋理,MipLevels=1,Usage=0,Pool=D3DPOOL_MANAGED

 b)建立可以作為渲染目標的紋理,MipLevels=1,Usage=1,Pool=D3DPOOL_DEFAULT,取紋理第0個表面Texture.GetSurfaceLevel(0, surface);然後設定為渲染目標Device.SetRenderTarget(0, surface);,這樣一樣ID3DXLine、ID3DXFont都可以繪製到當前紋理了(太基礎了,沒什麼人講,弄了好久才明白),渲染完後應該還原

13、紋理之間可以通過Device.StrechRect、Device.UpdateSurface來進行資料複製(拉伸和原樣複製,無法使用Alpha混合的效果)

14、Alpha混合,用於給紋理疊加顏色或疊加透明度,引數很多通過Device.SetRenderState來設定,用好了可以化腐朽為神奇

//設定Alpha混合模式
    Sprite._Begin(D3DXSPRITE_DONOTSAVESTATE);
    Device.SetRenderState(D3DRS_ALPHABLENDENABLE, 1);
    Device.SetRenderState(D3DRS_SRCBLEND, D3DBLEND_BLENDFACTOR);
    Device.SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
    Device.SetRenderState(D3DRS_BLENDFACTOR,
      D3DCOLOR_ARGB(Round(255.0* Rate),Round(255.0* Rate),Round(255.0* Rate),Round(255.0* Rate)));
//繪製紋理
TDXManager.Sprite.Draw(texture, nil, 0, nil, $FFFFFFFF);
//設定透明度
  Device.SetRenderState(D3DRS_ALPHABLENDENABLE, 1);
  Device.SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
  Device.SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
  Device.SetRenderState(D3DRS_SRCBLENDALPHA, D3DBLEND_ONE);
  Device.SetRenderState(D3DRS_BLENDFACTOR, D3DCOLOR_ARGB(255, 255, 255, 255));
//然後繪製紋理。。。
TDXManager.Sprite.Draw(texture, nil, 0, nil, $FFFFFFFF);


有空了我會上個圖,最煩寫渲染不上圖的,沒圖對比根本看不懂嘛


相關推薦

個人DirectX3D2D程式設計理解

很多年前就知道DirectX是用來做遊戲的,從DOS時代直接操作視訊記憶體,到Windows時代只能通過驅動,並覺得DirectX的API太多,弄不清楚,感覺太麻煩,一直以來想寫個遊戲都是用GDI,但是GDI的效率很低,遊戲做不大,只好硬著頭皮去啃DirectX的SDK了

淺談個人面向物件的程式設計理解(一)

    如今的很多程式設計師,可以很好地使用設計模式和麵向物件的設計理念,來設計和實現自己的應用程式。其實,我個人覺得,不管是面向物件,還是結構化程式設計,從流程和邏輯來看,其本質都是一樣的,不一樣的是分析和實現的思路,而面向物件由於其更加貼近與實際現實,分析和實現起來更加“容易”一些,但是,如果對面向物件

Day 1 python學習,個人計算機硬體的一些理解

  1. 什麼是語言  語言是一個事物與另外一個事物溝通的介質  python則是人(程式設計師)與計算機溝通的介質   2. 什麼是程式設計  程式設計就是程式設計師將自己想要讓計算機做的事情用程式語言翻譯出來寫到一系列的檔案中  

個人Redis的一些簡單理解

這是個人在這邊寫的第二篇文章 畢業一年半了,從合肥轉戰來到上海,最大變化的是頭髮稀少了好多...... 今天寫寫redis,以及叢集方面的東西    redis的作用百度很多,確實相比一些佔用jvm記憶體的一些快取資料作用要強大的多,光效能這方面就完爆了.. 我也是一名r

視訊檔案頭解析--mpeg-個人mpg檔案結構的理解

1、一個mpg檔案可以只包含視訊內容,那麼檔案開頭以0x000001B3作為起始碼 2、以0x000001BA 開頭,就意味著同時包含音訊資料和視訊資料,如果沒有音訊資料,則以0x000001B3開頭 3、一個mpg檔案可以包含多個pack,每個pack的起始碼都是0x0

個人主席樹演算法的理解

首先借主席樹發明人的一段話: ..這個東西是當初我弱不會劃分樹的時候寫出來替代的一個玩意..被一小撮別有用心的人取了很奇怪的名字> < 想法是對原序列的每一個字首[1..i]建立出一顆線段樹維護值域上每個數的出現次數,然後發現這樣的樹是可以減的,然後就沒有然

個人觀察者模式的理解

問題:觀察者模式有什麼用?通常被用來實現事件處理系統,當一個主題物件發生改變的時候,所有的觀察者都會發生改變;假如我們現在需要測量人的身高體重,電子秤顯示的數值會隨著被測量的人不同而顯示不同的資料,這個時候我們就可以把人的身體資料看為主題物件(Subject),把電子秤看為觀

個人外掛和鉤子的理解

看了很多文章,但對於外掛和鉤子的理解還是有點模糊。 談談我現在的看法:外掛很好理解,就是對系統功能擴充套件模組。而系統中實現了擴充套件功能的抽象外掛類。此時,如果開發者想要開發一個新功能,只需要繼承抽象類,實現其必要的一些方法,加入一部分自己想要實現的功能(function

軟件工程作業2.1:闡述軟件工程的理解,學完這門課自己能學到什麽,學完後能什麽

包括 數據結構和算法 很多 上線 可維護性 修復 學習 應用 實現 對軟件工程這門課的理解   軟件工程是把系統的、有序的、可量化的方法應用到軟件的開發、運營和維護上的過程。在軟件工程中,遠遠不止很多人以為的只是單純地進行軟件開發,其實真正的軟件開發的時間只是軟件工程中的一

個人OAUTH1.0簡單理解

arch 開放 html 第三方 proc details ref 分享 RoCE 我畫了一個簡單的圖來了解一下OAUTH1.0請求的交互過程,附圖如下:簡單解釋一下:OAuth1.0是基於http實現,為了交互的安全性設計上看起來會稍微復雜,OAuth1.0獲得的acce

二分法思想的理解 及 結對程式設計情況彙報

一、對二分法思想的理解 1.特點:又稱為折半演算法,是分治策略的一個典型例子。主要是用於:在已排好序的n個元素組成的陣列a[0:n-1]中,找出一個特定的元素x。 2.基本思想:(1)將n個元素分成個數大致相同相同的兩半,然後取a[n/2]與x作比較。       (2)如果x = a[n/2],則已找

個人stacking的思想理解

主要分為幾個基礎模型,一個元模型 對於基礎模型,採用K折交叉的方式來取樣資料,並分別進行訓練,這樣對於每個模型,都會用K組取樣資料來進行訓練,從而得到K個不同的模型版本 假設現在基礎模型有KNN,SVM, 那麼對基礎模型訓練後會得到如下幾個模型: KNN_model1, KNN_mo

個人作業系統的啟動原理的理解

於淵的《自己動手寫作業系統》是一本不錯的用程式碼記錄,一步步完成一個小型的作業系統的書。下載地址:https://pan.baidu.com/s/1j1MfEFcfU_fFamkjovOMRA,提取碼:bjwv。需要有組合語言基礎的讀者閱讀。 計算機的啟動過程如下:通電啟動

關於個人Spring Mvc 的理解

Spring Mvc 執行流程 傳送請求--->通過dispatcherservlet--->尋找到該請求對應的控制器--->進入Service處理--->Dao處理--->依次返回到控制器--->再返回到頁面 Spring Mvc 兩

poj 2406 poj 1961 個人吉大KMP模板的理解 KMP 基礎題--找週期串

好佩服寫kmp程式碼的人...   看死了終於看得有點明白了...... 學kmp先看兩個比較好的總結 這兩個講解非常好 摘一句我認為最重要的話 預處理出這樣一個數組P[j],表示當匹配到B陣列的第j個字母而第j+1個字母不能匹配了時,新的j最大是多少。P[j]應該是

個人細粒度和粗粒度的理解

看了一些網上的介紹,說下個人對粗細粒度的理解: interface   Info{   public int getId(int id);   public String getName(Stri

個人銀行知識的幾點認識和理解

最近,恰逢參加了公司的一個銀行知識的培訓,想想參加公司這麼久,已經是第三次參加銀行系統知識的培訓了,前2次都是日本人講的,主要講一些日本銀行的基礎業務知識以及下一代銀行系統的大致構架,聽來聽去還是沒什麼太多的瞭解,一來可能是對這方面沒有太多的經驗,二來可能是由於語言方面的

個人MobileNet V2的理解

我不準備具體描述MobileNet V2的結構。我只想在論文中尋找一些更加本質的東西,關於普通卷積分解、feature map線性組合以及啟用函式的,更加本質的東西。首先,引入一個概念,layer activation。指的其實就是是卷積層的輸出。我們知道layer acti

談談個人Spring的理解

現在開始將會把我面試中遇到的問題做一個總結每一條問題作為一篇簡短的部落格敘述. 1.你對spring的理解是什麼? 答: spring: 1)開源框架 2)IoC(控制反轉),將類的建立和依賴關係寫在配置檔案裡,由配置檔案注入,實現了鬆耦合 3)AOP 將安全,事務

(新手入門)個人redis的理解

(新手入門)個人對redis的理解 redis是一個ANSI c語言編寫的、支援網路的、基於記憶體的可持久化的 日誌型、Key——Value資料庫,並提供了多種API redis主要解決了高可用的問題,在大併發情況下,如果所有的請求直接訪問資料庫,會出現連線異常的問題,另外,由於redi