반응형

http://www.ogre3d.org/tikiwiki/Ogre+Android&structure=Development#Porting_Ogre_to_Android

Android and C++

Android officially supports native applications built using C or C++. Unfortunately the C++ for Android is currently too sparse for Ogre to be ported using the official development kit(called the NDK(external link)). The most serious feature missing the exception support. Since Ogre makes heavy use of exception, this missing feature would make it very difficult to create a stable port for Android.

Luckily Android is a very open OS. We don't actually need to use the official NDK to develop native applications that work on Android devices. An awesome community member namedCrystax(external link) has created versions of the NDK matched to official NDK releases which fully support C++. By using this custom build system we can create working native applications for Android without having to modify the underlying Android OS.

허허 NDK 가 너무 열악하게 안드로이드를 지원한다는 글을 보고 오우거에서 안드로이드는 개발하기 힘든것인가 라는 생각을 하면서 웹을 뒤져보다가 이 포럼을 봤는데 허허 안드로이드측의 답변일세 ㅋ

대략 해석해놓자면..

핵심 내용은 다행히 안드로이드는 오픈OS 이다. 오우거제작팀(?)은 사실상 안드로이드디바이스에서 돌아가는 native 응용프로그램을 개발하기 위한 공식적인 NDK 사용을 필요로하지 않는다.

Crystax 이라 불리는 멋진 공통구성원이 C++을 완전히 지원하는 공식적인 NDK 에 매칭되는 버전을 만들었다.

이 custom build system 으로 오우거제작팀(?)은 기초가되는 안드로이드 OS를 수정없이 native application 을 만들었다.


아래 주소는 돌아다니다가 우연히 오우거를 안드로이드에 올려놓은 경험담을 적어놓은 곳

http://blog.zcube.kr/

반응형
반응형

어딘가에서 오우거 조사한 pdf 파일

3DMath 2011-05-03 21:53:44 주소복사
조회 23 스크랩 0

그냥 발표용인듯.. 

반응형
반응형

반응형
반응형

Crazy Eddie’s GUI System is a free library providing windowing and widgets for graphics APIs / engines where such functionality is not natively available, or severely lacking. The library is object orientated, written in C++, and targeted at games developers who should be spending their time creating great games, not building GUI sub-systems!




http://www.cegui.org.uk/wiki/index.php/Main_Page


동적인 상자들을 연결해 놓아 유연하게 연결 표시 해주는 라이브러리 인듯..



Main Page

From CEGUI Wiki - Crazy Eddie's Gui System for Games (Open Source)

Jump to: navigation, search

Welcome to Crazy Eddie's GUI System

Crazy Eddie's GUI System is a free library providing windowing and widgets for graphics APIs / engines where such functionality is not natively available, or severely lacking. The library is object orientated, written in C++, and targeted at games developers who should be spending their time creating great games, not building GUI sub-systems!

  • Take a look at our binary demos (precompiled for win32 only)
  • Do you like CEGUI? Help us become even better and read our wiki wishlist!

To edit this wiki or to contribute to this site, you must be a registered on our forums
When signing up you are required to fill in an authorisation code, the code is presently: iwillnotspam

Featured Videos from our YouTube Channel

Downloading and Installing

Working with CEGUI

  • Documentation: Information about getting documentation to match with your download
  • Tutorials: All tutorials to help you getting started with CEGUI
  • How-To series: How to deal with a specific feature of CEGUI
  • Manuals: Some more advanced material on using CEGUI

CEGUI for Content Creators

Community Projects

The last 5 additions to the wiki

The last 5 changes to the wiki

Personal tools
Namespaces
Variants
Actions

반응형
반응형
MyGUI is a library for creating Graphical User Interfaces (GUIs) for games and 3D applications. The main goals of mygui are: speed, flexibility and ease of use.

[License: open source]




http://mygui.info/






MyGUI v3.2.0 Released!

February 24th, 2012

Main changes in 3.2.0:

  • Improved font display:
    • Decreased texture memory usage (typically by 50% or more).
    • Added support for Windows FON/FNT bitmap fonts and for embedded SBIT bitmaps in TrueType fonts.
    • Added support for overlapping glyphs.
    • Simple text shadows added (optional).
    • Full FontViewer support to load and create new fonts.
  • Added a new SkinEditor tool.
  • Improved the LayoutEditor and FontEditor tools.
  • Made lots of other improvements and fixes.

More detailed changelog.

MyGUI v3.0.1 Released!

February 13th, 2010

This release contain few fixed bugs, changed license and improved CMake scripts. No API changes was made and this release is highly recommended for those who previously downloaded MyGUI 3.0.0. Changelog.

We also decided to add small exclusion in LGPL for static linking (details).

MyGUI 3.0.0 Released!

January 10th, 2010

Main changes:

  • rendering separated from core, we also implemented pure DirectX and OpenGL renderers in addition to OGRE render.
  • heavily reworked resources system.

For a detailed list see changelog.

MyGUI 2.2.3 Released!

October 4th, 2009

This is bugfix release aimed for those who use 2.2.2 and not using MyGUI from trunk. Strongly recommended for update.

You can download source package here: MyGUI 2.2.3.

SubWidgets

  • subwidget EditText was reimplemented
  • word wrap support in edit mode
  • cursor and text selecting with ManualFont

Widget

  • fixed problem with inherited Disabled and Visible conditions

We have made lots of changes in upcoming MyGUI 3.0 and we working on it very active, but still not ready to release it, so we decided to update current release.

IRC channel

June 7th, 2009

IRC channel was created!
Server: irc.quakenet.org
Channel: #mygui
Welcome!

MyGUI 2.2.2 released!

March 27th, 2009

After long time of active development we finally stopped adding lots of new features, improved everything else and made new stable release, MyGUI 2.2.2. It has lots of changes and improvements since the previous 2.2.0_RC1 version.

You can download source package here: MyGUI 2.2.2.

Here’s list of major changes: Read the rest of this entry »

MyGUI for C#

March 25th, 2009

We have implemented generator wrappers for the library. Generator parsed data from doxygen, and with the help of templates, performs the generation of wrappers. At the moment there are templates for C# and Managed C++. It is also possible to setup generator for other languages if the need arises.

1. C# – MyGUI.Export.dll (exported functions) + MyGUI.Sharp.dll (wrapper using P/Invoke)
2. Managed C++ – MyGUI.Managed.dll (wrapper using CLR)

At this time, a wrapper does not support Mogre due to specifics of the latter, but we are working in this direction, and version that supports Mogre will be presented .
Generator, wrappers and a demo is now available in MyGUI svn: http://my-gui.svn.sourceforge.net/svnroot/my-gui

Blog started!

March 17th, 2009

What’s actually pretty. Here we’ll place announces and some docs about MyGUI architecture.

Now site works a little bit slow, but I think we’ll solve this problem. Fix CSS/JavaScript bugs. Fix content :) .



2007 – Current year 

반응형
반응형

http://begin.pe.kr/category/Ogre3D%20%EC%82%BD%EC%A7%88%EB%9E%80/Basic%20Tutorial%201

'Ogre3D 삽질란/Basic Tutorial 1'에 해당되는 글 3건

  1. 2008/11/08 기초 튜토리얼 1-1
  2. 2008/11/08 기초 튜토리얼 1-2
  3. 2008/11/08 기초 튜토리얼 1-3 (마지막) (5)

기초 튜토리얼 1-1

Ogre3D 삽질란/Basic Tutorial 1 2008/11/08 16:58

기초 튜토리얼 1 (번역 : n_Sys)

입문자 튜토리얼 1: SceneNode, Entity, SceneManager 구성

튜토리얼을 진행하다가 문제점이 생기면 Help 포럼(http://www.ogre3d.org/phpBB2/viewforum.php?f=2) 문의하세요.

목차

* 1 미리 알아야 것들

* 2 소개

* 3 시작하기

* 3.1 최초 코드

* 3.2 문제점 해결하기

* 3.2.1 Message Box 문제

* 3.2.2 환결성정 파일이나 DLL 파일이 없는 문제

* 3.2.3 리소스나 플러그인 문제점들

* 3.2.4 비주얼 스튜디오에서 프로그램이 동작하지 않는문제

* 4 오우거 엔진 동작과정

* 4.1 장면관리자(SceneManager) 기초

* 4.2 엔티티(Entity) 기초

* 4.3 장면노드(SceneNode) 기초

* 5 오우거 응용프로그램 실행하기

* 6 좌표와 벡터

* 7 추가적인 객체 삽입하기

* 8 엔티티에 대해서..

* 9 장면노드에 대해서..

* 10 해볼만 것들

* 10.1 확대(Scale)

* 10.2 회전(Rotations)

* 11 오우거 실행환경

* 11.1 DLLs and Plugins

* 11.2 환경설정 파일

* 11.3 어플리케이션 테스트를 위한 나은 환경 구성하기

* 12 맺음말

미리 알아야 것들

튜토리얼은 C++ 프로그래밍을 할줄 알고 오우거 어플리케이션을 셋업하고 실행할 안다는 가정하에 진행됩니다. (만약 오우거 어플리케이션 설정에 문제점이 있으면 컴파일러별 프로그램 설정 가이드를 참고하세요. - 역자주 : 프로그램 설정 가이드는 번역을 생략합니다) 튜토리얼은 설정가이드에서 설정이외의 사전 지식은 필요 없습니다..

소개

이번 튜토리얼에서는 오우거엔진에서 가장 기초적인 구성물을 소개합니다. (장면관리자-SceneManager, 장면노드-SceneNode, 엔티티-Entity 객체) 앞으로 코드의 많은부분을 다루지는 않을것이지만 독자가 오우거 엔진을 시작하는데 필요한 일반적인 컨셉들에 촛점을 맞출 입니다.

튜토리얼을 진행하면서 독자는 진행단계에 맞추어서 천천히 코드를 스스로 입력하고 결과물을 지켜 필요성이 있습니다. 오우거엔진의 개념을 따라잡는대에는 이것만한 방법이 없습니다! 대충 눈으로 훑고 넘어가지 마세요.

시작하기

최초 코드

튜토리얼에서는 미리 작성된 기본코드를 사용할 것입니다. 나중에 내용을 채우게 createScene 함수를 제외하고는 모두 무시하셔도 됩니다. 나중에 오우거 어플리케이션이 어떻게 동작되는지를 자세하게 살펴볼 예정이지만 지금은 이제 시작한 단계에 불과합니다. 독자가 사용하는 컴파일러에서 프로젝트를 생성하고 아래 코드를 포함한 소스파일을 추가하세요.

#include "ExampleApplication.h"

class TutorialApplication : public ExampleApplication

{

protected:

public:

TutorialApplication()

{

}

~TutorialApplication()

{

}

protected:

void createScene(void)

{

}

};

#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32

#define WIN32_LEAN_AND_MEAN

#include "windows.h"

INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT )

#else

int main(int argc, char **argv)

#endif

{

// Create application object

TutorialApplication app;

try {

app.go();

} catch( Exception& e ) {

#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32

MessageBox( NULL, e.what(), "An exception has occurred!", MB_OK | MB_ICONERROR | MB_TASKMODAL);

#else

fprintf(stderr, "An exception has occurred: %s\n",

e.what());

#endif

}

return 0;

}


만약 오우거SDK Windows 에서 사용한다면 "[OgreSDK_DIRECTORY]\samples\include" 디렉토리(ExampleApplication.h 파일이 있는곳) include 가능하도록 프로젝트에 추가해 주세요. 만약 오우거엔진 소스를 직접 사용하신다면 [OgreSource_DIRECTORY]\Samples\Common\include" 추가해 주세요. 비록 코드가 까만 화면에 프레임수를 보여주는 썰렁한 화면만 보여주는 프로그램이지만 일단은 컴파일 실행이 되도록 해두세요. 다음 과정에서 화면에 뭔가를 추가할 입니다.

프로그램이 동작되면 WASD 키로 움직이고 마우스로 주변을 둘러보는 기능을 합니다. ESC 키는 종료키 입니다.

문제점 해결하기

만약 진행하는데 문제점이 발생하면 'Setting Up An Application'(http://www.ogre3d.org/wiki/index.php/SettingUpAnApplication) 에서 컴파일러 속성을 체크해 보거나 Ogre.log 파일에서 자세한 에러정보를 참조하세요. 만약 도움이 필요하다면 포럼을 검색 (http://www.ogre3d.org/phpBB2/search.php) 주세요. 아마 다른 많은 사람들도 똑같은 문제점을 겪었을 겁니다. 만약 새로운 이슈라면 포럼규칙 (http://www.ogre3d.org/phpBB2/viewtopic.php?t=11886) 읽어보시고 질문(http://www.ogre3d.org/phpBB2/viewforum.php?f=2) 하세요. Ogre.log 파일에서 에러와 관련된 항목이나 예외사항, 에러메세지, 컴파일러 디버거에서 제공하는 정보들을 제공하시는 것이 다른 유저들로부터 답변을 받는데 도움이 것입니다.

나중에 있을 튜토리얼에서는 문제점 해결방법을 포함하지 않을 입니다. 그러니 문제점이 발생되면 여기 이어지는 섹션을 주의깊게 살펴보세요.

Message Box 문제

유니코드를 지원하는 비주얼스튜디오를 사용한다면 다음 에러가 생길 있습니다 :

error C2664: 'MessageBoxW' : cannot convert parameter 2 from 'const char *' to 'LPCWSTR'

Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast

문제는 MessageBox 함수가 유니코드(Unicode) 받아야 시점에 안시(ANSI) 코드를 받아서 일어난 에러입니다. 이걸 고치기 위해서는 다음라인을 고쳐 주세요 :

MessageBox( NULL, e.what(), "An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL);

라인을 다음 라인처럼 수정합니다:

MessageBoxA( NULL, e.what(), "An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL);

또는 컴파일러에서 유니코드지원 기능을 끄는 방법도 있습니다. 그러나 그렇게 하면 유니코드지원 기능 자체를 사용하지 못하게 됩니다.

에러가 발생하는 이유는 "MessageBox" 함수가 자동적으로 MessageBoxA (ANSI) 또는 MessageBoxW (Wide/Unicode) 프로젝트 설정에 기준하여 선택하기 때문입니다. 코드에서는 ANSI버젼을 강제적으로 사용하게끔 하게 하여 에러를 고칩니다.

환결성정 파일이나 DLL 파일이 없는 문제

새롭게 작성한 프로그램을 빌드하려는데 DLL 파일이 없다거나 환경설정파일(*.cfg) 없다고 빌드가 안된다면 아마 OgreSDK 폴더로부터 복사하지 않았기 때문일 겁니다. 비주얼스튜디오 에서 릴리즈 모드로 빌드할때 릴리즈 실행파일은 [ProjectFolder]\bin\release 생성하고 디버그 실행파일은 [ProjectFolder]\bin\debug 폴더에 생성됩니다. OgreSDK 폴더의 "*.dll" 파일과 "*.cfg" 파일을 해당 폴더로 복사해 주어야 합니다. 다시 말하면 [OgreSDK]\bin\release 폴더로부터 [ProjectFolder]\bin\release 폴더로 복사하고 [OgreSDK]\bin\debug 로부터 [ProjectFolder]\bin\debug 복사해야 한다는 입니다. 그리고 resources.cfg 파일이 옳바른 경로를 가르키도록 수정해줄 필요도 있습니다. 다음 섹션에서 부분에 대해서 자세하게 다룰 입니다.

리소스나 플러그인 문제점들

Plugin.cfg 파일과 Resources.cfg 파일을 실행파일과 같은 폴더에 두세요. Plugin.cfg 파일은 오우거엔진에게 어떤 렌더링 라이브러리가 사용 가능한지(Direct3D9, OpenGL, 기타등등..) 알려줍니다. Resources.cfg 파일은 ExampleApplication 클래스나 텍스쳐, 메쉬, 그리고 스크립트가 어디에 위치하고 있는지에 대한 상세한 경로를 기술합니다. 둘다 텍스트 파일기때문에 어렵지 않게 내부에서 가르키는 경로를 옳바른 경로로 수정할 있습니다. 경로가 잘못된다면 오우거엔진 설정 대화상자로 아무런 렌더링 라이브러리를 선택할 없게 되거나 화면상으로 에러메세지를 출력하거나 Ogre.log 파일에 다음과 비슷한 에러메세지를 보게 겁니다.:

Description: ../../Media/packs/OgreCore.zip - error whilst opening archive: Unable to read zip file

경우에는 Resources.cfg 파일을 열고 폴더 위치를 오우거엔진에 포함된 미디어 폴더가 위치한 포인트로 경로를 바꿔주세요. 알아 두셔야 할것은 $(변수) 같은 환경경로변수 파일 내부에서 사용할 없습니다.

비주얼 스튜디오에서 프로그램이 실행되지 않는문제

만약 비주얼스튜디오 또는 비주얼 C++ 에서 어플리케이션을 생성하고 실행하는데 환경설정문제가 있다면 다수의 경우 디버거 설정문제 입니다. 만약 플레이버튼(메뉴에서 Start Debugging 누르는것과 동일) 누르고 환경설정 파일(*.cfg) 찾을 없다는 예외처리 메세지를 보게 된다면 작업 디렉토리 (Working Directory) 제대로 설정되지 않았다는 입니다.

이러한 문제점을 해결하기위한 정확한 해결방법은 비주얼 C++ 버젼에 따라서 다양하기때문에 제가 정확한 해결방법을 제시할 없지만 기본적인 해결 방법은 동일합니다. 프로젝트의 Solution explorer 에서 (Solution 자체가 아닙니다) 오른쪽 클릭을 하고 properties 메뉴로 갑니다. 어딘가에 디버깅 옵션을 위한 속성이 있을겁니다. 디버깅 옵션에는 "Working Directory" 입력창이 있을겁니다. 입력창에 해당 프로젝트의 실행파일이 생성 되는 위치로 바꿔주세요.

만약 여기다가 입력해야 할지 모르겠으면 "Command" 입력란에 입력된 내용을 똑같이 "Debugging" 넣어주세요. 예를 들면 비주얼C++ 2003에서는 "Command" 입력란은 "..\..\bin\$(ConfigurationName)\$(TargetFileName)" 비슷해야 합니다. "Working Directory" 내용에서는 파일명(TargetFileName) 제거해야 합니다. 이런 경우에는 작업디렉토리는 "..\..\bin\$(ConfigurationName)" 되어야 합니다. 정확한 입력은 비주얼C++ 버젼에 따라 다르고 빌드환경에 따라서도 달라집니다. 그렇기 때문에 작업을 하기전에 Command 입력란을 체크해 두세요. 작업디렉토리의 릴리즈모드와 디버그 모드 둘다 바꾸는것도 잊지 마세요.

비주얼C++ 2005에서는 전체적으로 많이 다를겁니다. "..\..\bin\$(ConfigurationName)" 먼저 해보시는걸 권장하고, 여전히 문제가 지속된다면 Help 포럼에서 상담을 받아보세요.

이렇게 하는 이유는 오우거엔진은 실행파일과 동일한 디렉토리에 특정한 중요한 필수 파일들을 필요로 하기때문에 Working Directory 필수적으로 있어야 하는 파일들이 포함된 디렉토리가 되어야 합니다..


Trackback 1 : Comment 0

기초 튜토리얼 1-2

Ogre3D 삽질란/Basic Tutorial 1 2008/11/08 12:06

오우거 엔진 동작과정

광범위한 주제군요. 앞으로 여러타입의 SceneManager Entity, SceneNode 들과 함께 작업할 입니다. 3가지 클래스들은 오우거 어플리케이션을 구성하는 중요한 구성원들 입니다..

SceneManager 기초

화면상에 표시되는 모든것은 SceneManager 의해 관리됩니다(상상해 보세요). 어떠한 객체들을 화면에 표시하면 SceneManager 객체들의 위치와 움직임을 관리하는 클래스 입니다. 장면을 보기위해 카메라를 생성하면 SceneManager 카메라(추후 튜토리얼에서 다루게 됩니다) 위치를 관리합니다. 평면, 빌보드, , 기타등등.. SceneManager 사용자가 생성한 모든것을 관리합니다.

SceneManager 여러가지 타입이 있습니다. 지형을 그리는 SceneManager, BSP 맵을 그리는 SceneManager, 그리고 많은것들이 있습니다. 다양한 타입의 SceneManager 여기서(http://www.ogre3d.org/wiki/index.php/SceneManagersFAQ) 확인할 있습니다. 튜토리얼을 진행하면서 점점 다양한 SceneManager 들을 다루게 것입니다.

Entity 기초

Entity 장면에 그릴 있는 객체타입중 하나입니다. 3D 메쉬로 표현할 있는 모든것은 Entity 라고 생각하셔도 됩니다. 로봇도 Entity 될수 있고 물고기, 걸어다닐 있는 넓은 땅떵어리도 넓은 형태의 Entity 있습니다. 그러나 , 빌보드, 파티클, 카메라 몇가지 들은Entity 없습니다.

알아두셔야 것은 장면에 그려질 있는 객체들은 그들의 위치와 방향 정보와는 별개로 분리되어 있다는 입니다. 무슨 의미냐면 하나의 Entity 한번의 과정만으로는 그릴 없다는 입니다. 대신에 Entity SceneNode 객체에 (attach)붙여야 하며 SceneNode 붙여진 Entity 위치와 방향에 대한 정보를 가지게 됩니다.

SceneNode 기초

앞서 얘기한대로, SceneNode attach 모든 객체들에 대한 방향과 위치정보를 가지고 있습니다. Entity 생성했을때 SceneNode attach 하기 전에는 실제적으로 그려지지 않습니다. 추가로 말씀드리자면 SceneNode 자체는 화면에 출력되는 객체가 아닙니다. SceneNode 생성하고 Entity attach 해야만 화면상에 뭔가가 그려지게 됩니다.

SceneNode attach 되는 객체의 수에 제한을 받지 않습니다. 예를 들자면 화면을 돌아다니는 캐릭터가 하나 있고 스스로 빛을 내는 후광효과를 내고 싶다고 합시다. 이것을 구현하기위해서 먼저 SceneNode 생성하고 캐릭터 Entity 생성한 해당 SceneNode attach 합니다. 다음 객체를 생성한 아까 생성했던 SceneNode attach 합니다. SceneNode 다른 SceneNode attach 가능하며 이것은 node 들의 계층적 구도를 구현할 있도록 줍니다. 나중에 있을 튜토리얼에서 나은 SceneNode attachment 사용법에 대해서 다룰 예정입니다.

SceneNode 가장 중요한 컨셉중 하나는 SceneNode 위치는 항상 부모 SceneNode 상대적 이라는 각각의 SceneManager 들은 최초의 root node를 가지는데 그 root node 다른 모든 SceneNode 들이 attach 된다는 입니다.

오우거 응용프로그램 실행하기

, 이제 앞서 작성해 코드로 돌아갑시다. TutorialApplication::createScene 멤버함수를 찾으세요. 튜토리얼에서는 함수의 내용만 수정할 입니다. 우리가 먼저 해야 일은 우리가 하고 있는지를 확인할 있도록 주변광 (ambient light) 설정하는 입니다. 우리는setAmbientLight 호출하고 적용할 컬러를 설정할 입니다. 참고로 ColourValue 생성자는 red, green, blue 3가지 색상값을 받는데 각각은 0 1사이의 실수 범위를 가집니다. 라인을 createScene 추가하세요 :

mSceneMgr->setAmbientLight( ColourValue( 1, 1, 1 ) );

다음으로 해야할 일은 Entity 생성하는 입니다. SceneManager createEntity 멤버함수호출에서 처리합니다 :

Entity *ent1 = mSceneMgr->createEntity( "Robot", "robot.mesh" );

여기서 잠깐 가지 질문들이 예상되는군요. 가장먼저 mSceneMgr 어디서 온것이며 관련함수 호출시 어떤 매개변수를 줘야 하는걸까요? 여기서 mSceneMgr 변수는 현재의 SceneManager 객체(ExampleApplication 클래스에서 이미 생성되어 있습니다) 가르킵니다. createEntity 첫번째 매개변수는 만들고자 하는 Entity 이름을 의미합니다. 모든 Entity 들은 고유한 이름을 가져야 합니다. 만약 2개의 Entity 들이 같은 이름을 가진 다면 에러를 발생시킬 입니다. "robot.mesh" 매개변수는 Entity 사용될 메쉬를 의미합니다. 전체적으로 다시말해, ExampleApplication 클래스가 앞으로 사용되어질 메쉬를 미리 메모리에 로드시켜놓은 입니다.

지금 우리는 Entity 생성했고 이제는 SceneNode attach 해야 합니다. 모든 SceneManager 루트 SceneNode 가지고 있고

우리는 루트 SceneNode 로부터 자식 node 생성해 나갈 입니다.

SceneNode *node1 = mSceneMgr->getRootSceneNode()->createChildSceneNode( "RobotNode" );

명령은 먼저 현재 사용되는 SceneManager 통해서 getRootSceneNode 부릅니다. 다음 결과값 포인터(루트 SceneNode입니다) 로부터 createChildSceneNode 호출하게 됩니다. createChildSceneNode 매개변수는 만들어질 SceneNode 이름입니다. Entity 클래스처럼 2 SceneNode들이 같은 이름을 가질 수는 없습니다.

드디어, 로봇이 그려질 위치를 전달하기위해 Entity SceneNode attach 차례입니다 :

node1->attachObject( ent1 );

그리고 끝입니다! 컴파일하고 어플리케이션을 실행하세요. 화면에 있는 로봇 하나를 발견하실것 입니다.

참고 : Robot.mesh OgreCore.zip 파일에 포함되어 있지 않습니다. 튜토리얼을 따르면서 지금 시점에서 어플리케이션이 실행은 되지만 아무것도 표시되지 않을 있습니다. 어플리케이션이 정상적으로 실행되기 위해서 resources.cfg 파일에서 디렉토리를 옳바르게 수정해야 합니다 :

FileSystem=../../media/materials/programs

FileSystem=../../media/materials/scripts

FileSystem=../../media/materials/textures

FileSystem=../../media/models

좌표와 벡터

진행하기 전에, 스크린 좌표계와 오우거 벡터 객체에 대해서 알아야 합니다. 오우거(다른 그래픽 엔진들과 마찬가지로) x, z 축으로 수평면을 표현하고, y 축은 수직축으로 사용됩니다. 지금 모니터를 바라보는 시점에서 x 축은 왼쪽에서 오른쪽 방향이며 오른쪽 방향이 x 양의 방향입니다. y 축은 모니터 바닥에서 윗쪽 방향이며 모니터의 상위쪽이 y 향의 방향입니다. z 축은 모니터 내부에서 바깥쪽 방향이며 스크린 바깥쪽 방향이 z 양의 방향입니다.

로봇이 x 양의 방향을 바라보고 있을까요? 이건 메쉬자체의 속성이자, 메쉬가 어떻게 디자인 되었는가에 따라 다릅니다. 오우거는 사용되는 모델의 방향에 대해서는 상관하지 않습니다. 로드되어지는 각각의 메쉬는 "기본 시작방향" 제각각 다를 있습니다.

2차원(Vector2), 3차원(Vector3), 4차원(Vector4) 이렇게 다양한 차원을 위해서 벡터 클래스가 정의되어 있으며 이중 Vector3 가장 자주 쓰입니다. 만약 벡터개념에 익숙치 않다면 오우거를 이용해 본격적으로 뭔가를 하기전에 복습 하시기를 권합니다.

(http://en.wikipedia.org/wiki/Vector_%28spatial%29)

수학적인 벡터 지식은 복잡한 프로그램을 다룰때 무척 유용하게 쓰입니다.

추가적인 객체 삽입하기

이제 좌표계가 어떻게 적용되는지 이해했으니 살펴보던 코드로 돌아갑시다. 작성했던 3줄의 코드에서 로봇이 나타날 위치를 설정한 부분은 없습니다. 대부분의 오우거 함수들은 디폴트 매개변수값을 가지고 있습니다. 예를 들면 SceneNode::createChildSceneNode 멤버함수는 3개의 매개변수를 가지는데 SceneNode 이름, SceneNode 위치, 마지막으로 SceneNode 바라볼 최초 회전값을 가집니다. 위치값은 보시는것 처럼 (0, 0, 0) 적용되었습니다. 이번에는 원점에서 떨어진 위치에다가 추가적인 SceneNode 만들어 봅시다 :

Entity *ent2 = mSceneMgr->createEntity( "Robot2", "robot.mesh" );

SceneNode *node2 = mSceneMgr->getRootSceneNode()->createChildSceneNode( "RobotNode2", Vector3( 50, 0, 0 ) );

node2->attachObject( ent2 );

예전과 비교해 별반 다를바 없어 보입니다. 2가지 부분을 제외하곤 이전에 했던것과 완전 똑같은 코드를 입력했습니다. 가장 먼저 Entity SceneNode 이름을 조금 다르게 설정했습니다. 두번째는 시작위치를 root SceneNode 부터 x축에서 50 단위 거리만큼 떨어지게 설정했습니다(기억해야 것은 모든 SceneNode 위치는 그들의 부모와 상대적인 위치를 가집니다). 컴파일하고 데모를 실행시켜 보십시오. 2개의 로봇이 나란히 있습니다.

Entity 대해서..

Entity 클래스는 매우 광범위 하며, Entity 객체의 모든 사용법을 여기서 설명하지는 않을 이지만.. 시작하기에는 충분할 입니다. 지금 바로 쓰기에 유용한 몇몇 Entity 멤버함수들을 여기서 집고 넘어가고 싶습니다.

첫번째는 Entity::setVisible Entity::isVisible 입니다. 간단하게 함수를 호출하는것만으로 어떠한 Entity 라도 보여지거나 숨겨질 있습니다.만약 Entity 숨기고 나중에 표시해야 한다면 Entity 파괴하고 다시 생성하는것 대신에 함수를 호출하세요.참고로 Entity 들을 위해서 "Pool" 준비할 필요는 없습니다. 메모리에 읽혀질 때마다 모든 객체의 메쉬와 텍스쳐는 한번만 실제적으로 메모리에 적재되기 때문에 메모리공간을 절약하기위해 노력하실 필요가 없습니다. 오직 상대적으로 부담이 적은 Entity 생성과 파괴에 대한 비용부담만 생각하시면 됩니다.

getName 함수는 Entity 이름을 반환하며, getParentSceneNode 함수는 해당 Entity attach 되어 있는 SceneNode 반환합니다.

SceneNodes 대해서..

SceneNode 클래스는 매우 복잡합니다. SceneNode 있는 많은것들이 있는데 가장 유용한 몇가지의 기능들을 살펴볼 것입니다. getPosition setPosition 이용해 SceneNode 위치를 설정하거나 얻어낼 있습니다. SceneNode 연관된 객체의 위치를 translate 명령을 통해서 이동이 가능합니다. SceneNode 객체의 위치를 설정하는것 뿐만 아니라 크기와 회전역시 담당합니다. Scale 함수를 이용해서 객체의 크기를 설정할 있습니다. pitch, yaw, 그리고 roll 함수로 객체를 회전시킬 있습니다. resetOrientation 통해서 수행된 모든 회전을 리셋시킬 수도 있습니다. setOrientation, getOrientation 그리고 rotate 함수들을 이용해서 세부적인 회전을 수행할 수도 있습니다. Quaternions(사원수) 대해서는 많은 튜토리얼을 다루기 전에는 언급하지 않을 예정입니다.

독자는 이미 attachObject 적이 있을것입니다. 만약 SceneNode attach 객체에 변화를 주고 싶다면 여기에 소개되는 연관된 함수들이 매우 유용하게 쓰일 것입니다 : numAttachedObjects, getAttachedObject (여러가지 상황별 함수들이 있음), detachObject (이것 역시 다양한 상황별 함수가 있음), detachAllObjects. 부모 SceneNode 자식 SceneNode 다루는 함수들은 서로 동일하게 쌍으로 존재합니다.

모든 위치이동이 부모 SceneNode 의해 연관되어 수행되는 이상 2개의 SceneNode 들을 함께 이동시키는건 매우 쉽습니다. 현재 어플리케이션 소스에는 다음코드가 존재합니다 :

Entity *ent1 = mSceneMgr->createEntity( "Robot", "robot.mesh" );

SceneNode *node1 = mSceneMgr->getRootSceneNode()->createChildSceneNode( "RobotNode" );

node1->attachObject( ent1 );

Entity *ent2 = mSceneMgr->createEntity( "Robot2", "robot.mesh" );

SceneNode *node2 = mSceneMgr->getRootSceneNode()->createChildSceneNode( "RobotNode2", Vector3( 50, 0, 0 ) );

node2->attachObject( ent2 );

만약 5번째 줄을 상태에서 :

SceneNode *node2 = mSceneMgr->getRootSceneNode()->createChildSceneNode( "RobotNode2", Vector3( 50, 0, 0 ) );

이렇게 고치게 된다면? :

SceneNode *node2 = node1->createChildSceneNode( "RobotNode2", Vector3( 50, 0, 0 ) );

RobotNode 자식노드 RobotNode2 만들게 됩니다. node1 움직이는것은 node2 같이 움직이게 되지만 node2 이동은 node1 영향을 주지 않습니다. 예를 들어 코드는 RobotNode2 이동시킵니다.

node2->translate( Vector3( 10, 0, 10 ) );

다음의 코드는 RobotNode 움직이고 RobotNode2 RobotNode 자식인 이상 RobotNode2 동일하게 같이 움직이게 됩니다 :

node1->translate( Vector3( 25, 0, 0 ) );

이런 수행을 하는데 계산하는데 어려움이 있다면 가장 좋은 방법은 최상위 루트 SceneNode 시작하여 아래방향으로 진행하는 입니다. 예를 들면(본문에서 예처럼), node1 로부터 시작하여 (0, 0, 0) (25, 0, 0) 으로 이동시킴으로 node1 위치는 (25, 0, 0) 만큼 부모의 위치로부터 상대적인 공간에 위치하게 됩니다. node2 (50, 0, 0) 에서 시작하여 (10, 0, 10) 으로 이동시 켰으므로 새로운 위치는 (60, 0, 10) 만큼 부모의 위치로부터 상대적인 공간에 위치하게 됩니다.

, 이것들이 실제로 어디에 위치하는지 알아봅시다. 루트 SceneNode 에서 시작합니다. 이것의 위치는 항상 (0, 0, 0) 입니다. 지금 node1 위치는 (root + node1) : (25, 0, 0) = (25, 0, 0) 되겠죠. 별거 아니군요.

, 그럼 현재 node2 node1 자식이므로 이것의 위치는 (root + node1 + node2): (0, 0, 0) + (25, 0, 0) + (60, 0, 10) = (85, 0, 10) 됩니다.

이건 SceneNode 계층적인 위치 구조를 설명하기위한 예시에 불과합니다. 아마 아주 가끔씩 노드들의 절대위치를 계산해야 경우가 생길겁니다.

마지막으로 알아두실 SceneNode Entity 이름은 getSceneNode getEntity 함수 호출로 얻을 있기 때문에 만드는 SceneNode 마다 포인터들을 따로 보관해 필요가 없습니다. 특별히 자주 쓰는것만 쓰기 쉽도록 관리해 주시면 됩니다.

Trackback 0 : Comment 0

기초 튜토리얼 1-3 (마지막)

Ogre3D 삽질란/Basic Tutorial 1 2008/11/08 12:04

해볼만 것들

이제 여러분은 Entity, SceneNode 그리고 SceneManager 기본기를 익혔습니다. 위에서 언급한 소스로부터 로봇을 추가하고 제거하는것을 해보길 권합니다. 해보셨으면 createScene 내용을 모두 지우고 다음의 소스코드들을 동작시켜 보시기 바랍니다 :

Scale

SceneNode scale 함수를 이용해서 메쉬의 크기를 조절할 있습니다. 스케일 수치를 바꿔보고 어떻게 바뀌는지 확인해 보세요 :

Entity *ent1 = mSceneMgr->createEntity( "Robot", "robot.mesh" );

SceneNode *node1 = mSceneMgr->getRootSceneNode()->createChildSceneNode( "RobotNode" );

node1->attachObject( ent1 );

node1->scale( .5, 1, 2 );

Entity *ent2 = mSceneMgr->createEntity( "Robot2", "robot.mesh" );

SceneNode *node2 = mSceneMgr->getRootSceneNode()->createChildSceneNode( "RobotNode2", Vector3( 50, 0, 0 ) );

node2->attachObject( ent2 );

node2->scale( 1, 2, 1 );

Rotations

yaw, pitch, roll 함수에 Degree 또는 Radian 수치를 적용해서 객체를 회전시킬 있습니다. Pitch x 축을 주위로 회전합니다. yaw y 그리고 roll z축을 중심으로 회전합니다.

오른손으로 방향을 있습니다 : 엄지손가락을 축으로 다음 다른 손가락이 가르키는 방향이 양의 각도입니다. 예를 들면 pitch(Degree(90)) 라면 엄지손가락은 오른쪽을 가르키고 다른 손가락은 회전방향을 의미합니다. 차근차근 생각해 보세요.

사용자 삽입 이미지

각도(Degree) 수치 조절과 위치변화를 다양하게 조합해 보세요 :

Entity *ent1 = mSceneMgr->createEntity( "Robot", "robot.mesh" );

SceneNode *node1 = mSceneMgr->getRootSceneNode()->createChildSceneNode( "RobotNode", Vector3( -100, 0, 0 ) );

node1->attachObject( ent1 );

node1->yaw( Degree( -90 ) );

Entity *ent2 = mSceneMgr->createEntity( "Robot2", "robot.mesh" );

SceneNode *node2 = mSceneMgr->getRootSceneNode()->createChildSceneNode( "RobotNode2");

node2->attachObject( ent2 );

node2->pitch( Degree( -90 ) );

Entity *ent3 = mSceneMgr->createEntity( "Robot3", "robot.mesh" );

SceneNode *node3 = mSceneMgr->getRootSceneNode()->createChildSceneNode( "RobotNode3", Vector3( 100, 0, 0 ) );

node3->attachObject( ent3 );

node3->roll( Degree( -90 ) );


Ogre
실행환경

OgreSDK "bin" 폴더 아래의 debug 또는 release 폴더에서 있는 많은 파일들 (*.dll, *.cfg) 섹션에서 참조할 있습니다. 디버그버젼으로 생성된 프로그램은 OgreSDK debug 폴더내의 파일들을 이용하고 릴리즈버젼의 프로그램은 release 폴더의 파일들을 사용하게 됩니다.

섹션의 대부분은 윈도우즈 환경하에서 다뤄집니다. 리눅스에서도 기본적인 사항들은 동일하게 적용되지만 몇몇 사항들은 약간 다를 있습니다. 만약 리눅스에서 오우거엔진 사용시 문제가 발생하면 오우거 help포럼에 글을 남겨주세요.

DLLs and Plugins

우리는 방금 오우거 환경에서 흥미로운 체험을 해봤습니다. 이제 평상시에 오우거 라이브러리를 사용할때 어떤 편리한 점이 있는지 설명하고자 합니다.

오우거는 크게 3개의 중요그룹으로 나눠지는데, 메인 라이브러리, 플러그인 그리고 써드파티 라이브러리로 나뉘어 집니다.

Main library.

첫번째 그룹은 오우거 라이브러리 자체와 밀접하게 연관되는 공유 라이브러리들을 포함합니다. OgreMain.dll 오우거본체 라이브러리가 포함됩니다. dll 파일은 cg.dll 같은 몇몇 다른 라이브러리를 필요로 합니다. DLL 들은 반드시 항상 오우거 어플리케이션과 함께 포함되어야 합니다.

Plugins.

두번째 공유 라이브러리는 플러그인 입니다. 오우거는 효율적인 기능성분할을 위해 공유라이브러리로 기능을 나누었으며 라이브러리들은 유저의 어플리케이션이 필요로 하는 정도에 따라서 기능을 제공할 도있고 그렇지 않을 있습니다. 오우거와 함께 사용되는 기본적 플러그인들은 "Plugin_" 이라는 prefix 시작되는 파일명을 가집니다. 유저가 필요로하는 플러그인은 유저 스스로 새로운 플러그인을 작성할 있지만, 어떤 튜토리얼에서도 다루지는 않을 계획입니다. 오우거는 렌더링 시스템을 위해서도 플러그인을 사용합니다(OpenGL, DirectX, 기타등등). 이러한 플러그인들은 "RenderSystem_" 이라는 prefix 가집니다. 플러그인들을 추가하거나 삭제하는것 으로도 유저의 어플리케이션의 렌더링 시스템을 설정할 있습니다. 다음과 같은 상황에서는 매우 유용한데 만약 유저가 (예를들면) OpenGL에만 해당되는 쉐이더 프로그래밍이나 특별한 작업을 하는경우 또는 DirectX 에서 동작되는 프로그램에서 OpenGL 기능을 강제로 끄고 싶을때 유저는 단순히 해당되는 렌더링시스템 플러그인을 제거하는 만으로도 기능은 제공되지 않도록 있십니다. 추가적으로 만약 유저가 비표준 플랫폼을 염두한다면 튜토리얼에서는 다루지는 않지만 유저만의 렌더링시스템 플러그인을 작성할 수도 있습니다. 플러그인을 어떻게 제거하는지는 다음 섹션에서 다룰 입니다.


써드파티 라이브러리와 helper 라이브러리.

세번째 공유라이브러리는 써드파티 라이브러리와 helper 라이브러리입니다. 오우거 자체로는 그냥 그래픽 렌더링 라이브러리일 입니다. GUI 시스템이라던지 입력컨트롤, 물리엔진, 기타등등.. 이러한 기능들은 가지고 있지 않습니다. 다른 라이브러리들을 사용하기위해서 다음과 같은 절차를 거쳐야 합니다. 오우거 데모들과 SDK 소수의 써드파티 helper 라이브러리들을 포함하고 있습니다. CEGUI 라이브러리는 오우거와 통합된 GUI 시스템이며 "OgreGUIRenderer.dll" "CEGUI*" 부터 시작되는 파일들은 GUI 시스템의 일부 입니다. CEGUI 사용하는 방법은 나중에 있을 튜토리얼에서 다루어질 입니다. 키보드와 마우스입력은 OIS(입력 시스템) 통해서 최종 처리됩니다. OIS OIS.dll 포함합니다. 이것들 말고도 다른 기능(물리엔진이나 사운드)들을 제공하는 라이브러리들 역시 존재하며(SDK 포함되지 않은것들) 이와 관련된 많은 정보는 위키와 같은 다른 포럼에서 찾을 있습니다.

가장 실용적이고 진정한 문제는 바로 눈앞에서 스스로 테스트 해보는 어플리케이션에서 나오며 모든 기능을 상태(아무것도 제거하지 않은상태) 하에서 테스트해 있습니다. 유저의 어플리케이션 배포가 준비되었을때 릴리즈모드에서 빌드를 해야 것이고 어플리케이션이 필요로 하는 모든 릴리즈용 DLL 파일은 포함되어야 해야 하며, 쓰지않는 DLL 파일은 제거되어야 입니다. 만약 프로그램이 CEGUI 쓰지 않지만 OIS 쓸때, CEGUI 관련 DLL 파일들을 포함하는데 고민할 필요는 없지만 OIS DLL 파일은 반드시 포함되어야 합니다. 그렇지 않으면 어플리케이션은 실행되지 않을 입니다.

환경설정 파일

오우거는 몇몇 환경설정파일을 사용합니다. 파일들은 어떠한 플러그인이 로드되어야 할지, 어플리케이션의 리소스들은 어디에 위치되었는지, 기타등등을 제어합니다. 이제 각각의 환경설정 파일들이 어떠한 일을 하는지 간단하게 살펴볼 것입니다. 만약 세부적인 궁금증이 있다면 바로 오우거 help 포럼으로 보내주세요.

plugins.cfg 파일은 유저의 어플리케이션이 사용하는 플러그인들을 포함합니다. 만약 유저 어플리케이션에서 플러그인을 추가하거나 제거하고 싶다면 파일을 수정하면 됩니다. 플러그인을 제거하기 위해서는 간단히 해당 라인을 제거하거나 라인 가장 앞에 # 붙이는 것으로 주석처리를 하면 됩니다. 플러그인을 추가하고 싶다면 "Plugin=[PluginName]" 같이 라인을 추가하면 됩니다. 참고로 플러그인 이름 끝에 ".DLL" 붙이지 마세요. 플러그인은 "RenderSystem_" 또는 "Plugin_" 으로 시작되어서도 안됩니다. 오우거가 플러그인들을 찾는 위치를 수정하기위해 "PluginFolder" 변수를 수정할 수도 있습니다. 상대경로, 절대경로 모두 사용가능하지만 $(변수) 형태의 환경변수는 사용할 없습니다.

resources.cfg 파일은 오우거가 리소스를 찾기위해 검색해야할 디렉토리 리스트를 담고 있습니다. 리소스는 스크립트, 메쉬, 텍스쳐, 기타 여러가지를 포함하고 있습니다. 절대경로, 상대경로 모두 사용 가능하지만 $(변수) 같은 환경변수는 사용할 없습니다. 참고로 오우거는 하위폴더를 검색하지 않기때문에 만약 여러단계의 폴더를 입력할 필요가 있다면 일일이 작성해 주어야 합니다. 예를 들면 "res\meshes" "res\meshes\small" 디렉토리 트리구조를 가진다면 위해 리소스 파일이 포함된 경로의 2가지 진입점을 리소스 파일에 추가해야 합니다.

media.cfg 파일은 리소스의 일부분에 대한 상세한 정보를 말해줍니다. 지금 시점에서는 수정할 필요가 없으므로 자세한 설명은 생략하겠습니다. 자세한 정보는 메뉴얼과 오우거 포럼에서 찾을 있습니다.

ogre.cfg 파일은 오우거 환경설정 화면에서 생성됩니다. 파일은 유저의 컴퓨터와 그래픽 설정 내용을 기술합니다. 다른 사람들이 각각 다른 설정을 가지는 처럼 유저가 어플리케이션을 배포할때는 파일이 같이 포함되어서는 안됩니다. 유의하실 점은 환경설정을 통하지 않고 파일을 직접적으로 수정하시면 안됩니다.

quake3settings.cfg 파일은 BSPSceneManager 함께 사용됩니다. BSPSceneManager(지금 시점에서는 쓰지 않습니다) 사용하기 전에는 필요하지 않은 파일이므로 무시하세요. 유저 어플리케이션에서 필요없다면 배포하지 마세요. 반면에, 만약 유저가 BSPSceneManager 이용한다면 프로그램의 필요성에 의해 포함될 있습니다.

모든 환경설정 파일들은 오우거에 직접적인 영향을 줍니다. 오우거는 "plugins.cfg", "resources.cfg", 그리고 "media.cfg" 파일들이 실행시 반드시 참조 가능해야합니다. 나중에 있을 튜토리얼에서는 파일들에 관한 내용과 세부적인 작업을 위해 어떻게 그들의 위치정보와 내용을 수정해야 할지를 다룰 입니다.

어플리케이션 테스트를 위한 나은 환경 구성하기

윈도우즈에서 비주얼C++ 사용하는 사람에게만 해당되는 내용입니다.

앞서 여러번 언급했던것 처럼(문제해결 섹션을 포함하여), 오우거는 유저의 프로그램에서 사용되는 각종 환경설정파일, DLL, 미디어 리소스 자원들에 대한 접근이 가능해야 합니다. 많은 사람들은 문제를 위해 OgreSDK bin 폴더로 부터 유저의 프로젝트 디렉토리로 필요한 DLL 파일들을 실행파일과 같은 위치로 복사하여 해결합니다. 방법이 아마 게임이든 다른종류의 프로그램이든 배포에 있어서 최고의 방법일 지도 모릅니다. 배포를 위해서 각종 플러그인을 넣고 빼고 하는 귀찮은 과정을 생략할 있기 때문이죠. 모든 DLL 파일들을 각각의 오우거 프로젝트 폴더로 복사해 넣는것은 공간적, 시간적 낭비임에도 불구하고 많은 상황에서 발생되고 있습니다. 여기 그런 낭비를 줄일 있는 방법이 몇가지 있습니다.

한가지 대안은 OgreSDK DLL 파일들을(플러그인 빼고) 윈도우즈 시스템 폴더로 복사하는 입니다. 이건 오우거를 이용한 실행파일이 어디에 있던간에 필요한 DLL 파일에 접근할 있는게 장점입니다. 작업을 수행하려면 resources.cfg, plugins.cfg 파일에서 media 폴더와 plugins 폴더의 절대경로를 알맞게 각각 수정해 줘야 합니다. 그럼 어디서 프로젝트를 생성하던지 수정된 환경설정 파일들만bin\debug bin\release 디렉토리로 부터 복사하기만 하면 됩니다. 그러나 저는 OgreSDK DLL 파일들의 위치관리가 안될것 같아서 개인적으로는 쓰지 않는 방식입니다. 오우거는 자주 새버젼이 발표되는데 방법으로 업데이트 하려면 귀찮아 집니다.

나은 대안으로는 OgreSDK 파일들은 그대로 놔두고 프로젝트의 작업디렉토리를 OgreSDK bin\release bin\Debug 디렉토리로 설정하는 입니다. 이렇게 하려면 프로젝트의 속성(디버깅 옵션에서)에서 "Working Directory" 입력창 내용을 "C:\OgreSDK\bin\$(ConfigurationName)" 바꿔 주세요. 기본값이 아닌 다른경로로 오우거를 설치했다면 "C:\OgreSDK" 부분을 실제로 설치한 경로로 바꿔줘야 합니다. 그렇게 하신다면 오우거 프로그램 동작을 위해서 아무런 파일도 복사하지 않아도 됩니다. 접근방법이 제가 개인적으로 사용하는 방법입니다. 가지 단점은 환경설정파일을 수정해야 경우, 모든 오우거 프로젝트를 수정해야 한다는것인데.. 안좋긴 합니다. 만약 접근방법을 이용하고 유저 프로젝트를 위해 환경설정파일을 수정해야 한다면 방법 대신에 하던대로 모든 파일을 프로젝트로 복사해 넣으시고 작업디렉토리를 원래 지정되어졌던 내용으로 바꿔주세요.

맺음말

이제 독자는 SceneManager, SceneNode 그리고 Entity 클래스에 대한 기초지식을 습득했습니다. 여기서 소개드린 모든 함수들에 대해서 억지로 익숙해질 필요는 없습니다. 소개드린것은 가장 기초적인 객체들이며 앞으로 자주 쓰이게 것입니다. 다음에 있을 몇몇 튜토리얼에서 여기서 소개드린 모든 것이 자연스럽게 친숙해 것입니다.

그리고 오우거 환경을 설정하는데에도 익숙해져야 합니다

반응형
반응형

http://cafe.naver.com/ogre3d.cafe?iframe_url=/ArticleRead.nhn%3Farticleid=3823&

아이폰에 오우거엔진 사용할때는

사용언어가 objective-c로 개발해야 하는건가요??

초보의 질문이었습니다 ㅎㅎ


  • 2011/03/30 16:42

    제가 드린 질문은 게임로직을 코딩할때..
    오우거를 사용하지 않으면...objective-c로 코딩해야하지만
    오우거를 사용할경우 c나 c++로 아이폰 개발을 할수 있는 환경이 되는건지 ..?
    이것이 궁금했습니다

  • 2011/03/30 16:51

    오브젝트씨가 c/c++ 을 같이 지원하기 때문에, 게임의 경우 대부분 기존 c/c++ 로 코딩하고 윈도 뛰우고 터치 이벤트 처리같은 ui 같은 부분은 코코아라고 하는 오브젝트씨 라이버리를 이용해야 하기때문에, 그 부분만 오브젝트씨로 작성해주면 됩니다. 그래서 오우거 엔진의 경우는 그냥 c/c++ 컴파일해서 ARM 네이티브 코드로 아이폰에 올라가게 됩니다.

  • 2011/03/30 16:52

    안드로이의 경우는 JNI 이용해서 c/c++ 컴파일된 네이티브 코드를 자바에서 호출하는 형태인데, 오브젝트씨가 자바로 바뀐거라고 보면 되겠습니다.

  • 2011/03/30 17:06

    harkon님 답변 감사합니다 ㅎㅎ

반응형
반응형

1.7 이상 버전은 이러한데 이 미만 버전 older versions 는 다르다

http://www.ogre3d.org/licensing 를 참고.

OGRE 1.7 and later

MIT License

Ogre is released under the MIT License, which is a permissive open source license. The only condition is that you distribute the license text included in our distribution with any software that uses OGRE.

Licensing FAQ

Older Versions

This section only applies if you’re using OGRE 1.6 or earlier.


http://www.ogre3d.org/licensing/licensing-faq


Licensing FAQ

  1. Q: Is OGRE really free?
    If you abide by the open source licensing conditions, yes.
  2. Q: Do I have to release my own source code if I use OGRE?
    A: No.
  3. Q: Do I have to release changes I make to OGRE?
    A: From Ogre 1.7 we use the MIT license, which does not require you to do this. However, you should consider the maintenance overhead of keeping your own custom version of OGRE, versus the advantages you might get from participating in the community (such as bugfixes and extensions that others may make on top of yours).
  4. Q: What do I need to do to abide by the MIT license?
    A: Simply include our license text somewhere in your own software distribution; this could be in a text file, in a printed manual, in the credits, etc.
  5. Q: Do I have to display an OGRE logo in my application, in splash screen or startup sequence for example?
    A: No, although we appreciate the publicity if you would like to do this!
  6. Q: At what point do I have to ensure that I’ve complied with the license?
    A: When you distribute any part of your application to a third party.


반응형
반응형

OGRE 설치 & Source 빌드 - window, vs2008 기준, OGRE 1.7.2 Source For Windows

송정헌 2011-02-27 04:21:49 주소복사
조회 1153 스크랩 0

Ogre 설치 가이드

http://www.ogre3d.org/tikiwiki/Prerequisites


1. Visual Studio 2008 (VC9) 버전을 사용할 경우 Microsoft Update 2008 sp1 를 설치 해야한다

다운 목록 :

ATL security fix available from Microsoft Update 2008 sp1

http://www.microsoft.com/downloads/en/details.aspx?familyid=2051a0c1-c9b5-4b0a-a8f5-770a549fd78c&displaylang=en


MinGW 에 대한 설명, 뭐 일단 무료라함

http://blog.naver.com/byuckdan?Redirect=Log&logNo=100123459348

반드시 GCC 4.4.X 를 기반으로 하고 있는 MinGW 를 설치 해야 하며

http://www.ogre3d.org/tikiwiki/Prerequisites 에 기록할 당시 쓰여진 버전은

GCC 4.4.1 을 기반으로 하고 있는 tdm-mingw-1.908.0-4.4.1-2 이다

설치할 적에 Check for updated files on the TDM/MinGW server 체크를 해제 해야

tdm-mingw-1.908.0-4.4.1-2 가 설치 가능하다, 구 버전을 사용하기 위함

tdm-mingw-1.908.0-4.4.1-2.exe

http://code.google.com/p/gcc-offline/downloads/detail?name=tdm-mingw-1.908.0-4.4.1-2.exe&can=2&q=


Direct3D 렌더시스템을 사용하기 위해 DirectX SDK - February 2010 를 설치 한다.

window 정품 유효성 검사를 거친 후 설치 가능함

오래 걸리니 다운 받아 놓으면서 다음을 진행하자, 그전에 SDK 를 다운 받고 DXSDK_DIR 를 등록하는 과정을

기억하고 있어야 함

DirectX SDK - February 2010

동일한 주소:

http://www.microsoft.com/downloads/en/details.aspx?displaylang=en&FamilyID=2c7da5fb-ffbb-4af6-8c66-651cbd28ca15###

dx 설치후 cmd 에서 다음을 등록해야 한다

C:\>set DXSDK_DIR
DXSDK_DIR=C:\Program Files\Microsoft DirectX SDK (February 2010)\

Boost 설치는 필수는 아니고 옵션 사항이다.

대략 Boost 를 설치할 경우 빽그라운드 를 로딩할 경우 좀 더 빠른 시간에 Boost threads 로 로딩할 수 있다 함

Ogre 에서 권하는 버전은 1.44.0 버전임

vs2003~vs2010 유저는 부스트 인스톨러로 설치 할 수 있다, 라고 하는데

오우거 홈페이지에서 링크해놓은 링크가 깨진것 같다

boost URL 이 바뀐듯..

그리하여 다음 주소에서 인스톨러를 받을 수 있다.

http://www.boost-consulting.com/download/

실제 받을 수 있는 URL -> http://www.boost-consulting.com/download/boost_1_44_setup.exe

Boost, 무료

http://sourceforge.net/projects/boost/files/boost/1.44.0/boost_1_44_0.zip/download

설치중 옵션에서 다음을 선택

Select your compiler and "Multithreaded" and "Multithreaded Debug".

http://sourceforge.net/projects/ogre/files/ogre-dependencies-vc%2B%2B/1.7/OgreDependencies_MSVC_20101231.zip/download

MinGW 유저는 아래 boost 설치 가이드를 통하여 빌드 한다.

http://www.boost.org/doc/libs/1_44_0/more/getting_started/windows.html


소스

Visual Studio Dependencies

MinGW 컴파일러

MinGW Dependencies


Dependencies
Visual Studio users need to compile the dependencies themselves: Visual Studio Dependencies
MinGW users can grab the precompiled MinGW Dependencies

Unpack the dependencies into either your Ogre source directory, your Ogre build directory or somewhere else.
The directory should be named Dependencies if put into either the source or the build directory.
If you choose to place it elsewhere, you can name it however you like, as long as you're setting an environment variable OGRE_DEPENDENCIES_DIR pointing to its location.

It's recommended to use the last option - OGRE_DEPENDENCIES_DIR - as it makes it easier to manage several different dependencies (vc9, vc10, mingw) on the same computer, against the same Ogre source directory.

Be sure to build the dependencies if using Visual Studio! Find the solution file in Dependencies/src. And don't forget to build in both configurations: debug and release.


오우거 설치 : http://www.ogre3d.org/download/source

Once you have downloaded, if you are new to using OGRE you can find information in the wiki about building OGRE from source, and a series of tutorials.

필요한 툴 파일들 설치

http://www.ogre3d.org/tikiwiki/tiki-index.php?page=Building+Ogre

http://www.ogre3d.org/tikiwiki/Prerequisites

Make sure that you've sorted out the Prerequisites before attempting to build Ogre with CMake!

  1. Make sure you have downloaded, extracted and built the dependencies package
  2. Download CMake. You want the 'Win32 installer' release in the binary distribution section
  3. Run the CMake installer, install wherever you like
  4. Launch CMake via Start > Program Files > CMake 2.8 > CMake
  5. In the "Where is the source code" box, type or browse to the root directory of your OGRE source (the one that contains the OgreMain folder)
  6. In the "Where to build the binaries" box, type or browse to any folder you like - this will be where the build output will go (libraries, headers, dlls & sample exes). The folder does not have to exist yet. Note that you can run this process more than once with different output folders if you want (but we won't complicate matters now)
  7. Hit the 'Configure' button near the bottom of the screen
  8. Pick your target compiler, e.g. "Visual Studio 8 2005"
  9. Answer 'Ok' when asked if you want to create the build directory
  10. Wait for the configure process to finish
  11. The screen will now have a bunch of configuration options on it, which will be red (this is to indicate this is the first time you've seen them). You can see the potential for customising your build here, but for now just click the 'Configure' button again
  12. The values will turn grey, and the 'Generate' button at the bottom will now be enabled. Click 'Generate'
  13. Build files will now be generated in the location you picked, and CMake will say "Generating done"

오우거 빌드파일 뽑아내기

출처 : http://lancekun.com/tc/149

1.7부터 빌드방식이 바뀌어서 몇분들이 도움을 요청하시길래 간단히 컴파일법을 작성하겠습니다.
프로젝트로인해 오랜만의 포스팅이네요 ㅎ

일단 http://www.ogre3d.org/download/source 에 접속하여서
OGRE 1.7.0 RC1 Source For Windows Microsoft Visual C++ Dependencies Package
이 두개를 받습니다.

압축을 풀고 내용물을 한폴더로 모으면 위와 같이 두개의 폴더가 보이는데요.
Dependencies 폴더를 ogre 폴더속으로 넣어줍시다.
(참고: CMake로 컴파일시 한글경로인식이 않되기때문에 경로설정을해줌 C:\ogre-v1-7-0RC1\ogre )

그뒤에 Dependencies 폴더속 Dependencies\src 에 가보면 OgreDependencies 라는 이름으로
각 솔루션 파일이있는데 각자의 VisualStudio에 맞는 솔루션파일을 실행시켜서 솔루션채로 빌드해줍시다.
(저같은경우 VC9을 사용하니 OgreDependencies.VS2008.sln 실행)

: 이때 VS2008.sln 의 Debug, Release 모드 빌드함

여기까지는 이전 오우거 버젼컴파일하는것과 동일하였습니다.
이전에는 여기까지한뒤에 기본적으로 들어있던 OgreMain.sln을 찾아서 컴파일을 해주었는데요
1.7부터는 CMake를 통해 빌드를해야하더라구요.

그러므로 CMake를 받으러 http://www.cmake.org/cmake/resources/software.html 에 접속해서
Windows ZIP으로 되어있는것을받읍시다.(CMake자주사용하시는분아니면 그때그때받아쓰면됨)

자.. 다운이 다되었으면 \bin\cmake-gui.exe 를 실행시킵시다.

이제 CMake로 컴파일 CMakeList가 있는 폴더와 Output을 받아드릴 폴더를 설정해줍니다.
%주의 오우거폴더의 경로에 한글이 있으면 컴파일에 실패합니다.
%주의 CMake의 경로에 한글이있으면 컴파일되지않습니다.

그뒤에 Configure 버튼을 눌러줍니다.

그러면 위와 같은 창이 뜨는데요 여기서 자신이 사용하는 VisualStudio나 각각의 개발환경을
선택해주고 Finish를 눌러줍니다.


정상적으로설정이 되어있는 상태라면 위와같은 화면이 나타날것입니다.

이상태에서 Configure 버튼을 한번더 눌러준뒤 Generate 버튼을 눌러주면 Output되는 폴더속에
OGRE.sln 라는 이름의 솔루션 파일이 생성된것을 확인할수있습니다.


이후는 이전의 버젼을 사용했던것과 같이 엔진라이브러리를 컴파일한후 쓰시고싶은대로 쓰시면
되는겁니다아

엔진 컴파일후 샘플브라우져를 실행한 화면

반응형
반응형


http://coreafive.tistory.com/46

NiAlphaAccumlator
Z버퍼 어플리케이션이 알파 블랜딩된 오브젝트들을 씬 그래프의 원하는 어디에든 놓으면서 렌더링을 정확하게 처리할 수 있도록 해주는 accumulator입니다.
알파블랜딩된 오브젝트들은 서로와 관련하여 정렬된 순서로 그려야 합니다.
알파 블랜딩된 오브젝트들을 마지막에 정렬된 순서대로 그리지 않으면 시각적인 인위적 현상이 생길 수 있다.
이 accumlator는 불투명한 오브젝트드를 정렬하는 불필요한 작업을 없애주면서 알파 블랜딩된 오브젝트들은 뒤에서 앞으로 정렬합니다.
accumlator는 알파 블랜딩 오브젝트들만 미뤄두고 알파블랜딩이 꺼진 오브젝트들은 RegisterObjectArray에 대한 호출 동안에 즉시 렌더링되게 놔둡니다.
각 오브젝트들의 경계 영역의 중심점이나 가장 앞쪽의 점을 바탕으로 간단한 z-sort를 통해 이들을 정렬함으로써 이를 달성합니다.
이런식으로 모든 불투명한 오브젝트가 씬 그래프에서 운행되는 순서대로 제일 먼저 그려진 뒤에, 그 다음 알파 블랜딩된 오브젝트들이 뒤에서 앞으로 정렬된 순서대로 그려집니다.

NiStream
게임브리오 익스포트를 통해 익스포트한 씬 그래프를 로드해야 할때나, 자체적인 어플리케이션으로 미리 저장해둔 씬 그래프를 로드하려고 할 때 사용되어집니다.
여기서 NIF파일을 로드하기 위해 NiApplication::ConvertMediaFilename함수를 사용하는 데, 이 함수는 SetMediaPath로 지정된 경로를 사용해서 완전한 경로를 생성합니다.

bool NIF_Files::CreateScene()
{
// 불투명 오브젝트를 먼저 그린 뒤에,
// 알파 블랜딩된 오브젝트를 z-sort에 따라 순서대로 뒤에서부터 앞으로 그리도록
// 알파 블랜딩 정렬을 설정한다.
NiAlphaAccumulator* pkAccum = NiNew NiAlphaAccumulator;
m_spRenderer->SetSorter(pkAccum);

NiStream kStream;

bool bSuccess = kStream.Load( NiApplication::ConvertMediaFilename( "WORLD.NIF" ) );

if( !bSuccess )
{
// 예외처리
return false;
}

// 최상위 노드를 리턴하여 저장한다.
m_spScene = (NiNode*)kStream.GetObjectAt(0);

// NIF파일에 등록되어있는 카메라를 검색하여 설정하도록 처리합니다.
if( !FindSceneCamera() )
{
// 예외처리
return false;
}
}

NiCamera
씬 그래프의 카메라를 나타냅니다.
이 객체는 고유의 기하하적 표현이 없으나 월드 공간에서 자신의 위치와 방향을 결정하기 위해 부모의 변환을 이용합니다. 이런 구성은 게임브리오에서 카메라가 씬 그래프에 어태치되게 해주며, 안에 있는 카메라와 유도 카메라를 자동으로 따라다니게 만듭니다.

NiNode
신 그래프의 내부 노드를 나타냅니다.
이 노드들은 임의의 개수를 자식으로 가질 수 있으며 Dynamic Effect는 영향을 줄 노드를 지정하는 데, 이 경우 서브트리에서 한 노드에 루트를 두고 있는 모든 객체들이 영향을 받게 됩니다.
노드 서브클래스들은 그 밑에 있는 서브트리에 대한 정렬 동작을 조절할 수 있습니다.
NiNode는 또한 피킹 시스템과 충돌 검사 시스템에 호출의 재귀적인 전달도 제공합니다.

bool NIF_Files::FindSceneCamera()
{
if( m_spScene )
{
// 씬에 설치된 카메라를 찾아서 리턴받아 저장하도록 처리한다.
m_spCamera = FindCamera( m_spScene );
}

return (m_spCamera != NULL);
}

NiCamera* NIF_Files::FindCamera( NiAVObject* pkObject )
{
// 카메라 타입인지를 검사한다.
// 그래서 이게 true라면 카메라 타입으므로
// 변환한 후 리턴한다.
if( NiIsKindOf( NiCamera, pkObject ) )
{
return (NiCamera*)pkObject);
}

// 노드 타입인지를 검사하여 노드 타입이면 실행한다.
else if( NiIsKindOf( NiNode, pkObject ) )
{
// 노드 타입의 객체로 형변환한다.
NiNode* pkNode = (NiNode*) pkObject;

// 노드의 자식 개수만큼 루프를 실행한다.
for (unsigned int ui = 0; ui < pkNode->GetArrayCount(); ui++)
{
// 카메라 타입의 노드를 찾는다.
// 즉 카메라가 여러개 있어도 가장 먼저 찾는 놈을 리턴하도록 처리되겠다.
NiCamera* pkFoundCamera = FindCamera(pkNode->GetAt(ui));
if (pkFoundCamera)
return pkFoundCamera;
}
}
}

반응형
반응형

블로그 이미지

3DMP engines

3D그래픽스 물리 수학, 프로그래밍 GPU Shader 게임엔진 알고리즘 디자인패턴 matlab etc..





boost::str( boost::wformat(  L"%d %d %d %d   %d %d") % (Tm->tm_year+1900) %  (Tm->tm_mon+1)%  Tm->tm_mday   

                                                                                %  Tm->tm_hour %  Tm->tm_min %  Tm->tm_sec );



이와같은 구문에서  (Tm->tm_year+1900) ,  (Tm->tm_mon+1)에 괄호를 치지않으면 에러가난다





이하 첨부내용



http://bit1010.tistory.com/21






기본 사용법

CString
CString str;
str.Format("%s%03d", szSomeVar, nSomeVar);

타입 안정성을 중요시하는 C++ 에서는 안타깝게도 CString의 Format 계열 함수가 제공 되지 않는다.
그래서 버퍼를 잡아 C의 런타임함수인 sprintf 함수를 사용하는수 밖에 없다.
그러나 C++에서는 stream 객체가 있으므로 sprintf 보다 우아(?) 하게 사용 할수 있다.

#include <sstream>로 사용할수 있으며 input/output/ input&output 버전이 따로 존재한다.

stringstream  in & out
ostringstream out
istringstream in

유니 코드 버전은 위의 클래스 네임에 w만 앞쪽에 붙여 주면되고
stringstream 내의 함수 중에 str() 멤버 함수로 string 클래스의 객체와 같이 연동해서 쓸 수 있다.

STL
#include <string>
#include <sstream>
#include <iomanip>
 
using namespace std;
ostringstream strStream;
strStream << szSomeVar << setw(3) << setfill('0') << nSomeVar;
string str = strStream.str();

BOOST
#include <boost/format.hpp>
#include <string>
 
std::string someString;
someString = boost::str(boost::format("%s%03d") % szSomeVar % nSomeVar);

CString의 Format에 해당하는 STL 코드와 BOOST 코드




직접 구현하기

1. 코드프로젝트 
STL Format 

CString의 Format같은 기능을 함수로 구현해 놓은게 있다.
근데 VC6에선 제대로 컴파일이 안된다. 우선 string의 clear는 stlport에는 없다.

2. 권진호님
sprintf 와 string 과의 만남

3. codein.co.kr

#define _MAX_CHARS 8000

int Format(std::stringtxtconst TCHARszFormat,...)

{ 

    std::vector<TCHAR_buffer(_MAX_CHARS);

    va_list argList;

    va_start(argList,szFormat);

#ifdef _UNICODE

    int ret = _vsnwprintf(&_buffer[0],_MAX_CHARS,szFormat,argList);

#else

    int ret = _vsnprintf(&_buffer[0],_MAX_CHARS,szFormat,argList);

#endif

    va_end(argList);

    txt.assign(&_buffer[0],ret);

    return ret;

}


4. 본인은 CString의 FromatV함수로 간단히 구현했음.  차라리 CString을 사용하는게 낫지 않냐고 하시면..
내부 구현은 나중에 제대로 테스트후 적용해도 된다. ㅋ

UINT StrPrintf( string& rstr, const char *pFmt, ...  )
{  
    va_list args;
    va_start(args, pFmt);
    
    CString csMsg;
    csMsg.FormatV(pFmt, args);
    rstr = csMsg;
    
    va_end(args);
    return rstr.length();
}


반응형
반응형

제공: 한빛미디어 네트워크 기사

원문: http://www.onlamp.com/pub/a/onlamp/2006/04/06/boostregex.html
저자: Ryan Stephens, 한동훈 역

텍스트를 검색하고, 파싱하는 과정은 어수선하다. 처음에는 문자열을 토큰으로 나누고, 구조를 재빨리 해석하는 간단한 문제처럼 보였던 것이 루프, if/then 문장, 버그로 이뤄진 안개같은 상태로 변하다가 종국에는 반쯤 아니 완전히 정신나간 상태까지 진행된다. 처음에는 URL에서 호스트 이름을 가져오는 것처럼 쉬운 것이 나중에는 로그 파일을 분석하고, 날짜로 된 문자열을 검사하는 것과 같은 복잡한 작업으로 발전하고, 점점 다루기 어려운 것으로 변한다.

오래 전부터 정규식은 이런 진흙탕에서 프로그래머들을 구원했다. 작지만 암호같은 정규식은 원하는 거의 모든 형식을 표현할 수 있으며, 복잡한 파싱 코드를 작성하는 임무로부터 개발자들을 구원해준다. 정규식은 강력할 뿐만 아니라, 어떤 언어에서든지 사용할 수 있으며, Perl에서는 정규식이 코드의 대부분을 차지한다. 현대 프로그래밍 언어들은 정규식에 대해 표준화된 방법으로 지원한다. 여기에는 펄, 자바, C#, 루비, 파이썬등이 있다. 슬프게도, C++은 이 목록에 없다. 정규식에 대해 유일하게 표준화된 방법은 몇 안되는 POSIX C API 함수들 뿐이다. 그렇더라도 걱정하지는 마라. 아직 C++에는 희망이 있다.

존(John Maddock)이 한시적인 표준 라이브러리로 만든  Boost.Regex 라이브러리가 이 문제를 해결해준다. 더 좋은 소식은 C++ 표준화위원회(TR1)에서 C++의 다음 표준 라이브러리의 표준 라이브러리로 Boost.Regex를 포함시키기로 했다는 점이다. 이제부터 C++에서 정규식을 사용한다면 이 라이브러리를 사용하면 된다. 이 라이브러리는 모두의 것이다.

Boost.Regex를 사용하면 간단한 매칭(전화번호 검사 같은 것)에서 검색 및 치환 같은 모든 작업을 할 수 있다. 여기서는 Boost.Regex로 할 수 있는 다음 기본 기능들을 설명할 것이다.

  • 매칭
  • 간단한 파싱
  • 열거(Enumeration)
이 글을 모두 읽은 다음에는 Boost.Regex로 무엇을 할 것인가에 대한 좋은 아이디어만 생각하면 된다. Boost.Regex를 시작하기 전에, 정규식에 대한 간단한 소개부터 하겠다.

배경 및 정의

정규식 구문은 그 자체로 완전한 언어이며, 정규식을 이해하기 완전히 이해하려면 몇 줄의 설명으로는 어림도 없다. 따라서, 여기서는 간단한 내용만 소개할 것이며, 원한다면 정규식에 대해 보다 많은 것들을 설명하고 있는 페이지들을 참고 자료로 제공할 것이다.

정규식은 정규식 엔진이 해석하고, 대상 문자열에 적용하기 위한 문자들로 구성된 문자열이다. C++에서 정규식 엔진은 Boost.Regex에 해당한다. 엔진은 문자열에 대해 식을 평가하고, 해당 식이 대상 문자열의 일부분이라면 전체 문자열이 일치하는지, 아닌지를 확인한다. 정규식이 문자열의 일부분이라면, 불리언 표현 값이나 실제로 식을 만족하는 텍스트를 결과로 가져올 수 있다.

이 글에서는 일부러 매치(match)와 검색(search)을 특별한 의미로 사용한다. 주어진 문자열을 정규식이 매치한다고 얘기할 때는 전체 문자열이 식을 만족한다는 것을 의미한다. 예를 들어, 다음과 같은 정규식을 생각해보자.

역주: match와 search를 보통은 구별하지 않고, "검색한다"라고 얘기하지만, 저자가 match와 search를 구분하기 때문에 match는 매치로 옮겼다.

a+|b+

위 식은 a가 한 번 이상 나오거나 b가 한 번 이상 나오는 문자열을 매치한다. + 기호의 의미는 "문자가 한 번 또는 그 이상의 문자들을 매치하라"이다. 파이프 연산자(|)는 논리적으로 "또는"이라는 의미이다. 따라서, 다음과 같은 문자열은 위 정규식과 매치된다.

a
aaaaa
b
bbbb

그러나, 다음 문자열은 매치되지 않는다.

ab
aac
x

정규식 a+|b+이 의미하는 것은 의사코드로 "문자열이 a로만 되어 있고, a가 한 번 이상 나오는 경우 또는 문자열이 b로만 되어 있고, b가 한 번 이상 나오는 경우에 true를 반환하라"이다.

반대로, 문자열에서 정규식을 만족하는 하위 문자열을 찾는 경우에는 결과가 달라진다. 앞과 같은 정규식을 사용해서도 다음 문자열을 매치할 수 있다.

mxaaabfc
aabc
bbbbbxxxx

이는 대상 문자열의 하위문자열이 정규식을 만족하기 때문이다. 이 작은 차이 때문에 Boost.Regex에서 정규식을 테스트하는데 사용하는 클래스와 함수가 달라진다.
표1은 자주 쓰이는 정규식 토큰을 요약한 것이다. 테이블을 이용해서 몇 가지 예제를 제시하고, 그에 대해 살펴본 다음에 정규식이 갖는 표현력을 살펴보고, 예제 1의 코드를 복사해서 약간의 실험을 진행할 것이다. 일단, 정규식을 사용해서 텍스트를 검색하고, 파스하는 것이 쉽다는 것을 알게 되면, 이것을 사용할 수 밖에 없을 것이다.

기호      의미
c         특수문자가 아니라면 문자 c를 한 번 매치한다.
^         줄의 시작을 매치한다.
.         새 라인이 아닌 모든 문자를 매치한다
$         줄의 끝을 매치한다
|         식들의 논리 OR
()        그룹 표현
[]        문자 클래스 정의
*         0번 또는 그 이상의 매치
+         1번 또는 그 이상의 매치
?         0 또는 1번의 매치
{n}       표현식을 n번 매치
{n,}      표현식을 최소한 n번 매치
{n, m}    최소 n번에서 최대 m번까지 매치하는 식
\d        숫자
\D        숫자를 제외한 문자
\w        _을 포함한 알파벳 문자
\W        알파벳이 아닌 문자
\s        공백 문자(\t, \n, \r, \f)
\S        공백 문자가 아닌 것
\t        탭
\n        새 라인
\r        캐리지 리턴
\f        폼 피드(Form Feed)
\m        메타 문자(^, ., $, |, (), [], *, +, ?, \, or /)들을 이스케이프

나는 표준처럼 널리 쓰이는 펄 스타일의 정규 표현식을 사용하고 있다. POSIX는 표준화된 기본 문법과 확장 문법 두 가지를 정의하고 있으며, Boost.Regex는 이들 두 가지를 모두 제공하고 있지만, 여기서는 설명하지 않을 것이다. 표 1에서 나열한 것보다 더 많은 것들이 있지만, 정규표현식을 배우기에는 위의 것으로충분하다. 펄 스타일의 정규식에 대해 보다 자세한 참고자료를 원한다면 펄의 regex 문서를 찾아보면 되며, Boost.Regex에서만 사용하는 옵션에 대해서는 부스트 문서 페이지를 읽어보면 된다. 또한 인터넷에서 "regular expression syntax"로 검색하면 많은 결과들을 찾아볼 수 있다.

이제, 이걸로 무엇을 할까? 먼저, 9자리 숫자로 되어 있는 SSN - 한국의 주민번호에 해당 -을 생각해보자. SSN은 세번째와 다섯번째 숫자 다음을 하이픈(-)으로 구분한다. 즉, XXX-XX-XXXX와 같은 형식으로 사용하며, 다음과 같은 간단한 정규식으로 이를 검증할 수 있다.

\d{3}\-\d{2}\-\d{4}

\d는 숫자를 매치하며, \d 다음의 {3}는 숫자가 연속해서 세 번 나오는 것을 의미한다. 즉, \d\d\d 대신에 사용한다. \-는 하이픈(-)을 의미한다. 하이픈은 정규식에서 메타문자로 사용하기 때문에 앞에 \을 붙여서 하이픈(-)을 찾는다. 위 식은 지금 설명한 이 규칙을 사용한 것이다. 즉, 숫자 2개, 하이픈, 숫자 4개도 같은 규칙이다.

어떤 사람의 이름이 Johnson인지, Johnston인지 찾아보고 싶다면 다음과 같이 쓸 수 있다.

Johnst{0,1}on
Johnson|Johnston
Johns(on|ton)

첫번째 예에서 {0,1}은 여기에 올 수 있는 문자의 수를 의미한다. 여기서는 문자 t가 0번 또는 한 번 올 수 있음을 의미한다. 두번째는 논리 OR 연산자를 괄호없이 사용한 것이며, 세번째는 논리 OR 연산자를 괄호와 함께 사용한 것이다.

매칭

앞에서 설명한 것처럼, 전체 문자열이 식을 만족하면 문자열이 정규식과 일치(match)한다고 한다. 예1은 정규식을 사용하는 간단한 프로그램이지만, 정규식을 만족하는 문자열이 있는지를 알려줄 수 있다. 컴파일하고 실행하면서 정규식이 동작하는 것을 살펴보고, 정규식이 무엇인지 느껴보기 바란다.

#include <iostream>
#include <string>
#include <boost/regex.hpp>  // Boost.Regex lib

using namespace std;

int main( ) {

   std::string s, sre;
   boost::regex re;

   while(true)
   {
      cout << "Expression: ";
      cin >> sre;
      if (sre == "quit")
      {
         break;
      }
      cout << "String:     ";
      cin >> s;

      try
      {
         // Set up the regular expression for case-insensitivity
         re.assign(sre, boost::regex_constants::icase);
      }
      catch (boost::regex_error& e)
      {
         cout << sre << " is not a valid regular expression: \""
              << e.what() << "\"" << endl;
         continue;
      }
      if (boost::regex_match(s, re))
      {
         cout << re << " matches " << s << endl;
      }
   }
}

예제1. 간단한 정규식 테스트 프로그램

예제의 첫번째는 boost/regex.hpp를 포함하는 것이다. 이 헤더 파일은 Boost.Regex 라이브러리를 사용하는데 필요한 모든 것을 담고 있다. (부스트 라이브러리의 압축을 풀고, 빌드하는 것은 간단하며, 이에 대한 내용은 "부스트 시작하기"를 참고하기 바란다)

다음은 boost::regex 클래스다. 이 클래스는 정규식 그 자체를 포함하고 있다. 표준 문자열 클래스와 마찬가지로 narrow 문자와 wide 문자를 위한 클래스 템플릿((regex = basic_regex<char> and wregex = basic_regex<wchar_t>)을 지원한다.

regex 클래스에 정규식을 정의하기 전에는 흥미로운 것은 없다. 멤버 함수, 할당 연산자와 생성자를 해석하고, 정규식을 컴파일한다. 만약, 제대로 생성되지 않았다면 regex_error 예외를 일으킨다. assign에 대소문자 구분 무시를 의미하는 boost::regex_constants::icase를 사용했다.

마지막으로, regex_match가 모든 것을 처리한다. 여기에 사용된 매개변수는 대상 문자열과 regex 객체이다. 문자열이 표현식을 만족하면 true를 반환하고, 그렇지 않으면 false를 반환한다.

문자열을 정규식에 매칭하기 위해 Boost.Regex를 사용하는 가장 간단한 예이다. 이런 형식은 유효성 검사와 파싱에서 가장 일반적으로 사용된다.

유효성 검사

일반적으로, 사람들이 컴퓨터에 입력하는 모든 것은 의심해야하며, 검사하는 것이 필요하다. 물론, 문자 하나하나씩 비교하는 간단한 방법, if/then 구문을 이용해서 문자열의 유효성을 검사할 수 있다. 그렇지만 왜 그렇게 하는가? 보기에 지저분한 문자 하나하나씩 파싱하는 코드를 작성하느라 시간을 낭비하지말고, 코드를 간결하고, 작성하는 의도를 명확하게 할 수 있는 정규식을 사용하는 것이 낫다.

사용자가 일상적으로 잘못 입력하는 것 중에 좋은 예가 URL이다. 설정 파일이나 사용자가 입력한 위치에서 URL을 읽어들이는 응용프로그램이 있다고 해보자. 첫번째는 네트워크 라이브러리에 이 URL을 전달하기 전에 이 값이 올바른지 검증하는 것이다. 또는, 네트워크 라이브러리를 작성하고 있다면, URL을 해석하기 전에 URL의 형식이 맞는지부터 검사해야 한다. URL은 최소한 세 가지 구성요소 즉, 프로토콜, 호스트 이름, 경로로 되어 있다.

ftp://downloads.foo.com/apps/linux/patch.gz

FTP, HTTP, HTTPS 프로토콜을 사용할 수 있으며, URL을 검사하는 정규식은 다음과 같다.

(ftp|http|https):\/\/(\w+\.)*(\w*)\/([\w\d]+\/{0,1})+

호안의 첫번째 표현식, (ftp|http|https),은 프로토콜을 검사한다. 이 표현식은 URL에서 세 가지 프로토콜 중에 하나만 매치한다. 다음은 콜론(:)과 슬래시다. 슬래시는 제어 문자로 사용하기 때문에 여기서는 역슬래시(\)를 함께 사용해서 슬래시(/)를 표현한다. 다음은 (\w+W.)*(\w*)인데 foo.com 또는 foo와 같은 형태를 허용하는 것으로, 호스트 이름에서 문자와 숫자를 표시한다. 다음은 슬래시(/)이고, 그 다음은 ([\w\d]+\/{0,1})+이다. 이 식은 /downloads/w32/utils와 같은 형태의 경로 이름을 매치한다.

예제 1을 이용해서 다음과 같은 코드를 쉽게 작성할 수 있다.

try
{
   boost::regex re("(ftp|http|https):\/\/(\w+\.)*(\w*)\/([\w\d]+\/{0,1})+");
   if (!boost::regex_match(url, re))
   {
      throw "Your URL is not formatted correctly!";
   }
}
catch (boost::regex_error& e)
{
   cerr << "The regexp " << re << " is invalid!" << endl;
   throw(e);
}

regex_match는 문자열, char *, 이터레이터 범위, |' 표준 라이브러리 알고리즘을 처리하는 오버로딩 메서드를 갖고 있다.

앞의 코드 조각은 문법 검사를 수행한다. 문자열이 정규표현식을 만족하면, 행복할 것이다. 정규식의 길은 이걸로 끝이 아니다. 문자열의 구조를 검증하는 간단한 것 말고, 보다 복잡한 것들을 처리하는 것이 필요한 경우도 있다. 예를 들어, URL에서 호스트이름을 추출하는 것처럼, 문자열의 일부를 추출하고 그것을 처리하는 경우도 필요하다.

파싱

regex_match는 문자열이 표현식을 만족하는가의 여부만 확인하는 것 외에 문자열을 부분부분으로 나누는 것도 가능하다. match_result 객체에 결과를 저장하며, match_result는 결과를 조사하기 위해 반복(iterate)하는 시퀀스-표준 라이브러리 시퀀스를 의미-이다. 

예제 2는 예제1을 수정한 버전이다. 새 버전에서는 match_result<const char*>을 typedef한 cmatch를 포함하고 있다. 표준 라이브러리 문자열과 마찬가지로, Boost.Regex는 narrow 문자열과 wide 문자열을 모두 지원한다.

#include <iostream>
#include <string>
#include <boost/regex.hpp>

using namespace std;

int main( ) {

   std::string s, sre;
   boost::regex re;
   boost::cmatch matches;

   while(true)
   {
      cout << "Expression: ";
      cin >> sre;
      if (sre == "quit")
      {
         break;
      }

      cout << "String:     ";
      cin >> s;

      try
      {
         // Assignment and construction initialize the FSM used
         // for regexp parsing
         re = sre;
      }
      catch (boost::regex_error& e)
      {
         cout << sre << " is not a valid regular expression: \""
              << e.what() << "\"" << endl;
         continue;
      }
      // if (boost::regex_match(s.begin(), s.end(), re))
      if (boost::regex_match(s.c_str(), matches, re))
      {
         // matches[0] contains the original string.  matches[n]
         // contains a sub_match object for each matching
         // subexpression
         for (int i = 1; i < matches.size(); i++)
         {
            // sub_match::first and sub_match::second are iterators that
            // refer to the first and one past the last chars of the
            // matching subexpression
            string match(matches[i].first, matches[i].second);
            cout << "\tmatches[" << i << "] = " << match << endl;
         }
      }
      else
      {
         cout << "The regexp \"" << re << "\" does not match \"" << s << "\"" << endl;
      }
   }
}

예제2. 하위포현식을 사용한 문자열 파싱

예제2에서 matches는 sub_match 객체의 시퀀스다. sub_match 클래스는 멤버 first와 second를 갖고 있다. 이들은 원래 문자열에서 첫번째와 마지막에서 하나 지난(one-past-the-last)을 가리킨다. matches[0]는 원래 문자열 전체를 담고 있으며, sub_match 객체의 인덱스 [1..n]은 원래 표현식에서 상응하는 하위 표현식을 매치한 하위 문자열 n개를 가리킨다.

하위 표현식은 괄호 안에 포함된 원래 정규식의 일부분이다. 예를 들어, 다음 정규식은 하위 정규식을 세 개 갖고 있다.

(\d{1,2})\/(\d{1,2})\/(\d{2}|\d{4})

이 정규식은 MM/DD/YY 또는 MM/DD/YYYY의 형태로 된 날짜들을 매치한다. 여기서는 값의 의미에 대해서는 검증하지 않기 때문에, 월에 해당하는 MM이 12보다 클 수도 있다. 어떻게 하면 각 부분을 잡아낼 수 있는가? 그림1이 아이디어를 설명해준다. 위 정규식을 문자열 11/5/2005에 사용하면 match_results 객체는 그림1과 같이 보게된다.

그림1 
그림1. regex_match의 결과

이 날짜를 해석하고 나면, matches에는 4개의 요소를 갖게 된다. 인덱스 0의 요소는 전체 문자열을 가리키며, matches에 있는 각 요소들은 원래 문자열에서 해당하는 하위 표현식을 만족하는 요소들을 가리킨다. 전체 문자열은 정규표현식을 매치하며, 각각의 하위 표현식은 match_results 시퀀스에서 인덱스 1-3으로 이용할 수 있다.

사용하고 있는 하위 표현식의 타입에 따라, match_results의 내용이 놀라운 것일 수도 있다. 위 URL 예제를 생각해보자. 정규 표현식은 하위 표현식 네 개를 갖고 있다. 굵은 글씨로 하위 표현식을 표시했다.

(ftp|http|https):\/\/(\w+\.)*(\w*)\/([\w\d]+\/{0,1})+

하위 표현식을 반복하는 것은(예를 들어, (\w+\.)*) 하위 표현식이 몇 번이든 매치할 수 있다는 것을 의미한다. 따라서, 매치된 결과는 차례대로 match_results에 저장된다. URL 정규 표현식을 사용해서 예제 2의 예제를 실행한 결과는 다음과 같이 된다.

정규식: (ftp|http|https):\/\/(\w+\.)*(\w*)\/([\w\d]+\/{0,1})+
문자열:     http://www.foo.com/bar
        matches[0] = http://www.foo.com/bar
        matches[1] = http
        matches[2] = foo.
        matches[3] = com
        matches[4] = bar

결과에서 "www."이 빠졌다는 것을 바로 눈치챘을 지도 모른다. 하위 표현식을 반복하는 것은 마지막으로매치된 하위 표현식만 저장하기 때문이다. 예를 들어, URL에서 전체 호스트 이름을 잡아내고 싶다면, 다음과 같이 굵은 괄호로 표시된 하위 표현식을 추가해야 한다.

(ftp|http|https):\/\/((\w+\.)*(\w*))\/([\w\d]+\/{0,1})+

이는 여러 개의 하위 표현식을 전체 호스트이름으로 묶는다. match_results 시퀀스에서 상응하는 sub_match 객체의 순서는 중첩된 하위 표현식의 트리가 깊이 우선, 왼쪽에서 오른쪽으로 탐색하는 순서로 결정된다. 수정된 정규식을 사용했을 때의 출력 결과는 다음과 같다.

표현식: (ftp|http|https):\/\/((\w+\.)*(\w*))\/([\w\d]+\/{0,1})+
문자열:     http://www.foo.com/bar
        matches[0] = http://www.foo.com/bar
        matches[1] = http
        matches[2] = www.foo.com
        matches[3] = foo.
        matches[4] = com
        matches[5] = bar

matches[2]에서 호스트 이름에 대한 하위 표현식의 매치 결과가 표시되는 것을 제외하면 이전과 동일하다.

이 기술을 사용해서 정규 표현식 구문을 연습해보면, 문자열을 검증하고, 파싱하는 작업 등에 Boost.Regex를 사용할 수 있을 것이다. 그러나, 이 예제들은 정규식의 강력한 능력의 일부분만 살펴본 것에 불과하다. 정규식에 익숙하지 않다면, 보다 많은 실험을 해보기 바란다. 아마, 정규식을 사용해서 여러분이 원하는 것을 얼마나 많이 할 수 있는지 안다면 놀랄 것이다.

검색

전체에서 하나의 문자열을 매칭하고 파싱하는 것은 원하는 문자열을 포함한 문자열을 찾아주는 검색의 문제를 해결해 주지 못한다. 

매칭과 마찬가지로, Boost.Regex는 정규식을 이용해서 문자열을 검색하는 두 가지 방법을 제공한다. 가장 간단한 경우로, 주어진 문자열과 정규 표현식의 매치 여부만 알고 싶은 경우다. 예제 3은 파일에서 각 라인을 읽어서, 정규표현식과 만족하는 문자열이 있으면, 해당 라인을 출력하는 grep을 간단하게 구현한 것이다.

#include <iostream>
#include <string>
#include <boost/regex.hpp>
#include <fstream>

using namespace std;
const int BUFSIZE = 10000;

int main(int argc, char** argv) {

   // Safety checks omitted...
   boost::regex re(argv[1]);
   string file(argv[2]);
   char buf[BUFSIZE];

   ifstream in(file.c_str());
   while (!in.eof())
   {
      in.getline(buf, BUFSIZE-1);
      if (boost::regex_search(buf, re))
      {
         cout << buf << endl;
      }
   }
}

예제3 간단한 grep

regex_match를 사용한 방법과 같이 regex_search를 사용할 수 있다.

주어진 패턴을 매치하는 모든 하위 문자열을 열거할 수도 있다. 예를 들어, 웹 크롤러를 작성하고 있고, 페이지 내에 사용된 모든 A 태그에 대해 반복하고 싶다고 해보자. A 태그를 잡아내기 위해 다음과 같은 정규 표현식을 사용할 수 있다.

<a\s+href="([\-:\w\d\.\/]+)">

grep 예제처럼 전체 라인을 반환하는 대신, 대상 URL만 필요하기 때문에 match_results에서 두번째 하위 표현식을 사용한다. 예제 4는 예제 3을 살짝 고친것이다.

#include <iostream>
#include <string>
#include <boost/regex.hpp>
#include <fstream>

using namespace std;
const int BUFSIZE = 10000;

int main(int argc, char** argv) {

   // Safety checks omitted...
   boost::regex re("<a\\s+href=\"([\\-:\\w\\d\\.\\/]+)\">");
   string file(argv[1]);
   char buf[BUFSIZE];
   boost::cmatch matches;
   string sbuf;
   string::const_iterator begin;
   ifstream in(file.c_str());

   while (!in.eof())
   {
      in.getline(buf, BUFSIZE-1);
      sbuf = buf;
      begin = sbuf.begin();

      while (boost::regex_search(begin, sbuf.end(), matches, re))
      {
         string url(matches[1].first, matches[1].second);
         cout << "URL: " << url << endl;
         // Update the beginning of the range to the character
         // following the match
         begin = matches[1].second;
      }
   }
}

예제4. A 태그를 사용하여 반복하기

예제 4에 작성된 정규표현식은 역슬래시를 많이 사용하고 있다. 특정 문자를 두 번 이스케이프하기 위해 필요하다. 한번은 컴파일러를 위해서, 다른 한 번은 정규 표현식 엔진을 위해서 이스케이프한 것이다.

예제 4는 예제3에서 사용한 것과 다른 regex_search 메서드를 사용한다. 이 버전은 검색된 문자들의 범위의 시작과 끝을 나타내는 양방향 이터레이터 인자를 두 개 사용한다. 매칭되는 하위 문자열에 접근하기 위해 matches[1].second가 나타내는 마지막 매치 다음에 문자를 시작지점을 나타내게 업데이트하는 한다.

이것이 일치한 패턴을 모두 나열하는 유일한 방법은 아니다. 이터레이터를 이용하는 쪽을 선호한다면 정규표현식 검색에서 결과에 대한 이터레이터 인퍼테이스를 제공하는 regex_token_iterator를 사용할 수 있다. 예제 4에서 URL 검색 결과에 대해 반복하는 부분을 다음과 같이 고칠 수 있다.

   // Read the HTML file into the string s...
   boost::sregex_token_iterator p(s.begin(), s.end(), re, 0);
   boost::sregex_token_iterator end;

   for (;p != end;count++, ++p)
   {
      string m(p->first, p->second);
      cout << m << endl;
   }

이게 전부는 아니다. 첫번째 토큰 이터레이터는 생성자의 마지막 인자로 0을 전달한다. 이는 정규 표현식을 만족하는 문자열에 대해 반복하라는 의미다. 이 값을 -1로 하면, 정규식을 만족하지 않는 하위 문자열에 대해 반복하라는 의미가 된다. 다시 말해서, 문자열을 토큰으로 나눈다. 각 토큰은 정규 표현식을 만족하는 것이 된다. 이를 사용하면 복잡한 구분자로 되어 있는 문자열을 원하는 토큰으로 나눌 수 있게 해준다. 예를 들어, 웹 페이지를 파싱하는 복잡한 경우에도 문서를 각 영역별로 나눌 수 있다.

확인할 것

여기서 설명한 것보다 Boost.Regex는 더 많은 것들을 제공한다. Boost.Regex 페이지의 문서는 많은 예제들을 제공하고 있으며, 위에서 설명한 문자열 검색외에 다음과 같은 것들도 할 수 있다.
  • 펄과 Sed 스타일의 형식 변환을 사용하는 검색과 치환
  • POSIX 기본 정규표현식과 확장 정규 표현식의 사용
  • 유니코드 문자열과 비표준 문자열 형식의 사용

정규표현식을 실험해보기 바란다. 같은 일을 하는 다양한 방법들이 존재하며, 원하는 것을 하는 정규식을 간결하게 만들 수 있는 방법이 없는지 확인해봐야 한다. 

결론

Boost.Regex는 C++에서 정규표현식 엔진을 구현하는 라이브러리다. 복잡하고, 번거로운 문자열 파싱 코드를 작성하는 대신, 이 라이브러리를 사용해서 문자열에 정규표현식을 사용해서 매치, 검색, 또는 검색 & 치환을 할 수 있다. Boost.Regex는 다음 버전의 C++ 표준 라이브러리로 승인되었으며, TR1의 구현(tr1 네임스페이스)에서 이것을 보게 될 것이다. 

Ryan Stephens은 애리조나 템페에 살고 있는 소프트웨어 엔지니어, 라이터, 학생이다. 그는 모든 언어로 프로그래밍하는 것, 특히 C++로 프로그래밍하는 것을 즐긴다.

 

 

출처 : http://network.hanbitbook.co.kr/view.php?bi_id=1218


블로깅한 포스트 : http://blog.naver.com/mydaylee/140035640151

반응형
반응형

http://blog.shar.kr/22 



들어가며

티스토리 블로그에 구글 맞춤검색을 적용하는 방법에 대한 포스팅입니다.
들어가기에 앞서 미리 블로그의 포스트들에 대한 정보가 구글에 등록되어 있어야 검색이 이루어지므로, 사이트맵의 정보가 담긴 XML을 제작하시거나, 간편히 구글에 RSS 피드를 등록해 주시기 바랍니다.

블로그 RSS 피드 등록 - http://blogsearch.google.co.kr/ping

이 포스트를 작성하면서 보니, iframe 을 이용한 호스팅 방식이 사라지고, '2페이지', 혹은 '검색 결과만'으로 변경된 모양입니다.
덕분에 어거지로 기존에 생성되었던 코드를 이용하여 적용시키는 식으로 포스트를 작성하게 되어 전체적인 내용이 다소 지저분해진 점 미리 양해 부탁드립니다.


구글 맞춤 검색엔진 생성

구글 맞춤 검색엔진은 다음 링크에서 만들 수 있습니다.
구글 맞춤검색 - http://www.google.co.kr/cse/

맞춤검색 엔진 만들기를 클릭하세요.

이름, 설명, 검색할 사이트를 알맞게 채우시고, 버전은 표준형을 선택한 뒤 다음 단계로 넘어갑니다.

디자인을 설정하는 단계입니다.
검색창은 어차피 스킨의 검색창 디자인을 사용할 것이기 때문에 검색 결과의 디자인만 보고 다음으로 넘어가도록 합니다.

드 생성이 완료되었다고 나오는데 무시하고 '디자인'을 클릭합니다.

제가 예전에 만들었을 때에는 iframe 설정 옵션이 있었는데, 이번에 포스팅을 하면서 보니 iframe 옵션이 사라졌다고 합니다. 하지만 기존에 생성되었던 코드를 이용하면 되므로 별 상관은 없습니다.
여기서는 일단 '2페이지'나 '검색결과만'을 선택하고 저장하도록 합니다.

아직 블로그에 삽입 할 맞춤 검색엔진 코드가 완성이 된 것이 아니므로, 구글 맞춤검색 페이지를 닫지 말아주시기 바랍니다.

 


티스토리 스킨 수정

맞춤 검색엔진의 코드는 티스토리의 스킨을 수정하면서 완성시키도록 하겠습니다.

검색 결과를 출력할 부분

찾기를 이용하여 부분을 찾도록 합니다.


찾았다면 HTML 구조에 유의하여 </div> 위에다가 다음 코드를 붙여 넣습니다.

<!-- Google CSE 검색결과 부분 시작 -->
<div id="cse-search-results"></div>
<script type="text/javascript">
    var googleSearchIframeName = "cse-search-results";
    var googleSearchFormName = "cse-search-box";
    var googleSearchFrameWidth = 가로너비; // 반드시 자신의 블로그 너비에 맞게 수정해 주세요!!
    var googleSearchDomain = "www.google.co.kr";
    var googleSearchPath = "/cse";
</script>
<script type="text/javascript" src="http://www.google.com/afsonline/show_afs_search.js"></script>
<!-- Google CSE 검색결과 부분 끝 -->
위 코드를 붙여넣은 다음, 반드시 googleSearchFrameWidth 의 값을 자신의 블로그 너비에 맞도록 수정해 주시기 바랍니다.

붙여넣은 코드 예시

여기서 주의하실 것은, 기존에 존재하는 검색 결과 출력 부분의 코드를 지워버리면 태그가 정상 작동하지 않는다는 문제점이 존재합니다.

만약, 구글 검색시마다 나오는 ""에 해당하는 글 0건이라는 글귀가 보기 싫다면, 이 부분을 다음과 같이 변경해 주시기 바랍니다.
[변경 전]
<div class="searchList"> <!-- 본문 검색 결과 리스트 -->
    <h3>&quot;&quot;에 해당되는 글 건</h3>
    <ol>
        <s_list_rep>

[변경 후]
<div class="searchList"> <!-- 본문 검색 결과 리스트 -->
    <script language="javascript">
        var str = "";
        if (str != "") { document.write("                    <h3>&quot;&quot;에 해당되는 글 건</h3>"); }
    </script>
    <ol>
        <s_list_rep>
※ 이 부분은 스킨의 구조에 따라 약간씩 차이가 있을 수 있습니다.

이는 검색 단어를 나타내주는 치환자인 이 존재할 경우에만 해당 문구를 출력해 주는 스크립트로, 이 상태에서는 태그를 선택했을 경우에만 "~"에 해당하는 글 X건이라는 글귀가 보여지게 됩니다.

검색창 부분

찾기를 이용하여 <s_search>를 찾도록 합니다.


찾으셨다면 기존에 존재하는 검색창은 주석처리( <!-- 와 --> 로 감싸면 됩니다.) 해 버리시고, 다음의 코드를 붙여 넣도록 합니다.
검색 고유 ID는 구굴의 검색엔진 제어판에서 맞춤검색엔진 v2 에 해당하는 아이디를 쓴다
<!-- Google CSE 검색창 부분 시작 -->
<script type="text/javascript" src="http://www.google.com/jsapi"></script>
<script type="text/javascript">
    google.load('search', '1');
    google.setOnLoadCallback(function() {
        google.search.CustomSearchControl.attachAutoCompletion(
        '검색엔진 고유 ID',
        document.getElementById('q'),
        'cse-search-box');
    });
</script>
<form action="http://자신의 주소/search" id="cse-search-box">
    <input type="hidden" name="cx" value="검색엔진 고유 ID" />
    <input type="hidden" name="cof" value="FORID:11" />
    <input type="hidden" name="ie" value="UTF-8" />
    <input id="스킨의 검색창 id" class="스킨의 검색창 스타일 클래스" type="text" name="q" />
</form>
<!-- Google CSE 검색창 부분 끝 -->

검색엔진의 고유 ID는 구글 맞춤검색 제어판의 '기본사항'에서 확인하실 수 있습니다.
다음 이미지를 참조하셔서 '기본사항' 하의 검색엔진 고유 ID 를 복사하여 위 코드를 적절히 수정하도록 합니다.


이제 블로그에 설치가 완료되었습니다.
새로 변경된 방식으로 설치하는 것은 먼저 적용해 본 후에 추가하도록 하겠습니다.


반응형

+ Recent posts