목차

     

     


     

     

    Framework

     

    desc.Usage =

    D3D11_USAGE_IMMUTABLE -  GPU 읽기만 가능
    -  IMMUTABLE은 접근 불가. 랜더링용으로만 이 버퍼를 사용하겠다.
    -  속도가 가장 빠르다
    D3D11_USAGE_DYNAMIC -  CPU 쓰기만, GPU 읽기만 가능
    -  DYNAMIC은 IMMUTABLE보다 느림 //정점 수정할 일이 있을때 사용
    D3D11_USAGE_DEFAULT; -  초기화 시 자주 사용.
    D3D11_USAGE_STAGING; -  CPU GPU 무조건 읽기 쓰기 가능하도록 열어줌.
    -  가장 느림.

     

      CPU GPU 속도 특징
    D3D11_USAGE_DEFAULT X (RAM->VRAM) O (VRAM->RAM) 중간 CreateBuffer 초기화 시 한번 사용
    D3D11_USAGE_IMMUTABLE X (RAM->VRAM) X (VRAM->RAM) 빠름 접근 불가. 더 이상 변경할 일이 없을 때 사용. 랜더링용으로만 버퍼를 사용 시 사용. ex. IndexBuffer
    D3D11_USAGE_DYNAMIC O (RAM->VRAM) X (VRAM->RAM) 중간 정점 수정할 일이 있을때 사용
    D3D11_USAGE_STAGING O (RAM->VRAM) O (RAM->VRAM) 느림 무조건 읽기 쓰기 가능하도록 열어줌

     

    Index Buffer처럼 바뀔일이 없는 경우는 거의 IMMUTABLE를 사용한다.

     

     

    https://learn.microsoft.com/en-us/windows/win32/api/d3d11/ne-d3d11-d3d11_usage

     

    D3D11_USAGE (d3d11.h) - Win32 apps

    Identifies expected resource use during rendering. The usage directly reflects whether a resource is accessible by the CPU and/or the graphics processing unit (GPU).

    learn.microsoft.com

     

     

    shader->AsMatrix("World")->SetMatrix();

     

    cbuffer $Global

    {

        world

        color

    }

     


    Buffer

     

    Buffers.h

    더보기
    #pragma once
    
    class VertexBuffer
    {
    public:
    	VertexBuffer(void* data, UINT count, UINT stride, UINT slot = 0, bool bCpuWrite = false, bool bGpuWrite = false);
    	~VertexBuffer();
    
    	UINT Count() { return count; }
    	UINT Stride() { return stride; }
    	ID3D11Buffer* Buffer() { return buffer; }
    
    	void Render();
    
    private:
    	ID3D11Buffer* buffer; //Wrapper class형식의 작업
    
    	void* data; //정점 정보
    	UINT count; //정점 개수
    	UINT stride;//정점 하나의 크기
    	UINT slot;
    
    	bool bCpuWrite;
    	bool bGpuWrite;
    };
    
    
    
    class IndexBuffer
    {
    public:
    	IndexBuffer(void* data, UINT count);
    	~IndexBuffer();
    
    	UINT Count() { return count; }
    	ID3D11Buffer* Buffer() { return buffer; }
    
    	void Render();
    
    private:
    	ID3D11Buffer* buffer;
    
    	void* data;
    	UINT count;
    };
    
    
    
    class ConstantBuffer
    {
    public:
    	ConstantBuffer(void* data, UINT dataSize);
    	~ConstantBuffer();
    
    	ID3D11Buffer* Buffer() { return buffer; }
    
    	void Render();
    
    private:
    	ID3D11Buffer* buffer;
    
    	void* data;
    	UINT dataSize;
    };

     

     

    Buffers.cpp

    더보기
    #include "Framework.h"
    #include "Buffers.h"
    
    VertexBuffer::VertexBuffer(void * data, UINT count, UINT stride, UINT slot, bool bCpuWrite, bool bGpuWrite)
    	: data(data), count(count), stride(stride), slot(slot)
    	, bCpuWrite(bCpuWrite), bGpuWrite(bGpuWrite)
    {
    	D3D11_BUFFER_DESC desc;
    	ZeroMemory(&desc, sizeof(D3D11_BUFFER_DESC));
    	desc.ByteWidth = stride * count;
    	desc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
    
    	if (bCpuWrite == false && bGpuWrite == false)
    	{
    		desc.Usage = D3D11_USAGE_IMMUTABLE; //GPU 읽기만 가능 //IMMUTABLE은 접근 불가. 랜더링용으로만 이 버퍼를 사용하겠다. 속도가 가장 빠르다
    	}
    	else if (bCpuWrite == true && bGpuWrite == false)
    	{
    		desc.Usage = D3D11_USAGE_DYNAMIC; //CPU 쓰기만, GPU 읽기만 가능 //DYNAMIC은 IMMUTABLE보다 느림 //정점 수정할 일이 있을때 사용
    		desc.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE;
    	}
    	else if (bCpuWrite == false && bGpuWrite == true)
    	{
    		//CPU 쓰기 가능 - UpdateSubResource
    		desc.Usage = D3D11_USAGE_DEFAULT;
    	}
    	else
    	{
    		desc.Usage = D3D11_USAGE_STAGING;
    		desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
    	}
    
    	D3D11_SUBRESOURCE_DATA subResource = { 0 };
    	subResource.pSysMem = data;
    
    	Check(D3D::GetDevice()->CreateBuffer(&desc, &subResource, &buffer));
    }
    
    VertexBuffer::~VertexBuffer()
    {
    	SafeRelease(buffer);
    }
    
    void VertexBuffer::Render()
    {
    	UINT offset = 0;
    	D3D::GetDC()->IASetVertexBuffers(slot, 1, &buffer, &stride, &offset);
    }
    
    
    
    IndexBuffer::IndexBuffer(void * data, UINT count)
    	: data(data), count(count)
    {
    	D3D11_BUFFER_DESC desc;
    	ZeroMemory(&desc, sizeof(D3D11_BUFFER_DESC));
    
    	desc.ByteWidth = sizeof(UINT) * count;
    	desc.BindFlags = D3D11_BIND_INDEX_BUFFER;
    	desc.Usage = D3D11_USAGE_IMMUTABLE;
    
    
    	D3D11_SUBRESOURCE_DATA subResource = { 0 };
    	subResource.pSysMem = data;
    
    	Check(D3D::GetDevice()->CreateBuffer(&desc, &subResource, &buffer));
    }
    
    IndexBuffer::~IndexBuffer()
    {
    	SafeRelease(buffer);
    }
    
    void IndexBuffer::Render()
    {
    	D3D::GetDC()->IASetIndexBuffer(buffer, DXGI_FORMAT_R32_UINT, 0);
    }
    
    
    
    ConstantBuffer::ConstantBuffer(void * data, UINT dataSize)
    	: data(data), dataSize(dataSize)
    {
    	D3D11_BUFFER_DESC desc;
    	ZeroMemory(&desc, sizeof(D3D11_BUFFER_DESC));
    
    	desc.ByteWidth = dataSize;
    	desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
    	desc.Usage = D3D11_USAGE_DYNAMIC;
    	desc.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE;
    
    	Check(D3D::GetDevice()->CreateBuffer(&desc, NULL, &buffer));
    }
    
    ConstantBuffer::~ConstantBuffer()
    {
    	SafeRelease(buffer);
    }
    
    void ConstantBuffer::Render()
    {
    	D3D11_MAPPED_SUBRESOURCE subResource;
    	D3D::GetDC()->Map(buffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &subResource);
    	{
    		memcpy(subResource.pData, data, dataSize); //pData = buffer의 데이터구역
    	}
    	D3D::GetDC()->Unmap(buffer, 0);
    }