RGB Transition
2023. 7. 28. 19:30ㆍ개인공부/Direct2D
RGB 분리
가장 먼저 원본 bitmap에서 RGB값들을 각각 분리했다. 각각의 추출할 색깔을 정해서 ID2D1Bitmap 객체로 생성하였다. 생성하는 과정에서 어제 공부한 unique_ptr을 사용해 보고싶었는데 ID2D1 객체의 경우 COM 객체쪽으로 Release를 따로 호출해서 해제하는 형식이기 때문에 ComPtr을 사용해서 따로 스마트포인터를 사용해야 했기 때문에 나중에 공부해서 사용 할 예정이다. 게임을 진행할때 런타임에 비트맵을 새로만들고 해제하는건 비효율적이므로 나중에 비트맵을 저장해서 쓰는 방법으로 코드를 바꿀 예정이다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
ID2D1Bitmap* D2DEffect::ExtractColor(ID2D1Bitmap* _orgin, EXTRACT_COLOR _color)
{
ID2D1Bitmap* resultBitmap = nullptr;
ID2D1Image* image = nullptr;
float R = 0.f, G = 0.f, B = 0.f;
switch (_color)
{
case EXTRACT_COLOR::RED:
R = 1.f;
break;
case EXTRACT_COLOR::BLUE:
B = 1.f;
break;
case EXTRACT_COLOR::GREEN:
G = 1.f;
break;
default:
break;
}
// [R B G A] 행렬과 matrix 행렬을 연산해서 최종적인 색깔을 만든다.
D2D1::Matrix5x4F matrix(
R, 0, 0, 0,
0, G, 0, 0,
0, 0, B, 0,
0, 0, 0, 1,
0, 0, 0, 0);
m_colorMatrix->SetValue(D2D1_COLORMATRIX_PROP_COLOR_MATRIX, matrix);
m_colorMatrix->SetInput(0, _orgin);
m_colorMatrix->GetOutput(&image);
D2D1_SIZE_U size = { static_cast<UINT32>(_orgin->GetSize().width)
, static_cast<UINT32>(_orgin->GetSize().height) };
resultBitmap = ConvertImageToBitmap(&image, size);
return resultBitmap;
}
|
cs |
RGB 효과
일단은 너무 눈이 아프다..... 게임에서 사용하기 위해서는 좀더 최소화하는 방법으로 사용이 필요해보인다.... 그래서 각각의 RGB 비트맵을 생성하고 비트맵의 offset을 서로 다르게 부여해서 효과를 구현하였다. 그 과정에서 블랜딩을 모드를 변경하였다. 블랜딩 모드를 변경함으로서 좀더 다양한 효과들의 구현이 가능해 보인다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
|
void D2DRenderer::DrawRGBTransition(const wstring& _key, Vector2 _position, const std::vector<Vector2>& _rgbOffset)
{
// RBG값으로 넣지않았다면 경고
assert(_rgbOffset.size() == 3);
auto iter = m_textures.find(_key);
assert(iter != m_textures.end() || !L"텍스처 파일이 로드되지 않았습니다");
D2DTexture* texture = iter->second;
// RBB 색상별로 Color 값을 추출해서 보관한다. 일단 매프레임마다 생성하지만 사용하게되면 저장해둘 필요가 있음
ID2D1Bitmap* red = m_effect->ExtractColor(texture->GetBitmap(), EXTRACT_COLOR::RED);
ID2D1Bitmap* blue = m_effect->ExtractColor(texture->GetBitmap(), EXTRACT_COLOR::BLUE);
ID2D1Bitmap* green = m_effect->ExtractColor(texture->GetBitmap(), EXTRACT_COLOR::GREEN);
// 그리는 대상 위치
Vector2 position = _position.ChangeYSign();
Vector2 halfSize{};
halfSize.x = texture->GetBitmap()->GetSize().width * 0.5f;
halfSize.y = texture->GetBitmap()->GetSize().height * 0.5f;
// 비트맵 원본
D2D1_RECT_F orgin{};
orgin.left = position.x - halfSize.x;
orgin.right = position.x + halfSize.x;
orgin.top = position.y + halfSize.y;
orgin.bottom = position.y - halfSize.y;
// RGB각각을 계산 RGB 순서대로
D2D1_RECT_F rect[3]{};
// 각각의 rect들을 계산한다.
for (int i = 0; i < 3; ++i)
{
rect[i].left = orgin.left + _rgbOffset[i].x;
rect[i].right = orgin.right + _rgbOffset[i].x;
rect[i].top = orgin.top + _rgbOffset[i].y;
rect[i].bottom = orgin.bottom + _rgbOffset[i].y;
}
// 기본 비트맵을 출력
m_deviceContext->DrawBitmap(texture->GetBitmap(), orgin
, 1.f, D2D1_BITMAP_INTERPOLATION_MODE_LINEAR, nullptr);
// 랜더링의 블랜딩 모드 변경 ADD 모드로 적용해야 RBGTransition이 예쁘게 적용
m_deviceContext->SetPrimitiveBlend(D2D1_PRIMITIVE_BLEND_MAX);
m_deviceContext->DrawBitmap(red, rect[0]
, 1.f, D2D1_BITMAP_INTERPOLATION_MODE_LINEAR, nullptr);
m_deviceContext->DrawBitmap(blue, rect[1]
, 1.f, D2D1_BITMAP_INTERPOLATION_MODE_LINEAR, nullptr);
m_deviceContext->DrawBitmap(green, rect[2]
, 1.f, D2D1_BITMAP_INTERPOLATION_MODE_LINEAR, nullptr);
// 블랜딩모드를 표준으로 변경한다
m_deviceContext->SetPrimitiveBlend(D2D1_PRIMITIVE_BLEND_SOURCE_OVER);
// 사용한 비트맵을 해제해준다
red->Release();
blue->Release();
green->Release();
}
|
cs |
'개인공부 > Direct2D' 카테고리의 다른 글
D2D 이펙트 공부 (0) | 2023.07.26 |
---|---|
Direct2D Effect 응용 (0) | 2023.07.25 |
스타크래프트 기능 구현 3 (0) | 2023.07.16 |
스타크래프트 기능 구현 2 (0) | 2023.07.14 |
충돌 연산 최적화 (0) | 2023.07.12 |