Direct3D 与 OpenGl虽然从整体语法和使用上具有一定的相似性,当在具体实现逻辑和命名上差距还是不小。慢慢体会。
Drect3D学习资料:https://www.lagou.com/lgeduarticle/96174.html
OpenGl学习资料:https://learnopengl.com/Getting-started/OpenGL
1、图元数据缓存(ID3D11Buffer)
ID3D11Buffer* m_vertex_buffer;
ID3D11Buffer* m_index_buffer;
ID3D11Buffer(缓冲接口):用于访问缓冲区资源。缓冲区通常存储顶点或索引数据。
ID3D11Buffer初始化(ID3D11Device::CreateBuffer)
// ID3D11Device* m_d3d11_device;
Vertex vertices[] = {
{float3(-1.0f, -1.0f, 0.0f), float2(0.0f, 1.0f)},
{float3(-1.0f, 1.0f, 0.0f), float2(0.0f, 0.0f)},
{float3( 1.0f, 1.0f, 0.0f), float2(1.0f, 0.0f)},
{float3( 1.0f, -1.0f, 0.0f), float2(1.0f, 1.0f)},
};
D3D11_BUFFER_DESC vertex_buffer_desc;
ZeroMemory(&vertex_buffer_desc, sizeof(vertex_buffer_desc));
vertex_buffer_desc.Usage = D3D11_USAGE_DEFAULT;
vertex_buffer_desc.ByteWidth = sizeof(vertices);
vertex_buffer_desc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
vertex_buffer_desc.CPUAccessFlags = 0;
vertex_buffer_desc.MiscFlags = 0;
D3D11_SUBRESOURCE_DATA vertices_data;
ZeroMemory(&vertices_data, sizeof(vertices_data));
vertices_data.pSysMem = vertices;
m_d3d11_device->CreateBuffer(&vertex_buffer_desc, &vertices_data, &m_vertex_buffer);
ID3D11Buffer初始化需要两个必要参数:缓存描述(D3D11_BUFFER_DESC);内存数据(D3D11_SUBRESOURCE_DATA),通过这两个参数可以准确的告诉GPU应给如何访问和处理数据
2、着色器创建与设置
ID3D11InputLayout* m_vertex_layout;
ID3D11VertexShader* m_vertex_shader;
ID3D11PixelShader* m_pixel_shader;
ID3D11InputLayout通过CreateInputLayout函数进行初始化,主要用于描述顶点着色器输入数据的布局,相当于glsl中的glVertexAttribPointer,使得输入buffer与hlsl中的POSITION、NORMAL、TEXCOORD等映射起来。
virtual HRESULT STDMETHODCALLTYPE CreateInputLayout(
/* [annotation] */
_In_reads_(NumElements) const D3D11_INPUT_ELEMENT_DESC *pInputElementDescs,
/* [annotation] */
_In_range_( 0, D3D11_IA_VERTEX_INPUT_STRUCTURE_ELEMENT_COUNT ) UINT NumElements,
/* [annotation] */
_In_reads_(BytecodeLength) const void *pShaderBytecodeWithInputSignature,
/* [annotation] */
_In_ SIZE_T BytecodeLength,
/* [annotation] */
_COM_Outptr_opt_ ID3D11InputLayout **ppInputLayout) = 0;
参数1:通过如下的eg,可以看出
const D3D11_INPUT_ELEMENT_DESC VertexPosNormalTex::inputLayout[3] = {
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 24, D3D11_INPUT_PER_VERTEX_DATA, 0 }
};
着色器设置:
m_pd3dImmediateContext->VSSetShader(m_pVertexShader2D.Get(), nullptr, 0);
m_pd3dImmediateContext->PSSetShader(m_pPixelShader2D.Get(), nullptr, 0);
m_pd3dImmediateContext->PSSetShaderResources(0, 1, m_pWoodTexture[0].GetAddressOf());
3、纹理资源
ID3D11ShaderResourceView:纹理资源
ID3D11SamplerState:采样器
4、常量缓冲区更新
该缓冲区相当于glsl的uniform
// ID3D11Buffer* m_pConstantBuffers[2]
D3D11_MAPPED_SUBRESOURCE mappedData;
HR(m_pd3dImmediateContext->Map(m_pConstantBuffers[0].Get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedData));
memcpy_s(mappedData.pData, sizeof(VSConstantBuffer), &m_VSConstantBuffer, sizeof(VSConstantBuffer));
m_pd3dImmediateContext->Unmap(m_pConstantBuffers[0].Get(), 0);