C++/유니티 엔진 모작(일시중지)

[유니티 엔진 제작] Resouce, Texture 만들기

나는야 개발자 2025. 2. 24. 07:34
반응형

enum class로 ResouceType 추가

//DirectX_Enums.h

#pragma once

namespace dir
{
	enum class eLayerType
	{
		None,
		BackGround,
		Title,
		Player,
		Max = 16,
	};

	enum class eResourceType
	{
		Texture,
		AudioClip,
		Prefab,
		End
	};
}

 

DirectX_Application 코드 수정

//DirectX_Application.h

//...나머지 생략
public:
 HDC GetHdc() { return mHdc; }
 
 //...나머지 생략

 

SpriteRenederer 코드 수정

//DirectX_SpriteRenderer

namespace dir
{
	SpriteRenderer::SpriteRenderer()
	{
	}

	//...나머지 생략

	void SpriteRenderer::Render(HDC hdc)
	{
		//Transform* tr = GetOwner()->GetComponent<Transform>();
		//Vector2 pos = tr->GetPosition();

		//Gdiplus::Graphics graphcis(hdc);
		//graphcis.DrawImage(mImgae, Gdiplus::Rect(pos.x, pos.y, mWidth, mHeight));
	}
    
    	//...나머지 생략
}

 

 

Resource 클래스 생성

#pragma once
//Resouce.h

#include "DirectX_Entity.h"

namespace dir
{
	class Resource : public Entity //이 클래스는 추상 클래스이며 메모리 할당 X 상속 받아서만 사용 가능 
	{
	public:
		Resource(dir::eResourceType type);
		virtual ~Resource();

		//이 함수는 순수 가상함수이고 실제 메모리 할당이 불가능한 함수
		//무조건 상속받아 사용하는 함수
		// /HRESULT란? bool과 같음 
		virtual HRESULT Load(const std::wstring& path) = 0;

		const std::wstring& GetPath() { return  mPath; }

		//참조로 보내면 원본을 그대로 하기 떄문에 포인트 정도만 할당함 
		void SetPath(std::wstring& path) { mPath = path; }

	private:
		dir::eResourceType mType;
		//경로 
		std::wstring mPath;
	};

}

 

Texture클래스 추가

//DirectX_Texture.h

#pragma once
#include "DirectX_Resource.h"

namespace dir::graphcis
{
	class Textrue : Resource
	{
	public:
		enum class eTextureType
		{
			Bmp,
			Png,
			None,
		};

		Textrue();
		~Textrue();

		virtual HRESULT Load(const std::wstring& path) override;

		UINT GetWidth() { return mWidth; }
		UINT GetHeight() { return mHeight; }
		HDC GetHdc() { return mHdc; }
		eTextureType GetTextureType() { return mType; }
		Gdiplus::Image* GetImage() { return mImgae; }
	private:
		eTextureType mType;

		//png파일 그릴때 사용 
		Gdiplus::Image* mImgae;

		//bmp파일 그릴때 사용
		HBITMAP mBit;

		//연결되서 사용될 hdc필요 
		HDC mHdc;

		UINT mWidth;
		UINT mHeight;
	};
}
//DirectX_Texture.cpp

#include "DirectX_Textrue.h"
#include "DirectX_Application.h"


//extern는 전역변수 존재함을 알리는 키워드
extern dir::Application application;

namespace dir::graphcis
{
	Textrue::Textrue() : Resource(dir::eResourceType::Texture)
	{
	}
	Textrue::~Textrue()
	{
	}
	HRESULT Textrue::Load(const std::wstring& path)
	{
		// 마지막에서 .을 기준으로 하면 확장자를 가져올 수 있음
		std::wstring ext = path.substr(path.find_last_of(L".") + 1);

		//bmp일때 
		if (ext == L"bmp")
		{
			mType = eTextureType::Bmp;
			mBit = (HBITMAP)LoadImageW(nullptr, path.c_str(), IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION);

			if (mBit == nullptr)
			{
				return S_FALSE;
			}

			BITMAP info = {};
			GetObject(mBit, sizeof(BITMAP), &info);

			mWidth = info.bmWidth;
			mHeight = info.bmHeight;

			//hdc만들어주기
			HDC mainDC = application.GetHdc();
			mHdc = CreateCompatibleDC(mainDC);

			HBITMAP oldbitmap = (HBITMAP)SelectObject(mHdc, mBit);
			DeleteObject(oldbitmap);
		}
		//png일때
		else if (ext == L"png")
		{
			mType = eTextureType::Png;
			mImgae = Gdiplus::Image::FromFile(path.c_str());
			if (mImgae == nullptr)
			{
				return S_FALSE;
			}

			mWidth = mImgae->GetWidth();
			mHeight = mImgae->GetHeight();
		}

		return S_OK;
	}
}

 

- Load함수의 ext 결과 값

첨부사진1

 

이미지 생성하던 Scene쪽 코드 수정

//DirectX_PlayScene.cpp

//...나머지 생략
void PlayScene::Initialize()
{
	//배경 이미지
	bg = object::Instantiate<Player>(eLayerType::BackGround, Vector2(0, 0));
	SpriteRenderer* sr = bg->AddComponent<SpriteRenderer>();
	graphcis::Textrue* tex = new graphcis::Textrue();
	tex->Load(L"D:\\Git\\Win_DirectX_Engine\\Resources\\CloudOcean.png");
}

//...나머지 생략

 

Resources코드 추가

//DirectX_Resources.h

#pragma once
#include "DirectX_Resource.h"

namespace dir
{
	class Resources
	{
	public:
		/// <summary>
		/// 리소스 가져오기 함수 
		/// </summary>
		template <typename T>
		static T* Find(const std::wstring& key)
		{
			//mResource에 검색
			auto iter = mResource.find(key);

			//없다면 nullptr
			if (iter == mResource.end())
			{
				return nullptr;
			}

			//형변환 후 리턴
			return dynamic_cast<T*>(iter->second);
		}

		/// <summary>
		/// 리소스 로드하기
		/// </summary>
		template <typename T>
		static T* Load(const std::wstring& key, const std::wstring& path)
		{
			//이미 존재하는지 체크
			T* resource = Resources::Find<T>(key);
			if (resource == nullptr)
				return resource;

			resource = new T();
			if (FAILED(resource->Load(path)))
				assert(false);

			resource->SetName(key);
			resource->SetPath(path);
			mResource.insert(std::make_pair(key, resource));
			return resource;
		}

	private:
		static std::map<std::wstring, Resources*> mResource;
	};
}


//DirectX_Resources.cpp
#include "DirectX_Resources.h"

namespace dir
{
	std::map<std::wstring, Resources*> Resources::mResource = {};
}

 

 

DirectX_Engine 프로젝트에 DirectX_Engine.h 파일 추가

 

#pragma once
#pragma once
#include "..//DirectX_SOURECE//DirectX_Resources.h"
#include "..//DirectX_SOURECE//DirectX_Textrue.h"

namespace dir
{

	void LoadResources()
	{
		Resources::Load<dir::graphcis::Textrue>(L"BG", L"D:\\Git\\Win_DirectX_Engine\\Resources\\CloudOcean.png");
	}
}

 

PlayScene.cpp 코드 수정

//..이하생략
void PlayScene::Initialize()
{
	//배경 이미지
	bg = object::Instantiate<Player>(eLayerType::BackGround, Vector2(0, 0));
	SpriteRenderer* sr = bg->AddComponent<SpriteRenderer>();
	auto bg = Resources::Find<graphcis::Textrue>(L"BG");
	sr->SetTexture(bg);

	Scene::Initialize();
}
//..이하생략

 

SpriteReneder.h 코드 수정

#pragma once
#include "J_GameObject.h"
#include "J_Component.h"
#include "J_Textrue.h"

namespace J
{
	class SpriteRenderer : public Component
	{
	public:
		SpriteRenderer();
		~SpriteRenderer();
		void Initialize() override;
		void Update()  override;
		void LateUpdate()  override;
		void Render(HDC hdc)  override;

		void SetTexture(graphcis::Textrue* texture) { mTexture = texture; }
		void SetSize(Vector2 size) { mSize = size; }
	private:
		graphcis::Textrue* mTexture;
		Vector2 mSize;
	};
}

- SetTexture와 SetSize 추가

 

Math코드 추가

#include "J_Math.h"


namespace math
{
	Vector2  Vector2::One = Vector2(1.0f, 1.0f);
	Vector2  Vector2::zero = Vector2(0, 0);
}

- 자주 사용하는 vector2 기능 추가

 

 

SpriteReneder.cpp파일 수정

#pragma once
#include "J_GameObject.h"
#include "J_Transform.h"
#include "J_SpriteRenderer.h"
#include "J_Textrue.h"

namespace J
{
	SpriteRenderer::SpriteRenderer() :mSize(Vector2::One), mTexture(nullptr), Component()
	{
	}
	SpriteRenderer::~SpriteRenderer()
	{
	}
	void SpriteRenderer::Initialize()
	{
	}
	void SpriteRenderer::Update()
	{
	}
	void SpriteRenderer::LateUpdate()
	{
	}
	void SpriteRenderer::Render(HDC hdc)
	{
		if (mTexture == nullptr)//텍스쳐 세팅 필요 
		{
			assert(false);
		}

		Transform* tr = GetOwner()->GetComponent<Transform>();
		Vector2 pos = tr->GetPosition();

		//각 타입별 처리 
		if (mTexture->GetTextureType() == graphcis::Textrue::eTextureType::Bmp)
		{
			//투명값이 없을 경우 TransparentBlt을 이용해 제거하여 사용 가능 
			TransparentBlt(hdc, pos.x, pos.y,
				mTexture->GetWidth() * mSize.x, mTexture->GetHeight() * mSize.y,
				mTexture->GetHdc(), 0, 0,
				mTexture->GetHeight(), mTexture->GetHeight(),
				RGB(255, 0, 255));
		}
		else if (mTexture->GetTextureType() == graphcis::Textrue::eTextureType::Png)
		{
			Gdiplus::Graphics graphics(hdc);
			graphics.DrawImage(mTexture->GetImage(),
				Gdiplus::Rect(pos.x, pos.y, mTexture->GetWidth() * mSize.x, mTexture->GetHeight() * mSize.y));
		}

		//Gdiplus::Graphics graphcis(hdc);
		//graphcis.DrawImage(mImgae, Gdiplus::Rect(pos.x, pos.y, mWidth, mHeight));
	}
}

- Render함수에 타입별 처리 추가 

 

 

#############################

- 25.02.24 : Texture 클래스 및 Resource클래스 추가

- 25.02.25 : Resources 클래스 및 LoadResource 코드 추가

- 25.03.04 : SpriteReneder.h 및 .cpp, Math, PlayScene 코드수정

 

반응형