PlayLevel.cpp
for AllFileList문 -> FullPath가져와서 LoadImg 실행함
PathObject : NameObject를 상속받음. Path를 가짐. 리소스들은 PathObject를 상속받을 것임.
Path만 받는 LoadImg, Path랑 Name 둘 다 받는 LoadImg 각각 만듦.
UWindowImage* UEngineResourcesManager::LoadImg(std::string_view _Path)
{
UEnginePath NewPath = UEnginePath(std::filesystem::path(_Path));
std::string FileName = NewPath.GetFileName();
return LoadImg(_Path, FileName);
}
UWindowImage* UEngineResourcesManager::LoadImg(std::string_view _Path, std::string_view _Name)
{
// 모든 이름은 대문자로
std::string UpperName = UEngineString::ToUpper(_Name);
if (true == Images.contains(UpperName))
{
MsgBoxAssert(std::string("경로 : ") + std::string(_Path) + "파일명 : " + std::string(_Name) + "이미 로드한 파일을 또 로드하려고 했습니다");
return nullptr;
}
UWindowImage* NewImage = new UWindowImage();
NewImage->SetName(UpperName);
NewImage->SetPath(_Path);
NewImage->Load(GEngine->MainWindow.GetWindowImage());
Images[UpperName] = NewImage;
return nullptr;
}
UWindowImage::Load()
경로와 이름을 이미 알 수 있어서 인자 필요없음. 윈도우 함수 사용할 건데 성공하면 true, 실패하면 false를 리턴하는 게 일반적이라서 얘도 bool 리턴하도록 함.
bool UWindowImage::Load(UWindowImage* _Image)
{
UEnginePath Path = GetEnginePath();
std::string UpperExt = UEngineString::ToUpper(Path.GetExtension());
if (".BMP" == UpperExt)
{
//HINSTANCE hInst, 이 이미지를 사용할 프로그램을 알려달라는건데. nullptr넣어도 괜찮다.
//LPCSTR name, // 경로
//UINT type, // 이미지 타입
//int cx, // 이미지를 로드할 크기 X 0을 넣으면 전체 크기로 로드
//int cy, // 이미지를 로드할 크기 Y 0을 넣으면 전체 크기로 로드
//UINT fuLoad 로드 옵션
// 비트맵을 제어할수 있는 핸들
HANDLE ImageHandle = LoadImageA(nullptr, Path.GetFullPath().c_str(), IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
hBitMap = reinterpret_cast<HBITMAP>(ImageHandle);
ImageType = EWIndowImageType::IMG_BMP;
}
else if (".PNG" == UpperExt)
{
ULONG_PTR gdiplusToken = 0;
Gdiplus::GdiplusStartupInput gdistartupinput;
Gdiplus::GdiplusStartup(&gdiplusToken, &gdistartupinput, nullptr);
// 멀티바이트 경로를 유니코드 경로로 변경하는 함수
std::wstring wPath = UEngineString::AnsiToUniCode(Path.GetFullPath());
Gdiplus::Image* pImage = Gdiplus::Image::FromFile(wPath.c_str());
Gdiplus::Bitmap* pBitMap = reinterpret_cast<Gdiplus::Bitmap*>(pImage->Clone());
Gdiplus::Status stat = pBitMap->GetHBITMAP(Gdiplus::Color(0, 0, 0, 0), &hBitMap);
if (Gdiplus::Status::Ok != stat)
{
MsgBoxAssert("Png 형식 리소스 로드에 실패했습니다.");
}
ImageType = EWIndowImageType::IMG_PNG;
}
ImageDC = CreateCompatibleDC(_Image->ImageDC);
HBITMAP OldBitMap = reinterpret_cast<HBITMAP>(SelectObject(ImageDC, hBitMap)); // ImageDC야 너는 BitMap그려야 해.
DeleteObject(OldBitMap);
// hBitMap에서 BitMapInfo로 얻어오겠다.
GetObject(hBitMap, sizeof(BITMAP), &BitMapInfo);
return true;
}
윈도우에서 이미지를 사용하기 위해서 지원하는 라이브러리.
헤더랑 다르게 라이브러리는 #pragma comment로 추가해서 사용
이 두 개가 엮여서 이미지라는 게 된다. 근데 이걸 하나로 묶어놓는 요소가 없음. 그래서 WindowImage라는 클래스에 엮어서 사용하는 거임. DC만 만들면 처음에 1,1짜리 HBITMAP이랑 연결돼있음. 윈도우에서 DC에 꼭 HBITMAP이 연결되어있도록 해놨음.
-> (HBITMAP)SelectObject(ImageDC, BitMap);
: HDC에 HBITMAP 연결시켜줌. 근데 원래 있던 1,1짜리가 남아있게 됨.(leak) 그래서 Delete해줘야함..
(SelectObject를 하면 반환값으로 이전 bitmap을 준다)
ImageDC = CreateCompatibleDC(_MainDC);
HBITMAP OldBitMap = (HBITMAP)SelectObject(ImageDC, BitMap);
DeleteObject(OldBitMap);
이미지 로드하고나서 render
void UImageRenderer::Render(float _DeltaTime)
{
if (nullptr == Image)
{
MsgBoxAssert("이미지가 존재하지 않는 랜더러 입니다");
}
FTransform ThisTrans = GetTransform();
FTransform OwnerTrans = GetOwner()->GetTransform();
// 컴포넌트의 위치는 부모에게서 상대적이기 때문에.
// 부모의 위치를 더해줘야 한다.
ThisTrans.AddPosition(OwnerTrans.GetPosition());
GEngine->MainWindow.GetWindowImage()->BitCopy(Image, ThisTrans);
}
BitBlt()
사용void UWindowImage::BitCopy(UWindowImage* _CopyImage, FTransform _Trans)
{
// HDC hdc, // => 어떤 이미지에
// int x,
// int y,
// int cx,
// int cy,
// HDC hdcSrc,
// int x1,
// int y1,
// DWORD rop
// 윈도우
HDC hdc = ImageDC;
// 이미지
HDC hdcSrc = _CopyImage->ImageDC;
BitBlt(
hdc, // HDC hdc,
_Trans.iLeft(), // int x,
_Trans.iTop(), // int y,
_Trans.GetScale().iX(), // int cx,
_Trans.GetScale().iY(), // int cy,
hdcSrc, // HDC hdcSrc,
0, // int x1,
0, // int y1,
SRCCOPY // DWORD rop => 이미지 그대로 고속 복사를 해라.
);
}
EnginePath::GetFullPath()
: Path의 string return
리소스 이미지 확장자 바꾸려면 이미지 편집 프로그램에서 포맷을 변경하고 저장해야 함.
winapi는 png파일을 출력하는 함수를 지원하지 않는다. bmp만 된다.
png파일을 로드해서 bmp로 변경해서 출력할 것이다.
UImage -> UWindowImage로 바꿈, Level2에서 Level1로 옮김. Window에 속한 기능에 가깝기 때문. PathObject 상속받아서 이름과 Path를 가질 수 있는 애가 됨.
NameObject Level2에서 Level0으로 옮김.
에디터 모드나 디버그에서는 속력을 따질 필요가 없다.(터지는 마당에 먼 속력) 게임에서 실제 실행되지 않을 내용에서는 속력을 따지지 않는다.