RGB Transition

2023. 7. 28. 19:30개인공부/Direct2D

RGB Transition

 

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, 000,
        0, G, 00,
        00, B, 0,
        0001,
        0000);
 
    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을 서로 다르게 부여해서 효과를 구현하였다. 그 과정에서 블랜딩을 모드를 변경하였다. 블랜딩 모드를 변경함으로서 좀더 다양한 효과들의 구현이 가능해 보인다.

RGB 효과 응용

 

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