< .NET 플랫폼에서의 2D 그래픽 프로그래밍 > 이 논문에서는 MS가 최신 기술이자 2006년쯤에 나올 새로운 OS인 롷혼(Windows XP 의 차세대 버전 )의 API인 WinFX의 기초가 될 .NET 라이브러리를 사용하여 Manage(관리) 환경에서의 2D 그래픽 프로그래밍에 대해서 소개 히고자 한다. 본 논문은 크게 두 가지의 주제로 나누어 설명을 하고자 한다. 첫째. GDI+를 이용한 2D 그래픽 프로그래밍의 소개 둘째. Managed DirectX를 이용한 그래픽 프로그래밍 의 소개. 참고로 이 글에 포함이 되어 있는 소스는 C# 으로 구성 되어져 있다. 특별히 C# 에 대해서 소개를 한다는 것은 워낙 방대한 내용이고 주제에 대해서 넘어서는 내용 이기에 별도로 언급하지 않는다. 이 글의 소스는 굳이 C#을 몰라도 이해가 가능한 부분이 많다고 생각되나 혹 모르는 분들은 양해를 부탁한다. 1. GDI+ 에 대해 GDI+는 Win32 API의 GDI 프로그래밍 방식을 개선/발전 시킨 것으로 .NET 뿐만 아닌 Windows 2000 이상의 플랫폼 이라면 Win32 API에서도 사용이 가능하다. GDI+는 .NET 에서 그래픽 작업을 위하여 제작 된 API로 특히 웹, Windows 컨트 롤을 염두에 두고 설게 되었다. GDI+ 는 API 라기 보다는 GDI를 감싼 레퍼이다. GDI+는 이해하기 쉽고 상속에 기반한 개체 모델을 제공한다. 특히 C++/MFC에 경험이 있는 프로그래머라면 GDI+의 개념을 쉽게 받아 들일 수 있을 것이다. GDI+의 특징 1. 창, 비트맵, 프린터라는 세 종류의 그리기 표면을 제공한다. 2. 2차원적인 선을 그릴 수 있는 도구를 제공한다. 무한히 다양한 브러시와 펜 을 사용해서 선, 도형, 다각형, 곡선을 그릴 수 있다. 3. 다양한 텍스트 그리기를 지원한다(앤티 엘리어싱도 제공한다). 4. 이미지를 읽었어 그리기도 가능하며 이미지를 생성하여 그 안에 그림을 그
42
Embed
< .NET 플랫폼에서의 2D 그래픽 프로그래밍 >cfs7.tistory.com/upload_control/download.blog?fhandle=YmxvZzE4MDA0... · < .NET 플랫폼에서의 2D 그래픽 프로그래밍
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
< .NET 플랫폼에서의 2D 그래픽 프로그래밍 >
이 논문에서는 MS가 최신 기술이자 2006년쯤에 나올 새로운 OS인 롷혼(Windows
XP 의 차세대 버전 )의 API인 WinFX의 기초가 될 .NET 라이브러리를 사용하여
Manage(관리) 환경에서의 2D 그래픽 프로그래밍에 대해서 소개 히고자 한다.
본 논문은 크게 두 가지의 주제로 나누어 설명을 하고자 한다.
첫째. GDI+를 이용한 2D 그래픽 프로그래밍의 소개
둘째. Managed DirectX를 이용한 그래픽 프로그래밍 의 소개.
참고로 이 글에 포함이 되어 있는 소스는 C# 으로 구성 되어져 있다. 특별히 C#
에 대해서 소개를 한다는 것은 워낙 방대한 내용이고 주제에 대해서 넘어서는 내용
이기에 별도로 언급하지 않는다. 이 글의 소스는 굳이 C#을 몰라도 이해가 가능한
부분이 많다고 생각되나 혹 모르는 분들은 양해를 부탁한다.
1. GDI+ 에 대해
GDI+는 Win32 API의 GDI 프로그래밍 방식을 개선/발전 시킨 것으로 .NET 뿐만
아닌 Windows 2000 이상의 플랫폼 이라면 Win32 API에서도 사용이 가능하다.
GDI+는 .NET 에서 그래픽 작업을 위하여 제작 된 API로 특히 웹, Windows 컨트
롤을 염두에 두고 설게 되었다.
GDI+ 는 API 라기 보다는 GDI를 감싼 레퍼이다.
GDI+는 이해하기 쉽고 상속에 기반한 개체 모델을 제공한다.
특히 C++/MFC에 경험이 있는 프로그래머라면 GDI+의 개념을 쉽게 받아 들일 수
있을 것이다.
GDI+의 특징
1. 창, 비트맵, 프린터라는 세 종류의 그리기 표면을 제공한다.
2. 2차원적인 선을 그릴 수 있는 도구를 제공한다. 무한히 다양한 브러시와 펜
을 사용해서 선, 도형, 다각형, 곡선을 그릴 수 있다.
3. 다양한 텍스트 그리기를 지원한다(앤티 엘리어싱도 제공한다).
4. 이미지를 읽었어 그리기도 가능하며 이미지를 생성하여 그 안에 그림을 그
리는 것도 가능하고 또한 다양한 포맷으로 저장도 가능하다.
5. 인쇄 지원으로 미리 보기 기능도 쉽게 구현 가능하다.
GDI+의 장점
1. GDI 이상의 능력을 제공한다. GDI 에서는 구현하기가 힘들었던 기능들인
반투명 효과, 그라데이션 브러시, 강력한 그래픽 패스 등을 제공한다.
2. GDI는 복잡 하여 사용이 까다로우나 GDI+는 간결 하면 한결 사용이 편리
하다.
3. GDI+는 개체 지향적 클래스 구조로 되어 있어 GDI+ 프로그래밍은 개체의
생성, 개체의 속성 설정, 개체의 메소드 호출로 이루어 진다.
4. 메소드 오버로딩을 사용한다. 따라서 어떤한 GDI+ 개체의 메소드를 호출
할 때 주어진 상황에 가장 적합한 인수들을 받는 버전의 메소드를 선택할
수 있다.
5. GDI+는 외곽선 그리기와 내부 채우기 사이의 차이를 인식하여 각각 서로
구별되는 처리수단을 제공하는 좀 더 유연한 그리기 인터페이스를 제공한
다.
6. GDI+는 상태 관리의 일부 측면들을 개발자로부터 은폐한다.
GDI+ 새로운 기능
1). 그라데이션 브러시
- GDI+는 도형, 패스 및 영역을 채우는 데 사용하는 선형 그라데이션 브러시와 패
스 그라데이션 브러시를 제공함으로서 GDI를 확장한다. 그라데이션 브러시는 또한
선, 곡선 및 패스를 그리는 데 사용할 수 있다. 선형 그라데이션 브러시를 사용하여
도형 내의 위치에 따라 색상이 변하도록 도형을 채울 수 있다.
도형을 패스 그라데이션 브러시로 채울 때에는 도형의 한 영역에서 다른 영역으로
이동할 때의 색상 변화를 다양하게 지정할 수 있다.
2). 카디널 스프라인
GDI+는 GDI에서 지원되지 않던 카디널 스플라인을 지원한다. 카디널 스플라인은
대형 곡선을 형성하는 개별 곡선 순서 집합이다. 스플라인은 점의 배열과 그 배열
의 각 점을 통과하는 패스에 의해 지정된다. 카디널 스플라인은 배열의 각 점을 날
카로운 모서리 없이 매끄럽게 통과하므로, 직선을 연결하여 생성한 패스보다 더 정
교하다.
3). 독립적인 패스 개체
GDI+에서 그리기는 Graphics 개체별로 수행되며 Graphics 개체와 분리된 여러
GraphicsPath 개체를 생성하고 유지할 수 있다. GraphicsPath 개체는 그리기가
끝나도 소멸되지 않기 때문에 같은 GraphicsPath 개체를 사용하여 패스를 여러 번
그릴 수 있다.
4). 변환 및 매트릭스 개체
GDI+는 회전이나 변형 등과 같은 변환 작업을 쉽고 유연하게 만들어 주는 강력한
도구인 Matrix 개체를 제공한다. 매트릭스 개체는 변형된 개체와 함께 동작한다.
예를 들어, GraphicsPath 개체는 Matrix 개체를 인수로 받는 Transform 메서드가
있다.
5). 확장 가능한 영역
GDI+에서는 GDI 보다 영역 지원 기능이 대폭 강화되었다. GDI 에서는 영역이
디바이스 좌표로 저장되며 영역에 적용할 수 있는 유일한 변환은 변형이다.
GDI+에서는 영역을 전역 좌표로 저장하며 영역에 크기 조절 등과 같은 모든 변환
매트릭스를 적용할 수 있다. 다음 예제에서는 크기 조절, 회전 후 변환 변형을
거친 영역을 보여 준다.
6). 알파 혼합
알파 혼합을 사용하면 채워진 색상의 투명성을 지정할 수 있다. 투명한 색상은
배경 색상과 혼합된다. 채워지는 색상의 투명성을 높일 수록 배경색이 잘 보인다.
7). 다양한 이미지 형식 지원
GDI+에서 제공되는 Image, Bitmap 및 Metafile 클래스를 사용하여 다양한 형식으로
이미지를 로드 및 저장하고 조작할 수 있습니다. 다음 형식이 지원됩니다. BITMAP.
GIF, JPEG, EXIF, PNG, TIFF, ICON, WMF, EMF
GDI+는 개발자에게 필요한 대부분의 그래픽 기능성을 제공하여 일관적이고 강력한
고성능 클래스들의 집합이다. 그러나 GDI+는 새로운 라이브러리로써 기능성에 제
한도 있어 때에 따라서는 GDI를 함께 사용 할 경우도 있다.
GDI+ 네임스페이스
GDI+ 관련 네임스페이스는 총 6개로 역할은 다음과 같다.
네임 스페이스 설명
System.Drawing 그리기 표면, 이미지, 색, 브러시, 펜, 글꼴 같은 기
본적인 그래픽 기능 제공
System.Drawing.Drawing2D 고급 레스터 및 벡터 그래픽 기능성을 제공
System.Drawing.Imaging System.Drawing 네임스페이스가 제공하는 것 이사
의 이미징 기능성을 제공
System.Drawing.Printing 인쇄 및 인쇄 미리 보기 기능성을 제공
System.Drawing.Text System.Drawing 네임스페이스가 제공하는 것 이상
의 글꼴 기능성을 제공
System.Drawing.Design 사용자 지정 컨트롤의 디자인 시점 지원을 개선하기
위한 기능성 제공
이 글에서는 GDI+의 모든 것을 다룰 수는 없으므로 게임프로그래밍과 밀접한
System.Drawing, System.Drawing.Drawing2D,
System.Drawing.Imaging 네임 스페이스에 있는 클래스들 위주로 설명 하려고 한
다.
2. GDI+ 프로그래밍
(1)간단한 C#을 사용한 GDI+ 프로그램
처음으로 간단하게 구성한 GDI+ 와 C# 으로 구성된 프로그램을 소개 하고자 한다.
여기에서 예제로 소개할 프로그램들은 모두 간단하므로 소스 설명과 함께 간단하게
설명하는 정도로 하고자 한다.
예) 1
using System;
using System.Windows.Forms;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Drawing.Text;
public class LineTextForm : Form
{
// Win32 기반에서는 OnPaint 와 같이 그리기 이벤트시 호출되는 함수 이다.
// OnPaint 는 오버라이드 할 수도 있고 아니면 delegate 로 위임 시킬 수도
있다.
protected override void OnPaint(PaintEventArgs e)
{
// 그래픽스 객체를 얻어온다.
Graphics g = e.Graphics;
// 검은색의 크기 3 의 펜을 하나 생성한다.
Pen blackPen = new Pen(Color.Black, 3);
// 0,0 에서 100,100 점을 생성한다.
Point startPoint = new Point(0, 0);
Point endPoint = new Point(100, 100);
// 위에서 생성한 펜으로 점 사이를 선으로 긋는다.
g.DrawLine(blackPen, startPoint, endPoint);
// 검은색 글자를 그리기 위해 검은색 브러시를 생성한다.
Brush blackBrush = new SolidBrush(Color.Black);
// ‘Times New Roman’글꼴 패밀리를 생성한다.
FontFamily familyName = new FontFamily("Times New Roman");
// 글꼴 패밀리를 이용하여 24 픽셀의 글꼴을 생성.
Font myFont = new Font(familyName, 24, FontStyle.Regular,
그러면 이후는 .NET에서 사용하는 DirectX인 Managed DirectX에 대해서 이야기
하겠다.
3. Managed DirectX
Managed DirextX에 대해서 아주 간단하게 설명하면 Microsoft(이하 MS)의 .NET
플랫폼에서 사용하는 DirectX라고 말 할 수 있다. DirectX 8.0까지는 .NET에서
DirectX를 사용할려면 InteOP라는 방식을 이용하여 간접적으로 사용하던 것을 9.0
에서 .NET에서도 편하게 사용 할 수 있도록 하였다. .NET이 객체의 관리
를 .NET 자체가 해주므로 .NET의 언어들을 Managed(관리) 언어라고 하는데 그래
서 기존의 DirectX에 Managed라는 수식어가 붙었다. 그래서 Managed DirectX는
기존의 DirectX와 구조가 거의 같으면서 사용이 더 쉬워졌다고 생각해도 될 것이다.
Managed DirectX는 다음의 컴포넌트로 구성되어 있다.
• Direct3D Graphics : 3D 그래픽 프로그래밍에 사용 하는 API 를 제공한다.
• DirectDraw : 비디오 메모리로의 하위 레벨 접근을 제공하여 빠른 렌더링을
실현시켜준다.
• DirectInput : 포스 피드백 기술의 완전 지원 등 다양한 입력 디바이스를
지원해 준다.
• DirectPlay : 멀티플레이어랑 네트워크 게임을 지원 한다.
• DirectSound : 디지털 샘플의 재생과 캡쳐를 지원한다.
• 오디오와 비디오 재생은 오디오 미디어와 비디오 미디어 재생 및 제어를
지원한다.
Managed DirectX의 장점
기존의 DirectX는 COM으로 되어 있어 이것을 사용하기 위해 InterOP 레
이어를 사용했으나 Managed DirectX는 바로 사용하므로 성능이 향상 된다.
Managed 코드는 코드의 양을 감소 시켜 생산성을 향상 시킨다. 인터페이
스가 고성능으로 쉽게 사용하는 Microsoft .NET Framework에 공통된 타
입의 인터페이스를 사용하여 아주 직관적이다.
Managed 코드를 사용하면 오브젝트의 해방 등 메모리 관리에 관한 대부분
의 작업에서 해방된다.
4. Managed DirectX를 사용하기 위한 환경
Managed DirectX를 사용하기 위해서는 MS의 .NET Framework 1.1 SDK와
DirectX 9 SDK, Visual Studio.NET 2002(및 상위 버전)가 필요하다.
.NET Framework1.1 SDK와 DirectX 9 SDK는 MS 웹 사이트에서 다운로드 받을
수 있다.
( 참고로 개발 PC가 아닌 PC에서 .NET용 프로그램을 실행하기 위해서는 .NET
Framework 1.1과 DirectX 9만 설치 되어 있으면 실행 가능하다.)
참고로 DirectX 9 SDK는 Managed DirectX 부분이 2004 Summer Update에서 약
간 변경된 사항이 있으므로 꼭 최신의 SDK를 설치 하기를 바란다.
Managed DirectX는 .NET용 언어인 C#, Visual Basic .NET 및 Managed C++ 언
어로 프로그래밍 하므로 위의 3 언어 중 하나를 선택해서 프로그래밍 해야 된다.
사실 위의 3개의 언어는 공통의 라이브러리를 사용하므로 언어 문법적인 부분이 다
를 뿐이지 사용하는 라이브러리는 같기 때문에 크게 차이는 나지 않는다고 볼 수
있다.
새롭게 프로그래밍 언어를 배우기 힘든 사람 중 기존에 Visual basic을 사용해본
사람은 Visual Basic .NET을 사용하고 C++을 사용할 줄 아는 사람은 Managed
C++를 사용하기를 추천하나 가능하면 MS에서 요즘 가장 밀고 있으며 .NET의 대
표 언어인 C#으로 사용하기를 바란다. 추천하는 이유는 최신의 언어라서 상당히 잘
만들어져 있으며 MS에서 .NET 샘플 프로그램을 주로 이 언어로 사용해서 만들기
때문에 MS의 강의나 샘플 프로그램을 볼 때 많은 도움이 되기 때문이다.
5. Managed DircetDraw 소개
Managed DirectDraw(이하 줄여서 MDD라고 하겠다)는 기존의 DirectX의 DirectDraw와
같다고 보면 된다. 이름을 봐도 비슷하지 하니 굿이 따로 설명하지 않아도 쉽게 알 수 있었
을 것이라고 생각한다.
MDD는 디스플레이 메모리, 하드웨어 블리트, 하드웨어 오버레이 지원, 플립, 서페이스 지
원을 직접 조작 할 수 있다. DirectDraw가 지원하는 기능을 모두 지원하면 각 인터페이스
의 구조와 이름도 흡사하다. 그래서 기존의 DirectDraw를 아는 사람은 아주 쉽게 적응 할
수가 있다.
요즘의 게임은 거의 3D로 제작하는 분위기라서 사실 2D를 한다는 것은 시대에 뒤떨어진다
는 느낌을 받을 수가 있는데 필자는 짧은 게임 개발 경험이 있지만 아무리 3D가 대세라고
하지만 2D로 만들 수 있는 게임이 있고(특히 온라인 웹 용 보드 게임은 굿이 3D를 사용할
의미가 없다라고 볼 수도 있다), 2D가 3D 보다는 게임 제작 방법이 훨씬 쉽고 다양한 기법
이 많이 공개되어 있었어 아직 .NET에 익숙하지 않던가 3D 개념이 약한 게임 프로그래머
들은 먼저 MDD를 습득하고 Direct3D로 넘어 가는 것이 아주 좋은 순서이지 않을까 생각
된다.
다음은 MDD의 구조에 대한 이해를 위해 기존의 DirectX 7.0의 DirectDraw와 각 중요
인터페이스를 서로 비교하면 다음과 같다.
참고로 아래의 MDD의 클래스는 모두 Microsoft.DirectX.DirectDraw 네임스페이스 안에
있다.
Managed DirectDraw DirectDraw 7.0
Cliper IDirectDrawClipper
ColorControl IDirectDrawColorControl
Device IDirectDraw7
DeviceCollection DirectDrawEnumerateEx 함수
DisplayModeCollection IDirectDraw7::EnumDisplayModes 함수
Palette IDirectDrawPalette
Surface IDirectDrawSurface7
SurfaceCaps IDirectDrawSurface7
SurfaceDescription IDirectDrawSurface7::SetSurfaceDesc 함수
이 이외에 Microsoft.DirectX.DirectDraw 네임스페이스 안에는 아주 많은 예외처리 인터
페이스가 있으며 프로그래밍 시 이것을 이용하면 안전하고 편리하게 예외에 대응 할 수가
있다( 참고로 .NET의 예외는 C++의 예외와 달리 오버헤드가 거의 없다).
그리고 MDD는 기존의 DirectDraw 7.0을 단순히 컨버전 한 것이 아니라 7.0에 없는 기능
이 추가되어 있어 상당히 편리하게 사용 할 수 있다( DX 7.0에는 없는 선 긋기 등이 있다).
MDD를 공부 할 때 기존의 DirectDraw와 비교하는 것은 필수 이다. 왜냐하면 MS가
DirectX 8.0부터 기존의 2D를 더 이상 지원하지 않는데, Managed DirectX에서도 3D는
아주 자세히 설명 하고 있지만 2D인 DirectDraw에 대해서는 거의 한 줄 정도의 설명 밖에
없었어 처음 DirectDraw를 접하는 사람은 거의 알 수가 없기 때문에 DirectDraw 7.0과
인터페이스 이름을 서로 비교하면서 DirectX 7.0 SDK의 DirectDraw 부분을 같이 봐야
이해를 할 수 있을 것이다(참고로 SummerUpdate 2004에서는 예제도 없어져 버렸다 -_-).
MDD가 기존의 DirectDraw와 거의 흡사하기 때문에 설명은 이것으로 간단하게 하고 이제
부터 프로그래밍 예를 들면서 설명하겠다 – 필자의 어설픈 설명보다는 실제 예를 보는 것이
이해에 더욱 도움이 될 것이라 생각된다.
그리고 예제를 설명하면서 코드에 나오는 C# 프로그래밍 부분은 간단하게만 설명하겠다.
6. Managed DirectDraw 프로그래밍
1) 윈도우 모드(창 모드) 애플리케이션
using System; using System.Drawing; using System.ComponentModel; using System.Windows.Forms; using Microsoft.DirectX; using Microsoft.DirectX.DirectDraw; namespace DXTest1 { public class Windowed : System.Windows.Forms.Form { private System.ComponentModel.Container components = null; // DirectDraw 관련 객체를 초기화 한다. private Device draw = null; private Surface primary = null; private Surface offscreen = null; private Clipper clip = null; private Rectangle destination = new Rectangle(); //! 이 프로그램의 생성자 public Windowed() { // 생성 할 윈도우를 초기화 한다. InitializeComponent(); // 디바이스를 만든 후 창모드로 지정 후 Surface를 만든다.