http://www.codeguru.com/cpp/cpp/cpp_managed/general/article.php/c16355/Using-WPF-with-Managed-C.htm#page-1



1. Introduction

The purpose of this article is two folds. At the first half we discuss what WPF is. In addition we studied why and how to program WPF using Managed C++ and high level overview of WPF architecture. Latter we scratch the surface of Loan Amortization with one working example of Loan Amortization in WPF using C++.

2. What is WPF?

Before going to study the WPF one might ask a question that what is WPF? WPF is abbreviation of "Window Presentation Foundation". It is a next generation presentation system for building window client application that can be run stand alone as well as in a Web Browser (i.e. XBAP Application). WPF is based on .Net environment, it means it is a managed code and theoretically can be written with any .Net based language such as Visual C#, VB.Net and Managed C++. WPF introduced with .Net 3.0 with few other important technologies such as Windows Communication Foundation (WCF) and Windows Workflow Foundation (WF), but here we are going to study only WPF.

WPF is the latest Microsoft technologies to create user interface. It was introduced with .Net 3.0 and then improved in .Net 3.5 and .Net 4.0 (Beta as of now). It does not depend on Windows Standard control; it draws everything from DirectX technology and takes full advantage of 3D graphics and hardware accelerator if available.

Most of the programmer thought that WPF is a feature of Visual C# and VB.Net can be done only in these languages. Although writing WPF programs in these languages are quite easy and fun, but it is not limited to only this. WPF is in fact a feature of .Net introduced with its version 3.5; therefore technically any .Net language can use it.

If this is a case then why there are so many WPF samples written only in C# and VB.Net codes even in MSDN? The best answer might be because of XAML. When using C# or VB.Net then we can take full advantage of XAML, which is not available in VC++.Net. It means when you are trying to write WPF code in Managed C++, then you are on your own and have to write code for everything. It may be a daunting task but not impossible and in fact there are few samples available with Microsoft SDK such as PlotPanel, RadialPanel, CustomPanel etc.

2.1. Why Managed C++ for WPF?

Next question is why should we use Managed C++ in Visual C++ to write WPF application when we can do the same thing in C# or VB.Net with XAML? There can be different reasons for it.

  • You lots of code base written in VC++ unmanaged code and it is not possible to rewrite everything in C#. You want to take advantage of both managed and unmanaged code in your project, such as using MFC document view architecture with rich user interface of WPF without creating any new DLL in C#.
  • Portion of your programs should be optimized for speed and for performance reason you write unmanaged code for it. WPF internally used the same technique for performance reason to call DirectX.
  • You want to hide the implementation of some portion of your program and or algorithm so no one can reverse engineer and write it as unmanaged code so no one can reverse engineer your code using ildasm.
  • Just for fun.

2.2. WPF Programming in VC++

To create simplest WPF program using Managed C++, you have to include reference of .Net components named windowsbase.dll, presentationcore.dll and presentationframeworkd.dll. In addition the program must be compiled using /clr switch because it is a managed code. Here is a diagram to show one project that has added references of these three DLL. To add the reference, right click on the project in the Solution Explorer tree and select "Reference..." from there.

If we want to create a simple windows based program then it would be something like this.

  1. #include <windows.h>
  2. using namespace System::Windows;
  3.  
  4. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
  5. LPSTR lpCmd, int nCmd)
  6. {
  7. MessageBox::Show("Hello World");
  8. }
This program does nothing more than simply display one message box. We can further shorten the program by using main instead of WinMain and avoid including windows.h header file altogether, but in that case we will see the black console window behind the message box.

If we want to make something more useful and interesting then we have to create objects of at least two classes Window and Application. But remember there can be only one object of Application class in the whole program. Here is the simplest program to show the usage of Window and Application class.

  1. #include <windows.h>
  2. using namespace System;
  3. using namespace System::Windows;
  4.  
  5. [STAThread]
  6. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
  7. LPSTR lpCmd, int nCmd)
  8. {
  9. Window^ win = gcnew Window();
  10. win->Title = "Hello World";
  11.  
  12. Application^ app = gcnew Application();
  13. app->Run(win);
  14. }
The output of this program is a blank window with a title "Hello World". Here Application class is used to start the WPF application, manage the state of application and application level variables and information, but there is no output of it. It is Windows class that is responsible to draw window on the screen. Run method should be the last method call in the program, because this method won't return until the program close. Return value of Run method is application exit code return to the operating system.

It is not necessary to pass the window object as a parameter in the run function of application class. We can call Run function without any parameter, but if we call the Run function without any parameter then we have to call the Show or ShowDilaog function of Window class before calling the Run. Difference between Show and ShowDialog is Show display the model dialog, on the other hand ShowDialog display the modeless dialog. For our simple application it doesn't make any difference.

You can inherit your classes from Window and Application classes to store some application specific or window specific information. But remember you class must be inherited using the "ref" keyword and use "gcnew" keyword to create an instance of it on managed heap. Here is a simple program to show the usage of user inherited Window and Application classes.

  1. #include <windows.h>
  2. using namespace System;
  3. using namespace System::Windows;
  4.  
  5. public ref class MyWindow : public Window
  6. {
  7. public:
  8. MyWindow()
  9. {
  10. Title = "Hello World";
  11. }
  12. };
  13.  
  14. public ref class MyApplication : public Application
  15. {
  16. };
  17.  
  18. [STAThread]
  19. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
  20. LPSTR lpCmd, int nCmd)
  21. {
  22. MyWindow^ win = gcnew MyWindow();
  23.  
  24. MyApplication^ app = gcnew MyApplication();
  25. app->Run(win);
  26. }
Output of this program is same as the previous one. In this program we can store all the application specific information in MyApplication class and Window specific information in MyWindow class. For example we set the title of the window in the constructor rather than in main after creating the object of it. We can also set other properties of window such as its back ground color, size, etc in the same place i.e. constructor.

These classes and their usages looks quite familiar with MFC. In MFC based application we also need object of two classes named CWinApp and CWnd. Similarly we create only one object of CWinApp based class and call the run method of CWinApp.

2.3. WPF Class Hierarchy

As we have seen before that to make smallest WPF application that display its own window we have to create objects of at least two classes named Window and Application. Before going further let's take a look at these two classes in little bit more detail. Here is a class diagram to show the inheritance chain for Application and Window class.



반응형

http://www.bcgsoft.com/FeatureTour/bcgcontrolbar-tour.htm



BCGSoft > Products > Product feature tour

Product feature tour

The feature is fully implemented
The feature is partially implemented
ProductBCGControlBar Pro (MFC)BCGSuite (MFC)BCGControlBar (Microsoft .NET)
General Application Look
Microsoft Office 2013 Look
Microsoft Office 2010 Look
Microsoft Office 2007 Look
Microsoft VS 2012 Look
Microsoft VS 2010 Look
Microsoft VS 2008 Look
Microsoft Office 2000/XP/2003 Look
Microsoft VS 6.0, VS.NET and VS 2005/2008 Look
Microsoft Internet Explorer Look
Microsoft Windows Themes Support
Carbon Look
Custom Application Look
Microsoft Office 2007/2010/2013 and Windows 7-style Ribbon Control
General Ribbon Features
Ribbon Designer
Ribbon Vista Aero Integration
Windows 7-like ("Scenic") Ribbon
Office 2010/2013-style Ribbon
Ribbon Panels
Ribbon Contextual Categories (Tabs)
Ribbon Elements
Ribbon KeyTips
Ribbon Palettes (Galleries)
Ribbon Customization
Ribbon Launch Button
Ribbon Main (Application) Button ("Perl")
Ribbon Backstage View
Ribbon Command Search
Ribbon Mini Toolbar ("Floaty")
Ribbon Status Bar
Ribbon Dialog Bar
Microsoft Office Style Toolbars
Microsoft Office XP/2000/2003/2007 look
Toolbar Editor
High and True color images support
"Pager" button (chevron)
Large icons support
Auto-build keyboard shortcut names in menus and ToolTips
Toolbar images
Toolbar images color transformation
"Locked" toolbars
Toolbar Menu buttons
Toolbar edit box buttons with spin button control and calculator
Toolbar combo box buttons
Toolbar font combo box and font size combo box buttons
Date/Time control for Toolbar
Built-in color picker
Built-in roll-up buttons (similar to CorelDraw)
Tabbed Toolbars
Explorer-style Toolbar
Microsoft Office Style Menus
Docking Microsoft Office-style menu bars with images
Microsoft Office 2000/XP/2003 menus (with recently used menu items)
Menu animations and shadows
Menu Tooltips
"Owner-draw" menu images
Left-side owner-draw logo
Most recently used (MRU) files and Windows list support
Microsoft Office-like "tear-off" ("detachable") menus
Right-alignment support for popup menus
Advanced Control Bars (Panes)
Shortcuts (Microsoft Outlook style) bar
Visual Studio 2005/2008/2010-style docking
Visual Studio style Docking/Resizable Control Bar
Microsoft Office-Style Task Pane
Visual Studio style Tabbed Control Bar
Visual Studio style Detachable Tabs
Visual Studio style Auto Hide Control Bars
Visual Studio style Toolbox
Advanced Dialog Bars
Application Bar
Enhanced Status Bar
Microsoft Office-style caption bar
Persistent rebars
Roll-up control bar
Microsoft Office style Print Preview
Advanced Document Management
MDI Tab Control
MDI Tab Groups
Persistent MDI State
Tabbed Views
OLE Document Support
Customization
Customizable toolbars and menus
Creation of user-defined toolbars at runtime
Context menu customization
Mouse event customization
Keyboard customization
Workspace manager
User defined tools
Alternative customization ("Alt+drag")
Quick customization
User-defined image editing (simple bitmap editor is included!)
Visualization and skins
Visualization and Skins
Visualization manager
Planner Control (Calendar)
Microsoft Outlook style Calendar
Day View
Work Week View
Week View
Month View
Single Appoinment
Recurring Events
Multi-Resource Support
Multi-Day and All Day Events
Integration with Calendar Control
Printing support
Chart Control
General Chart Features
Line Chart
Area Chart
Column and Bar Charts
Surface Chart
Pie, Doughnut and Torus Charts
Point Chart
Bubble Chart
Stock Chart
Histogram Chart
Long Data Line Chart
Historical Line Chart
Pyramid Chart
Funnel Chart
Radar Chart
Polar Chart
Ternary Chart
Chart Axis
Chart Series
Chart Virtual Series
Chart Data Markers
Chart Data Labels
Chart Legend
Chart Zoom and Scroll
Chart Objects
Chart and Plot Area
Chart Trendline Support
Chart Transitions Support
Chart Visualization Features
Chart Interoperability with other Library Components
Grid and Report Controls
General Grid Features
Grid Cell Types
Grid Virtual Mode
Grid Field Chooser
Grid Grouping Support
Grid Filter Support
Grid Filter Bar
Grid Merged Cells Support
Grid Data Binding
Grid Color Themes
Grid Frozen Columns
Grid Find Dialog
Hierarchical Grids
Report Control
Advanced Edit Control with IntelliSense and Syntax Highlighting
General Edit Control Features
Syntax Highlighting support
XML Schemas for Language Definition
Support for collapsible nodes (outlining)
Context-sensitive Tooltips
IntelliSense support
Line numbering
Markers and Color Blocks
Hyperlinks support
Symbol support
Undo/Redo support
Find and Replace
Export to HTML and RTF
MFC Document/View support
Gantt Control
General Gantt Control Features
Task types
Built-in resource grid
Task connectors
Collapsible groups (Grouped items)
Fully customizable appearance
Zoom In / Zoom Out
Gauges
Gauges Overview
Visual Designer for Gauges
Circular Gauges
Linear Gauges
Knob Control
Radial Menu
Rotation Control
Numeric Indicators
Color Indicators
Text Labels
Image Indicators
Analog Clock
Gauge Containers
Windows UI-style Tiles control
General Win UI-style Tiles control features
WinUI-style Tile Objects
WinUI-style Tile Badges
Diagram Control
General Diagram Control Features
Diagram Block Types
Miscellaneous GUI Controls
Property List (Grid) Control
Hyperlink control
Enhanced pushbutton
Menu button (Split button)
Advanced Tab Control
Microsoft Office-style color picker
Brush button
Advanced animation control
Microsoft Visual Studio-style editable list box
List header control
Font picker
Masked edit control
Date/Time control (date-time picker)
Calendar control
Duration control
Images with hot-spot areas
Edit control with a browse button
Calculator
Popup (Desktop Alert) Window
Tooltip Control
Breadcrumb Control
Tag Cloud Control
TreeMap Control
Dialogs
Skinned Dialogs and Forms Support
Resizable Dialogs and Forms
Advanced Property Sheet
Aero Wizard
Toolbar Customization dialog
Image Edit dialog
Brush Edit dialog
Text Format dialog
Office-like color selection dialog box
Key Map Dialog
Windows Management dialog
Textured dialogs
Enhanced file dialog box
Advanced Message Boxes
Progress ("Wait") dialog
Visual Studio Integration
Application Wizard
Integration Wizard
Build Wizard
MSDN-integrated Help
Shell Management
Shell management classes
Shell tree, list and breadcrumb controls
Windows 7 Taskbar Integration
Miscellaneous
Drawing manager
UNICODE support
High DPI Support
Microsoft Active Accessibility Support
Right-to-Left Languages Support
Localization
 

반응형

http://msdn.microsoft.com/ko-kr/library/ms235211(v=vs.100).aspx


/clr을 사용하여 MFC 및 ATL 코드 컴파일

Visual Studio 2010
이 항목은 아직 평가되지 않았습니다.이 항목 평가

이 항목에서는 공용 언어 런타임을 대상으로 기존 MFC 및 ATL 프로그램을 컴파일하는 방법에 대해 설명합니다.

/clr을 사용하여 MFC 실행 파일 또는 일반 DLL을 컴파일하려면

  1. 솔루션 탐색기에서 프로젝트를 마우스 오른쪽 단추로 클릭하고 속성을 클릭합니다.

  2. 프로젝트 속성 대화 상자에서 구성 속성 옆의 노드를 확장하고 일반을 선택합니다. 오른쪽 창의 프로젝트 기본값 아래에서공용 언어 런타임 지원을 공용 언어 런타임 지원(/clr)으로 설정합니다.

    동일한 창에서 MFC 사용이 공유 DLL에서 MFC 사용으로 설정되어 있는지 확인합니다.

  3. 구성 속성에서 C/C++ 옆의 노드를 확장하고 일반을 선택합니다. 디버깅 정보 형식이 /ZI가 아니라 프로그램 데이터베이스(/Zi)로 설정되어 있는지 확인합니다.

  4. 코드 생성 노드를 선택합니다. 최소 다시 빌드 사용을 아니요(/Gm-)로 설정합니다. 또한 기본 런타임 검사를 기본값으로 설정합니다.

  5. 구성 속성에서 C/C++를 선택한 다음 코드 생성을 선택합니다. 런타임 라이브러리가 다중 스레드 디버그 DLL(/MDd) 또는다중 스레드 DLL(/MD) 중 하나로 설정되어 있는지 확인합니다.

  6. Stdafx.h에서 다음 줄을 추가합니다.

    #using <System.Windows.Forms.dll>

반응형




Visual Studio 2010 의 VC++ 활용설명 / Win32 콘솔 응용 프로그램 및 CLR 설정 

2012/10/27 16:55

복사http://blog.naver.com/gusteam/150150354612


 

 

제목 : VisualStudio 2010의 VC++ 설정 / Win32 콘솔 응용 프로그램 및 CLR 설정

 

작성자 : 블로거(처음)

문제점 :

 1. VC++ 용 디렉토리 구조를 바꿀 수는 없나?

 2. 프로젝트를 열지 않는 상태의 도구의 디렉토리 설정을 할 수 없나?

 

해결점 :

 1. 바꿀수 있습니다.

 [ VisualStudio를 시작합니다. 

 [ 하나의 프로젝트를 만듭니다. VC++용

 [ 솔루션 탐색기 탭에서 프로젝트 이름에 오른쪽 마우스 클릭합니다.

 [ 속성(R)을 클릭 후 구성 속성 항목에서

 [ VC++ 디렉토리 항목을 변경시켜 줍니다.
 2. VisualStudio 2010 VC++에서는 프로젝트 생성 후에 가능합니다.

 

 문제점 : Win32 콘솔 응용 프로그램에서 CLR를 사용할 수 있는 방법은?

 [ Visual Studio 2010 시작

 [ 프로젝트  - Win32 콘솔 응용 프로그램을 만듭니다.

 [ 솔루션 탐색기 탭에서 프로젝트 이름을 마우스 오른쪽 클릭을 해 줍니다.

 [ 속성(R)창에서 옵션(창)이 뜨고 아래쪽 구성 속성의 일반(탭)을 선택하면

 [ 오른쪽 창에 공용 언어 런타임 지원 항목을 ( 공용 언어 런타임 지원 /clr ) 선택

 [ 헤더 파일(stdafx.h) 파일을 엽니다.

[ 헤더 파일(stdafx.h ) 파일의 #pragma once 아래의 다음의 코드를 삽입해 줍니다.

 #pragma once

 #include ..... // 해당 인크루드 파일들이 있을 수도 없을 수도 있습니다.

 using namespace System; //이 라인을 추가해 줍니다. 

 

 [ 이렇게 해줌으로써 .NET CLR 언어를 사용 있게 되겠습니다.

 [ (mscordll.dll) 설정 방법은 블로그 검색을 참조하십시요.

 

 

[ 다음은 Win32 콘솔 응용 프로그램 상에서 CLR 설정하는 방법을 그림으로 보여줍니다. ]

 







 

  

 

반응형


CEGUI 사용시 GUI를 제외한 렌더링화면이 나오지 않거나 이상하게 렌더링될때  CEGUI

2009/06/14 20:16

복사http://blog.naver.com/woocom2/90048906712


CEGUI를 내가 사용하는 프레임워크에 붙여봤다.
그런데 이상한 현상하게도 GUI를 제외한 메쉬나 오브젝트들이 렌더되지 않았다.
처음시작에 잠깐 1프레임 보이다 사라진다.

포럼과 CEGUI카페를 찾아봤지만 겨우겨우 포럼에서 방법을 찾았다.
CEGUI가 디바이스를 가지고 RenderState를 변경하는 듯했다.
그래서 CEGUI가 렌더되고 나서는 RenderState를 복구해주지 않을 경우 렌더화면이 외곡되거나 나타나지 않는 것이다.
이것을 해결하기 위해서는 
IDirect3DStateBlock9* 인터페이스를 사용해서 RenderState를 저장했다가 매 프레임마다 복구시켜주는 과정이 필요하다.

사용법은 이렇다.
//...
 IDirect3DStateBlock9*            m_OriRenderState;        
//...

// 렌더링 세팅이 끝난후
device->CreateStateBlock(D3DSBT_ALL, &m_OriRenderState);

// 렌더링
if( SUCCEEDED( device->BeginScene() ) )
{
        m_OriRenderState->Apply();           // CEGUIDirectX9렌더러가 RenderState를 변경시키므로 원래 랜더상태 복원
        DrawScene();                               // 카메라 위치와 캐릭터, 임의로 생성된 박스를 그린다.        
        CEGUI::System::getSingleton().renderGUI();
        pTextOut->DrawText(fpsText);        // 프레임을 나타낸다.        
        device->EndScene();
        device->Present(0,0,0,0);
}

반응형

CEGUI - 2005에서 한글폰트 출력하기


2007.10.18 01:10

폰트가 정말 깔끔하게 나온다. 맘에 들어 꺄악.

CEGUI포럼을 검색하다 보니 중국어 출력 관련 질문이 있었는데 그 부분을 참고 했다.

원문 : http://www.cegui.org.uk/phpBB2/viewtopic.php?t=2503&highlight=language

 

1. 한글폰트를 포함하는 .font를 만들고 그것을 FontManager로 로드합니다.

폰트 정보를 로드한 후 폰트의 이름을 기본 폰트로 설정해 줍니다. 여기에서 한 가지 팁은 CEGUI에서 한글 폰트를 사용하면 폰트를 비트맵으로 변환하여 읽어들인다는 것입니다. 비트맵으로 변환하는 과정에서 폰트의 사이즈가 크거나, 한자를 포함하여 폰트자체의 용량이 크게되면 안된다는 것입니다. 한자를 포함하는 폰트를 사용하게 되면 폰트를 비트맵으로 변환하는 과정에서 데드락이 걸린다고 하는군요. 실질적으로 소스를 살펴보겠습니다.

- .font

<?xml version="1.0"?>

<Font Name="Tahoma-12" Filename="HMKMAMI.TTF" Type="FreeType" Size="24" NativeHorzRes="1024" NativeVertRes="768" AutoScaled="true" AntiAlias="true"/>


- .cpp

CEGUI::FontManager::getSingleton().createFont ("Tahoma-12.font");
CEGUI::System &sys = CEGUI::System::getSingleton();
sys.setDefaultFont((CEGUI::utf8*)"Tahoma-12");

 

2. 소스를 살펴보면 출력할 폰트를 UTF8로 변환하는 코드를 볼 수 있다.

 std::wstring szWstring(L"노바 - Nest Of Valuable Academy");
 char *szUtf8String = NULL; 
 int iLengthAnsiString = 0; 
 iLengthAnsiString = WideCharToMultiByte(CP_UTF8, 0,szWstring.c_str(), szWstring.capacity(), NULL, 0, NULL, NULL); 
 szUtf8String = new char[ iLengthAnsiString]; 
 memset(szUtf8String, 0, sizeof(char)*(iLengthAnsiString)); 
 WideCharToMultiByte(CP_UTF8, 0,szWstring.c_str(), szWstring.length(), szUtf8String, iLengthAnsiString, NULL, NULL); 
 wnd->setText((CEGUI::utf8*)szUtf8String);
 delete [] szUtf8String; 
 szUtf8String = NULL;

위의 코드처럼 unicode -> UTF8로 변환하는 작업을 거쳐야 한글 출력이 가능합니다.

 

3. 2007년 10월 19일 추가작성

위의 코드는 수 많은 UI를 코드에 단다고 했을 때 범용성이라고는 누꼽만큼도 없는 코드입니다. 단지 한글 출력이 가능하다라는 정도의 소스가 되겠습니다. 그래서 필요한 것은 시스템인코딩된 멀티바이트를 UTF8로 인코딩을 시키는 코드를 작성해야 합니다. 그런데! (시스템인코딩)멀티바이트 -> (UTF8)멀티바이트로 변환을 시키는 함수가 없기 때문에 멀티바이트->유니코드->멀티바이트로 변환 과정을 거쳐 UTF8로 변환 시켜야 합니다.

이번 작업으로 한글변환에 대한 기본지식은 어느정도 생긴것 같습니다. widechar가 유니코드. multybyte가 완성형 그러니깐 일반적인 char형 변수. UTF8은 char형이나 UTF8인코딩 변환 과정을 거친다는 것입니다.

멀티바이트 문자열의 길이는 strlen()함수를 통해 알 수 있고 유니코드는 lstrlen()함수를 통해 알 수 있습니다. 하루 동안 삽질 하면서 정말 많은 문서를 봤지만 기억에 남는건..그닥없습니다.ㅎ

그냥 두서 없이 함수 구현부만 적어 놓겠습니다.

 

char* CEGUIApplication::ANSI_TO_UTF8(char *szANSI) 

    int nLen = MultiByteToWideChar(CP_ACP, 0, szANSI, -1, NULL, NULL); 
    LPWSTR lpwsz = new WCHAR[nLen]; 
    MultiByteToWideChar(CP_ACP, 0, szANSI, -1, lpwsz, nLen); 
    int nLen1 = WideCharToMultiByte(CP_UTF8, 0, lpwsz, nLen, NULL, NULL, NULL, NULL); 
    LPSTR lpsz = new CHAR[nLen1]; 
    WideCharToMultiByte(CP_UTF8, 0, lpwsz, nLen, lpsz, nLen1, NULL, NULL); 
    delete []lpwsz; 
    return lpsz; 
}

이런식으로 해 놓고!

CEGUI에서의 사용은 아래와 같이 하면 되겠습니다.

 

wnd->setText((CEGUI::utf8*)ANSI_TO_UTF8("윤경옥-NOVA"));

궂이 UTF8로 변환을 시켜주는 이유는 CEGUI::String형이 UTF8로 인코딩 되어 있기 때문입니다.

2003버젼에서는 이런 변환 과정이 필요없지만 2005는 프로그램의 버그로 보이는 문제 때문에 UTF8로 인코딩을 해도 한글 출력이 잘 되지 않는다고 하는군요. 이런 공개용 라이브러리를 공부 하는데 가장 좋은 방법은 외국 사이트의 포럼을 통해서가 가장 효과적인 것 같습니다.

 

짧은 프로그래머 생활 이었지만 코딩을 할 때마다 뼈저리게 느끼는건 하늘 아래 새로운 것이 없다는 말 처럼 내가 지금 겪고 있는 문제를 과거에 누군가는 반드시 겪었었고, 앞으로도 반드시 겪게 될거라는 것입니다. 이런 논리속에서 프로그래머에게 필요한 기술의 하나가 정보수집 능력에 있는것 같습니다.




  • 2007/10/30 17:18답글

    신고

    전 똑같이 해봐도 안되네요..;;온리 영어만 출력되구ㅡ,ㅡ; 
    ANSI_TO_UTF8함수랑 밑에 settext 만 추가해주면 출력이 되는건가요?
    폰트는 tohoma 쓰고있어요.
    디버깅을 해보니 마지막 return lpsz변수에 한글이 무참히 깨져있네요..;;영문은 살아있고

  • 2007/10/30 22:45답글

    신고

    일단 소스를 살펴보면 .font파일을 로딩한걸 보실 수 있을겁니다.
    그 파일을 열어보면 xml로 구성하려는 폰트와 폰트의 사이즈 정보가 들어가 있습니다.
    여기에 한글출력이 가능한 폰트를 입력해줘야 됩니다.
    위에 작성한 타호마폰트는 .font에 폰트 정보를 임의적으로 준 이름이거나 시스템폰트입니다.
    추가적으로 CEGUI에서 사용하는 폰트는 실시간 해당 한글폰트의 텍스쳐를 생성해서 출력해주는 방식입니다. 이는 컴파일과정에서 일어납니다.

  • 2007/12/11 19:44답글

    신고

    멀티바이트를 유니코드로 바꾸고 유니코드를 UTF8로 바꾸는것은 
    inline
    std::wstring convMbcs2Uni(const std::string &mstr)
    {
    USES_CONVERSION;
    std::wstring wstr(A2W(mstr.c_str()));
    return wstr;
    }
    inline
    std::string convUni2Utf8(const std::wstring &wstr)
    {
    USES_UTF8_CONVERSION;
    std::string ustr(W2A(wstr.c_str()));
    return ustr;
    }
    #define CONV_MBCS_UTF8(a) convUni2Utf8(convMbcs2Uni(a)).c_str()
    이런식으로 할수도 있더군요

반응형

CEGUI 그냥 사용하기엔 정말 무겁습니다.|CEGUI분석
전체공개2008.03.30 00:07

현재 버젼이 어느 정도 안정화 단계에 접어 들었기 때문에 추후 버젼업 시에 관련 부분 패치를 포기하시고,

라이브러리 자체를 뜯어 고치셔야 상용게임 수준에서는 필요하다고 봅니다.

 

1. freetype라이브러리의 실시간 비트맵폰트 생성 부분.

내부 캐싱은 지원하질 않습니다. 특정 비트맵폰트가 필요하면 그 폰트의 페이지에 있는 모든 폰트를 그려넣은 텍스쳐를 생성합니다. 정확히 유니코드의 완성형 코드 구성이 어떻게 이뤄졌는지는 모르겠으나 "가"라는 글자를 치면.."가 갸 거 겨"와 같은 앞 뒤에 있을 수 있는 글자가 포함된 텍스쳐를 생성한다는 겁니다. 이는 소스상에서 수정할 수 있습니다. 어떤거였는지 생각은 나질 않으나 CEGUIText? 클래스의 선언부에 이 텍스쳐 안에 포함될 글자의 숫자를 define해놓은게 있습니다. 아마 256 정도로 define을 해놨는데 확실히 그 보다 작은 수로 하면 텍스쳐 생성 및 write시간이 적게 걸립니다. 장단점은 있겠죠? 텍스쳐를 크게 만들고 연관글자의 입력시 텍스쳐 생성에 대한 시간이 없을 수 있다는 겁니다. 이러한 부분은 비트맵폰트 텍스쳐의 캐싱코드를 포함해서 만들어야 될 거란 생각이 듭니다.

 

2. 지나친 update()함수의 호출.

UI라이브러리는 업데이트 함수의 호출을 통해 메모리버퍼의 내용과 프로퍼티 설정 내용을 동일시 시켜줍니다. CEGUI의 업데이트는 너무 무겁고, 너무 자주 호출됩니다. 특정 프로퍼티 설정이 변경이 되면 바로 업데이트 함수를 호출해주면서 버퍼의 내용과 프로퍼티를 동일 시 시켜주는데 그럴 필요 없다는 겁니다. 렌더링 전에 한 번만 호출해 주면 된다는 겁니다.

 

3. CEGUI::String클래스.

요 놈은 std::string클래스를 랩핑해서 만든 클래스 입니다. 맵 저장 시 정렬 순서에 대한 오퍼레이터와 몇 가지 차이점이 있으나 큰 차이는 보이질 않습니다. 그런데!!!! 디버깅 시에 String객체의 내용을 조사식 창에서 확인할 수 없습니다. 팁이라면 std::string과 CEGUI::String클래스간의 변환은 c_str()매서드를 통해 이루어질 수 있습니다. 이 클래스에 대한 중요한 얘기를 할게 있었는데 잠깐 다른 생각 하는세 까먹었습니다.

 

4. UTF-8 인코딩

이 놈 역시 상당히 거슬립니다. CEGUI에 들어가는 문자열은 모두 UTF-8로 인코딩을 시켜야합니다. 멀티바이트와 유니코드는 알겠는데UTF-8? 음 저 역시 깊게 설명 드릴 수는 없고 UTF-32인코딩 방식이 일반적으로 쓰이는 방식이기 때문에 UTF-8인코딩 형식의 문자열로 바꿀려면 멀티바이트 설정의 솔루션에서는 멀티바이트(UTF-32)를 유니코드로 변환 하고 이걸 다시 멀티바이트(UTF-8)로 변환을 거쳐야 합니다. 변환 관련 Flag중에 인코딩 형식을 설정해주는게 있습니다.

 

5. 지나친 Render()함수의 호출.

Update()함수와는 또 다른 개념입니다. 프레임윈도우에 CEGUIStaticImage를 3개를 attach시킨 캐릭터 상태표시창이 있었는데 이거 하나 그릴 때 Render()함수가 27번이 호출이 됐습니다. 사각형 이미지의 경우(물론 룩앤필 설정에서 이를 최소화 시킬 수 있습니다. staticimage의 looknfeel설정을 각 테두리 이미지는 하나도 없에고 배경만 남기는 겁니다.)Left-Top, Left-Middle, Left-Bottom과 같이 각 각을 9번 렌더링 합니다. 이걸 최적화 시키기 위해서는 CEGUITexure클래스의 연관관계를 파악 후에 Update()함수에 의해 최종적으로 완성된 버퍼를 하나의 텍스쳐에 옮겨담고 한 번만 렌더링 하는 겁니다.

 

6. 수 많은 예외처리

예외처리는 때론 유용하지만 때론 불편합니다.

 

 

제가 사용하면서 느낀 건 이 정도의 이유라 상용게임에서 사용하기엔 무리가 있다는겁니다.

이 작성자의 게시글|더보기
http://acasia.na.mu
http:://actionslove.tistory.com ..
덧글 4개||조회수 916
  • 2008/03/30 20:37답글

    신고

    오~ 그렇군요.. 시간 절약이 많이 되는 정보네요
    감사합니다 ^^

  • 2008/04/30 17:01답글

    신고

    연구하신 내용을 이렇게 보기좋게 올려주셔서 정말 감사드립니다.
    지금 회사 프로젝트 진행하면서 CEGUI 로 ui 구현하려고 하는데, 이글을 보고 많이 고민이 됩니다.
    현재는 CustomUI 를 개조해서 쓰고 있는데요 ... CEGUI 퍼포먼스 문제가 제일 고민이네요 ㅡㅡ;;;

  • 2008/07/22 11:55답글

    신고

    1번에 내부 캐싱이 무슨 뜻인지 잘 모르겠습니다. 구체적으로 설명해줄 수 있나요?

  • 2008/07/22 12:50답글

    신고

    사용하지 않는 텍스쳐와 사용하는 텍스쳐를 구분하여 적절한 타이밍에 메모리에서 해제를 하는 것과 같은 일을 캐싱이라는 단어로 표현했습니다. CEGUI라이브러리 내부적으로 이러한 글자 텍스쳐에 대한 캐싱을 하지 않기 때문에 프레임워크의 업데이트 타임에 레퍼런스 카운트를 체크해서 메모리를 해제 해주는 부분을 구현할 필요가 있을 듯 합니다. 내부적으로는 조합형 폰트를 출력할 때 해당 폰트의 앞 뒤 몇개를 동시에 만듭니다. 이렇게 만들어진 텍스쳐를 맵에서 관리를 하구요. 텍스쳐맵에 대한 해제 시점을 CEGUI::System을 해제 할 때 함께 메모리에서 삭제 됩니다.

반응형

http://juree.tistory.com/980



GPG Study에서 퍼온글입니다. 
CEGUI에서 한글 구현하려고 고생하고있는데. 글 올려주셔서 감사합니다.


전에 CEGUI에 대해 정리해둔게 있어서 옮깁니다. 
먼저 CEGUI는 www.cegui.org.uk 에서 받을 수 있습니다. 
이곳에서 
cegui_mk2-0.4.0(<-최신버전 드래그 앤 드롭구현)
cegui_mk-0.4.0-deps-common(안에 dependencies 와 Samples를 같은 디렉토리 안데 넣습니다.) 
cegui_mk-0.4.0-deps-vc71-xerces(역시 안에 dependencies 와 Samples를 같은 디렉토리 안데 넣습니다.) 
이 세 파일을 받으신후에 (root:cegui_mk2makefileswin32VC++7.1) 안에 있는 프로젝트 파일을 열어 빌드를 합니다. 
빌 드한후에 (root:cegui_mk2lib)안에 여러가지 lib화일이 만들어져 있을겁니다. 이들중 CEGUIBase.lib가 가장 중요한 lib입니다. 이 파일을 라이브러리 경로에 포함하시고 실행파일 안에 있는 CEGUIBase.dll, devil.dll, ilu.dll등등의 파일을 자신의 어플리케이션으로 옴기면 준비는 다 된것입니다.(이후 자신의 어플리케이션을 빌드할때 CEGUI헤더파일과 lib포함) 

다음 자신의 그래픽엔진에 맞는 XXXCEGUIRederer와 XXXTexture를 만들면 됩니다. 이는 안에 순수 가상클래스로 만들어진 renderer와 Texture를 상속받고 인터페이스 대로 구현만 하면 됩니다. 이렇게 하면 XXXCEGUIRenderer.lib, XXXCEGUIRenderer.dll 이 만들어 지고 자신의 어플리케이션에CEGUIBase.lib, XXXCEGUIRenderer.lib를 포함하면 됩니다. 

이후 한글을 사용하기 위해서는 font파일을 만들어야 합니다. 이파일을 열어서 


< ?xml version="1.0" ? > 
< Font Name="Tahoma-12" Filename="NGULIM.ttf" Type="Dynamic" Size="12" NativeHorzRes="800" NativeVertRes="600" AutoScaled="true" > 
< GlyphRange StartCodepoint= "44032" EndCodepoint= "55203" / > 
< GlyphSet Glyphs="上下" / > 
< /Font >


이 안에 이미지폰트나 트루타입폰트 설정을 해주면은 됩니다. 여기서 중요한것만 설명하면 Filename은 폰트 이름 전 새굴림(NGULIM.ttf)을 사용했습니다. type 폰트종류 Dynamic은 투루타입 Static은 이미지폰트, 이 폰트에서 한글을 사용하기 위해서는 Glyph명령을 사용해서 폰트내에서 사용할 문자코드를 정해줘야 합니다. 
위에서 GlyphRange 문자코드(10진수)의 시작과 끝을 정해주는 겁니다. 위에서 44032는 폰트내에서 "가"에 해당하는 문자코드이고 55203은 한글문자코드의 마지막코드입니다. 이 외에도 특수 문자나 한자등의 사용을 위해 개별적으로 입력시 GlyphSet Glyphs = " " <--여기에 원하는 문자를 넣어 주면 됩니다. 

그리고 나서 자신의 코드에서 button->setText((CEGUI::utf8*)"미션1"); 이런식으로 사용하면 됩니다.그러고 나서 저장할때 파일->저장 고급 옵션 에서 유니코드로 저장하시면 됩니다. 이상이 한글 출력부분이고.. 

한글 입력시에는 CEGUI는 기본적으로 GUI만 구현되어 있습니다. Ogre, irricht, 그곳예제에서도 한글입력에 대해서는 찾을 수 없습니다. 위에 열거한 것들의 입력부분이 한글이나 비영미권의 언어를 지워하지 않습니다. 그래서 입력부분은 따로 구현해 줘야 합니다. 한/영 키를 인식해서 키보드에서 들어오는 신호를 해당 문자코드로 변환해주는 부분은 자신이 직접 구현해야 합니다. 

이상입니다. 그외 세부적인 부분 Scheme, layout 다중폰트 사용등은 레퍼런스문에다 잘 나와있습니다.
--위의 내용보고 구현한 예제입니다.

반응형

http://cafe.naver.com/cegui/139


http://cafe.naver.com/cegui/2 이글에서 혜윰님이 말씀하신 CEGUI::System::Destroy 라는 함수가 없더라구요...

그대신 CEGUI::System::GetInstance().detstroysingleton인가하는 메소드가 있긴한데

보호영역이라서 사용이않되고 영역을 변경해서 컴파일해봤지만 무수한 메모리릭은 그대로 나더라구요

그래서 cegui포럼을 검색해서 답을 찾았습니당...

 delete CEGUI::System::getSingletonPtr();

로  System의 싱글톤 클래스를 받아와서 해야되는거엿더구요 -ㅇ-;;;;킁

이걸해도 나는 메모리릭!!!!!!!!!!!!!!!!!!!!!!!!!!

누수추적해봣더니 Renderer에서 나오는 릭이엇습니다

고로  delete m_myRenderer; 를 해줬습니다     m_myRenderer는 CEGUI::DirectX9Renderer* 이고요 ㅎ

이랫더니 메모리 누수 빠이 빠이 ><

순서를 바꿔서 렌더러 부터 해제를 시켜봤더니 메모리 오류가 뜨더라구요.

System를 먼져 해제하면서 렌더러속에있는 텍스쳐를 먼져 삭제해주고 렌더링 객체를 삭제해야하는데

렌더링 객체부터 삭제하면 System이 렌더링객체속 텍스쳐를 삭제 못해줘서 뜨는듯 하더라구요

그러므로 System을 먼져 릴리즈후 렌더러를 릴리즈시켜주면 될꺼같네요

 

고로 정리하자면

 delete CEGUI::System::getSingletonPtr();      //CEGUI::System의 싱글톤 포인터를 받아와서 해제시킨다
 delete m_myRenderer;                                //CEGUI::DirectX9Renderer를 해제시킨다.

                                                               // delete는 System-> Renderer순으로

 

ps. 카테고리 선택하는데 cegui분석에 올릴려햇는데 않올려지네요 -ㅇ-;; 응용이라 할정도는 아니라서요;;

운영진님이 혹시 보신다면 글이동좀 부탁드릴꼐요 ㅠㅠ

반응형


[CEGUI] CEImagesetEditor 실행시 CEGUISILLYImageCodec_d 혹은 CEGUISILLYImageCodec 을 찾을 수 없다는 에러  기타 / 프로그래밍관련 

2010/11/10 10:52

복사http://blog.naver.com/saram95/90099853121


[CEGUI] CEImagesetEditor 실행시 CEGUISILLYImageCodec_d 혹은 CEGUISILLYImageCodec 을 찾을 수 없다는 에러
* 아래 기준이 되는 버젼
CEGUI-SDK-0.6.1
CEImagesetEditor-0.6.1

CEImagesetEditor 를 실행할 경우

Debug 모드일 경우
CEImagesetEditor:OnInit - Error: DynamicModule::DynamicModule - Failed to load module 'CEGUISILLYImageCodec_d': The specified module could not be found.

Release 모드일 경우
CEImagesetEditor:OnInit - Error: DynamicModule::DynamicModule - Failed to load module 'CEGUISILLYImageCodec': The specified module could not be found.

메세지가 뜬다.

이 경우 DLL 파일들을 찾지 못하는 경우이다.
$(CEGUI)\bin 폴더에있는 아래 DLL 파일들을 해당 폴더에 넣어주면 된다. 
Debug 모드 경우
$(CE_IMAGESET_EDITOR)\bin 의 Debug 설정 폴더 에 아래 파일들을 넣어준다.
- CEGUIBase_d.dll 
- CEGUIExpatParser_d.dll 
- CEGUIFalagardWRBase_d.dll 
- CEGUISILLYImageCodec_d.dll 
- CEGUITGAImageCodec_d.dll (technically not needed, but always a good idea) 
- OpenGLGUIRenderer_d.dll 
- SILLY_d.dll


Release 모드 경우
$(CE_IMAGESET_EDITOR)\bin 의 Release 설정 폴더 에 아래 파일들을 넣어준다.
- CEGUIBase.dll 
- CEGUIExpatParser.dll 
- CEGUIFalagardWRBase.dll 
- CEGUISILLYImageCodec.dll 
- CEGUITGAImageCodec.dll (technically not needed, but always a good idea) 
- OpenGLGUIRenderer.dll 
- SILLY.dll

* SILLY_d.dll 또는 SILLY.dll 이 CEGUI에 없을 경우
SILLY-0.1.0 와 같은 SDK 나 LIB 들을 다운 받아 넣어준다.
후에 사용될경우를 생각하여 $(CEGUI)\bin 에 같이 넣어주자

반응형

'프로그래밍(Programming) > GUI' 카테고리의 다른 글

CEGUI 한글설정  (0) 2012.12.02
CEGUI 메모리 해제(릴리즈)  (0) 2012.11.27
[CEGUI] DirectX9/Direct3D 에서 사용하기  (0) 2012.11.19
CEGUI 설치 및 CEGUI VC++ 설정  (0) 2012.11.19
Native WPF 4 PropertyGrid  (1) 2012.11.19




#ifdef _DEBUG
#pragma comment( lib, "CEGUIBase_d.lib" )
#pragma comment( lib, "CEGUIDirect3D9Renderer_d.lib" )
#else
#pragma comment( lib, "CEGUIBase.lib" )
#pragma comment( lib, "CEGUIDirect3D9Renderer.lib" )
#endif

이부분을제거하고  각각 Debug, Release 모드에 해당 lib 를 속성-링크-입력에서 넣어도 됨




[CEGUI] DirectX9/Direct3D 에서 사용하기  CEGUI / 게임개발 

2012/02/02 17:34

복사http://hsengine.co.kr/20149812028


 [CEGUI] DirectX/Direct3D 에서 사용하기

CEGUI를 DirectX/Direct3D/다이렉트/다이렉트X 에 이용해서 간단히 윈도우를 띄어보겠다. 

HSEngine을 이용하지만 DirectX와 사용하는게 같으니 수정해서 사용해야 한다. 

 

 

선언:

#include <CEGUI.h>
#include <RendererModules\Direct3D9\CEGUIDirect3D9Renderer.h>
#ifdef _DEBUG
#pragma comment( lib, "CEGUIBase_d.lib" )
#pragma comment( lib, "CEGUIDirect3D9Renderer_d.lib" )
#else
#pragma comment( lib, "CEGUIBase.lib" )
#pragma comment( lib, "CEGUIDirect3D9Renderer.lib" )
#endif
CEGUI::Direct3D9Renderer* myRenderer;
 
초기화:
    CEGUI::Direct3D9Renderer& myRenderer = CEGUI::Direct3D9Renderer::bootstrapSystem( HSE.m_pd3dDevice );
    CEGUI::Renderer *pRenderer = CEGUI::System::getSingleton().getRenderer();
    CEGUI::Direct3D9Renderer* Renderer = static_cast<CEGUI::Direct3D9Renderer*>(pRenderer);
    Renderer->postD3DReset();

    CEGUI::DefaultResourceProvider* rp = 
               static_cast<CEGUI::DefaultResourceProvider*>(CEGUI::System::getSingleton().getResourceProvider());

    rp->setResourceGroupDirectory("schemes", "datafiles/schemes/");
    rp->setResourceGroupDirectory("imagesets", "datafiles/imagesets/");
    rp->setResourceGroupDirectory("fonts", "datafiles/fonts/");
    rp->setResourceGroupDirectory("layouts", "datafiles/layouts/");
    rp->setResourceGroupDirectory("looknfeels", "datafiles/looknfeel/");
    rp->setResourceGroupDirectory("lua_scripts", "datafiles/lua_scripts/");


    CEGUI::Imageset::setDefaultResourceGroup("imagesets");
    CEGUI::Font::setDefaultResourceGroup("fonts");
    CEGUI::Scheme::setDefaultResourceGroup("schemes");
    CEGUI::WidgetLookManager::setDefaultResourceGroup("looknfeels");
    CEGUI::WindowManager::setDefaultResourceGroup("layouts");
    CEGUI::ScriptModule::setDefaultResourceGroup("lua_scripts");

    SchemeManager::getSingleton().create("TaharezLook.scheme");

    System::getSingleton().setDefaultMouseCursor("TaharezLook", "MouseArrow");

    WindowManager& winMgr = WindowManager::getSingleton();
    DefaultWindow* root = (DefaultWindow*)winMgr.createWindow("DefaultWindow", "Root");
    System::getSingleton().setGUISheet(root);

    FrameWindow* wnd = (FrameWindow*)winMgr.createWindow("TaharezLook/FrameWindow", "Demo Window");
    root->addChildWindow(wnd);
    wnd->setPosition(UVector2(cegui_reldim(0.25f), cegui_reldim( 0.25f)));
    wnd->setSize(UVector2(cegui_reldim(0.5f), cegui_reldim( 0.5f)));
    wnd->setMaxSize(UVector2(cegui_reldim(1.0f), cegui_reldim( 1.0f)));
    wnd->setMinSize(UVector2(cegui_reldim(0.1f), cegui_reldim( 0.1f)));
    wnd->setText("Hello World!");


    FrameWindow* wnd2 = (FrameWindow*)winMgr.createWindow("TaharezLook/FrameWindow", "Demo Window2");
    root->addChildWindow(wnd2);
    wnd2->setPosition(UVector2(cegui_reldim(0.0f), cegui_reldim( 0.0f)));
    wnd2->setSize(UVector2(cegui_reldim(0.5f), cegui_reldim( 0.5f)));
    wnd2->setMaxSize(UVector2(cegui_reldim(1.0f), cegui_reldim( 1.0f)));
    wnd2->setMinSize(UVector2(cegui_reldim(0.1f), cegui_reldim( 0.1f)));
    wnd2->setText("HSEngine");
 
키보드와 마우스관련 CEGUI로 넘겨주기:(직접짠 클래스에 맞게 되어있으므로 수정해야된다.)

float dt=HSE.dt; CEGUI::System * ceguiPtr = CEGUI::System::getSingletonPtr(); ceguiPtr->injectTimePulse( dt ); ceguiPtr->injectMousePosition(HSObject::m_HSInput.x, HSObject::m_HSInput.y); if(HSObject::m_HSInput.BtnDown(0)) CEGUI::System::getSingleton().injectMouseButtonDown(CEGUI::LeftButton); if(HSObject::m_HSInput.BtnDown(1)) CEGUI::System::getSingleton().injectMouseButtonDown(CEGUI::RightButton); if(HSObject::m_HSInput.BtnDown(2)) CEGUI::System::getSingleton().injectMouseButtonDown(CEGUI::MiddleButton); if(HSObject::m_HSInput.BtnUp(0)) CEGUI::System::getSingleton().injectMouseButtonUp(CEGUI::LeftButton); if(HSObject::m_HSInput.BtnUp(1)) CEGUI::System::getSingleton().injectMouseButtonUp(CEGUI::RightButton); if(HSObject::m_HSInput.BtnUp(2)) CEGUI::System::getSingleton().injectMouseButtonUp(CEGUI::MiddleButton);

반응형

블로그 이미지

3DMP engines

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

by 송정헌




CEGUI.sin 와 CEGUISamples.sin 의 각 프로젝트 전체에 아래와 같이 파일을 포함한다 




[include]

C:\CEGUI\include;C:\CEGUI\cegui\include;C:\CEGUI\cegui\include\elements;

C:\CEGUI\cegui\include\falagard;C:\CEGUI\cegui\include\RendererModules\Direct3D9



[lib]

C:\CEGUI\lib;C:\CEGUI\lib\dynamic;C:\CEGUI\lib\ReleaseWithSymbols;C:\CEGUI\lib\static



위의 것을 복사해 붙여넣고 다이렉트는 자신의 로컬경로에서 포함시키면 됨







[CEGUI] CEGUI 설치 및 CEGUI VC++ 설정  

2012/02/02 17:23

복사http://hsengine.co.kr/20149811131


 CEGUI 설치와 CEGUI VC++ 설정

 

cegui 설치방법과 cegui 설정하는 방법에 대해 설명하겠다.

CEGUI를 다운받기 위해 CEGUI 사이트에 접속한다.

 

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

 

 

 

Crazy Eddie's GUI System - Downloads 에서 최신버전을 클릭한다.

 

Library Source Downloads에서 운영체제에 맞는 소스코드를 다운받는다.

 

그리고 Binary Dependency Downloads for MSVC++에서 VC++버전에 맞는것을 찾아 다운받는다.

 

 

Library Source Downloads에서 다운받는 압축파일을 풀고. (예: C:\CEGUI)

 

Binary Dependency Downloads for MSVC++에서 받은 압축파일을 열어 dependencies 폴더안에 있는 파일들을 아까 압축푼곳에 압축을 풀어 덮어쓴다. 

 

이제 C:\CEGUI\projects\premake 로 이동한다.

 

여기서 오우거엔진이나 일리히트엔진에 이용할꺼면 config.lua 파일을 수정해야된다.

 

config.lua파일에 찾아보면 아래와 같은 내용이 있다.

 

자신에 맞게 직접 수정해주면 된다. (Direct3D9을 이용할꺼면 따로 수정하지 않아도 된다.)

 

그리고 오우거나 일리히트엔진은 따로 경로 설정을 해야된다.

 

 

이제  build_vs2008.bat 파일와 build_samples_vs2008.bat을 실행한다. (버전에 맞는걸로 실행)

 

 

 

 

그러면 CEGUI.sln, CEGUISamples.sln 파일이 생성된다.

 

열어서 빌드만 해주면 된다.

 

C:\CEGUI\bin 폴더에서 Samples 들을 실행해볼 수 있다.

 

 

VC++ 설정

 

 

lib

C:\CEGUI\lib

C:\CEGUI\lib\dynamic

C:\CEGUI\lib\ReleaseWithSymbols

C:\CEGUI\lib\static

 

include

C:\CEGUI\include

C:\CEGUI\cegui\include

C:\CEGUI\cegui\include\elements

C:\CEGUI\cegui\include\falagard

C:\CEGUI\cegui\include\RendererModules\Direct3D9 (여기서 Direct3D9 대신 Irrlicht, Ogre, OpenGL, Direct3D10 등.. 추가할 수 있다. 자신이 사용할것에 따라 설정한다.)

 

반응형

 

다운주소 http://www.codeproject.com/Articles/87715/Native-WPF-4-PropertyGrid

 

 

 

 


출처 : http://gamedevforever.tistory.com/211

 

 

 

툴의 꽃 프러퍼티 그리드를 사용해보자 ( PropertyGrid for WPF )

 
 
 

게임을 제작하게 되면 게임에 등장하는 여러 오브젝트들을 만들게 됩니다. 그런데 이 오브젝트들은 많은 속성 값을 가지게 됩니다. 위치라든가, 크기, 속도, 텍스쳐는 어느 것을 쓰는지, 이 객체에 쓰일 이펙트는 어떤 것인지 같은 것 말입니다. 보통 이런 속성 값들은 툴을 이용해 제어하게 됩니다. 그런데, 이 속성 값들을 지정해주기 위해서는 입력 필드가 필요하겠지요?

 

윈폼이나 WPF에서는 체크박스, 텍스트박스 같은 기본 컨트롤등이 제공되고 있습니다. 이 컨트롤들을 이용해 위에서 말한 속성 값들을 정의 할 수 있습니다. 하지만 많은 수의 속성 값들을 제어 하기에는 역부족입니다. 각각의 오브젝트들이 같은 속성 값을 가지고 있는 것도 아니고, 오브젝트 종류에 따라 많게는 수십가지의 속성 값을 필요로 하는데 이 많은 속성 값들을 위한 입력 필드들을 재구성하고, 추가하는 것을 만들라 하면 누구라도 멘붕이 올 것입니다.

 

벌써 부터 하기 싫어진다...

 

수많은 속성 값들을 손쉽게 제어할수 있는 컨트롤이 있으면 어떨까요? 게다가 제작도 간편해야 합니다. 툴을 만들때 딱! 하니 뙇! 하고 나와주면 얼마나 좋겠습니까? 그런데 그게 실제로 존재합니다.

 


ㅋㅋㅋㅋ

 

그게 무엇인지 알아보기 전에 다른 이름 있는 게임 엔진 툴들은 이것을 어떻게 처리 하고 있는지 한번 살펴 보죠.

 

 

 

 

 

내노라 하는 게임 엔진들을 보면 항상 보이는 놈이있죠. 직접 툴을 만들어 보시면서 사용해보신 분들도 계실겁니다. 바로 프로퍼티 그리드 ( Property Grid )죠. 이 프로퍼티 그리드는 그 이름 답게 수많은 속성 값들을 제어할수 있게 도와주는 아주 유용한 컨트롤입니다. 특히 이 프로퍼티 그리드가 유용한 이유 중 하나가 바로 다양한 타입의 값들을 제어 할수 있다는 것입니다.


툴에서 사용되는 많은 속성 값들은 타입이 제각각 입니다. 단순 불린 ( Boolean ) 타입 부터 정수, 실수는 물론이고, Point, Vector3/4, 16진수 컬러값까지 다양한 값들이 존재합니다. 프로퍼티 그리드는 이런 다양한 타입들을 한 곳에서 제어할수 있는 수단을 제공해주죠. 불린은 체크박스 형태로, 스핀 컨트롤로 정교한 실수값 설정, 브러시 컨트롤을 이용한 색 추출, 그리고 포인트나 벡터 같이 동시에 다수의 값들이 필요한 타입까지도 말이지요.

 

좋습니다. 그렇다면 어떻게 해야 이 프로퍼티 그리드라는 놈을 내가 만드는 툴에 뙇~ 하고 넣을 수 있을까요? 안타깝게도 이 프로퍼티 그리드라는 놈은 WPF에서 기본으로 제공해주는 컨트롤이 아닙니다.


이런 고자 같은 WPF 같으니...

 

그렇다면 어떻게 WPF에서 프로퍼티 그리드를 사용해야 하는가? 고맙게도 이미 많은 능력자 분들께서 WPF에서 프로퍼티 그리드를 사용할수 있게 만들어 공개해두셨습니다. MS도 참 웃긴게 비쥬얼 스튜디오 Visual Studio 에서도 사용 되는 컨트롤을 왜 기본으로 제공 안해주는지 모르겠습니다(블렌드 Blend 같은 툴 팔아먹으려고 그러는 것 같아요).

 

일단 제가 찾아서 사용해본 몇몇 프로퍼티 그리드등이 있는데, 각각 구현 방식도 다르고, 비쥬얼도 다르지만 가장 제대로 작동하고, 사용하기 쉬웠던 것은 Jaime Olivares 라는 분이 만드신 Native WPF 4 PropertyGrid 였습니다.

 

 

프로퍼티 그리드를 사용하기 위해서는 먼저 C#의 프로퍼티에 대해 알아야합니다. 이 프로퍼티 기능은 C++ 식으로 말하면 일종의 Getter/Setter 인터페이스라고 할수 있습니다. 소스를 보시면 쉽게 이해 되실 겁니다.

  1. public class Person  
  2. {  
  3.     public enum Gender { Male, Female }  
  4.   
  5.     private string m_strName;  
  6.     private int m_iAge;  
  7.     private Gender m_eGender;  
  8.   
  9.     public Person()  
  10.     {  
  11.         m_strName = "친절한티스";  
  12.         m_iAge = 21;  
  13.         m_eGender = Gender.Male;  
  14.     }  
  15.   
  16.     public string nameProp  
  17.     {  
  18.         set { m_strName = value; }  
  19.         get { return m_strName; }  
  20.     }  
  21.   
  22.     public int ageProp  
  23.     {  
  24.         set { m_iAge = value; }  
  25.         get { return m_iAge; }  
  26.     }  
  27.   
  28.     public Gender genderProp  
  29.     {  
  30.         set { m_eGender = value; }  
  31.         get { return m_eGender; }  
  32.     }  
  33. }  

멤버 변수는 private 으로 설정 되어있고, 그 멤버 변수에 대한 nameProp, ageProp, genderProp 프로퍼티들이 선언 되어있습니다. 외부에서 멤버 변수의 값을 쓰거나 읽을때 이 프로퍼티들을 이용하게 되죠.

  1. Person prop = new Person();  
  2. prop.nameProp = "김포프";  
  3. prop.ageProp = 22;  
  4. prop.genderProp = Person.Gender.Female;  

...이렇게 말이죠.

 

갑자기 C#의 프로퍼티 기능에 대해서는 왜 말하는 거지? 하고 의아해 하실 수 있는데, 프로퍼티 그리드가 바로 이 프로퍼티 기능을 이용하기 때문입니다. 게다가 무려 프로퍼티를 선언해 두면 프로퍼티 그리드에서 알아서 컨트롤에 생성을 해줍니다!!!!!!!

 

그렇다면 정말로 프로퍼티 그리드에 위의 속성값들이 나오는지 만들어보겠습니다. 두큰두큰~ 위에서 받은 WpfPropertyGrid.cs 파일을 프로젝트에 추가 해주고 아래 그림과 같이 프로젝트에 참조를 추가 해줍니다.

 

 

그리고 프로퍼티 그리드를 추가할 윈도우 xaml 파일을 열어 아래와 같이 추가해줍니다.

 

 

이제 프로퍼티 그리드에 표시해줄 속성 값을 가지고 있는 오브젝트를 생성해서 적용해주면 됩니다.
  1. public MainWindow()  
  2. {  
  3.     InitializeComponent();  
  4.   
  5.     Person prop = new Person();  
  6.     prop.nameProp = "김포프";  
  7.     prop.ageProp = 22;  
  8.     prop.genderProp = Person.Gender.Female;  
  9.   
  10.     // 프로퍼티 그리드에 적용  
  11.     propertyGrid1.SelectedObject = prop;  
  12. }  

끝입니다. 참쉽죠? 정말 제대로 나올까요? 한번 실행해보겠습니다.

 

 

22살의 아리따리운 미소녀 김포프 프로퍼티 그리드가 나타났습니다. 우왕~ 그런데 좀 이상하군요. 카테고리 분류도 없고, 속성값 이름도 프로퍼티 이름이 그대로 나옵니다. 다른 엔진 툴에서 사용되는 프로퍼티 그리드를 보면 카테고리도 잘 분류되어있고, 속성값 이름들도 그럴싸하게 명명되어 있는데 말이죠. 이를 바꿔주기 위해서는 C#의 Attributes를 이용해주어야 합니다.

  1. public class Person  
  2. {  
  3.     public enum Gender { Male, Female }  
  4.   
  5.     private string m_strName;  
  6.     private int m_iAge;  
  7.     private Gender m_eGender;  
  8.   
  9.     public Person()  
  10.     {  
  11.         m_strName = "박기헌";  
  12.         m_iAge = 31;  
  13.         m_eGender = Gender.Male;  
  14.     }  
  15.   
  16.     [Category("인적사항")]  
  17.     [DisplayName("이름")]  
  18.     public string nameProp  
  19.     {  
  20.         set { m_strName = value; }  
  21.         get { return m_strName; }  
  22.     }  
  23.   
  24.     [Category("인적사항")]  
  25.     [DisplayName("나이")]  
  26.     public int ageProp  
  27.     {  
  28.         set { m_iAge = value; }  
  29.         get { return m_iAge; }  
  30.     }  
  31.   
  32.     [Category("기타등등")]  
  33.     [DisplayName("성별")]  
  34.     public Gender genderProp  
  35.     {  
  36.         set { m_eGender = value; }  
  37.         get { return m_eGender; }  
  38.     }  
  39. }  

Category와 DisplayName Attributes를 추가 하였습니다. 어떻게 바뀌었을까요?



카테고리가 생겼고, 속성 값명도 지정해준대로 잘 나옵니다. 짝짝짝~~...계속
( 예상보다 내용이 너무 길어져서... 상하로 나눠서 써야 할것 같군요. 진짜 연재가 되어버렸네... )







 

 

지난 글에서 WPF에 프로퍼티 그리드를 적용하는 방법을 살펴 보았습니다. 이 것으로 다양한 속성 값들을 툴에서 컨트롤 할수 있게 되었죠. 그런데 앞서 언급했던 것처럼 여러 속성 값들의 타입이 각자 제각각입니다. 그 중 많이 쓰이는 타입 중 하나가 벡터3 ( Vector3 )이 있습니다. 위치를 나타낼때 많이 쓰이는 이 타입의 값을 프로퍼티 그리드에서 어떻게 표시해야 될까요? 아마 밑의 그림과 같이 표시할 수도 있을 겁니다.

 

 

벡터3의 x, y, z 성분들을 각각 하나의 값으로 보고 값을 입력 받을수 있도록 하는 것이죠. 하지만 벡터3의 타입이 많이 쓰이게 된다면 관리 해야될 속성값이 기하급수적으로 늘어나게 될 것입니다. 다른 방법은 없을까요?

 

보통 엔진단에서 보면 벡터를 하나의 타입으로 간주하고 사용을 합니다. 툴에서도 같은 식으로 써야 논리적으로 맞을것 같습니다. 벡터 클래스를 하나 만들기로 하죠.

  1. // 간단한 벡터3 타입 클래스  
  2. public class Vector3  
  3. {  
  4.     public float m_fX;  
  5.     public float m_fY;  
  6.     public float m_fZ;  
  7.   
  8.     public Vector3()  
  9.     {  
  10.         m_fX = 0;  
  11.         m_fY = 0;  
  12.         m_fZ = 0;  
  13.     }  
  14. }  

그리고 이 클래스를 프로퍼티 그리드에 등록하겠습니다.

  1. // 중복 코드는 생략  
  2. public class Person  
  3. {  
  4.     private Vector3 m_vLocate;  
  5.   
  6.     [Category("기타등등")]  
  7.     [DisplayName("위치")]  
  8.     public Vector3 locProp  
  9.     {  
  10.         set { m_vLocate = value; }  
  11.         get { return m_vLocate; }  
  12.     }  
  13. }  

한번 실행해 보죠.

 

 

프로퍼티 그리드에 등록은 되는 것 같습니다. 하지만 값을 입력할라 치면, 아래와 같은 오류 메시지가 뜹니다.

 

 

이유는 입력한 값을 Vector3 타입으로 변환 할수 없기 때문입니다. 즉, 입력한 값 ( 보통 문자열 )에서 Vector3 타입으로 변환해 줄수 있는 변환기가 필요하다는 것 입니다. 그렇다면 변환기를 만들어주도록 하죠.

  1. // Vector3 변환기  
  2. public class Vector3Convter : TypeConverter  
  3. {  
  4.     // string 으로 부터 변환이 가능한가?  
  5.     public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)  
  6.     {  
  7.         if (sourceType == typeof(string))  
  8.         {  
  9.             return true;  
  10.         }  
  11.         return base.CanConvertFrom(context, sourceType);  
  12.     }  
  13.   
  14.     // string 으로 부터 vector3로 변환  
  15.     public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)  
  16.     {  
  17.         if (value is string)  
  18.         {  
  19.             string[] v = ((string)value).Split(new char[] { ',' });  
  20.             return new Vector3(float.Parse(v[0]), float.Parse(v[1]), float.Parse(v[2]));  
  21.         }  
  22.         return base.ConvertFrom(context, culture, value);  
  23.     }  
  24.   
  25.     // vector3 에서 string으로 변환  
  26.     public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType)  
  27.     {  
  28.         if (destinationType == typeof(string))  
  29.         {  
  30.             return ((Vector3)value).m_fX + "," + ((Vector3)value).m_fY + "," + ((Vector3)value).m_fZ;  
  31.         }  
  32.         return base.ConvertTo(context, culture, value, destinationType);  
  33.     }  
  34. }  

변환기를 만들어 주기 위해서는 TypeConver 클래스를 상속 받아 CanConvertFrom, CanvertFrom, CanConvertTo, ConvertTo 4가지 함수를 재정의 해주어야 합니다. 여기서는 CanConvertTo가 그닥 필요치 않아 생략 되었습니다( 자세한 내용은 MSDN 참조 ). 변환기 클래스를 만들었으면 이제 벡터3 프로퍼티에 변환기를 등록해줍니다.

  1. // 중복 코드는 생략  
  2. public class Person  
  3. {  
  4.     private Vector3 m_vLocate;  
  5.   
  6.     [Category("기타등등")]  
  7.     [DisplayName("위치")]  
  8.     [TypeConverter(typeof(Vector3Convter))] // 변환기 등록  
  9.     public Vector3 locProp  
  10.     {  
  11.         set { m_vLocate = value; }  
  12.         get { return m_vLocate; }  
  13.     }  
  14. }  

이제 프로퍼티 그리드에서 벡터3 타입이 제대로 입출력 되는지 확인해보도록 하죠.


 

 

 

실행을 해보니 벡터3의 기본값인 0, 0, 0이 출력됩니다. 그리고 10, 55, 38을 입력하면, 아까와 같은 오류 없이 제대로 입력이 됩니다. ( 그외 맞지 않는 문자열등이 입력될 때를 대비해 변환기에서 예외처리를 해주면 좋습니다 )

 

이처럼 변환기를 통해 기본 타입 이외의 타입들을 관리 할수 있는 방법을 알아봤습니다. 하지만 여기서 좀더 유저 편의성을 높일수 있는 방법이 있습니다. 예로 특정 정수값이 있는데, 이 값은 0 ~ 100까지 값을 가집니다. 그런데 이 값을 직접 입력받는 것이 아니라 슬라이더 컨트롤러(Slider)를 이용해 값을 정할수 있다면 어떨까요? 사용자 입장에서도 꽤나 편리 할것 같습니다.
프로퍼티 그리드에 기본적으로 제공되는 기본 컨틀롤러 이외의 커스텀 컨트롤러를 추가하는 방법을 알아보겠습니다. 위에 이야기한 슬라이더 컨트롤러를 추가해보도록 하죠.
  1. public class CustomSlider : ExtendedPropertyValueEditor  
  2. {  
  3.     public CustomSlider()  
  4.     {  
  5.         // Template for normal view  
  6.         string template1 = @"  
  7.             <DataTemplate  
  8.                 xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'  
  9.                 xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'  
  10.                 xmlns:pe='clr-namespace:System.Activities.Presentation.PropertyEditing;assembly=System.Activities.Presentation'   
  11.                 xmlns:wpg='clr-namespace:PropertyGrid;assembly=PropertyGrid' >   
  12.                 <DockPanel LastChildFill='True'>  
  13.                         <TextBox Text='' Width='40' TextAlignment='Center' />  
  14.                         <Slider x:Name='slider1' Value='' Margin='2,0,0,0' Minimum='' Maximum='' />  
  15.                 </DockPanel>  
  16.             </DataTemplate>";  
  17.   
  18.         // Load templates  
  19.         using( var sr = new MemoryStream( Encoding.UTF8.GetBytes( template1 ) ) )  
  20.         {  
  21.             this.InlineEditorTemplate = XamlReader.Load( sr ) as DataTemplate;  
  22.         }  
  23.     }  
  24. }  
먼저 ExtendedPropertyValueEditor 클래스를 상속 받아 CustomSlider 클래스를 만듭니다. 그 다음 XAML을 통해 슬라이더 컨트롤러 DataTemplate을 구성합니다. 여기서 끝이 아닙니다. 이 컨트롤러와 바인딩할 객체가 있어야합니다. 즉, 슬라이드를 움직이면 그 슬라이더 값이 저장될 곳이 있어야 합니다. 위 코드를 보면 미리 Binding Value.xxx 형태로 바인딩이 적용되어있습니다. 
슬라이더 컨트롤러의 경우 현재값, 최소값, 최대값, 단계값 총 4개의 값이 필요합니다. 이를 위해 따로 슬라이더 컨트롤러를 위한 클래스를 하나 정의해주도록 하겠습니다.
  1. public class SliderValue<T>  
  2. {  
  3.     public SliderValue(T value, T min, T max, T step)  
  4.     {  
  5.         Value = value;  
  6.         Min = min;  
  7.         Max = max;  
  8.         Step = step;  
  9.     }  
  10.   
  11.     public T Value { getset; }  
  12.     public T Max { getset; }  
  13.     public T Min { getset; }  
  14.     public T Step { getset; }  
  15. }  
이제 실제로 슬라이더 컨트롤러를 프로퍼티 그리드에 사용해보도록 하겠습니다.
  1. // 중복 코드 생략  
  2. public class Person  
  3. {  
  4.     private SliderValue<int> m_iAge;  
  5.   
  6.     public Person()  
  7.     {  
  8.         m_iAge = new SliderValue<int>(22, 0, 100, 1);  
  9.     }  
  10.   
  11.     [Category("인적사항")]  
  12.     [DisplayName("나이")]  
  13.     [Editor(typeof(CustomSlider), typeof(PropertyValueEditor))]  
  14.     public SliderValue<int> ageProp  
  15.     {  
  16.         set { m_iAge = value; }  
  17.         get { return m_iAge; }  
  18.     }  
  19. }  


실제 슬라이더 컨트롤러가 적용된 스샷입니다. 슬라이더를 움직이면 0 부터 100까지 값을 조절할수 있고, 직접 값을 입력하면 슬라이더 컨트롤러도 같이 움직이는 것을 확인할 수 있습니다. 단, 직접 입력시에는 0~100까지 제한이라는 예외처리가 안되어있기 때문에 이를 위해서는 추가 작업을 해주어야 합니다.
위의 슬라이더 컨트롤러 XAML을 살펴보면 UpdateSourceTrigger=PropertyChanged 라는 구문이 있습니다. 이는 값이 변경 되었을때 PropertyChanged 이벤트를 날려주기 위함이지요. 이 이벤트를 받는 방법을 구현해보도록 하겠습니다. 

PropertyChanged 이벤트를 받기 위해서는 INotifyPropertyChanged 클래스를 상속 받아야 합니다. 앞서 구현한 SliderValue 클래스를 조금 수정하도록 하겠습니다.

  1. // 중복 코드 생략  
  2. public class SliderValue<T> : INotifyPropertyChanged  
  3. {  
  4.     private T mValue;  
  5.     public T Value  
  6.     {  
  7.         get  
  8.         {   
  9.             return mValue;  
  10.         }  
  11.         set  
  12.         {  
  13.             mValue = value;  
  14.             OnPropertyChanged("Value");  
  15.         }  
  16.     }  
  17.  
  18.     #region INotifyPropertyChanged Members  
  19.     public event PropertyChangedEventHandler PropertyChanged;  
  20.     private void OnPropertyChanged(String info)  
  21.     {  
  22.         if (PropertyChanged != null)  
  23.         {  
  24.             PropertyChanged(thisnew PropertyChangedEventArgs(info));  
  25.         }  
  26.     }  
  27.     #endregion  
  28. }  

이제 슬라이더 컨트롤러를 통해 값이 변경 되면 PropertyChanged 이벤트를 받을수 있게 되었습니다. 슬라이더 컨트롤러를 사용하는 Person 클래스에 슬라이더 컨트롤러의 PropertyChanged 이벤트를 받을수 있는 콜백 함수를 등록 하면 슬라이더 컨트롤러의 값이 변경 되었을 때의 작업을 수행할 수 있습니다.

  1. public class Person  
  2. {  
  3.     public Person()  
  4.     {  
  5.         m_iAge = new SliderValue<int>(22, 0, 100, 1);  
  6.         m_iAge.PropertyChanged += new PropertyChangedEventHandler(SliderPropChanged);  
  7.     }  
  8.   
  9.     // CustomSlider에서 값이 변경 되었다~  
  10.     private void SliderPropChanged(object sender, PropertyChangedEventArgs e)  
  11.     {  
  12.         if (e != null)  
  13.         {  
  14.         }  
  15.     }  
  16. }  
  17.  

 

 

반응형

+ Recent posts