【DirectX3D】零基础画三角形

本文系 学习 DirectX tutorial 笔记  ,原文及代码参考     directxtutorial.com/Lesson.aspx?lessonid=9-4-4

//------------------------------------------------------------------------------------------------------------------------------------------

初始化

DirectX是一系列COM 对象,其中一种是Direct3D,其创建释放也比较简单

d3d->CreateDevice() 
d3d->Release()

Swap Chain and Page Swapping

Direct3D 先是把图像画到后台缓存(back buffer),然后根据后台缓存更新前台缓存(front buffer)。不断的交换两buffer,可以快速的

显示图片。

The Basic Direct3D Program

1. 创建全局变量以及函数原型;

2. 创建D3D初始化程序; 

3. 创建render frame函数; 

4. 关闭释放资源

// include the basic windows header files and the Direct3D header file 
#include <windows.h> 
#include <windowsx.h> 
#include <d3d9.h> 
// include the Direct3D Library file 
#pragma comment (lib, "d3d9.lib") 
// global declarations 
LPDIRECT3D9 d3d;    // the pointer to our Direct3D interface 
LPDIRECT3DDEVICE9 d3ddev;    // the pointer to the device class 
// function prototypes 
void initD3D(HWND hWnd);    // sets up and initializes Direct3D 
void render_frame(void);    // renders a single frame 
void cleanD3D(void);    // closes Direct3D and releases memory 
// the WindowProc function prototype 
LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);

其中

D3D初始化

// this function initializes and prepares Direct3D for use 
void initD3D(HWND hWnd) 
{ 
    d3d = Direct3DCreate9(D3D_SDK_VERSION);    // create the Direct3D interface 
    D3DPRESENT_PARAMETERS d3dpp;    // create a struct to hold various device information 
    ZeroMemory(&d3dpp, sizeof(d3dpp));    // clear out the struct for use 
    d3dpp.Windowed = TRUE;    // program windowed, not fullscreen 
    d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;    // discard old frames 
    d3dpp.hDeviceWindow = hWnd;    // set the window to be used by Direct3D 
    // create a device class using this information and information from the d3dpp stuct 
    d3d->CreateDevice(D3DADAPTER_DEFAULT,   //Adapter, 
                      D3DDEVTYPE_HAL,                 //Device Type 
                      hWnd, 
                      D3DCREATE_SOFTWARE_VERTEXPROCESSING, 
                      &d3dpp,                         // D3DPRESENT_PARAMETERS 
                      &d3ddev); 
}

关于swapEffect ,定义使用的交换链类型,有三种交换链

image

createDevice()

Flexible Vertex Formats

Direct3D使用灵活顶点格式Flexible Vertex Format(FVF),可以按需要进行修改。在定义顶点格式时,常包含顶点的location以及

diffuse color。比如我们可以定义

#define CUSTOMFVF (D3DFVF_XYZRHW | D3DFVF_DIFFUSE)    

我们在书写灵活顶点改格式要按这个顺序来   顶点位置信息>RHW值>顶点混合权重>顶点法向量>漫反射颜色>镜面反射>纹理坐标

在Direct3D中常用的FVF格式取如下表格

image

根据上面的定义的 CUMSTOMFVF,我们可以创建如下的顶点格式

struct CUSTOMVERTEX 
{ 
    FLOAT x, y, z, rhw;    // from the D3DFVF_XYZRHW flag 
    DWORD color;    // from the D3DFVF_DIFFUSE flag 
}

创建三角形的三个顶点

CUSTOMVERTEX OurVertices[] = 
{ 
    {320.0f, 50.0f, 1.0f, 1.0f, D3DCOLOR_XRGB(0, 0, 255),}, 
    {520.0f, 400.0f, 1.0f, 1.0f, D3DCOLOR_XRGB(0, 255, 0),}, 
    {120.0f, 400.0f, 1.0f, 1.0f, D3DCOLOR_XRGB(255, 0, 0),}, 
};

随后,顶点缓存, 顶点缓存是存储游戏中的顶点/模型接口。通常使用CreateVertexBuffer()。其函数的定义如下所示

HRESULT CreateVertexBuffer( 
    UINT Length,             //the size of the buffer 
    DWORD Usage,       //sometimes there are special ways to use vertices 
    DWORD FVF,            //this is the FVF code we constructed earlier 
    D3DPOOL Pool,      //where to create  the vertex buffer and how 
    LPDIRECT3DVERTEXBUFFER9 ppVertexBuffer, 
    HANDLE* pSharedHandle);     //“Reserved, set this parameter to NULL ”

image

 

根据该函数定义,我们可以定义出程序需要的顶点缓存如下:

LPDIRECT3DVERTEXBUFFER9 v_buffer; 
d3ddev->CreateVertexBuffer(3*sizeof(CUSTOMVERTEX), 
                           0, 
                           CUSTOMFVF, 
                           D3DPOOL_MANAGED, 
                           &v_buffer, 
                           NULL);

当模型很复杂、顶点数量很大时,我们需要使用索引缓存,其原理也很简单,如下所示(图片来自 google),我们可以用4个顶点,6个索引表示一个正方形

                                            image

为保证顶点缓存完好不可为其他程序修改,我们需要lock,

HRESULT Lock(UINT OffsetToLock, 
             UINT SizeToLock,            //if only want to lock part,tell how bytes far should start 
             VOID** ppbData,           // void* 
             DWORD Flags);
VOID* pVoid;    // the void* we were talking about 
v_buffer->Lock(0, 0, (void**)&pVoid, 0);    // locks v_buffer, the buffer we made earlier

拷贝顶点到顶点缓存,拷贝完,可以解锁,从而对该部分进行操作

memcpy(pVoid, OurVertices, sizeof(OurVertices));    // copy vertices to the vertex buffer

最终的程序段即是如下:

void init_graphics(void) 
{ 
    // create three vertices using the CUSTOMVERTEX struct built earlier 
    CUSTOMVERTEX vertices[] = 
    { 
        { 320.0f, 50.0f, 0.5f, 1.0f, D3DCOLOR_XRGB(0, 0, 255), }, 
        { 520.0f, 400.0f, 0.5f, 1.0f, D3DCOLOR_XRGB(0, 255, 0), }, 
        { 120.0f, 400.0f, 0.5f, 1.0f, D3DCOLOR_XRGB(255, 0, 0), }, 
    }; 
    // create the vertex and store the pointer into v_buffer, which is created globally 
    d3ddev->CreateVertexBuffer(3*sizeof(CUSTOMVERTEX), 
                               0, 
                               CUSTOMFVF, 
                               D3DPOOL_MANAGED, 
                               &v_buffer, 
                               NULL); 
    VOID* pVoid;    // the void pointer 
    v_buffer->Lock(0, 0, (void**)&pVoid, 0);    // lock the vertex buffer 
    memcpy(pVoid, vertices, sizeof(vertices));    // copy the vertices to the locked buffer 
    v_buffer->Unlock();    // unlock the vertex buffer 
}

Drawing the primitive

在开始画之前,需要认识这三个函数

setFVF() 告诉D3D 使用什么FVF,因为我们可以定义不同的顶点格式。

SetStreamSource()

HRESULT SetStreamSource(UINT StreamNumber,        //which vertex buffer we are drawing from 
                        LPDIRECT3DVERTEXBUFFER9 pStreamData,    // pointer to the vertex buffer we create earlier 
                        UINT OffsetInBytes,                  //the number of bytes into the vertex buffer we should start from 
                        UINT Stride);                          // the size of each vertex

DrawPrimitive()

HRESULT DrawPrimitive(D3DPRIMITIVETYPE PrimitiveType,    // type of primitive that is used 
                      UINT StartVertex,                            // the number of first vertex we will put on the screen 
                      UINT PrimitiveCount);       

       image

最后释放资源:

最后画出来的就是这样的了:

image

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不负初心

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值