打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
第128讲 MDx11Frame(8)


上一讲我们说了DirectX11的初始化,初始化很简单,因为是固定的步骤和方法,简单的理一下:


1,使用D3D11CreateDevice接口创建ID3D11Device和ID3D11DeviceContext。

2,使用ID3D11Device::CheckMultisampleQualityLevels检查是否支持多重采样。

3,填充DXGI_SWAP_CHAIN_DESC结构体创建交换链。

4,IDXGISwapChain的创建需要几个步骤,相对来说这是最讨厌的一个了,下面大概说一下创建过程:


DXGI_SWAP_CHAIN_DESC swapChainDesc = { 0 };

swapChainDesc.BufferDesc.Width = width; //窗口的宽度

swapChainDesc.BufferDesc.Height = height;//窗口高度

swapChainDesc.BufferDesc.RefreshRate.Denominator = 1;// 刷新率 分子

swapChainDesc.BufferDesc.RefreshRate.Numerator = 60; // 分母

swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;//用于秒速缩放枚举,想要了解更多查看MSDN

swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;//用于描述扫描线绘制模式的枚举,同上

swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;//用于描述显示格式的枚举类型,同上

swapChainDesc.BufferCount = 1;//后缓冲区个数,1个足够

swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;//Usage,这些具体的查看MSDN就好

swapChainDesc.Flags = 0;// 描述交换链行为,默认为0既可

swapChainDesc.OutputWindow = m_hwnd; //主窗口句柄,指定显示的窗口


这个结构体这么填充即可,如果想要了解得更多,可以查看MSDN。


在填充好这个结构体后我们接下来看看怎么创建交换链,这个过程不是有参考的书籍我也不知道怎么创建,或者要慢慢的查阅MSDN了。

为了创建交换链,我们需要获取IDXGIFactory工厂接口,但是没有一个方法可以直接获取该接口,所以我们需要从ID3D11Device着手,COM组件就是这样,很多东西没有直接暴露,但是我们可以通过一个现有的查询未知的,所以我们现在拥有ID3D11Device接口,于是可以查询IDXGIDevice接口。

IDXGIDevice *dxgiDevice(NULL);

p_d3dDevice->QueryInterface(__uuidof(IDXGIDevice), reinterpret_cast(&dxgiDevice));

IDXGIDevice 可以获取IDXGIAdapter接口,IDXGIAdapter接口最终可以获取我们的工厂接口IDXGIFactory。

IDXGIAdapter *dxgiAdapter(NULL);

dxgiDevice->GetParent(__uuidof(IDXGIAdapter), reinterpret_cast(&dxgiAdapter));

IDXGIFactory *dxgiFactory(NULL);

dxgiAdapter->GetParent(__uuidof(IDXGIFactory), reinterpret_cast(&dxgiFactory));

result = dxgiFactory->CreateSwapChain(p_d3dDevice, &swapChainDesc, &p_swapChain);


最后终于创建出我们想要的交换链。


5,有了交换链后可以创建渲染目标视图:


ID3D11Texture2D* backBufferTexture;


result = p_swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&backBufferTexture);

result = p_d3dDevice->CreateRenderTargetView(backBufferTexture, 0, &p_backBufferTarget);



6, 创建深度模板buffer

7,将深度模板buffer和渲染目标视图绑定到渲染管道。

8,设置渲染窗口


ok,整个DirectX11的初始化就这样,好吧,我不善于说,也不善于写,不过还是希望能够对家有点帮助。


上一讲我们将DirectX的第一个程序给跑起来了,不过上面没啥东西,这一讲我们准备在上面花点什么东西,那就从最简单的开始,画一个正方行。


DirectX 对图元的绘制主要是按三角形来绘制,好吧,我的表达感觉怎么这么怪呢,当然不是只能画三角形,只是常规都是画三角形,因为三角形效率高啊,嗯,这可能不是很有力的说服力,它可以绘制各种图元,这里不展开说,为什么呢,因为等大家熟悉了之后这些东西也就全都明白了,这里我们还是说三角形吧。


我们来看看这么绘制三角形,三角形当然要有三个点,所以如果要绘制一个四边形那么我们就要绘制两个三角形,那么就是6个点,比如说四边形的四个顶点为ABCD,那么我们绘制的时候就要准备两组三角形的数据,分别为什么ABC和CBD。每一个顶点要有属于的自己的坐标,当然这时最基本的,我们可以还有色彩,在DirectX里面色彩通常用四个浮点数表示,分别为rgba,同样我们可以纹理坐标,纹理为什么先预留,后面再说。


在DirectX里面通常用XMFLOAT3类型表示顶点,他有xyz三个分量,用XMFLOAT4表示颜色,有xyzw分量,用XMFLOAT2表示二维纹理坐标,有xy分量。ok,知道这些后我们可以简单的定义出四边形的顶点类型:


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


statuc VertexType{

XMFLOAT3 Pos;

XMFLOAT4 Colour;

XMFLOAT2 Tex;

};


D3D11_INPUT_ELEMENT_DESC PCTLayout[3] =

{

    { 'POSITION', 0, DXGI_FORMAT_R32G32B32_FLOAT,

      0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },

    { 'COLOR', 0, DXGI_FORMAT_R32G32B32A32_FLOAT,

      0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },

    { 'TEXCOORD', 0, DXGI_FORMAT_R32G32_FLOAT,

      0, 28, D3D11_INPUT_PER_VERTEX_DATA, 0 },

};



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


D3D11_INPUT_ELEMENT_DESC 关于这个结构体 ,怎么说呢,要写说的话得不少篇幅,好吧,但又好像没多大用,自己百度一下就好了,那就这么愉快的决定了,我们继续向前。我们接下来创建一个布局和顶点buffer


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


pLayoutManager = new MDx11LayoutManage(dx_GetDevice());

pBufferManager = new MDx11BufferManage(dx_GetDevice());


pLayoutManager->dx_FxComplieFile('FX/MDx11WindowFX.fx');

pTechnique = pLayoutManager->dx_GetTechFromEF('MDx11WindowTech');

pLayout = pLayoutManager->dx_CreatInputLayout(PCTLayout, ARRAYSIZE(PCTLayout), 'MDx11WindowTech');


VertexType Points[] = {

{ { -100.5, 100.5, 1 }, { 1.f, 0.f, 0.f, 1.f }, { 0.f, 0.f } },

{ { 100.5, 100.5, 1 }, { 0.f, 1.f, 0.f, 1.f }, { 0.f, 0.f } },

{ { -100.5, -100.5, 1 }, { 0.f, 0.f, 1.f, 1.f }, { 0.f, 0.f } },


{ { -100.5, -100.5, 1 }, { 0.f, 0.f, 1.f, 1.f }, { 0.f, 0.f } },

{ { 100.5, 100.5, 1 }, { 0.f, 1.f, 0.f, 1.f }, { 0.f, 0.f } },

{ { 100.5, -100.5, 1 }, { 1.f, 0.f, 0.f, 1.f }, { 0.f, 0.f } }

};


pVertexBuffer = pBufferManager->dx_CreateVectexBuffer(Points, ARRAYSIZE(Points));


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

MDx11WindowFX.fx 文件的内容待会贴出。ok,现在我们可以绘制了


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

class FirstDirectWindow : public MDx11Base{

public:

FirstDirectWindow(){

}


~FirstDirectWindow(){}

bool dx_LoadContent(){

try{

std::vector indexs;

std::vector points;


points.push_back({ { -100.5, 100.5, 1 }, { 1.f, 0.f, 0.f, 1.f }, { 0.f, 0.f } });

points.push_back({ { 100.5, 100.5, 1 }, { 0.f, 1.f, 0.f, 1.f }, { 0.f, 0.f } });

points.push_back({ { -100.5, -100.5, 1 }, { 0.f, 0.f, 1.f, 1.f }, { 0.f, 0.f } });


points.push_back({ { -100.5, -100.5, 1 }, { 0.f, 0.f, 1.f, 1.f }, { 0.f, 0.f } });

points.push_back({ { 100.5, 100.5, 1 }, { 0.f, 1.f, 0.f, 1.f }, { 0.f, 0.f } });

points.push_back({ { 100.5, -100.5, 1 }, { 1.f, 0.f, 0.f, 1.f }, { 0.f, 0.f } });

pLayoutManager = new MDx11LayoutManage(dx_GetDevice());

pBufferManager = new MDx11BufferManage(dx_GetDevice());

pLayoutManager->dx_FxComplieFile('FX/MDx11WindowFX.fx');

pTechnique = pLayoutManager->dx_GetTechFromEF('MDx11WindowTech');

pLayout = pLayoutManager->dx_CreatInputLayout(PCTLayout, ARRAYSIZE(PCTLayout), 'MDx11WindowTech');


pVertexBuffer = pBufferManager->dx_CreateVectexBuffer(&points[0], points.size());

return true;

}

catch (std::runtime_error e){

box::ErrorBox(e.what());

return false;

}

}

void dx_Render();


private:

MDx11BufferManage* pBufferManager{ nullptr };

MDx11LayoutManage* pLayoutManager{ nullptr };

LPD3D11EFFECTTECHNIQUE pTechnique{ nullptr };

ID3D11Buffer*   pVertexBuffer{ nullptr };;

ID3D11InputLayout*     pLayout{ nullptr };


};


void FirstDirectWindow::dx_Render(){

if (!dx_GetDevice() || !dx_GetContext()){

return;

}

float clearColor[4] = { 0.f, 0.f, 0.25f, 1.0f };

dx_GetContext()->ClearRenderTargetView(p_backBufferTarget, clearColor);

dx_GetContext()->ClearDepthStencilView(p_depthStencilView, D3D11_CLEAR_DEPTH, 1.0f, 0.0f);

size_t strit = sizeof(BasicPCT);

size_t offset = 0;

static float walk = -0.01;

mCamera.dx_Walk(walk);

mCamera.dx_UpDateMatrix();

static float angle = 0;

angle += 0.1;

dx_GetContext()->IASetVertexBuffers(0, 1, &pVertexBuffer, &strit, &offset);

dx_GetContext()->IASetIndexBuffer(pIndexBuffer, DXGI_FORMAT_R32_UINT, 0);

dx_GetContext()->IASetInputLayout(pLayout);

dx_GetContext()->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);


XMMATRIX word = XMMatrixIdentity();

word = word*mCamera.dx_GetModeViewMatrix() *mCamera.dx_GetProjectMatrix();

pLayoutManager->dx_GetMatrixFromEF('MWorldMatrix')->SetMatrix(reinterpret_cast(&word));


D3DX11_TECHNIQUE_DESC techdesc = pLayoutManager->dx_GetTichDescFromEF('MDx11WindowTech');

for (int i = 0; i < techdesc.passes;="">

pTechnique->GetPassByIndex(i)->Apply(i, dx_GetContext());

dx_GetContext()->Draw(6, 0);

}

dx_GetSwapChain()->Present(0, 0);

}



下面是Fx文件


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


matrix   MWorldMatrix;


struct VSSceneIn

{

float3 pos : POSITION;

float4 colour : COLOR;

    float2 tex : TEXCOORD;

};


struct PSSceneIn

{

float4 pos : SV_Position;

float4 colour : COLOR;

float2 tex : TEXCOORD;

};



DepthStencilState DisableDepth

{

DepthEnable = FALSE;

DepthWriteMask = ZERO;

};


DepthStencilState LessEqualDSS

{

DepthEnable = TRUE; 

DepthFunc = LESS_EQUAL; 

}; 



SamplerState WindowSampler

{

Filter = MIN_MAG_MIP_LINEAR;

AddressU = Border;

AddressV = Border;

};


RasterizerState Rasterstate

{

DepthClipEnable = false;

FillMode = Solid;

CullMode = Back;

FrontCounterClockwise = false;

ScissorEnable = false;

};



RasterizerState RasterstateForObj

{

DepthClipEnable = false;

FillMode = Solid;

CullMode = Back;

FrontCounterClockwise = true;

ScissorEnable = false;

};


// Vertex shader

PSSceneIn VSMain(VSSceneIn input)

{

PSSceneIn output = (PSSceneIn)0.0;

output.pos = mul(float4(input.pos,1),MWorldMatrix);

output.tex = input.tex;

output.colour = input.colour;

return output;

}



float4 PSMain(PSSceneIn input) : SV_Target

{

return input.colour;

float4 colour = MWindowTexture.Sample(WindowSampler, input.tex);

return input.colour*colour;

}



// Techniques

technique11 MDx11WindowTech

{

pass P0

{

SetVertexShader(CompileShader(vs_5_0, VSMain())); 

SetGeometryShader(NULL); 

SetPixelShader(CompileShader(ps_5_0, PSMain())); 

SetDepthStencilState(LessEqualDSS, 0); 

SetRasterizerState(Rasterstate); 

}

}

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


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

下面我们来执行程序看看。

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

int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE prevInstance, LPWSTR cmdLine, int cmdShow)

{

INITCOM;

MWindow w;

TestDirctWindow d3dwindow;

if (!d3dwindow.dx_Init(&w)){

return 0;

}

w.Show();

return w.Run();

}


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

好吧,我们算是接触了DirectX的东西,接下来就是大家慢慢摸索的事啦,哈哈。


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

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
猫都能学会的Unity3D Shader入门指南(一)
【Visual C++】游戏开发笔记二十七 Direct3D 11入门级知识介绍
计算三角形的面积
【新提醒】【图文】手把手教你[转换]+[排版] MDX格式词库
友元------求两点之间的距离
Chaptor8 Texturing (Introduction to 3D Game Programing with DirextX 11)自读
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服