WIN32API FrameWork/한단계씩 직접 구현

36. 이미지의 투명 처리

hyrule 2022. 5. 25. 22:21

http://hyrule.tistory.com/111 

 

*** 공부 방법 ***

1. 코딩을 해야 하는 부분은 첫 부분에 변수나 함수, 메소드에 대한 선언이 코드블럭으로 표시되어 있다. //ex) MakeFunction(); 2. 코드블럭 하단에는 해당 선언에 대한 구현 로직이 작성되어 있다. 처

hyrule.tistory.com

 


 

- 애니메이션을 잘 보면, 텍스처가 그려지는 사각형 부분이 아예 덮히는 것을 확인할 수 있다.

그리고 싶은 부분(테두리) 바깥은 투명하게 처리해야되는 게 맞지 않을까?

 

- .bmp 이미지 파일은 투명 데이터를 가지고 있지 않지만, 우리는 '특정 색깔을 정해서' 그 색을 출력하지 않을 수 있다.

-- 이를 '컬러 키' 방식이라고 한다.

CF) 이외에도 투명을 처리하는 방식은 '블렌딩' 방식이 존재한다.

 

- 일단 출력되지 않을 색깔을 정해야 하는데, 일반적으로 '마젠타(R255 G0 B255)' 색상이 많이 쓰이는 편이다. 색상이 쨍해서 잘 쓰이지 않는 색상이기 때문이다.

- 그림판에서 양동이 툴로 사용하지 않는 부분에 마젠타 색상을 부어놓자.


[사전 지식]

COLORREF ColorKey = RGB(255, 0, 255);

- COLORREF: unsigned int 타입

- RGB(R, G, B): RGB값을 지정해주는 매크로


TransparentBlt(hDC, (int)RenderLT.x, (int)RenderLT.y,
    (int)m_Size.x, (int)m_Size.y, m_Texture->GetDC(),
    0, 0, (int)m_Size.x, (int)m_Size.y, m_Texture->GetColorKey());

1번: HDC

2,3번: 그릴 위치

4,5번: 그릴 사이즈

6,7번: 메모리 DC

8,9번: 이미지에서 뽑아올 시작점 -> 스프라이트에서 사용함. 지금은 스프라이트가 아니므로 0, 0

10, 11번: 이미지에서 뽑아올 시작점으로부터 얼마 만큼 그릴것인지

12번: 컬러키 지정


- 사용하지 않을 색상을 정했으면, ImageInfo 구조체도 해당 색상을 표시하지 않기 위해 RGB값을 들고 있어야 한다.

 

- 해당 변수를 구조체에 추가한다.

-- EnableColorKey: 컬러키를 사용할지 말지 여부를 bool타입으로 저장하는 변수. 기본값 false

-- ColorKey: 컬러키 색을 저장하는 COLORREF 변수. 기본값 마젠타

더보기
struct ImageInfo
{
    HDC      hMemDC;
    HBITMAP  hBmp;
    HBITMAP  hPrevBmp;
    BITMAP   BmpInfo;
    COLORREF ColorKey;
    bool     ColorKeyEnable;

    ImageInfo() :
        hMemDC(0),
        hBmp(0),
        hPrevBmp(0),
        BmpInfo{},
        ColorKey(RGB(255, 0, 255)),
        ColorKeyEnable(false)
    {
    }

    ~ImageInfo()
    {
        // 도구를 원래대로 돌려준다.
        SelectObject(hMemDC, hPrevBmp);
        DeleteObject(hBmp);
        DeleteDC(hMemDC);
    }
};

 

<CTexture::SetColorKey()>

- 컬러 키를 지정해주는 메소드.

 

- R, G, B 값을 unsigned char로 받고, vector의 인덱스를 int로 받는다.

-- R = 255, G = 0, B = 255, index = -1로 기본값을 지정해 준다.

-- -1 이외의 숫자가 들어오면 해당 인덱스의 ImageInfo만 설정해준다.

 

 

<CTexture::GetColorKey()>

- 인덱스를 인자로 전달하여 컬러키값을 얻어온다. 기본값 0(애니메이션 없이 파일 하나일 떄 자동으로 출력되도록)

 

<CTexture::GetEnableColorKey()>

- 인덱스를 인자로 전달하여 컬러키 기능 활성화 여부를 얻어온다. 기본값 0

 

** GetDC() 메소드도 기본값을 0으로 해준다. 지난번에 기본값을 주지 않았었음.

 

- 이 메소드들을 CTextureManager, CResourceManager, CSceneResource, CGameObject에서도 쓸 수 있게 해준다.

-- CGameObject -> CSceneResource -> CResourceManager -> CTextureManager -> CTexture

더보기
//Texture.h

public:
    HDC GetDC(int index = 0) const
    {
        return m_vecImageInfo[index]->hMemDC;
    }

    void SetColorKey(unsigned char r = 255, 
        unsigned char g = 0, 
        unsigned char b = 255, 
        int index = -1);

    COLORREF GetColorKey(int index = 0)  const
    {
        return m_vecImageInfo[index]->ColorKey;
    }

    bool GetColorKeyEnable(int index = 0)  const
    {
        return m_vecImageInfo[index]->ColorKeyEnable;
    }

 

 

//Texture.cpp

void CTexture::SetColorKey(unsigned char r, unsigned char g, unsigned char b, int index)
{
	if (index != -1)
	{
		m_vecImageInfo[index]->ColorKey = RGB(r, g, b);
		m_vecImageInfo[index]->ColorKeyEnable = true;
	}
		
	else
	{
		size_t size = m_vecImageInfo.size();
		for (size_t i = 0; i < size; ++i)
		{
			m_vecImageInfo[i]->ColorKey = RGB(r, g, b);
			m_vecImageInfo[i]->ColorKeyEnable = true;
		}
	}
}

- 그럼 이제 CGameObject에서 SetTexture() 메소드를 통해 텍스처를 설정하고 나서

SetColorKey() 메소드를 호출하면 컬러키를 사용하도록 설정된다.

bool CMonster::Init(CGameObject* Obj)
{

	SetTexture("Monster", TEXT("pepe.bmp"));
    
    //인자를 넣지 않으면, 자동으로 마젠타 색상으로 컬러키를 설정한다.
	//애니메이션일 경우, 모든 애니메이션 프레임에 대해 마젠타 색상을 컬러키로 지정해준다.
	SetColorKey();
    
    //...
    
    //오브젝트의 사이즈와 이미지의 사이즈를 일치시켜 주자.
    SetSize(150.f, 133.f);

GameFrameworkStepbyStep_36_TransparentBlt.zip
2.37MB