第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<void**>(&

dxgiDevice));

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

IDXGIAdapter *dxgiAdapter(NULL);

dxgiDevice->GetParent(__uuidof(IDXGIAdapter), reinterpret_cast<void**>(&

dxgiAdapter));

IDXGIFactory *dxgiFactory(NULL);

dxgiAdapter->GetParent(__uuidof(IDXGIFactory), reinterpret_cast<void**>(&

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<unsigned>indexs;

std::vector<BasicPCT>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;

staticfloat walk = -0.01;

mCamera.dx_Walk(walk);

mCamera.dx_UpDateMatrix();

staticfloat 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<
float*>(&

word));


D3DX11_TECHNIQUE_DESC techdesc = pLayoutManager->dx_GetTichDescFromEF(“MDx11WindowTech”);


for (int i = 0;

i <techdesc.Passes;

++i){

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();

}


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

第128讲 MDx11Frame(8)

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


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

回复D查看目录,回复数字查看相应章节


原文始发于微信公众号(

C/C++的编程教室

):第128讲 MDx11Frame(8)

|

发表评论