한국어
Qt
 

얼마전 Qt 3D Studio 1.0이 정식으로 릴리즈되었는데 간단히 소개하고자한다.

 

3D Studio는

현대적인 3D GUI를제공하는 어플리케이션을 구현하기위해 3D 디자인 + 소프트웨어 개발을 위한 도구이다.Qt3DStudio.jpg

3D Studio와 함께 Viewer를 통해 실시간으로 3D UI를 확인 할 수 있어서 빠르고 쉽게 개발이 가능하다.

3D Studio는 또 함께 제공되는 다양한 라이브러리 및 Photoshop, Maya, MODO 등에서 모델링된 .dae형식(COLLADA (COLLAborative Design Activity))이나 FBX 파일을 가져와 사용할 수 있다. (Open Source로는 블렌더가 있다!)

또한 QtQuick이나 Qt프레임워크의 다른 모듈과 통합할 수 있어서 어플리케이션 기능 확장도 용이하도록 설계되었다.

 

지원 플랫폼으로는 

현재 1.0 기준으로 Windows, Mac, Linux에서 사용할 수 있는데, 다만 리눅스의 경우 미리 컴파일된 바이너리는 아직 제공되지 않으므로 소스크드를 직접 컴파일해야한다.

 

2017년 11월에 1.0 릴리즈 이후 2.0 릴리즈를 2018년 5월 경에 할 예정이고 NVIDIA 렌더링 엔진을 탑재하고 새로운 기능과 개선이 있을거라고 한다. 사용자 측면에서는 1.0에서 개발된 산출물을 2.0에서 사용 못하는건 아니라고 하니 안심해도 될듯하다. (2.0에서 Qt3D 기반의 엔진이 탑재)

 

오픈 소스 사용자의 경우 Qt 3D Studio Editor와 Runtime이 GPLv3 라이센스가 적용된다.

 

Qt 3D Studio 시작

윈도우즈의 경우 온라인 설치프로그램을 통해 바이너리를 제공하지만 필자의 경우 소스코드를 직접 컴파일하였다.

 

git이 설치되어 있다면 아래의 명령으로 복제하여 소스코드를 받을 수 있다.

git clone --recursive https://codereview.qt-project.org/qt3dstudio/qt3dstudio

 

직접 컴파일시에는 빌드지침을 따르도록 한다.

 

예제 어플리케이션

아래 주소는 위에 보이는 클러스터 예제 소스코드 저장소이다. 

https://git.qt.io/public-demos/qt3dstudio.git

 

몇가지 중요 개념들

 

Qt 3D Studio에서 프로젝트를 생성하면 .uia파일과 .uip파일이 만들어 지는데 각각 어플리케이션과 프레젠테이션 파일을 뜻한다.

이 두가지 개념은 매우 중요한데 어플리케이션은 프로젝트의 진입점으로 프로젝트의 루트에 오직 하나만 존재하여 아래 여러 프레젠테이션을 참조할 수 있도록 해준다. 아래는 간단한 예제 프로젝트를 만든것인데 .uia파일을 에디터로 열어보면 XML형식으로 작성됨을 알 수있고 .uip 파일 정보를 담고있다. 

<?xml version="1.0" encoding="UTF-8"?>
<application xmlns="http://qt.io/qt3dstudio/uia">;
    <assets initial="second">
        <presentation id="second"    src="second.uip"/>
    </assets>
    <statemachine ref="#logic">
        <visual-states>
            <state ref="Initial">
                <enter>
                    <goto-slide element="main:Scene" rel="next"/>
                </enter>
            </state>
        </visual-states>
    </statemachine>
</application>

 

프레젠테이션은 실제 개발자가 Studio를 이용하여  다른 모델링툴로 생성된 2D, 3D 어셋을 포함거나 애니메이션, 어떤 액션들을 구성하고 하나 이상의 레이어를 합성하여 화면을 구성하는 파일이다. 프레젠 테이션은 하위 여러 프레젠테이션을 참조하여 구성하는 것도 가능하다. 

 

아래는 .uip파일의 XML코드인데 실제 화면 구성에 필요한 정보들이 존재한다. QML과 통합하여 어플리케이션을 개발할 때 각 요소의 path로 접근하여 런타임시에 각 요소의 속성을 바꾸는 것도 가능하다.
<?xml version="1.0" encoding="UTF-8" ?>
<UIP version="3" >
    <Project >
        <ProjectSettings author="" company="" presentationWidth="800" presentationHeight="480" maintainAspect="False" >
            <CustomColors count="16" >#ff5500 #ffffff #ffffff #ffffff #ffffff #ffffff #ffffff #ffffff #ffffff #ffffff #ffffff #ffffff #ffffff #ffffff #ffffff #ffffff</CustomColors>
        </ProjectSettings>
        <Classes >
            <Effect id="Corona" name="Corona" sourcepath="effects/Corona.effect" />
            <Behavior id="CameraLookAt" name="CameraLookAt" sourcepath="scripts/CameraLookAt.qml" />
        </Classes>
        <Graph >
            <Scene id="Scene" >
                <Behavior id="CameraLookAt_001" class="#CameraLookAt" />
                <Layer id="Layer" >
                    <Camera id="Camera" />
                    <Light id="Light" />
                    <Effect id="Corona_001" class="#Corona" />
                    <Component id="RoundedCube" >
                        <Model id="RoundedCube_001" >
                            <Material id="Default" name="Default" />
                        </Model>
                    </Component>
                </Layer>
            </Scene>
        </Graph>
        <Logic >
            <State name="Master Slide" component="#Scene" >
                <Add ref="#Layer" />
                <Add ref="#Camera" />
                <Add ref="#Light" />
                <State id="Scene-Slide1" name="Slide1" playmode="Looping" >
                    <Add ref="#CameraLookAt_001" name="CameraLookAt" >
                        <Action id="CameraLookAt-Action" eyeball="True" triggerObject="" event="onPressureDown" targetObject="#CameraLookAt_001" handler="start" />
                    </Add>
                    <Add ref="#Corona_001" name="Corona" />
                    <Add ref="#RoundedCube" name="RoundedCube" >
                        <AnimationTrack property="rotation.x" type="EaseInOut" >0 0 100 100 2.3571 0 100 100 10 0 100 100</AnimationTrack>
                        <AnimationTrack property="rotation.y" type="EaseInOut" >0 0 100 100 2.3571 42 100 100 10 0 100 100</AnimationTrack>
                        <AnimationTrack property="rotation.z" type="EaseInOut" >0 0 100 100 2.3571 56 100 100 10 0 100 100</AnimationTrack>
                    </Add>
                </State>
            </State>
            <State name="Master Slide" component="#RoundedCube" >
                <Add ref="#RoundedCube_001" name="RoundedCube" edgetess="4" endtime="5000" locked="False" pivot="0 0 0" rotation="0 0 0" sourcepath="models/RoundedCube-1/meshes/RoundedCube.mesh" tessellation="None" />
                <Add ref="#Default" locked="False" />
                <State id="RoundedCube-Slide1" name="Slide1" />
            </State>
        </Logic>
    </Project>
</UIP>


아래 QML코드는 마우스 클릭 시 "second" 프레젠테이션에 존재하는 "RoundedCube"의 Material 요소에 접근하여 색상을 바꾸는 간단한 예제 코드이다. 

import QtQuick 2.6
import QtQuick.Window 2.2
import QtStudio3D 1.0
Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")
    property bool greenTheme: false
    Studio3D{
        anchors.fill: parent
        Presentation {
            id: cluster
            source: "qrc:/second/second.uia"
            Element{
                id: cubeMaterial
                elementPath: "second:Scene.Layer.RoundedCube.RoundedCube.Default"
            }
        }
    }
    MouseArea{
        anchors.fill: parent
        onClicked: {
            if(greenTheme)
            {
                cubeMaterial.setAttribute("diffuse.r", 1.0);
                cubeMaterial.setAttribute("diffuse.g", 1.0);
                cubeMaterial.setAttribute("diffuse.b", 1.0);
                greenTheme = false
            }
            else
            {
                cubeMaterial.setAttribute("diffuse.r", 0.0);
                cubeMaterial.setAttribute("diffuse.g", 0.666667);
                cubeMaterial.setAttribute("diffuse.b", 0.0);
                greenTheme = true
            }
        }
    }
}

 

cubeMaterial을 통해 RoundedCube의 Material에 접근가능하다. 참고로 elementPath를 알아내기 쉬운 방법이 있는데 3D Studio의 Layer Pallete에서 특정 요소의 마우스 오른쪽 버튼 메뉴의 "Copy Object Path" 항목을 클릭하면 path가 클립보드로 복사된다. 
copyObjectPath.png

 

프레젠테이션은 하나 이상의 레이어를 구성하여 만들어 지는데 레이어는 하위 레이어의 내용위에 그려지는 상위 레이어와 합성되어 프레젠테이션의 시각적 결과가 만들어 진다.
 
프레젠테이션의 구성요소에는 또 슬라이드라는 것이 존재하는데 이것은 마이크로소프트사의 파워포인트를 생각하면 이해하기 쉽다. 파워포인트의 슬라이드 처럼 각 슬라이드에 전혀 다른 콘텐츠를 구성하거나 미세한 변화, 애니메이션 효과를 줄 수 도있다. 
슬라이드를 추가 하려면 오른쪽 마우스 버튼을 클릭하여 "New Slide"를 클릭하거나 기존에 존재하는 슬라이드를 복사하면되고 프로젝트 palette나 액션 palette 의 각 요소들을 슬라이드에 추가하여 구성한다.
여러 슬라이드 간에 미묘한 변화를 일으키는 컨텐츠를 만들려면 모든 슬라이드에 존재하는 요소가 필요한데 이를 위해 마스터 슬라이드가 하나씩 존재한다. 이 슬라이드에 배치된 요소는 모든 슬라이드에 존재하게된다.
다만 이 경우 요소들의 속성들이 마스터 슬라이드에 연결되어 있어서 다른 슬라이드의 요소에 영향을준다.
특정 슬라이드 요소의 속성만을 변경하고자 한다면 속성의 연결을 해제해야 하는데 Inspector palette의 각 속성에서 마우스 오른쪽 버튼을 클릭하여 "Unlink Property from Master Slide" 항목을 선택하면 된다.
 
아래는 간단하게 QML과 통합된 형태로 구현된 예제이다.
소스코드 -> Qt3D_Example.7z 또는 git@gitlab.com:pjk1985/Qt3DStudioExample.git
QML로 통합하여 텍스트 요소의 속성을 다국어 처리하는 방법은 다국어 어플리케이션 개발 문서를 참조하자. 
 

Qt3DStudio_Example.png

 

번호 제목 글쓴이 날짜 조회 수
공지 Qt프로그래밍(QtQuick) Beginner를 위한 글 읽는 순서 운영자 2019.01.05 92381
20 Windows환경에서 mingw로 Qt 5.10 정적(static)빌드 file makersweb 2018.02.01 6688
19 다국어 지원 어플리케이션 개발 file makersweb 2018.01.27 4170
18 Qt 어플리에이션 전역에 폰트 설정 makersweb 2018.01.24 7043
» Qt 3D Studio 시작하기 file makersweb 2018.01.11 4863
16 QPA 플러그인과 HTML5 Backend file makersweb 2017.12.27 1968
15 임의의 메모리 영역(QImage)에 QPainter를 이용하여 그리기 file makersweb 2017.12.19 4868
14 QML에서 undefined를 확인하는 방법 makersweb 2017.11.29 2678
13 QPA 플러그인과 EGLFS file makersweb 2017.11.21 5588
12 타임스탬프( timestamp) 유닉스 시간 makersweb 2017.10.19 3155
11 Qt Logging Rule, Qt 프레임워크 로그 출력 makersweb 2017.01.13 5669
10 QString 문자열에서 숫자만 추출해서 QString으로 반환 makersweb 2017.01.10 4951
9 멀티 스레드환경, 스레드에 안전한 이벤트처리 makersweb 2016.10.27 6157
8 Ubuntu Linux에서 Qt Creator 설치 file makersweb 2016.03.06 12343
7 QtConcurrent를 이용하여 쓰레드를 만드는 방법과 MapReduce file makersweb 2016.01.24 10403
6 Qt 프로그래밍의 시작 makersweb 2015.10.25 16126
5 Qt의 스레드간 시그널 슬롯의 커넥션타입 [1] makersweb 2015.10.24 12118
4 Qt의 시그널 슬롯 시스템 file makersweb 2015.10.20 26162
3 QQuickImageProvider 를 이용한 Qml 에서 이미지 표시 makersweb 2015.10.18 7117
2 Qml 사용자 ScrollBar 구현 file makersweb 2015.07.24 7653
1 z-order 를 컨트롤 하기위한 방법 makersweb 2015.05.13 8212