[DirectX11] 062 Texture Buffer
글의 요약 설명 부분. 150자를 적어주세요. 글의 요약 설명 부분. 150자를 적어주세요. 글의 요약 설명 부분. 150자를 적어주세요. 글의 요약 설명 부분. 150자를 적어주세요. 글의 요약 설명 부분. 150자를 적어주세요. 글의 요약 설명 부분. 150자입니다
목차
Texture Buffer
Shader | |
RawBuffer.fx | |
Framework | |
Render | |
Buffer.h .cpp Render2D.h .cpp 생성 |
|
UnitTest | |
DirectCompute | |
RawBufferDemo.h .cpp | |
Main.h .cpp |
fx
Render2D.fx
더보기
#include "00_Global.fx"
#include "00_Light.fx"
cbuffer CB_Render2D
{
matrix View2D;
matrix Projection2D;
};
struct VertexOutput
{
float4 Position : SV_Position0;
float2 Uv : Uv0;
};
VertexOutput VS(VertexTexture input)
{
VertexOutput output;
output.Position = WorldPosition(input.Position);
output.Position = mul(output.Position, View2D);
output.Position = mul(output.Position, Projection2D);
output.Uv = input.Uv;
return output;
}
float4 PS(VertexOutput input) : SV_TARGET0
{
return DiffuseMap.Sample(LinearSampler, input.Uv);
}
technique11 T0
{ //레이어 순서대로 그리기 위해 DepthEnable_False 깊이를 꺼줌.
P_DSS_VP(P0, DepthEnable_False, VS, PS)
}
TextureBuffer.fx
더보기
Texture2DArray<float4> Input;
RWTexture2DArray<float4> Output;
[numthreads(32, 32, 1)] //스레드를 32개로 쪼갠다. 스레드의 최대값은 1024
void CS(uint3 id : SV_DispatchThreadID)
{
float4 color = Input.Load(int4(id, 0)); //id는 x,y,z 정보
//Output[id] = 1.0f - color; //색상이 반전되게 나오게 할 때 사용.
Output[id] = (color.r + color.g + color.b) / 3.0f; //흑백효과
}
technique11 T0
{
pass P0
{
SetVertexShader(NULL);
SetPixelShader(NULL);
SetComputeShader(CompileShader(cs_5_0, CS()));
}
}
Buffers
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;
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;
};
class CsResource
{
public:
CsResource();
virtual ~CsResource();
protected:
virtual void CreateInput() {}
virtual void CreateSRV() {}
virtual void CreateOutput() {}
virtual void CreateUAV() {}
virtual void CreateResult() {}
void CreateBuffer();
public:
ID3D11ShaderResourceView* SRV() { return srv; }
ID3D11UnorderedAccessView* UAV() { return uav; }
protected:
ID3D11Resource* input = NULL;
ID3D11ShaderResourceView* srv = NULL; //Input
ID3D11Resource* output = NULL;
ID3D11UnorderedAccessView* uav = NULL; //Output
ID3D11Resource* result = NULL;
};
class RawBuffer : public CsResource
{
public:
RawBuffer(void* inputData, UINT inputByte, UINT outputByte);
~RawBuffer();
private:
void CreateInput() override;
void CreateSRV() override;
void CreateOutput() override;
void CreateUAV() override;
void CreateResult() override;
public:
void CopyToInput(void* data);
void CopyFromOuput(void* data);
private:
void* inputData;
UINT inputByte;
UINT outputByte;
};
class TextureBuffer : public CsResource
{
public:
TextureBuffer(ID3D11Texture2D* src);
~TextureBuffer();
private:
void CreateSRV() override;
void CreateOutput() override;
void CreateUAV() override;
void CreateResult() override;
public:
UINT Width() { return width; }
UINT Height() { return height; }
UINT ArraySize() { return arraySize; }
ID3D11Texture2D* Output() { return (ID3D11Texture2D *)output; }
ID3D11ShaderResourceView* OutputSRV() { return outputSRV; }
private:
UINT width, height, arraySize;
DXGI_FORMAT format;
ID3D11ShaderResourceView* outputSRV;
};
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 읽기
}
else if (bCpuWrite == true && bGpuWrite == false)
{
desc.Usage = D3D11_USAGE_DYNAMIC; //CPU 쓰기, GPU 읽기
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);
}
D3D::GetDC()->Unmap(buffer, 0);
}
CsResource::CsResource()
{
}
CsResource::~CsResource()
{
SafeRelease(input);
SafeRelease(srv);
SafeRelease(output);
SafeRelease(uav);
SafeRelease(result);
}
void CsResource::CreateBuffer()
{
CreateInput();
CreateSRV();
CreateOutput();
CreateUAV();
CreateResult();
}
RawBuffer::RawBuffer(void * inputData, UINT inputByte, UINT outputByte)
: CsResource()
, inputData(inputData), inputByte(inputByte), outputByte(outputByte)
{
CreateBuffer();
}
RawBuffer::~RawBuffer()
{
}
void RawBuffer::CreateInput()
{
if (inputByte < 1) return;
ID3D11Buffer* buffer = NULL;
D3D11_BUFFER_DESC desc;
ZeroMemory(&desc, sizeof(D3D11_BUFFER_DESC));
desc.ByteWidth = inputByte;
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
desc.MiscFlags = D3D11_RESOURCE_MISC_BUFFER_ALLOW_RAW_VIEWS;
desc.Usage = D3D11_USAGE_DYNAMIC;
desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
D3D11_SUBRESOURCE_DATA subResource = { 0 };
subResource.pSysMem = inputData;
Check(D3D::GetDevice()->CreateBuffer(&desc, inputData != NULL ? &subResource : NULL, &buffer));
input = (ID3D11Resource *)buffer;
}
void RawBuffer::CreateSRV()
{
if (inputByte < 1) return;
ID3D11Buffer* buffer = (ID3D11Buffer *)input;
D3D11_BUFFER_DESC desc;
buffer->GetDesc(&desc);
D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
ZeroMemory(&srvDesc, sizeof(D3D11_SHADER_RESOURCE_VIEW_DESC));
srvDesc.Format = DXGI_FORMAT_R32_TYPELESS;
srvDesc.ViewDimension = D3D11_SRV_DIMENSION_BUFFEREX;
srvDesc.BufferEx.Flags = D3D11_BUFFEREX_SRV_FLAG_RAW;
srvDesc.BufferEx.NumElements = desc.ByteWidth / 4;
Check(D3D::GetDevice()->CreateShaderResourceView(buffer, &srvDesc, &srv));
}
void RawBuffer::CreateOutput()
{
ID3D11Buffer* buffer = NULL;
D3D11_BUFFER_DESC desc;
ZeroMemory(&desc, sizeof(D3D11_BUFFER_DESC));
desc.ByteWidth = outputByte;
desc.BindFlags = D3D11_BIND_UNORDERED_ACCESS;
desc.MiscFlags = D3D11_RESOURCE_MISC_BUFFER_ALLOW_RAW_VIEWS;
Check(D3D::GetDevice()->CreateBuffer(&desc, NULL, &buffer));
output = (ID3D11Resource *)buffer;
}
void RawBuffer::CreateUAV()
{
ID3D11Buffer* buffer = (ID3D11Buffer *)output;
D3D11_BUFFER_DESC desc;
buffer->GetDesc(&desc);
D3D11_UNORDERED_ACCESS_VIEW_DESC uavDesc;
ZeroMemory(&uavDesc, sizeof(D3D11_UNORDERED_ACCESS_VIEW_DESC));
uavDesc.Format = DXGI_FORMAT_R32_TYPELESS;
uavDesc.ViewDimension = D3D11_UAV_DIMENSION_BUFFER;
uavDesc.Buffer.Flags = D3D11_BUFFER_UAV_FLAG_RAW;
uavDesc.Buffer.NumElements = desc.ByteWidth / 4;
Check(D3D::GetDevice()->CreateUnorderedAccessView(buffer, &uavDesc, &uav));
}
void RawBuffer::CreateResult()
{
ID3D11Buffer* buffer;
D3D11_BUFFER_DESC desc;
((ID3D11Buffer *)output)->GetDesc(&desc);
desc.Usage = D3D11_USAGE_STAGING;
desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
desc.BindFlags = D3D11_USAGE_DEFAULT;
desc.MiscFlags = 0;
Check(D3D::GetDevice()->CreateBuffer(&desc, NULL, &buffer));
result = (ID3D11Resource *)buffer;
}
void RawBuffer::CopyToInput(void * data)
{
D3D11_MAPPED_SUBRESOURCE subResource;
D3D::GetDC()->Map(input, 0, D3D11_MAP_WRITE_DISCARD, 0, &subResource);
{
memcpy(subResource.pData, data, inputByte);
}
D3D::GetDC()->Unmap(input, 0);
}
void RawBuffer::CopyFromOuput(void * data)
{
D3D::GetDC()->CopyResource(result, output);
D3D11_MAPPED_SUBRESOURCE subResource;
D3D::GetDC()->Map(result, 0, D3D11_MAP_READ, 0, &subResource);
{
memcpy(data, subResource.pData, outputByte);
}
D3D::GetDC()->Unmap(result, 0);
}
TextureBuffer::TextureBuffer(ID3D11Texture2D * src)
{
D3D11_TEXTURE2D_DESC srcDesc;
src->GetDesc(&srcDesc);
width = srcDesc.Width;
height = srcDesc.Height;
arraySize = srcDesc.ArraySize;
format = srcDesc.Format;
D3D11_TEXTURE2D_DESC desc;
ZeroMemory(&desc, sizeof(D3D11_TEXTURE2D_DESC));
desc.Width = width;
desc.Height = height;
desc.ArraySize = arraySize;
desc.Format = format;
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
desc.MipLevels = 1;
desc.SampleDesc.Count = 1;
ID3D11Texture2D* texture = NULL;
Check(D3D::GetDevice()->CreateTexture2D(&desc, NULL, &texture));
D3D::GetDC()->CopyResource(texture, src);
input = (ID3D11Resource *)texture;
CreateBuffer();
}
TextureBuffer::~TextureBuffer()
{
}
void TextureBuffer::CreateSRV()
{
ID3D11Texture2D* texture = (ID3D11Texture2D *)input;
D3D11_TEXTURE2D_DESC desc;
texture->GetDesc(&desc);
D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
ZeroMemory(&srvDesc, sizeof(D3D11_SHADER_RESOURCE_VIEW_DESC));
srvDesc.Format = desc.Format;
srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
srvDesc.Texture2DArray.MipLevels = 1;
srvDesc.Texture2DArray.ArraySize = arraySize;
Check(D3D::GetDevice()->CreateShaderResourceView(texture, &srvDesc, &srv));
}
void TextureBuffer::CreateOutput()
{
ID3D11Texture2D* texture = NULL;
D3D11_TEXTURE2D_DESC desc;
ZeroMemory(&desc, sizeof(D3D11_TEXTURE2D_DESC));
desc.Width = width;
desc.Height = height;
desc.ArraySize = arraySize;
desc.Format = format;
desc.BindFlags = D3D11_BIND_UNORDERED_ACCESS | D3D11_BIND_SHADER_RESOURCE;
desc.MipLevels = 1;
desc.SampleDesc.Count = 1;
Check(D3D::GetDevice()->CreateTexture2D(&desc, NULL, &texture));
output = (ID3D11Resource *)texture;
}
void TextureBuffer::CreateUAV()
{
ID3D11Texture2D* texture = (ID3D11Texture2D*)output;
D3D11_TEXTURE2D_DESC desc;
texture->GetDesc(&desc);
D3D11_UNORDERED_ACCESS_VIEW_DESC uavDesc;
ZeroMemory(&uavDesc, sizeof(D3D11_UNORDERED_ACCESS_VIEW_DESC));
uavDesc.Format = DXGI_FORMAT_UNKNOWN;
uavDesc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2DARRAY;
uavDesc.Texture2DArray.ArraySize = arraySize;
Check(D3D::GetDevice()->CreateUnorderedAccessView(texture, &uavDesc, &uav));
}
void TextureBuffer::CreateResult()
{
ID3D11Texture2D* texture = (ID3D11Texture2D*)output;
D3D11_TEXTURE2D_DESC desc;
texture->GetDesc(&desc);
D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
ZeroMemory(&srvDesc, sizeof(D3D11_SHADER_RESOURCE_VIEW_DESC));
srvDesc.Format = desc.Format;
srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
srvDesc.Texture2DArray.MipLevels = 1;
srvDesc.Texture2DArray.ArraySize = arraySize;
Check(D3D::GetDevice()->CreateShaderResourceView(texture, &srvDesc, &outputSRV));
}
이전 코드와 비교하여 수정된 부분 확인
Texture Buffer Demo
TextureBufferDemo.h
더보기
#pragma once
#include "Systems/IExecute.h"
class TextureBufferDemo : public IExecute
{
public:
virtual void Initialize() override;
virtual void Ready() override {}
virtual void Destroy() override {}
virtual void Update() override;
virtual void PreRender() override {}
virtual void Render() override;
virtual void PostRender() override;
virtual void ResizeScreen() override {}
private:
Texture* texture;
TextureBuffer* textureBuffer;
Render2D* render2D;
};
TextureBufferDemo.cpp
더보기
#include "stdafx.h"
#include "TextureBufferDemo.h"
void TextureBufferDemo::Initialize()
{
Shader* shader = new Shader(L"62_TextureBuffer.fx");
texture = new Texture(L"Environment/Compute.png");
render2D = new Render2D();
render2D->GetTransform()->Scale(D3D::Width(), D3D::Height(), 1);
render2D->GetTransform()->Position(D3D::Width() * 0.5f, D3D::Height() * 0.5f, 0);//중심점이 (0, 0, 0)
textureBuffer = new TextureBuffer(texture->GetTexture());
shader->AsSRV("Input")->SetResource(textureBuffer->SRV());
shader->AsUAV("Output")->SetUnorderedAccessView(textureBuffer->UAV());
UINT width = textureBuffer->Width();
UINT height = textureBuffer->Height();
UINT arraySize = textureBuffer->ArraySize();
float x = ((float)width / 32) < 1.0f ? 1.0f : ((float)width / 32);
float y = ((float)height / 32) < 1.0f ? 1.0f : ((float)height / 32);
//위에서 32로 나눈 후 나온 나머지값 처리. ceilf()는 소수점 올림
shader->Dispatch(0, 0, (UINT)ceilf(x), (UINT)ceilf(y), arraySize);
render2D->SRV(textureBuffer->OutputSRV());
}
void TextureBufferDemo::Update()
{
render2D->Update();
}
void TextureBufferDemo::Render()
{
}
void TextureBufferDemo::PostRender()
{
render2D->Render();
}
Render2D
Render2D.h
더보기
#pragma once
class Render2D : public Renderer
{
public:
Render2D();
~Render2D();
void Update();
void Render();
void SRV(ID3D11ShaderResourceView* srv);
private:
struct Desc
{
Matrix View;
Matrix Projection;
} desc;
private:
ConstantBuffer* buffer;
ID3DX11EffectShaderResourceVariable* sDiffuseMap;
};
Render2D.cpp
더보기
#include "Framework.h"
#include "Render2D.h"
Render2D::Render2D()
: Renderer(L"62_Render2D.fx")
{
//(0, 0, -1) -> (0, 0, 0) 전방 바라보는 방향. 이렇게하면 수직은 (0, 1, 0)이 된다.
D3DXMatrixLookAtLH(&desc.View, &Vector3(0, 0, -1), &Vector3(0, 0, 0), &Vector3(0, 1, 0));
//직교투영. Orthographic
D3DXMatrixOrthoOffCenterLH(&desc.Projection, 0, D3D::Width(), 0, D3D::Height(), -1, +1);
buffer = new ConstantBuffer(&desc, sizeof(Desc));
shader->AsConstantBuffer("CB_Render2D")->SetConstantBuffer(buffer->Buffer());
VertexTexture vertices[6];
vertices[0].Position = Vector3(-0.5f, -0.5f, 0.0f);
vertices[1].Position = Vector3(-0.5f, +0.5f, 0.0f);
vertices[2].Position = Vector3(+0.5f, -0.5f, 0.0f);
vertices[3].Position = Vector3(+0.5f, -0.5f, 0.0f);
vertices[4].Position = Vector3(-0.5f, +0.5f, 0.0f);
vertices[5].Position = Vector3(+0.5f, +0.5f, 0.0f);
vertices[0].Uv = Vector2(0, 1);
vertices[1].Uv = Vector2(0, 0);
vertices[2].Uv = Vector2(1, 1);
vertices[3].Uv = Vector2(1, 1);
vertices[4].Uv = Vector2(0, 0);
vertices[5].Uv = Vector2(1, 0);
vertexBuffer = new VertexBuffer(vertices, 6, sizeof(VertexTexture));
sDiffuseMap = shader->AsSRV("DiffuseMap");
}
Render2D::~Render2D()
{
SafeDelete(buffer);
}
void Render2D::Update()
{
Super::Update();
}
void Render2D::Render()
{
Super::Render();
buffer->Render();
shader->Draw(0, Pass(), 6);
}
void Render2D::SRV(ID3D11ShaderResourceView * srv)
{
sDiffuseMap->SetResource(srv);
}
실행화면
'⭐ DirectX > DirectX11 3D' 카테고리의 다른 글
[DirectX11] 064~65 Bone 위치에 충돌체 삽입하기 (0) | 2023.03.06 |
---|---|
[DirectX11] 063 Compute Shader - GetAnimationBone 구현하기 (0) | 2023.03.06 |
[DirectX11] 061 Thread Group, SV_GroupID (0) | 2023.03.02 |
[DirectX11] 060 Compute Shader (0) | 2023.02.28 |
[DirectX11] 059 Raw Buffer (0) | 2023.02.28 |
댓글
이 글 공유하기
다른 글
-
[DirectX11] 064~65 Bone 위치에 충돌체 삽입하기
[DirectX11] 064~65 Bone 위치에 충돌체 삽입하기
2023.03.06 -
[DirectX11] 063 Compute Shader - GetAnimationBone 구현하기
[DirectX11] 063 Compute Shader - GetAnimationBone 구현하기
2023.03.06 -
[DirectX11] 061 Thread Group, SV_GroupID
[DirectX11] 061 Thread Group, SV_GroupID
2023.03.02 -
[DirectX11] 060 Compute Shader
[DirectX11] 060 Compute Shader
2023.02.28