GDI+에 대하여

GDI+는 잘 알다시피 전통적인 윈도우 API가 제공하는 GDI에서 더 나아가, 더 향상된 그래픽과 더 깔끔해진 프로그래밍 패러다임을 제공하는 그래픽 API이다. 사실, 닷넷에서는 애초에 기본 그래픽 API가 GDI+이다. (System.Drawing 네임스페이스)

GDI+는 벌써 10년 전, 닷넷 프레임워크가 첫 등장하고 윈도우와 오피스에 XP라는 브랜드가 붙던 시절에 도입되었다. MS가 제공하는 API로는 흔치 않게 C언어 함수도 아니고 그렇다고 DirectX 같은 COM도 아닌, C++ 언어 형태로 되어 있다. 물론, 그래도 실제로 링크를 해 보면 symbol들은 다 C언어 함수 호출 형태로 된다. C++ 클래스는 단순히 C 함수를 호출하는 wrapper인 것이다.

GDI+는 여러 편리한 기능을 많이 제공하지만, 무엇보다도 벡터 그래픽에 안티앨리어싱을 넣기 위해서라도 쓰지 않을 수 없다. 이런 간단한 기능은 그냥 기존 GDI 함수에다가도 옵션을 확장해서 좀 넣어 주지 하는 아쉬움이 있다. 재래식 GDI로도 안티앨리어싱된 텍스트는 얼마든지 찍을 수 있는 것처럼 말이다. (LOGFONT 구조체에 글꼴의 품질을 지정하는 추상화 계층이 있기 때문에, 나중에 추가된 안티앨리어싱 기능도 얼마든지 지정 가능)

재래식 GDI는 열악하던 컴퓨터 환경에서 최대한 장치 독립적인 추상적인 그래픽 계층을 구현하는 게 목표였다. 그래서 래스터 그래픽보다는 벡터 그래픽에, 애니메이션보다는 정적인 그래픽에 초점이 가 있었다. 그 추상화 계층이 확장성 측면에서 편리한 점은 분명 있었지만, 색깔을 하나 바꾸려고 해도 펜이나 브러시를 다시 만들고, 도스 시절의 그래픽 프로그래밍 때는 할 필요가 없었던 GDI 객체 관리를 해야 하니 상당히 불편했다.

그래서 GDI는 게임 그래픽용으로는 적합하지 않은 구석이 있었다. 물론, 지금과 같은 틀을 유지하면서도 JPG/PNG 이미지를 지원하고, 알파 채널 비트맵 Blit이나 별도의 gradient fill 함수를 추가하고, 윈도우 2000처럼 펜이나 브러시의 색깔을 손쉽게 바꿀 수 있는 DC pen/DC brush 같은 기능을 stock object로 넣는 등, 기능 개선이 꾸준히 진행돼 왔다. 하지만 MS 측에서는 이에 만족하지 못하고 이 참에 API를 근본적으로 갈아엎고 싶다는 욕망을 느꼈던 모양이다.

GDI+는 모든 API가 자신만의 별도의 namespace 안에 선언되어 있으며, POINT 같은 간단한 자료형도 자신만의 것을 재정의하여 쓸 정도로 기존 윈도우 API와는 거리를 두고 만들어졌다. 그리고 C++답게 같은 함수도 다양한 overload 버전이 존재하며, 좌표는 정수뿐만이 아니라 실수로도 받기 때문에 편리하다.

사소한 것이다만, 글자를 찍을 때 null-terminated string에 대해서 글자 길이 지정을 생략해도 되는 것 역시 마음에 든다.
전통적으로 윈도우의 GDI 함수들은 글자를 찍는 함수들은 문자열 길이를 반드시 지정해 주게 되어 있다. 왜냐하면 한 null-terminated string을 부분적으로 여러 줄에 걸쳐 찍어야 할 일도 있기 때문이다.

그러니 그런 API 디자인이 수긍은 가지만, 어차피 한 줄밖에 찍을 일이 없는 문자열을 매번 _wcslen 해 주는 것도 귀찮지 않은가. 예전에는 gdi가 아니라 user 계층에 있는 DrawText 같은 고수준 함수나 문자열 길이 지정을 -1로 생략이 가능했던 반면, GDI+는 이 정책이 좀 더 확대되었다.

GDI+는 GDI에 비해서 state machine으로서의 의미가 크게 퇴색했다. 그래서 그리기에 필요한 모든 정보들을 함수 호출 때 매개변수로 일일이 전달해 줘야 하는 경우가 많다. 가령, current position이라는 개념이 없기 때문에 MoveTo와 LineTo 따로가 아니며, SelectOjbect라는 개념도 없어져서 그리기 함수 때 매번 펜이나 브러시에 해당하는 개체를 따로 공급해 줘야 한다.

이런 디자인은 편리한 점도 있지만, 당장 화면에 뭔가를 찍는 드로잉 말고 벡터 path를 기록한다거나 메타파일 같은 걸 만들 때는, 내가 보기에 좀 불편하게 작용하는 점도 있는 것 같다. 가령, GDI에서는 똑같이 HDC이고 여기에다가 BeginPath를 해 주면 그때부터 path 그리기 모드로 GDI가 상태 관리를 하면서 동작한다. 그러던 것이 GDI+에서는 Graphics와 GraphicsPath라고 클래스가 아예 갈라졌다. 두 개체를 상태별로 분리한 건 분명 잘한 디자인이라는 거 인정한다.

하지만 Graphics 말고 GraphicsPath는 어차피 예전 위치에서 계속해서 이어서 그래픽을 기술하는 게 많은 만큼, 재래식 GDI처럼 current position이 있는 게 편리하지 않을까 싶다. 지금 API 체계에서는 직전 위치에 대한 정보를 응용 프로그램이 계속 공급해 줘야 한다.

또한, 복잡한 path를 화면에다 그릴 때, 예전 GDI는 지금 DC가 가지고 있는 펜과 브러시로 윤곽선을 그리고 내부를 채우는 것을 함수 호출 한 번으로 동시에 할 수 있었다. 그러나 GDI+는 선을 그리는 것과 내부를 채우는 것을 따로 해야 한다. path의 경계를 추출하여 래스터라이즈하는 것은 상당히 복잡한 계산이 필요한 작업인데, 동일한 작업이 비효율적으로 중복 적용되는 건 아닌지 우려된다.

즉, 본인은 GDI+에 대해서 참신한 기능은 분명 마음에 든다. 이 글에서 언급된 것 말고도 여러 고급 기능들이 있다. 윈도우 비스타 Aero와 연동하는 일부 드로잉 기능(가령, 클라이언트 영역에도 반투명 Aero 효과를 추가하고, 거기에다 글자를 찍는 것)은 오로지 GDI+로만 접근해야 하는 것도 있다.

하지만 (1) 그냥 재래식 GDI API에다가 옵션을 추가하는 형태로 구현했어도 충분해 보이는 것, (2) GDI+가 바꿔 놓은 API 디자인이 오히려 좀 불편하고 비효율적일 수도 있겠다 싶은 것에 대해 비판적인 안목을 갖고 있다. 속도가 재래식 GDI보다 꽤 느린 건 차치하고라도 말이다.

Posted by 사무엘

2012/04/28 08:39 2012/04/28 08:39
, ,
Response
No Trackback , 4 Comments
RSS :
http://moogi.new21.org/tc/rss/response/675

Trackback URL : http://moogi.new21.org/tc/trackback/675

Comments List

  1. Lyn 2012/04/28 13:19 # M/D Reply Permalink

    이젠 D2D의 시대... 근데... D2D로 만든 프로그램은 IE9/10밖에 없잖아... 안될거야 아마

  2. 주의사신 2012/04/28 15:33 # M/D Reply Permalink

    1. GDI+ 쓰면서 상당히 의아하게 여겼던 것이 둥근 모서리 사각형이 없다는 것이었습니다. 그래서 Path 이용해서 하나 만들어서 썼던 기억이 나네요.

    2. DirectX 10 렌더링 된 것 위에다가 GDI+로 뭔가 그리고 싶어서 DirectX의 포인터 열어 가지고 GDI+ 내용을 적어 주었던 기억이 납니다.

    현업이었다면, 아마 GDI+ 쓰지 않고 디자이너가 만든 그래픽을 쓰지 않았을까 하는 생각이 들기도 합니다.

  3. 사무엘 2012/04/28 19:08 # M/D Reply Permalink

    Lyn: 그렇죠. 이제는 GDI+에 대해서도 대체 API가 나왔죠. 하지만 GDI+는 디자인 방식이 굉장히 특이하긴 했습니다.

    주의사신: 네, Graphics 클래스에는 DrawRectangle만 있지 GDI 같은 RoundRect에 해당하는 개념은 없습니다.
    저는 DirectX 9 이후로 딱히 게임 쪽 프로그래밍을 한 적이 없어서 그래픽 기술이 어떻게 돼 가나 궁금해질 때가 있네요. ^^

  4. Lyn 2012/04/28 22:11 # M/D Reply Permalink

    그래픽기술은 이제 100% 프로그래밍쉐이더의 세계로 이사갔죠

    기본파이프라인을 아예 제공하지않는...

Leave a comment
« Previous : 1 : ... 1014 : 1015 : 1016 : 1017 : 1018 : 1019 : 1020 : 1021 : 1022 : ... 1608 : Next »

블로그 이미지

철도를 명절 때에나 떠오르는 4대 교통수단 중 하나로만 아는 것은, 예수님을 사대성인· 성인군자 중 하나로만 아는 것과 같다.

- 사무엘

Archives

Authors

  1. 사무엘

Calendar

«   2020/04   »
      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    

Site Stats

Total hits:
1353248
Today:
140
Yesterday:
527