곰바닥
코딩공방
곰바닥
전체 방문자
오늘
어제
  • 분류 전체보기 (28)
    • 유니티 (1)
    • DirectX (14)
      • 던파 모작 개발일지 (7)
      • 공부 내용 (7)
    • 언리얼 (13)
      • 엔진 공부 (5)
      • 이득우 네트워크 멀티플레이 (8)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • 유니티
  • 개발 일지
  • directx
  • 개발일지
  • 고

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
곰바닥

코딩공방

DirectX/공부 내용

DirectX:: Atlas Texture 처리

2022. 7. 14. 16:28

1. Hlsl

<hide/>
#include "TransformHeader.fx"

struct Input
{
    float4 Pos : POSITION;
    float4 Tex : TEXCOORD;
};

struct Output
{
    float4 Pos : SV_POSITION;
    float4 PosLocal : POSITION;
    float4 Tex : TEXCOORD;
};

cbuffer AtlasData : register(b1)
{
    float2 TextureFramePos;
    float2 TextureFrameSize;
};

Output TextureAtlas_VS(Input _Input)
{

    Output NewOutPut = (Output)0;
    NewOutPut.Pos = mul(_Input.Pos, WorldViewProjection);
    NewOutPut.Pos.w = 1.0f;
    NewOutPut.PosLocal = _Input.Pos;
    //----여기 까지 정점 변환 ----------------------------
    
    //Vertex의 Texcoord를 아틀라스 인덱스 이미지의 Texcoord와 일치시켜준다.
    NewOutPut.Tex.x = (_Input.Tex.x * TextureFrameSize.x) + TextureFramePos.x;
    NewOutPut.Tex.y = (_Input.Tex.y * TextureFrameSize.y) + TextureFramePos.y;
    
    return NewOutPut;
}

Texture2D Tex : register(t0);
SamplerState Sam : register(s0);
float4 TextureAtlas_PS(Output _Input) : SV_Target0
{
    return Tex.Sample(Sam, _Input.Tex.xy);
}

 

2. GameEngineTextureRenderer

아틀라스 텍스처를 사용하기 위해서는 텍스처를 Cut해야 한다.

 

GameEngineTextureRenderer는 Texture를 렌더링 해주는 Renderer다.

 

2-0. 멤버 변수

<hide/>
class GameEngineTextureRenderer : public GameEngineDefaultRenderer
{
private:
	//현재 텍스처. 애니메이션일 경우 CurTex가 바뀔 수 있다.
	GameEngineTexture* CurTex;
    //아틀라스 이미지의 UV좌표계에서 원하는 데이터
    //TextureAtlas의 AtlasData와 Link돼있다.
	float4 FrameData;
    
    //기타 함수
};

2-1. SetTexture

호출자 : GameEngineActor 등

 

하는 역할 : User가 원하는 이름의 텍스처를 검색한 후 존재한다면 CurTex에 할당해 준다.

<hide/>
//사용자용 인터페이스 함수
void GameEngineTextureRenderer::SetTexture(const std::string& _Name, UINT _Index)
{
	SetTexture(_Name);
	SetFrame(_Index);
}

void GameEngineTextureRenderer::SetTexture(const std::string& _Name)
{
	CurTex = ShaderResources.SetTexture("Tex", _Name);
}

 

2-2 SetFrame

하는 역할 : CurTex에서 Index에 해당하는 FrameData를 받아온다.

<hide/>
void GameEngineTextureRenderer::SetFrame(UINT _Index)
{
	FrameData = CurTex->GetFrameData(_Index);
}

 

2-1. GameEngineShaderResourcesHelper::SetTexture

호출자 : GameEngineTextureRenderer::SetTexture

 

하는 역할 : 그래픽 카드의 텍스처 데이터를 쉐이더의 Texture2D로 넘겨준다.

<hide/>
GameEngineTexture* GameEngineShaderResourcesHelper::SetTexture(const std::string& _Name, const std::string& _TextureName)
{
	if (false == IsTexture(_Name))
	{
		MsgBox("쉐이더에서 이러한 이름의 텍스처세팅를 사용한 적이 없습니다.");
		return nullptr;
	}

	std::string Name = GameEngineString::ToUpperReturn(_Name);

	GameEngineTexture* FindTexture = GameEngineTexture::Find(_TextureName);

	if (nullptr == FindTexture)
	{
		MsgBox("존재하지 않는 텍스처를 세팅 하려고 했습니다.");
		return nullptr;
	}

	std::multimap<std::string, GameEngineTextureSetter>::iterator NameStartIter
		= TextureSettingMap.lower_bound(Name);

	std::multimap<std::string, GameEngineTextureSetter>::iterator NameEndIter
		= TextureSettingMap.upper_bound(Name);

	//Name에 해당하는 Value값(Setter)을 순회하면서 Setter.Res에 FindTexture을 할당
    //또 쉐이더 세팅함수를 호출해서 FindTexture을 쉐이더에 전달한다.
	for (; NameStartIter != NameEndIter; ++NameStartIter)
	{
		BindTexture(NameStartIter->second, FindTexture);
	}

	return FindTexture;
}

 

2-3. GameEngineTexture::Cut

호출자 : 리소스 로드한 직후 (ex ContentsCore::Start)

 

하는 역할 : 이미지를 규격대로 자른 Pos와 Size를 CutData에 저장한다.

<hide/>
//사용자용 인터페이스 함수
void GameEngineTexture::Cut(const std::string& _Name, UINT _X, UINT _Y)
{
	GameEngineTexture* Texture = Find(_Name);

	if (nullptr == Texture)
	{
		MsgBoxAssert("존재하지 않는 텍스처를 자르려고 했습니다.");
		return;
	}

	Texture->Cut(_X, _Y);
}

void GameEngineTexture::Cut(UINT _X, UINT _Y)
{
	float SizeX = 1.0f / _X;
	float SizeY = 1.0f / _Y;

	float4 Start = float4::ZERO;

	for (size_t y = 0; y < _Y; y++)
	{
		for (size_t x = 0; x < _X; x++)
		{

			float4 FrameData;

			FrameData.PosX = Start.x;
			FrameData.PosY = Start.y;
			FrameData.SizeX = SizeX;
			FrameData.SizeY = SizeY;
			CutData.push_back(FrameData);
			Start.x += SizeX;
		}

		Start.x = 0.0f;
		Start.y += SizeY;
	}
}

 

2-4. GameEngineTexture::GetFrameData

호출자 : GameEngineTextureRenderer::SetFrame

 

하는 역할 : GameEngineTexture가 가지고 있는 CutData를 반환한다.

<hide/>
float4 GetFrameData(UINT _Index) 
{
    if (true == CutData.empty())
    {
        MsgBoxAssertString(GetNameCopy() + " 자르지 않은 텍스처를 사용하려고 했습니다.");
    }

    if (CutData.size() <= _Index)
    {
        MsgBoxAssertString(GetNameCopy() + " 프레임 범위를 초과했습니다.");
    }
    //vector<float4>
    return CutData[_Index];
}

 

'DirectX > 공부 내용' 카테고리의 다른 글

DirectX::Blend  (0) 2022.07.18
DirectX::FrameAnimation  (0) 2022.07.15
DirectX::GameEngineTexture & GameEngineSampler  (0) 2022.07.12
C++ Functional  (0) 2022.07.12
렌더링 파이프 라인 : ConstantBuffer  (0) 2022.07.11
    'DirectX/공부 내용' 카테고리의 다른 글
    • DirectX::Blend
    • DirectX::FrameAnimation
    • DirectX::GameEngineTexture & GameEngineSampler
    • C++ Functional
    곰바닥
    곰바닥

    티스토리툴바