• 북마크
  • 추가메뉴
어디로 앱에서 쉽고 간편하게!
애플 중고 거래 전문 플랫폼
오늘 하루 보지 않기
KMUG 케이머그

소프트웨어

[App 개발] Xcode 2.2 에서 카본 프로그램 만들자 (3)

본문

이번에는 본격적으로 Quartz 의 Core Graphics 를 이용해서 그림을 그려 보겠습니다.

참고 자료로는 애플 홈페이지에서 다운로드 받으실 수 있는 Quartz 2D Programming Guide 입니다.

프로그램의 기본 구조는 이전 소스와 거의 비슷합니다만, MyDraw() 함수의 전달 인수에 하나가 더 추가되었습니다.

OSStatus MyDraw( EventRef event, WindowRef window )

event 인수를 전달받는 이유는 이것으로 Core Graphics 컨텍스트를 얻어내기 위한 것입니다. 컨텍스트 (context) 란, 화면에 원하는 그림을 그리기 위하여 그래픽 시스템으로부터 얻어와야 하는 일종의 권한 같은 것입니다. 화면에 내 마음대로 그림을 그렸다가는 남의 윈도우에다가 마구 그림을 그려댈 수도 있기 때문에, 여러 개의 윈도우가 동시에 한 디스플레이를 공유하기 위해서 서로 질서를 잡아주는 역할을 하는 것입니다. 퀵드로우에서는 SetPort 를 사용했지만, 이제 Quartz 에서는 CGContext 를 사용하는 것이 약간 다른 점이겠습니다.

거두 절미하고 소스부터 먼저 보시지요.

--- MyDraw.h ---

#include <Carbon/Carbon.h>

void InstallMyDraw( WindowRef window ) ;
OSStatus MyDrawEventHandler( EventHandlerCallRef myHandler,
                                                         EventRef event,
                                                         void *userData ) ;

OSStatus MyDraw( EventRef event, WindowRef window ) ;


--- MyDraw.c ---

#include "MyDraw.h"

#include "MyDraw.h"

HIViewRef myHIView ;

void InstallMyDraw( WindowRef window )
{
        
        HIViewID myHIViewID = { 'mVue', 130 } ;
        EventTypeSpec        myHIViewSpec[] = {
        { kEventClassControl, kEventControlDraw },
        } ;
        OSStatus err ;
        
        HIViewFindByID( HIViewGetRoot( window ), myHIViewID, &myHIView ) ;
        
        err = InstallEventHandler( GetControlEventTarget( myHIView ),
                                                           NewEventHandlerUPP( MyDrawEventHandler ),
                                                           GetEventTypeCount( myHIViewSpec ),
                                                           myHIViewSpec,
                                                           (void *)myHIView,
                                                           NULL ) ;
        
}



OSStatus MyDrawEventHandler( EventHandlerCallRef myHandler,
                                                         EventRef event,
                                                         void *userData )
{
        
        OSStatus err = eventNotHandledErr ;
        
        switch( GetEventClass( event ) ) {
                case kEventClassControl :
                {
                        switch( GetEventKind( event ) )
                        {
                                case kEventControlDraw:
                                        err = MyDraw( event, (WindowRef)userData ) ;
                                        break ;
                        }
                        break ;
                }
                        
                default:
                        break ;
        }
        
        return err ;
        
}


OSStatus MyDraw( EventRef event, WindowRef window )
{
        
        OSStatus status = noErr ;
        CGContextRef myContext ;
        HIRect bounds ;
        int i, count = 0 ;
        
        CGMutablePathRef thePath ;
        
        status = GetEventParameter( event,
                                                                kEventParamCGContextRef,
                                                                typeCGContextRef,
                                                                NULL,
                                                                sizeof( CGContextRef ),
                                                                NULL,
                                                                &myContext ) ;
        require_noerr( status, CantGetGraphicsContext ) ;
        HIViewGetBounds( (HIViewRef) window, &bounds ) ;
        require_noerr( status, CantGetBoundingRectangle ) ;
        
        /////

        thePath = CGPathCreateMutable() ;
        
        CGContextBeginPath( myContext ) ;
        CGPathMoveToPoint( thePath, NULL, 0, 0 ) ;
        CGPathAddQuadCurveToPoint( thePath, NULL, 50, 100, 0, 200 ) ;
        CGPathAddQuadCurveToPoint( thePath, NULL, -50, 100, 0, 0 ) ;
        CGPathCloseSubpath( thePath ) ;

        CGContextTranslateCTM( myContext, bounds.size.width / 2, bounds.size.height / 2 ) ;
        for( i = 0 ; i < 360 ; i += 10 ) {
                if( count++ % 2 == 0 ) {
                        CGContextSetRGBFillColor( myContext, 0, 1, 0, 0.5 ) ;
                } else {
                        CGContextSetRGBFillColor( myContext, 0, 0, 1, 0.5 ) ;
                }
                CGContextRotateCTM( myContext, 10.0 * M_PI / 180.0 ) ;
                CGContextAddPath( myContext, thePath ) ;
                CGContextDrawPath( myContext, kCGPathFillStroke ) ;
        }
        
CantGetGraphicsContext:
CantGetBoundingRectangle:
                
        return status ;

}


많이 달라진 부분은 MyDraw() 함수입니다. 처음 부분은 CGContext 를 얻어내는 과정입니다. 그림을 그리기 위해서는 매번 반복되어야 하는 루틴이므로 미리 잘 저장해 두었다가 복사해서 붙여넣으면 되겠습니다.

        thePath = CGPathCreateMutable() ;
        
        CGContextBeginPath( myContext ) ;
        CGPathMoveToPoint( thePath, NULL, 0, 0 ) ;
        CGPathAddQuadCurveToPoint( thePath, NULL, 50, 100, 0, 200 ) ;
        CGPathAddQuadCurveToPoint( thePath, NULL, -50, 100, 0, 0 ) ;
        CGPathCloseSubpath( thePath ) ;


myContext 에 그대로 그림을 그릴 수도 있으나, 프로그램을 좀 더 재미있게 하기 위해서 여기서는 path 라는 것을 만들어 보겠습니다. path 는 그림을 그리는 경로, 혹은 과정이라고 할 수 있겠습니다. 어떤 도구를 이용해서 어떤 순서로 그림을 그릴 것인지를 순서대로 기록하는 것을 path 라고 보면 좋겠습니다. 이런 개념으로는 아도베 일러스트레이터를 많이 써보신 분들이 훨씬 더 센스있게 프로그램을 만드실 수 있을 것 같습니다.

thePath 에는 잎사귀 하나의 모양만을 갖고 있습니다. 잎사귀의 곡선은 베지어 툴을 이용하여 그렸습니다. Quartz 에서 곡선을 그리는 베지어 툴은 컨트롤 포인트를 한 개, 혹은 두 개를 쓸 수 있습니다. 매뉴얼을 살펴보시거나, 일러스트레이터 잘 하시는 분을 붙잡고 물어보세요. ㅎㅎㅎ

잎사귀 모양을 다 그리고 나면 thePath 를 저장하고, 이제는 이것을 화면에 출력하는 작업이 필요하겠지요.

        CGContextTranslateCTM( myContext, bounds.size.width / 2, bounds.size.height / 2 ) ;
        for( i = 0 ; i < 360 ; i += 10 ) {
                if( count++ % 2 == 0 ) {
                        CGContextSetRGBFillColor( myContext, 0, 1, 0, 0.5 ) ;
                } else {
                        CGContextSetRGBFillColor( myContext, 0, 0, 1, 0.5 ) ;
                }
                CGContextRotateCTM( myContext, 10.0 * M_PI / 180.0 ) ;
                CGContextAddPath( myContext, thePath ) ;
                CGContextDrawPath( myContext, kCGPathFillStroke ) ;
        }

CGContextTranslateCTM() 함수는 그림그리기 도구의 시작 위치가 어디인지를 지정합니다. 여기서는 매번 마찬가지로 화면의 정 중앙을 잡았습니다. 이제 그림 그리는 축을 10도씩 기울여 나가면서 잎사귀를 하나씩 그려 나갑니다. count 값이 홀수일 때에는 파란색, 짝수일 때에는 녹색으로 path 내부를 칠합니다. 알파값을 0.5 로 하여 둘이 서로 겹치는 부분에서 색상이 혼합되는 느낌을 주게 하였습니다. 0.5 이므로 반투명이 되지요.

프로그램을 직접 수행해 보면서 여러 가지로 프로그램을 조금씩 바꿔 나가면서 어떻게 변경되는지 확인해 보는것도 좋은 공부가 될 것입니다.
0 0
로그인 후 추천 또는 비추천하실 수 있습니다.
포인트 228,692
가입일 :
2003-02-18 14:12:30
서명 :
미입력
자기소개 :
미입력

최신글이 없습니다.

최신글이 없습니다.

댓글목록 2

향기님의 댓글

완료~ ^^

악동시니님의 댓글

댓글쓰기

적용하기
전체 529 건 - 4 페이지
2006.12
22

[App 개발] [질문] XCODE에서 외부 라이브러리 가져다 쓸 때..

안녕하세요. 두 가지 질문을 하려고 합니다. 최근에 OpenGL 프로그래밍을 하고 있습니다. 쉐이더를 쓰려면 필요하다는 GLEW  라이브러리를 AGL 로 빌드된 것을 다운 받아 헤더는 /usr/lo…

2006.10
09

[App 개발] 2.4로 업데이트 했는데도 여전히 깨지네요ㅠㅠ(사진첨부)

인코딩만 UTF-8로 하고 딴건 안했습니다. 프로젝트는 java->javatool로 했고요 이유를 모르겠네요 일단 업데이트형식으로 설치했는데 그래서 그럴까요

2006.10
09

[App 개발] Xcode 한글 깨짐 문제 (마스터님 봐주세요)

위와 같은 코딩을 하는데... 한글의 경우 깨져서 나오는데 프로젝트는 javatool로 했습니다. 환경과 파일인코딩 모두 UTF-8로 했습니다. 그래도 깨지던데... 어떻게 해결해야 하나요.. *ps: 스윙이나 웹 말고 일반적인 …

2006.08
27

[App 개발] OpenGL 질문....

1. 임플리먼테이션이 머죠 2. 소프트웨어와 하드웨어의 차이 3. 파이프라인이 무엇이죠 4. 파이프라인의 구조 부탁드립니다

2006.08
22

[App 개발] 마유라 는 한글이 잘 되는군요. ^^

InputStreamReader 의 속성을 SJIS 에서 EUC-KR 로 바꾸는 방법으로 미와 고스트는 안되는데 마유라 고스트는 잘 되는군요. 인텔 맥에서도 문제없이 돌아가고 있습니다. 영환님도 이미 컴파일 해보셨겠지만, 안되었으면 한 번 …

2006.01
03

[App 개발] Xcode 2.2 에서 C++ 프로그래밍 하기

아직 초보라서 잘 모르는데 어떻게 하는지 알려주세요... Project를 어떤 것을 선택해야하는지...

2005.12
19

열람중 [App 개발] Xcode 2.2 에서 카본 프로그램 만들자 (3)

이번에는 본격적으로 Quartz 의 Core Graphics 를 이용해서 그림을 그려 보겠습니다. 참고 자료로는 애플 홈페이지에서 다운로드 받으실 수 있는 Quartz 2D Programming Guide 입니다. 프로그램의 기본 구조는 이…

2005.12
17

[App 개발] Xcode 2.2 에서 카본 프로그램 만들자 (2)

윈도우 프로그래밍을 처음 공부한ㄴ 사람들이 한결같이 내놓는 불만은 "왜 이렇게 어렵냐" 라는 것입니다. 막말로, C 에서는 printf("Hello World\\n") ; 요거 하나만 하면 글을 볼 수 있는데, 윈도우에서는 글자 하나를 보…

2005.12
16

[App 개발] Xcode 2.2 에서 카본 프로그램 만들자 (1)

Xcode 새 버젼의 카본 어플리케이션 템플릿이 좀 더 친절해졌더군요. 한편, 지금까지 자기 고유의 이벤트 핸들러를 갖고 계시던 분들에게는 더 힘들어 졌더군요. ㅠㅠ 자 해 봅시다. 일단. Xcode 를 실행하고, File->N…

2005.08
15

[App 개발] XCode 2.1로 Maya plug-in 개발하기..?

Maya 6.0에서 제공하는 Maya API를 이용하여 plug-in을 개발하려고 help문서를 뒤져보니.. xcode는 예제의 프로젝트 파일을 컴파일해보라고 나와있는데.. xcode의 버전때문인지 컴파일이 되질 않는군요..-.- MSVC로 프로…