[D3D] RenderManager 구조 정리

vector·2025년 12월 5일

이번에는 RenderManager 구조 수정하기
현재는 쉐이더가 달라질 경우에 기존에 있던 부분이 날라가는 문제가 있었다. 이 문제를 해결하기 위해서 코드를 공용으로 모아두고 필요한 애들만 사용할 수 있게 하면서, 뭉체마다 할 수 있게끔 수정하자.

그렇기 위해서는 쉐이더에서 작업해주는게 현재로써는 가장 좋은 방향이라 생각한다.

Shader

  • RenderManager에 있던 코드를 Shader로 옮겨주는 작업

Shader.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;
};

Shdaer.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());
}

BindShaderDesc

  • RenderManager에는 Desc구조체들이 있어서 BindShaderDesc이라는 클래스로 변경

RENDER로 사용했던 코드 수정

  • Define.h에서 싱글턴으로 선언했던 부분 지우기
  • EnginePch.h에서 헤더 지우기
  • CameraLight에서 RENDER->Update()부분은 주석처리 (다른 곳에서 처리)
  • InstancingManager, ModelAnimator, ModelRenderer, Material에서는 RENDER를 shader로 수정
  • CameraLightMeshRenderer, ModelRenderer, ModelAnimatorRenderInstancing()에서 추가로 작업해주기

MeshRenderer.cpp

void MeshRenderer::RenderInstancing(shared_ptr<class InstancingBuffer>& buffer)
{
	if (_mesh == nullptr || _material == nullptr)
		return;

	auto shader = _material->GetShader();
	if (shader == nullptr)
		return;

	// GlobalData
	shader->PushGlobalData(Camera::S_MatView, Camera::S_MatProjection);
	// Light
	auto lightObj = SCENE->GetCurrentScene()->GetLight();
	if (lightObj)
		shader->PushLightData(lightObj->GetLight()->GetLightDesc());
}

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());
}

ModelAnimator.cpp

void ModelAnimator::RenderInstancing(shared_ptr<class InstancingBuffer>& buffer)
{
	if (_model == nullptr)
		return;

	if (_texture == nullptr)
		CreateTexture();

	// GlobalData
	_shader->PushGlobalData(Camera::S_MatView, Camera::S_MatProjection);
	// Light
	auto lightObj = SCENE->GetCurrentScene()->GetLight();
	if (lightObj)
		_shader->PushLightData(lightObj->GetLight()->GetLightDesc());
}

결과

  • TextureBufferDemo로 확인해보기

참고 강의

https://www.inflearn.com/courses/lecture?courseId=329791&tab=script&type=LECTURE&unitId=161167&subtitleLanguage=ko

profile
게임 클라이언트 프로그래머 준비중 (공부 및 기록용)

0개의 댓글