오늘은 기존에 사용하던 RenderManager 코드를 수정해주자.
지금은 쉐이더가 달라지면 기존에 있던 부분이 날라가는 문제점이 있다. 이 문제를 해결해주기 위하여 코드를 공용으로
모아두고 필요한 부분만 사용하지만 그것을 물체마다 할 수 있게 만들어주면 된다.
그렇게 하기위하여 쉐이더 클래스에 이 부분 코드를 넣어주고 데이터를 밀어넣는 부분에 만약에 버퍼가 없다면 버퍼를
생성하고초기화하는 부분도 같이 넣어주자.
Shader.h
#pragma once
#include "Pass.h"
#include "Technique.h"
#include "BindShaderDesc.h"
class Shader
{
public:
void PushGlobalData(const Matrix& view, const Matrix& projection);
void PushTransformData(const TransformDesc& desc);
void PushLightData(const LightDesc& desc);
void PushMaterialData(const MaterialDesc& desc);
void PushBoneData(const BoneDesc& desc);
void PushKeyframeData(const KeyframeDesc& desc);
void PushTweenData(const InstancedTweenDesc& desc);
private:
//프레임마다 한번만 세팅
GlobalDesc _globalDesc;
shared_ptr<ConstantBuffer<GlobalDesc>> _globalBuffer;
//정보넘겨주기
ComPtr<ID3DX11EffectConstantBuffer> _globalEffectBuffer;
TransformDesc _transformDesc;
shared_ptr<ConstantBuffer<TransformDesc>> _transformBuffer;
//정보넘겨주기
ComPtr<ID3DX11EffectConstantBuffer> _transformEffectBuffer;
LightDesc _lightDesc;
shared_ptr<ConstantBuffer<LightDesc>> _lightBuffer;
ComPtr<ID3DX11EffectConstantBuffer> _lightEffectBuffer;
MaterialDesc _materialDesc;
shared_ptr<ConstantBuffer<MaterialDesc>> _materialBuffer;
ComPtr<ID3DX11EffectConstantBuffer> _materialEffectBuffer;
BoneDesc _boneDesc;
shared_ptr<ConstantBuffer<BoneDesc>> _boneBuffer;
ComPtr<ID3DX11EffectConstantBuffer> _boneEffectBuffer;
KeyframeDesc _keyframeDesc;
shared_ptr<ConstantBuffer<KeyframeDesc>> _keyframeBuffer;
ComPtr<ID3DX11EffectConstantBuffer> _keyframeEffectBuffer;
InstancedTweenDesc _tweenDesc;
shared_ptr<ConstantBuffer<InstancedTweenDesc>> _tweenBuffer;
ComPtr<ID3DX11EffectConstantBuffer> _tweenEffectBuffer;
};
Shader.cpp
void Shader::PushGlobalData(const Matrix& view, const Matrix& projection)
{
if (_globalEffectBuffer == nullptr)
{
_globalBuffer = make_shared<ConstantBuffer<GlobalDesc>>();
_globalBuffer->Create();
_globalEffectBuffer = GetConstantBuffer("GlobalBuffer");
}
_globalDesc.V = view;
_globalDesc.P = projection;
_globalDesc.VP = view * projection;
_globalDesc.VInv = view.Invert();
_globalBuffer->CopyData(_globalDesc);
_globalEffectBuffer->SetConstantBuffer(_globalBuffer->GetComPtr().Get());
}
void Shader::PushTransformData(const TransformDesc& desc)
{
if (_transformEffectBuffer == nullptr)
{
_transformBuffer = make_shared<ConstantBuffer<TransformDesc>>();
_transformBuffer->Create();
_transformEffectBuffer = GetConstantBuffer("TransformBuffer");
}
_transformDesc = desc;
_transformBuffer->CopyData(_transformDesc);
_transformEffectBuffer->SetConstantBuffer(_transformBuffer->GetComPtr().Get());
}
void Shader::PushLightData(const LightDesc& desc)
{
if (_lightEffectBuffer == nullptr)
{
_lightBuffer = make_shared<ConstantBuffer<LightDesc>>();
_lightBuffer->Create();
_lightEffectBuffer = GetConstantBuffer("LightBuffer");
}
_lightDesc = desc;
_lightBuffer->CopyData(_lightDesc);
_lightEffectBuffer->SetConstantBuffer(_lightBuffer->GetComPtr().Get());
}
void Shader::PushMaterialData(const MaterialDesc& desc)
{
if (_materialEffectBuffer == nullptr)
{
_materialBuffer = make_shared<ConstantBuffer<MaterialDesc>>();
_materialBuffer->Create();
_materialEffectBuffer = GetConstantBuffer("MaterialBuffer");
}
_materialDesc = desc;
_materialBuffer->CopyData(_materialDesc);
_materialEffectBuffer->SetConstantBuffer(_materialBuffer->GetComPtr().Get());
}
void Shader::PushBoneData(const BoneDesc& desc)
{
if (_boneEffectBuffer == nullptr)
{
_boneBuffer = make_shared<ConstantBuffer<BoneDesc>>();
_boneBuffer->Create();
_boneEffectBuffer = GetConstantBuffer("BoneBuffer");
}
_boneDesc = desc;
_boneBuffer->CopyData(_boneDesc);
_boneEffectBuffer->SetConstantBuffer(_boneBuffer->GetComPtr().Get());
}
void Shader::PushKeyframeData(const KeyframeDesc& desc)
{
if (_keyframeEffectBuffer == nullptr)
{
_keyframeBuffer = make_shared<ConstantBuffer<KeyframeDesc>>();
_keyframeBuffer->Create();
_keyframeEffectBuffer = GetConstantBuffer("KeyframeBuffer");
}
_keyframeDesc = desc;
_keyframeBuffer->CopyData(_keyframeDesc);
_keyframeEffectBuffer->SetConstantBuffer(_keyframeBuffer->GetComPtr().Get());
}
void Shader::PushTweenData(const InstancedTweenDesc& desc)
{
if (_transformEffectBuffer == nullptr)
{
_tweenBuffer = make_shared<ConstantBuffer<InstancedTweenDesc>>();
_tweenBuffer->Create();
_tweenEffectBuffer = GetConstantBuffer("TweenBuffer");
}
_tweenDesc = desc;
_tweenBuffer->CopyData(_tweenDesc);
_tweenEffectBuffer->SetConstantBuffer(_tweenBuffer->GetComPtr().Get());
}
이렇게 수정해주고 RenderManager는 필요한 구조체만 남기고 없애주자. 그리고 이름을 BindShaderDesc로 바꿔주자. 그리고 RenderManager가 없어진부분을 이제 shader쪽에서 가져오거나 주석처리를 해주도록하자.
BindShaderDesc.h
#pragma once
#include "ConstantBuffer.h"
class Shader;
struct GlobalDesc
{
Matrix V = Matrix::Identity;
Matrix P = Matrix::Identity;
Matrix VP = Matrix::Identity;
Matrix VInv = Matrix::Identity;
};
struct TransformDesc
{
Matrix W = Matrix::Identity;
};
//Light
struct LightDesc
{
Color ambient = Color(1.f, 1.f, 1.f, 1.f);
Color diffuse = Color(1.f, 1.f, 1.f, 1.f);
Color specular = Color(1.f, 1.f, 1.f, 1.f);
Color emissive = Color(1.f, 1.f, 1.f, 1.f);
Vec3 direction;
float padding0;
};
struct MaterialDesc
{
Color ambient = Color(0.f, 0.f, 0.f, 1.f);
Color diffuse = Color(1.f, 1.f, 1.f, 1.f);
Color specular = Color(0.f, 0.f, 0.f, 1.f);
Color emissive = Color(0.f, 0.f, 0.f, 1.f);
};
//Bone 개수
#define MAX_MODEL_TRANSFORMS 250
#define MAX_MODEL_KEYFRAMES 500
#define MAX_MODEL_INSTANCE 500
struct BoneDesc
{
Matrix transforms[MAX_MODEL_TRANSFORMS];
};
//Animation
struct KeyframeDesc
{
int32 animIndex = 0;
uint32 currFrame = 0;
uint32 nextFrame = 0;
float ratio = 0.f;
float sumTime = 0.f;
float speed = 1.f;
Vec2 padding;
};
struct TweenDesc
{
TweenDesc()
{
curr.animIndex = 0;
next.animIndex = -1;
}
void ClearNextAnim()
{
next.animIndex = -1;
next.currFrame = 0;
next.nextFrame = 0;
next.sumTime = 0;
tweenSumTime = 0;
tweenRatio = 0;
}
float tweenDuration = 1.0f;
float tweenRatio = 0.f;
float tweenSumTime = 0.f;
float padding = 0.f;
KeyframeDesc curr;
KeyframeDesc next;
};
struct InstancedTweenDesc
{
TweenDesc tweens[MAX_MODEL_INSTANCE];
};
이렇게 바꿔주고 주석처리해준 Light와 Camera부분은 따로 관리주어야하는데 이 부분은 Scene쪽에서 관리해주도록
하자. RenderInstancing 부분이 있는 매쉬, 모델, 모델애니메이터에서 빛과 카메라 부분을 업데이트해주도록 하자. 일단 카메라와 빛의 개수 하나라고 가정하자. 이것은 나중에 직교투영하는 UI카메라를 구현할 때는 고쳐주어야 한다.
Scene.h
#pragma once
class Scene
{
public:
virtual void Start();
virtual void Update();
virtual void LateUpdate();
//추가
virtual void Add(shared_ptr<GameObject> object);
//제거
virtual void Remove(shared_ptr<GameObject> object);
unordered_set<shared_ptr<GameObject>> GetObjects() { return _objects; }
//일단 하나라고 가정하고 제일 처음꺼 가져오기
shared_ptr<GameObject> GetCamera() { return _cameras.empty() ? nullptr : *_cameras.begin(); }
shared_ptr<GameObject> GetLight() { return _lights.empty() ? nullptr : *_lights.begin(); }
private:
//물체를 가지고있는 추가 삭제 편하지만 순회에는 안좋다 검색활용
unordered_set<shared_ptr<GameObject>> _objects;
//카메라
unordered_set<shared_ptr<GameObject>> _cameras;
//빛
unordered_set<shared_ptr<GameObject>> _lights;
};
ModelRenderer.cpp
void ModelRenderer::RenderInstancing(shared_ptr<class InstancingBuffer>& buffer)
{
if (_model == nullptr)
return;
// GlobalData
_shader->PushGlobalData(Camera::S_MatView, Camera::S_MatProjection);
// Light
auto lightObj = SCENE->GetCurrentScene()->GetLight();
if (lightObj)
_shader->PushLightData(lightObj->GetLight()->GetLightDesc());
//Bones -> shader
BoneDesc boneDesc;
const uint32 boneCount = _model->GetBoneCount();
for (uint32 i = 0; i < boneCount; i++)
{
shared_ptr<ModelBone> bone = _model->GetBoneByIndex(i);
boneDesc.transforms[i] = bone->transform;
}
_shader->PushBoneData(boneDesc);
//부품
const auto& meshes = _model->GetMeshes();
for (auto& mesh : meshes)
{
if (mesh->material)
mesh->material->Update();
//BoneIndex
_shader->GetScalar("BoneIndex")->SetInt(mesh->boneIndex);
//IA
mesh->vertexBuffer->PushData();
mesh->indexBuffer->PushData();
//World position 넣어주기
buffer->PushData();
_shader->DrawIndexedInstanced(0, _pass, mesh->indexBuffer->GetCount(), buffer->GetCount());
}
}
고쳐준 다음 컴파일해주고 Client부분에 오류가 나는 부분을 수정해주자.
이렇게해주면 이제 다시 정상적으로 작동하는 것을 볼 수 있다.
이제 이렇게 해주는 것으로 우리가 여러가지 쉐이더를 사용할 수 있게 되었다.
'게임공부 > Directx11' 카테고리의 다른 글
[Directx11][C++][3D]27. Collision(Sphere) (3) | 2024.10.06 |
---|---|
[Directx11][C++][3D]26. ViewPort 이론 (0) | 2024.10.03 |
[Directx11][C++][3D]24. StructureBuffer (0) | 2024.10.02 |
[Directx11][C++][3D]23. TextureBuffer (3) | 2024.10.02 |
[Directx11][C++][3D]22. RawBuffer (1) | 2024.09.30 |