지식
 

지식 : 팁사용기   새글 5점 / 간단한 글 5점 / 답글 5점

 
  total 글수 2362
Xcode 2.2 에서 카본 프로그램 만들자 (3)
hongjuny
조회수 : 3,178
댓글 2
2005-12-19 07:52:43

이번에는 본격적으로 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 이므로 반투명이 되지요.

프로그램을 직접 수행해 보면서 여러 가지로 프로그램을 조금씩 바꿔 나가면서 어떻게 변경되는지 확인해 보는것도 좋은 공부가 될 것입니다.
애플 제품 구매 애플 교육할인 구매
짧은 주소  http://bit.ly/hHfUJj  

댓글댓글 : 2   
준범이*
2005-12-21 00:09:32
완료~ ^^
악동시니
2005-12-21 00:39:45
잘되는군요..




케이머그 이용 규정안내

신규사용자 이용안내

레벨제도 소개

Xcode 2.2 에서 카본 프로그램 만들자 (3) [지식 : 팁사용기] KMUG  
번호 제목 글쓴이 조회수 날짜
182
 데스크탑 화면 바꾸어 보기    베리 3263 2005/12/29
9:20 am
.
181
 환경설정-화면해상도 조절하기    베리 3014 2005/12/28
9:34 am
.
180
 환경설정에서 에너지절약 사용하기    베리 1981 2005/12/26
4:23 pm
.
179
 개인에 필요에 맞도록 시스템 환경설정하기    베리 2859 2005/12/24
8:54 pm
.
178
 dock에 자주 사용하는 프로그램 추가하기 덧글2    베리 2458 2005/12/24
8:53 pm
.
177
 dock 사용자 하기    베리 2232 2005/12/24
8:52 pm
..
176
 동영상 강좌 - 파인더 아이콘 바꾸어 보기    베리 2724 2005/12/22
1:47 pm
.
175
 동영상이 안보이시는 분...^^    베리 2513 2005/12/21
9:47 am
맥 사파리에서는 문제가 없는데요. 원도우 피씨에서 익스플로어에서 화면이 안보이네요. F5를 눌러서 새로고침을 여러번 하시기 바랍니다. 3-4번 하면 보여요... 원인은 분석중인데...꼭 찾아내겠습니다. ^^ 베리.
174
 동영상 강좌 - 파인더 원도우 사용자화 하기    베리 2633 2005/12/21
12:02 am
.
173
 동영상 강좌 - 휴지통 사용하기    베리 2490 2005/12/21
12:00 am
.
172
 동영상 강좌 - 빠른 파일 찾기    베리 2559 2005/12/20
11:59 pm
.
171
 동영상 강좌 - 홈폴더 사용하기    베리 2163 2005/12/20
11:57 pm
.
170
 동영상 강좌 - Mac os Dock 사용하기 덧글1    베리 3217 2005/12/20
11:55 pm
.
169
 동영상 강좌 - 파인더 사용하기 덧글2    베리 2356 2005/12/20
11:54 pm
.
168
 동영상 강좌 - 주소록 사용해보기    베리 2540 2005/12/20
11:03 am
.
167
   응용문제 덧글1 이미지    hongjuny 2021 2005/12/20
1:19 am
예전에 대입 학력고사에 본고사가 있던 시절, 서울대 본고사 문제에 나왔다는 전설의 그 문제! 사이클로이드라는 것이 있습니다. 이 예제는 사이클로이드와 똑같지는 않지만 대략 비슷한 원리입니다. 자전거 바퀴살에 불을 하나 달고 밤...
 Xcode 2.2 에서 카본 프로그램 만들자 (3) 덧글2 이미지    hongjuny 3178 2005/12/19
7:52 am
이번에는 본격적으로 Quartz 의 Core Graphics 를 이용해서 그림을 그려 보겠습니다. 참고 자료로는 애플 홈페이지에서 다운로드 받으실 수 있는 Quartz 2D Programming Guide 입니다. 프로그램의 기본 구조는 이...
165
 Xcode 2.2 에서 카본 프로그램 만들자 (2) 덧글9    hongjuny 1903 2005/12/17
11:35 am
윈도우 프로그래밍을 처음 공부한ㄴ 사람들이 한결같이 내놓는 불만은 "왜 이렇게 어렵냐?" 라는 것입니다. 막말로, C 에서는 printf("Hello Worldn") ; 요거 하나만 하면 글을 볼 수 있는데, 윈도우에서는 글...
164
 Xcode 2.2 에서 카본 프로그램 만들자 (1) 덧글13    hongjuny 2268 2005/12/16
12:32 pm
Xcode 새 버젼의 카본 어플리케이션 템플릿이 좀 더 친절해졌더군요. 한편, 지금까지 자기 고유의 이벤트 핸들러를 갖고 계시던 분들에게는 더 힘들어 졌더군요. ㅠㅠ 자 해 봅시다. 일단. Xcode 를 실행하고, File->N...
163
사용기  [Apple] Mac mini 리뷰 덧글9 이미지    김영권 11275 2005/12/15
11:25 am
2005년 1월 11일. 애플은 세계를 깜짝 놀라게 할 만한 새로운 매킨토시 시스템인 Mac mini를 발표하였다. Mac mini 가 발표된후 지금까지 경험할 수 없었던 슬림한 사이즈로인해 많은 화제를 불러일으켰다. 슬림한 사...



KMUG서비스안내    비욘드테크소개    광고/제휴    연락처/오시는길    공지사항    회원레벨가이드    사이트맵
Copyright ⓒ kmug.co.kr 2000~2019. All rights reserved 개인정보취급방침
지식 : 팁사용기