728x90
HLSL, Buffer 자원 관리 및 짧게 만드는 목적으로 프레임 워크를 고쳐쓸 예정
00_Global.fx
더보기
//----------------------------------------------------------------------------------
//Global CBuffer
//----------------------------------------------------------------------------------
cbuffer CB_PerFrame
{
matrix View;
matrix ViewInverse; //View값을 역행렬값
matrix Projection;
matrix VP; // View * Projection 결과값
float4 Culling[4];
float4 Clipping;
float Time;
float3 Padding; //바이트 채우기용
};
//자주 바뀌는 용도
cbuffer CB_World
{
matrix World;
};
//----------------------------------------------------------------------------------
//Functions
//----------------------------------------------------------------------------------
float4 WorldPosition(float4 position) //월드변환
{
return mul(position, World);
}
float4 ViewProjection(float4 position) //월드변환한 값으로 받음
{
position = mul(position, View);
return mul(position, Projection);
}
float3 WorldNormal(float3 normal) //NDC값을 받아서 출력
{
return mul(normal, (float3x3) World);
}
float3 ViewPosition() //카메라 위치
{
return ViewInverse._41_42_43;
}
//----------------------------------------------------------------------------------
//States
//----------------------------------------------------------------------------------
SamplerState PointSampler
{
Filter = MIN_MAG_MIP_POINT;
AddressU = Wrap;
AddressV = Wrap;
};
SamplerState LinearSampler
{
Filter = MIN_MAG_MIP_LINEAR;
AddressU = Wrap;
AddressV = Wrap;
};
RasterizerState FillMode_WireFrame
{
FillMode = WireFrame;
};
RasterizerState FrontCounterClockwise_True //반시계 방향도 그리게 만드는 옵션
{
FrontCounterClockwise = true;
};
RasterizerState Cullmode_Node //압뒤 상관없이 그려줌
{
CullMode = None;
};
DepthStencilState DepthEnable_False //깊이 검사옵션 안쓰기
{
DepthEnable = False;
};
//----------------------------------------------------------------------------------
// VS/PS
//----------------------------------------------------------------------------------
#define P_VP(name, vs, ps) \
pass name \
{ \
SetVertexShader(CompileShader(vs_5_0, vs())); \
SetPixelShader(CompileShader(ps_5_0, ps())); \
}
#define P_RS_VP(name, rs, vs, ps) \
pass name \
{ \
SetRasterizerState(rs); \
SetVertexShader(CompileShader(vs_5_0, vs())); \
SetPixelShader(CompileShader(ps_5_0, ps())); \
}
#define P_BS_VP(name, bs, vs, ps) \
pass name \
{ \
SetBlendState(bs, float4(0, 0, 0, 0), 0xFF); \
SetVertexShader(CompileShader(vs_5_0, vs())); \
SetPixelShader(CompileShader(ps_5_0, ps())); \
}
#define P_DSS_VP(name, dss, vs, ps) \
pass name \
{ \
SetDepthStencilState(dss, 1); \
SetVertexShader(CompileShader(vs_5_0, vs())); \
SetPixelShader(CompileShader(ps_5_0, ps())); \
}
#define P_RS_DSS_VP(name, rs, dss, vs, ps) \
pass name \
{ \
SetRasterizerState(rs); \
SetDepthStencilState(dss, 1); \
SetVertexShader(CompileShader(vs_5_0, vs())); \
SetPixelShader(CompileShader(ps_5_0, ps())); \
}
#define P_RS_BS_VP(name, rs, bs, vs, ps) \
pass name \
{ \
SetRasterizerState(rs); \
SetBlendState(bs, float4(0, 0, 0, 0), 0xFF); \
SetVertexShader(CompileShader(vs_5_0, vs())); \
SetPixelShader(CompileShader(ps_5_0, ps())); \
}
#define P_DSS_BS_VP(name, dss, bs, vs, ps) \
pass name \
{ \
SetDepthStencilState(dss, 1); \
SetBlendState(bs, float4(0, 0, 0, 0), 0xFF); \
SetVertexShader(CompileShader(vs_5_0, vs())); \
SetPixelShader(CompileShader(ps_5_0, ps())); \
}
Buffer.cpp,h
더보기
#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;
}
else if (bCpuWrite == true && bGpuWrite == false)
{
desc.Usage = D3D11_USAGE_DYNAMIC;
desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
}
else if (bCpuWrite == false && bGpuWrite == true)
{
desc.Usage = D3D11_USAGE_DEFAULT;
}
else
{
desc.Usage = D3D11_USAGE_STAGING;
desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE | D3D11_CPU_ACCESS_READ;
}
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.Usage = D3D11_USAGE_DYNAMIC;
desc.CPUAccessFlags = D3D11_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);
}
#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;
};
수정 예시
Hlsl 예시
더보기

수정 전 16_CubeMap.fx

수정후 16_CubeMap.fx


class Buffer
Mesh.cpp 예시(전)
더보기
#include "Framework.h"
#include "Mesh.h"
Mesh::Mesh(Shader * shader)
: shader(shader)
{
D3DXMatrixIdentity(&world);
sWorld = shader->AsMatrix("World");
sView = shader->AsMatrix("View");
sProjection = shader->AsMatrix("Projection");
sDiffuseMap = shader->AsSRV("DiffuseMap");
}
Mesh::~Mesh()
{
SafeDeleteArray(vertices);
SafeDeleteArray(indices);
SafeRelease(vertexBuffer);
SafeRelease(indexBuffer);
SafeDelete(diffuseMap);
}
void Mesh::Update()
{
}
void Mesh::Render()
{
if (vertexBuffer == NULL || indexBuffer == NULL)
{
Create();
CreateBuffer();
}
UINT stride = sizeof(VertexMesh);
UINT offset = 0;
D3D::GetDC()->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
D3D::GetDC()->IASetVertexBuffers(0, 1, &vertexBuffer, &stride, &offset);
D3D::GetDC()->IASetIndexBuffer(indexBuffer, DXGI_FORMAT_R32_UINT, 0);
sWorld->SetMatrix(world);
sView->SetMatrix(Context::Get()->View());
sProjection->SetMatrix(Context::Get()->Projection());
if (diffuseMap != NULL)
sDiffuseMap->SetResource(diffuseMap->SRV());
shader->DrawIndexed(0, pass, indexCount);
}
void Mesh::Position(float x, float y, float z)
{
Position(Vector3(x, y, z));
}
void Mesh::Position(Vector3 & vec)
{
position = vec;
UpdateWorld();
}
void Mesh::Position(Vector3 * vec)
{
*vec = position;
}
void Mesh::Rotation(float x, float y, float z)
{
Rotation(Vector3(x, y, z));
}
void Mesh::Rotation(Vector3 & vec)
{
rotation = vec;
UpdateWorld();
}
void Mesh::Rotation(Vector3 * vec)
{
*vec = rotation;
}
void Mesh::RotationDegree(float x, float y, float z)
{
RotationDegree(Vector3(x, y, z));
}
void Mesh::RotationDegree(Vector3 & vec)
{
rotation = vec * Math::PI / 180.0f;
UpdateWorld();
}
void Mesh::RotationDegree(Vector3 * vec)
{
*vec = rotation * 180.0f / Math::PI;
}
void Mesh::Scale(float x, float y, float z)
{
Scale(Vector3(x, y, z));
}
void Mesh::Scale(Vector3 & vec)
{
scale = vec;
UpdateWorld();
}
void Mesh::Scale(Vector3 * vec)
{
*vec = scale;
}
Vector3 Mesh::Forward()
{
return Vector3(world._31, world._32, world._33);
}
Vector3 Mesh::Up()
{
return Vector3(world._21, world._22, world._23);
}
Vector3 Mesh::Right()
{
return Vector3(world._11, world._12, world._13);
}
void Mesh::DiffuseMap(wstring file)
{
SafeDelete(diffuseMap);
diffuseMap = new Texture(file);
}
void Mesh::CreateBuffer()
{
//Create VertexBuffer
{
D3D11_BUFFER_DESC desc;
ZeroMemory(&desc, sizeof(D3D11_BUFFER_DESC));
desc.ByteWidth = sizeof(VertexMesh) * vertexCount;
desc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
D3D11_SUBRESOURCE_DATA data = { 0 };
data.pSysMem = vertices;
Check(D3D::GetDevice()->CreateBuffer(&desc, &data, &vertexBuffer));
}
//Create IndexBuffer
{
D3D11_BUFFER_DESC desc;
ZeroMemory(&desc, sizeof(D3D11_BUFFER_DESC));
desc.ByteWidth = sizeof(UINT) * indexCount;
desc.BindFlags = D3D11_BIND_INDEX_BUFFER;
D3D11_SUBRESOURCE_DATA data = { 0 };
data.pSysMem = indices;
Check(D3D::GetDevice()->CreateBuffer(&desc, &data, &indexBuffer));
}
}
void Mesh::UpdateWorld()
{
Matrix S, R, T;
D3DXMatrixScaling(&S, scale.x, scale.y, scale.z);
D3DXMatrixRotationYawPitchRoll(&R, rotation.y, rotation.x, rotation.z);
D3DXMatrixTranslation(&T, position.x, position.y, position.z);
world = S * R * T;
}
후
더보기
#include "Framework.h"
#include "Mesh.h"
Mesh::Mesh(Shader * shader)
: shader(shader)
{
D3DXMatrixIdentity(&world);
sWorld = shader->AsMatrix("World");
sView = shader->AsMatrix("View");
sProjection = shader->AsMatrix("Projection");
sDiffuseMap = shader->AsSRV("DiffuseMap");
}
Mesh::~Mesh()
{
SafeDeleteArray(vertices);
SafeDeleteArray(indices);
SafeDelete(vertexBuffer);
SafeDelete(indexBuffer);
SafeDelete(diffuseMap);
}
void Mesh::Update()
{
}
void Mesh::Render()
{
if (vertexBuffer == NULL || indexBuffer == NULL)
{
Create();
vertexBuffer = new VertexBuffer(vertices, vertexCount, sizeof(VertexMesh));
indexBuffer = new IndexBuffer(indices, indexCount);
}
vertexBuffer->Render();
indexBuffer->Render();
D3D::GetDC()->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
sWorld->SetMatrix(world);
sView->SetMatrix(Context::Get()->View());
sProjection->SetMatrix(Context::Get()->Projection());
if (diffuseMap != NULL)
sDiffuseMap->SetResource(diffuseMap->SRV());
shader->DrawIndexed(0, pass, indexCount);
}
void Mesh::Position(float x, float y, float z)
{
Position(Vector3(x, y, z));
}
void Mesh::Position(Vector3 & vec)
{
position = vec;
UpdateWorld();
}
void Mesh::Position(Vector3 * vec)
{
*vec = position;
}
void Mesh::Rotation(float x, float y, float z)
{
Rotation(Vector3(x, y, z));
}
void Mesh::Rotation(Vector3 & vec)
{
rotation = vec;
UpdateWorld();
}
void Mesh::Rotation(Vector3 * vec)
{
*vec = rotation;
}
void Mesh::RotationDegree(float x, float y, float z)
{
RotationDegree(Vector3(x, y, z));
}
void Mesh::RotationDegree(Vector3 & vec)
{
rotation = vec * Math::PI / 180.0f;
UpdateWorld();
}
void Mesh::RotationDegree(Vector3 * vec)
{
*vec = rotation * 180.0f / Math::PI;
}
void Mesh::Scale(float x, float y, float z)
{
Scale(Vector3(x, y, z));
}
void Mesh::Scale(Vector3 & vec)
{
scale = vec;
UpdateWorld();
}
void Mesh::Scale(Vector3 * vec)
{
*vec = scale;
}
Vector3 Mesh::Forward()
{
return Vector3(world._31, world._32, world._33);
}
Vector3 Mesh::Up()
{
return Vector3(world._21, world._22, world._23);
}
Vector3 Mesh::Right()
{
return Vector3(world._11, world._12, world._13);
}
void Mesh::DiffuseMap(wstring file)
{
SafeDelete(diffuseMap);
diffuseMap = new Texture(file);
}
void Mesh::UpdateWorld()
{
Matrix S, R, T;
D3DXMatrixScaling(&S, scale.x, scale.y, scale.z);
D3DXMatrixRotationYawPitchRoll(&R, rotation.y, rotation.x, rotation.z);
D3DXMatrixTranslation(&T, position.x, position.y, position.z);
world = S * R * T;
}
CreateBuffer와 Render 영역 부분이 많이 줄어들음
추가 보충
CBuffer란?
더보기



상수 버퍼라고 불리며 ConstantBuffer를 줄인말로 기존에 VertexBuffer같은 경우 1개씩 넘겨
줬다면 해당 버퍼는 구조체 형식으로 데이터를 넘겨주는 방식이다
쓰는이유
1. 구조체 타입을 한번에 데이터값을 넘겨줄수 있음
2. Cpu쪽에서 자주 값을 고쳐 쓰는 데이터를 사용 할 때 유용 (파티클, 카메라)
3. 큰 데이터를 한번에 넘길때
주의사항
1. 무족건 16바이트씩 넘겨줘야함
2. 4096바이트(4Mb)를 데이터 크기를 넘길수 없음 (왠만하면 안넘김
3. float4 형태로 읽기 때문에4바이트만 넘겨주면 12바이트 빈값을 같이 뭉쳐서 줘야함 예시로 아래 그림을 보면

위에 t, t2,t3는 문제가 없다 float3 = 12바이트 float = 4바이트 이므로 하지만 t4,t5에서 문제가 생긴다
주의 사항에도 있듯이 읽을땐 16바이트씩 잘라서 읽기 때문에 값이 변동되거나 이상하게 될 수 있기 때문이다
cbuffer 쓰는방법


사실 여태까지 fx 빈 영역에 변수 선언을 했는데 그 영역이 모두다 CBuffer 영역이였는데 아래
그림과 같이 이름을 정의한 구조체 CBuffer 만들어서 사용해도 된다
'DirectX > DirectX 3D_(구)' 카테고리의 다른 글
18_ModelEditor [1/2] (0) | 2021.07.13 |
---|---|
17_Framework (Transform, PerFrame, Renderer) (0) | 2021.07.13 |
16_CubeMap [ 1 / 2 ] (수정) (0) | 2021.07.06 |
15_Mesh (0) | 2021.07.06 |
13_BaseMap (0) | 2021.07.04 |