๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๐Ÿ“ Development Study/๐Ÿ–ผ GameProgramming 2D

Constant Buffer(์ƒ์ˆ˜ ๋ฒ„ํผ), Index Buffer(์ธ๋ฑ์Šค ๋ฒ„ํผ)

by eazuooz 2022. 12. 8.

์˜ˆ์ œ :)

https://github.com/eazuooz/YamYamEngine/commit/83ba804aa603c90876755b4782ed2eac0a126450

 

constatne buffer , index buffer · eazuooz/YamYamEngine@83ba804

Show file tree Showing 10 changed files with 165 additions and 30 deletions.

github.com

 

์…ฐ์ด๋”์—์„œ ์‹คํ–‰ํ•˜๋Š” ์ฝ”๋“œ๋Š” HLSL ์ฝ”๋“œ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

HLSL๋กœ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๊ณ  ์ปดํŒŒ์ผ ํ•˜๋ฉด ๋ฐ”์ดํŠธ์ฝ”๋“œ๊ฐ€ ๋งŒ๋“ค์–ด์ง„๋‹ค.

ํ•ด๋‹น ๋ฐ”์ดํŠธ ์ฝ”๋“œ๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” ์ธํ„ฐํŽ˜์ด์Šค๊ฐ€ ID3DBlob์ธํ„ฐํŽ˜์ด์Šค ์ด๋ฉฐ ์ด๋ฅผ ํ† ํ•ด ์…ฐ์ด๋” ์˜ค๋ธŒ์ ํŠธ๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.

 

์ƒ์ˆ˜๋ฒ„์™€ ์‹œ๋งจํ‹ฑ์Šค

struct VTX_IN
{
    float3 vPos : POSITION;
    float4 vColor : COLOR;
};

struct VTX_OUT
{
    float4 vPos : SV_Position;
    float4 vColor : COLOR;
};

cbuffer TRANSFORM : register(b0)
{
    float4 cbPos;
};

VTX_OUT VS_Test(VTX_IN _in)
{
    VTX_OUT output = (VTX_OUT) 0.f;
    
    output.vPos = float4(_in.vPos + cbPos.xyz, 1.f);
    output.vColor = _in.vColor;
    
    return output;
}

DirectX11 ์—์„œ๋Š” ๋ Œ๋”๋ง ํŒŒ์ดํ”„ ๋ผ์ธ์ด ์–ด๋–ค ๊ฐ’์„ ๋„˜๊ฒจ์•ผ ํ• ์ง€ ์•Œ๊ธฐ ์œ„ํ•ด ์‹๋ณ„์„ ํ•ด์•ผํ•  ํ•„์š”๊ฐ€ ์žˆ๋‹ค.

๊ทธ๊ฒƒ์ด '์‹œ๋งจํ‹ฑ์Šค' ์˜ ์—ญํ• ์ด๋ฉฐ ๋Œ€์†Œ๋ฌธ์ž๋ฅผ ๊ตฌ๋ณ„ํ•˜์ง€ ์•Š๋Š”๋‹ค.

SV_position ๊ฐ™์€ SV_๋กœ ์‹œ์ž‘ํ•˜๋Š” ์‹œ๋งจํ‹ฑ์Šค๋Š” ๋ Œ๋”๋ง ํŒŒ์ดํ”„๋ผ์ธ์—์„œ ํŠน๋ณ„ํ•œ ์˜๋ฏธ๊ฐ€ ์žˆ๋Š” ์‹œ๋งจํ‹ฑ์Šค๋กœ ์‚ฌ์šฉ๋œ๋‹ค.

 

 

Directx11 ๋ Œ๋”๋ง ํŒŒ์ดํ”„๋ผ์ธ์˜ ๊ฐ€์žฅ ์ฒซ ์Šคํ…Œ์ด์ง€์˜ ๋ฒ„ํ…์Šค์…ฐ์ด๋”์— ๋ฐ์ดํ„ฐ๋ฅผ ์ „๋‹ฌํ•˜๋Š” ์ž…๋ ฅ ์–ด์…ˆ๋ธ”๋Ÿฌ(Input Assembler)๋Š” ์ž…๋ ฅ ๋ ˆ์ด์•„์›ƒ ์˜ค๋ธŒ์ ํŠธ(Input layout object)์˜ ์‹œ๋ฉ˜ํ‹ฑ์Šค์™€ ๋ฒ„ํ…์Šค์…ฐ์ด๋”์˜ ์ž…๋ ฅ์‹œ๋ฉ˜ํ‹ฑ์Šค๋ฅผ ๋น„๊ตํ•จ์œผ๋กœ์จ ๋ฐ์ดํ„ฐ๊ฐ€ ํƒ€๋‹นํ•œ์ง€๋ฅผ ๊ฒ€์ฆํ•˜๋Š” ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•œ๋‹ค.

		InputLayouts[0].AlignedByteOffset = 0;
		InputLayouts[0].Format = DXGI_FORMAT_R32G32B32_FLOAT;
		InputLayouts[0].InputSlot = 0;
		InputLayouts[0].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
		InputLayouts[0].SemanticName = "POSITION";
		InputLayouts[0].SemanticIndex = 0;

		InputLayouts[1].AlignedByteOffset = 12;
		InputLayouts[1].Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
		InputLayouts[1].InputSlot = 0;
		InputLayouts[1].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
		InputLayouts[1].SemanticName = "COLOR";
		InputLayouts[1].SemanticIndex = 0;

		GetDevice()->CreateInputLayout(InputLayouts, 2,
			shader->GetVSCode()->GetBufferPointer()
			, shader->GetVSCode()->GetBufferSize()
			, shader->GetInputLayoutAddressOf());

 

์ƒ์ˆ˜๋ฒ„ํผ

์ƒ์ˆ˜๋ฒ„ํผ๋ฅผ ํ†ตํ•ด ํŒŒ์ดํ”„๋ผ์ธ์— ์ƒ์ˆ˜๋ฐ์ดํ„ฐ๋ฅผ ์ „๋‹ฌํ• ์ˆ˜ ์žˆ๋‹ค.

์ƒ์ˆ˜๋ฒ„ํผ๋Š” ์—ฌ๋Ÿฌ๊ฐœ๋ฅผ ๋งŒ๋“ค์–ด ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ์œผ๋ฉฐ ์–ด๋–ค ๊ธ€๋กœ๋ฒŒ ๋ณ€์ˆ˜๊ฐ’์ด ์–ด๋–ค ์ƒ์ˆ˜๋ฒ„ํผ์— ๋“ค์–ด์žˆ๋Š”๊ฐ€๋ฅผ ์ง€์ •ํ•˜๋ ค๋ฉด

๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ •์˜ํ•ด์•ผ ํ•œ๋‹ค.

cbuffer TRANSFORM : register(b0)
{
    float4 cbPos;
};

๊ตฌ์กฐ์ฒด๋ž‘ ๋น„์Šทํ•ด ๋ณด์ด์ง€๋งŒ ๋„ค์ž„์ŠคํŽ˜์ด์Šค์™€ ๋” ๋น„์Šทํ•œ ํ˜•ํƒœ์ด๋ฉฐ ์…ฐ์ด๋” ์ฝ”๋“œ์—์„œ๋Š” ๊ธ€๋กœ๋ฒŒ ๋ณ€์ˆ˜๋กœ ์ง์ ‘ ์ ‘๊ทผํ•œ๋‹ค.

 float4 cbPos;

์œ„์™€ ๊ฐ™์ด ๊ทธ๋ƒฅ ๊ธ€๋กœ๋ฒŒ ํ˜•ํƒœ์˜ ๋ณ€์ˆ˜๋กœ ์ง์ ‘ ์ ‘๊ทผ๋„ ๊ฐ€๋Šฅํ•˜๋‹ค.

 

์ƒ์ˆ˜๋ฒ„ํผ์— ์—‘์„ธ์Šค ํ• ๋•Œ๋Š” ๊ฐ๊ฐ์˜ ์ƒ์ˆ˜๋ฒ„ํผ๋ฅผ ๊ตฌ์กฐ์ฒด๋กœ ํ•˜์—ฌ ์ •์˜ ํ•ด๋‘”๋‹ค.

์ƒ์ˆ˜๋ฒ„ํผ์—๋Š” [ํŒŒ์ดํ”„๋ผ์ธ(์…ฐ์ด๋”)๋กœ๋ถ€ํ„ฐ ์ ์€ ๋ ˆ์ดํ„ด์‹œ๋กœ ์—‘์„ธ์Šค] [CPU๋กœ ์ธํ•œ ๋นˆ๋ฒˆํ•œ ๊ฐฑ์‹ ] ๊ฐ™์€ ์„ฑ๋Šฅ์ด ์š”๊ตฌ๋œ๋‹ค.

์ด๋กœ ์ธํ•ด ์ƒ์ˆ˜๋ฒ„ํผ์˜ ๋ฉ”๋ชจ๋ฆฌ ๊ตฌ์กฐ์—๋Š” [4๋ฐ”์ดํŠธ ์–ผ๋ผ์ด๋„ˆ๋จผํŠธ]๋กœ [๊ฐ์š”์†Œ 16๋ฐ”์ดํŠธ] ํ˜•ํƒœ๋กœ๋Š” ํ• ์ˆ˜ ์—†์œผ๋ฉฐ ์ „์ฒด ์‚ฌ์ด์ฆˆ๋Š” 16์˜ ๋ฐฐ์ˆ˜(4096 X 16 ๋ฐ”์ดํŠธ)] ๋ผ๋Š” ์กฐ๊ฑด์ด ๋ถ™์–ด์žˆ๋‹ค.

 

์ƒ์ˆ˜๋ฒ„ํผ๋Š” ๋ฒ„ํผ๋ฆฌ์†Œ์Šค์˜ ํ•œ ์ข…๋ฅ˜์ด๋‹ค. ์ด ๋•Œ๋ฌธ์— ๋ฒ„ํ…์Šค ๋ฒ„ํผ์™€ ๋งˆ์ฐฌ๊ฐ€์ง€ ๋ฐฉ์‹์œผ๋กœ ์ƒ์„ฑํ•œ๋‹ค.

 

๋ฒ„ํ…์Šค ๋ฒ„ํผ์™€ ๋‹ค๋ฅธ์ ์€ ๋ฐ”์ธ๋“œ ํ”Œ๋ž˜๊ทธ๋กœ D3D11_BIND_CONSTANT_BUFFER๋กœ ์ฃผ๋Š”๊ฒƒ ํ•˜๊ณ  

๋ฒ„ํผ ์‚ฌ์ด์ฆˆ๋Š” 4096 * 16 ์ดํ•˜์ธ 16๋ฐฐ์ˆ˜๊ฐ€ ์ด์–ด์•ผ ํ•œ๋‹ค๋Š”๊ฒƒ ์ •๋„์ด๋‹ค.

 

๋˜ ์ƒ์ˆ˜๋ฒ„ํผ๋Š” ๋ Œ๋”๋ง์‹œ ํ•„์š”ํ• ๋•Œ์˜ ๋ณ€๊ฒฝํ• ์ˆ˜ ์žˆ๊ธฐ์— ์„œ๋ธŒ ๋ฆฌ์†Œ์Šค์˜ ์ดˆ๊ธฐํ™”๋Š” ์ง€์ •ํ•˜์ง€ ์•Š๋Š”๋‹ค.

 

์ƒ์ˆ˜๋ฒ„ํผ์— ๊ฐ’์„ ์“ฐ๋Š” ๊ฒƒ์€ Usage๊ฐ€ D3D11_USAGE_DEFAAULT์ผ ๋•Œ์˜ ์„œ๋ธŒ๋ฆฌ์†Œ์Šค์— ์“ฐ๋Š” ๋ฐฉ์‹๊ณผ

D3D11_USAGE_DYNAMIC์ผ๋–„์— Map ~ UnMap์„ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ์‹์ด ์žˆ๋‹ค.

    void GraphicsDevice_DX11::BindConstantBuffer(ID3D11Buffer* buffer, void* data, UINT size)
    {
        D3D11_MAPPED_SUBRESOURCE subRes = {};
        mContext->Map(buffer, 0, D3D11_MAP::D3D11_MAP_WRITE_DISCARD, 0, &subRes);
        memcpy(subRes.pData, data, size);
        mContext->Unmap(buffer, 0);
    }

๊ทธ๋ฆฌ๊ณ  ์ƒ์ˆ˜๋ฒ„ํผ๊ฐ€ ์Žผ์ด๋”์—์„œ ์–ด๋–ค ์Šคํ…Œ์ด์ง€์—์„œ ์‚ฌ์šฉ๋ ๊ฒƒ์ธ์ง€ ์„ค์ •ํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค.

void GraphicsDevice_DX11::SetConstantBuffer(ShaderStage stage, CBTYPES type, ID3D11Buffer* buffer)
    {
        switch (stage)
        {
        case ya::graphics::ShaderStage::VS:
            {
                mContext->VSSetConstantBuffers((UINT)type, 1, &buffer);
            }
            break;
        case ya::graphics::ShaderStage::HS:
            {
                mContext->HSSetConstantBuffers((UINT)type, 1, &buffer);
            }
            break;
        case ya::graphics::ShaderStage::DS:
            {
                mContext->DSSetConstantBuffers((UINT)type, 1, &buffer);
            }
            break;
        case ya::graphics::ShaderStage::GS:
            {
                mContext->GSSetConstantBuffers((UINT)type, 1, &buffer);
            }
            break;
        case ya::graphics::ShaderStage::PS:
            {
                mContext->PSSetConstantBuffers((UINT)type, 1, &buffer);
            }
            break;
        case ya::graphics::ShaderStage::CS:
            {
                mContext->CSSetConstantBuffers((UINT)type, 1, &buffer);
            }
            break;
        default:
            break;
        }
    }

์ฒซ๋ฒˆ์จฐ ์ธ์ž๋Š” ์Šฌ๋กฏ๋ฒˆํ˜ธ, ๋‘๋ฒˆ์จฐ๊ฐ€ ์„ค์ •ํ•  ์ƒ์ˆ˜๋ฒ„ํผ์˜ ์ˆ˜, ์„ธ๋ฒˆ์งธ๊ฐ€ ์ƒ์ˆ˜๋ฒ„ํผ์˜ ์ฃผ์†Œ๋ฅผ ์„ค์ •ํ•œ๋‹ค.

 

์ƒ์ˆ˜๋ฒ„ํผ๋ฅผ ์„ค์ •ํ•œํ” ์Šฌ๋กฏ ๋ฒˆํ˜ธ๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ ์ปดํŒŒ์ผ ํ–ˆ์„๋•Œ์— ์…ฐ์ด๋” ํ•จ์ˆ˜์—์„œ ์‹ค์ œ ์‚ฌ์šฉ๋˜๋Š” ์ƒ์ˆ˜๋ฒ„ํผ๊ฐ€ ์Šฌ๋กฏ0๋ถ€ํ„ฐ ์ฝ”๋“œ์— ๊ธฐ์ˆ ๋œ ์ˆœ์„œ๋กœ ํ• ๋‹น๋œ๋‹ค.

 

๋ช…์‹œ์ ์œผ๋กœ ํ•˜๊ณ  ์‹ถ์œผ๋ฉด ์ƒ์ˆ˜๋ฒ„ํผ๋ฅผ ์ •์˜ํ• ๋•Œ cbuffer cbufferName : register(b0)์„ ์ง€์ •ํ•ด์ฃผ์–ด์„œ ํ• ๋‹นํ•  ์Šฌ๋กฏ๋ฒˆํ˜ธ๋ฅผ ์ง€์ •ํ• ์ˆ˜ ์žˆ๋‹ค.

์ฐธ๊ณ ๋กœ b0 b๋Š” buffer์˜ ์•ฝ์ž์ด๋ฉฐ ๊ทธ๋ฐ–์— t(ํ…์Šค์ณ), c(๋ฒ„ํผ ์˜คํ”„์…‹), s(์ƒ˜ํ”Œ๋Ÿฌ), u(Unorderd Access View)๋“ฑ์ด ์žˆ๋‹ค.

 

์ธ๋ฑ์Šค ๋ฒ„ํผ์˜ ์ƒ์„ฑ

 bool Mesh::CreateIndexBuffer(void* data, UINT Count)
    {
        mIndexCount = Count;
        mIBDesc.ByteWidth = sizeof(UINT) * Count;
        mIBDesc.BindFlags = D3D11_BIND_FLAG::D3D11_BIND_INDEX_BUFFER;
        mIBDesc.Usage = D3D11_USAGE_DEFAULT;
        mIBDesc.CPUAccessFlags = 0;

        D3D11_SUBRESOURCE_DATA subData = {};
        subData.pSysMem = data;

        if (!(GetDevice()->CreateBuffer(&mIBDesc, &subData, mIndexBuffer.GetAddressOf())))
            return false;

        return true;
    }

 

ํ•ด๋‹น ์ธ๋ฑ์Šค ๋ฒ„ํผ๋กœ ๊ทธ๋ ค์ฃผ๋ ค๋ฉด

์ธ๋ฑ์Šค ๋ฒ„ํผ๋ฅผ ๋ฐ”์ธ๋”ฉ ํ•ด์ฃผ๋ฉด ๋œ๋‹ค.

    void Mesh::BindBuffer()
    {
        UINT stride = sizeof(renderer::Vertex);
        UINT offset = 0;

        GetDevice()->BindVertexBuffer(0, 1, mVertexBuffer.GetAddressOf(), stride, offset);
        GetDevice()->BindIndexBuffer(mIndexBuffer.Get(), DXGI_FORMAT_R32_UINT, 0);
    }

 

'๐Ÿ“ Development Study > ๐Ÿ–ผ GameProgramming 2D' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

Scene, GameObject, Component  (0) 2022.12.21
Mesh, MeshRenderer  (0) 2022.12.21
Drawing a Triangle  (0) 2022.12.06
DirectX11 Initilize  (0) 2022.11.29
๋ Œ๋”๋ง ํŒŒ์ดํ”„๋ผ์ธ DirectX11  (2) 2022.11.29

๋Œ“๊ธ€