1   2   3
Ім'я файлу: Курсова (3) (1).docx
Розширення: docx
Розмір: 2331кб.
Дата: 27.01.2023
скачати
Пов'язані файли:
Кишеньковий довыдник.doc

Міністерство освіти і науки України

Львівський національний університет імені Івана Франка

Факультет електроніки та комп’ютерних технологій

Кафедра радіоелектронних та комп’ютерних систем

Курсова робота

з курсу «КРОС-ПЛАТФОРМНЕ ПРОГРАМУВАННЯ»

на тему:

Розробка 3д графіки у крос-платформному середовищі Qt

Виконав:

студент групи ФеІ – 24

спеціальності 122 – Комп’ютерні науки

_________________Юрасов В. Д.

Науковий керівник:

______________ ас. Гура В. Д.

«____» ___________2022 р.

Львів 2022

Анотація

Комп’ютерна графіка використовується у всіх галузях технологій:

  • фізика (дослідження поверхонь)

  • хімія (візуалізація хімічних процесів та структур)

  • математика (малювання графіків та візуалізація даних)

  • т. д.

З подальшим розвитком технологій збільшувалась і кількість сфер застосування комп’ютерної графіки. Нині одною з найпопулярніших є застосування 3D графіки у іграх. Кожен, так чи інакше, бачив або грав у різні комп’ютерні або мобільні ігри. У більшості з них використовують саме 3D графіку, у зв’язку з її простотою з урахуванням існуючих програм для моделювання та використання 3D моделей.

Але важливо розуміти і основи даної технології, що я і демонструю у даній курсовій роботі.

У цій курсовій роботі було розглянуто способи створення крос-платформних додатків з використанням комп’ютерної 3D графіки на різних мовах програмування на основі фреймворка Qt. Створено сцену з використанням об’єктів, створенних з примітивних фігур, світла, та скайбоксу. Для програмування було використано 2 мови: C++ та QML.

Annotation

Nowadays computer graphics is used in large number of different scientific works:

  • Physics (different processes and circuits)

  • Chemistry (visualization of chemistry processes and structures)

  • Math (data visualization and diagrams)

  • Etc.

With the further development of technologies, the number of fields of application of computer graphics also increased. Currently, one of the most popular is the use of 3D graphics in games. Everyone, one way or another, has seen or played various computer or mobile games. Most of them use 3D graphics, due to its simplicity and big variety of existing programs for modeling and usage of 3D models.

However, it is important to understand the basics of this technology, which I demonstrate in this course work.

In this course work, I researched ways to create cross-platform applications using computer 3D graphics in various programming languages ​​based on the Qt framework. Scene was created with usage of objects created from primitive shapes, light, and skybox. Two languages ​​were used for programming: C++ and QML.

Зміст

Вступ……………………………………………………………………5

1. Створення проекту………………………………………………...7

1.1 Створення проекту на С++……………………………………...7

1.2 Створення проекту на QML…………………………………....21

2. Результати проекту……………………………………………….24

Висновок……………………………………………………………...25

Список літератури…………………………………………………..26

Додатки……………………………………………………………….27

В ступ



Рисунок 1
Для розробки програмного забеспечення для даної курсової роботи було використано IDE (Integrated Development Environment – інтегроване середовище розробки) Qt Creator та фреймворк Qt 5 версії, оскільки разом з ним в комплекті йде модуль Qt3D, який створений для полегшання роботи з графікою за рахунок автоматизації деяких процесів. Дане середовище використовується для розробки та компіляція програми на різні платформи. Велика кількість відомих компаній мають продукти, які були розроблені за допомоги Qt:

  • KDE PLASMA

  • Unity 2D

  • Lumina

  • SDDM

Також Qt Creator дозволяє емулювати різні середовища, такі як Android, Linux, iOS. У даній курсовій було використано 2 мови програмування, С++ та QML. Обидві підтримуються середовищем зразу, без необхідності встановлювати додаткові розширення, як, наприклад, для розробки на пайтон необхідно довстановлювати бібліотеку pyqt необхідної версії.

С++ – мова програмування, яка підтримує декілька парадигм програмування: об’єктно, узагальнено та процедурно орієнтовану. У даному проекті я використав об’єктно орієнтовану частину даної мови. Вона проявляється у інкапсуляції власних методів та змінних та в унаслідуванні власних класів від заданих абстрактних класів.

QML – декларативна мова програмування, заснована на JavaScript, та призначена для створення користувацького інтерфейсу. Вона є частиною Qt Quick, середовища розробки користувацьких інтерфейсів поширюваного разом з Qt. Але у даному проекті вона була використана для зберігання сутностей об’єктів, які потім відображались на формі.

  1. Створення проекту

Оскільки в обох випадках ми будемо використовувати одинакове IDE та фреймворк, то багато аспектів розробки на обох мовах будуть співпадати. Тому спочатку розглянемо загальний процес розробки на прикладі мови С++, а потім підмітимо усі відміності при розгляді проекту на мові QML.

    1. Створення проекту на мові С++

Розглянемо особливості створення нашого проекту на мові C++.

Для початку нам потрібно створити сам проект. Для цього потрібно обрати відповідну кнопку на головній сторінці Qt Creator’а, або скачати його з офіційного сайту, якщо його у вас немає.



Рисунок 2

Серед даних варіантів вибираємо Qt Widget Application, який створить нам проект з пустою формою. Але оскільки ми не будемо використовувати стандарту форму, то при створені вибираємо не створювати її. Також важливо вибрати Qmake для створення .pro файлу, це мультиплатформний файл проекту, який qmake буде перетворювати на makefile конкретної платформи. Також потрібно змінити базовий клас з QMainWindow на QWidget. Інші налаштування можна вибирати на свій розсуд.




Рисунок 3-5

Перед нами відкриється стандартний проект, який містить у собі родин файл .cpp, один заголовочний файл та файл проекту, заходимо у нього та змінюємо перший рядок, замість бібліотеки gui підключимо 3dcore, 3dextra, 3drender та 3dinput. Застосування кожної бібліотеки ми побачимо незабаром. Після цих дій наш .pro файл має починатись з такого :



Рисунок 6

Далі необхідно змінити похідний клас на QguiApplication та замінити використовану бібліотеку на відповідну.



Рисунок 7

Тепер підготовки завершені і можан приступати до створення самого проекту. У першу чергу нам необхідно викликати саме вікно, для цього необхідно використати елемент бібліотеки Qt3Dextras, а іменно Qt3DWindow. Гарною практикою вважається підключення лишн необхідних елементів бібліотек, натомість усією. Я використовував даний принцип на протязі створення усієї програми, тому, щоб не показувати імпортований елемент кожен раз, знизу наведено усі експортовані елементи бібліотек.



Рисунок 8

Тепер запустивши нашу програму ми побачимо пусте вікно. Час добавити до нього примітивів, для прикладу я взяв тор. Щоб добавити його підключаємо відповідний елемент, заодне підключаємо Qtransform та QPhongmaterial який будемо використовувати при створені кожного наступного примітиву, це класи які використовуються відповідно для задання об’єкту положення у просторі (його координати та кут нахилу) та для надання об’єкту відблиску з можливістю змінювати його колір та колір самого об’єкту, він по суті є наперед заданою версією звичайного Qmaterial.

Особливу увагу слід звернути на елемент QEntity, оскільки на ньому буде грунтуватись уся ієрархія нашого проекту. Саме поняття сутності (Entity) у програмуванні означає об’єкт, який є набором первних компонентів і даних.



Рисунок 9

У Qt сутності відіграють ще одну, не менш важливу роль, при видаленні нашого проекту, наприклад при його завершенні, об’єкти будуть видалятися по ієрархії сутностей, тому важливо створити основний, так званий rootEntity, який будемо заповняти нашими об’єктами, які у свою чергу теж є сутностями, зі своїм наповненням. Видалення буде видалятися по принципу від віток до коріння, тобто спочатку видаляються усі об’єкти усередину нашої корінної сутності а вже в кінці і вона сама. Такий метод дозволяє більш ефективно звільняти пам’ять яку ці об’єкти використовують.

З метою дотримання даного принципу я створив головну сутність rootEntity, яку я заповнюю результатом функції CreateScene() у якій ми і будемо створювати саму сцену. Таким методом правильність ієрархії буде легко дотримуватися.

Для можливості бачити створені нами примітиви необхідно створити камеру, у якій ми настоюємо ‘лінзу’, іншими словами виставляємо початкову точку в яку дивиться камера, та її перспективу.

Повернемося до нашого тора, усередині створеної функції CreateScene() оголошуємо нову сутність для нашого примітиву, ми будемо створювати його для кожного окремого об’єкту сцени, тому більше уваги на ньому акцентуватись не буде. Потім оголошуємо відповідно Qtransform, QphongMaterial та QtorusMesh, це особливий клас, який містить у собі декілька функцій для полегшання створення тора, мінусом його є те, що ми не маємо доступу до кожної його точки окремо, якщо ж ми хочемо мати таку можливість, то нам потрібно вибрати клас QtorusGeometry натомість, але оскільки завданням даної курсової є лише знайомство з 3D графікою, то використовувати надалі ми будемо іменно Mesh, але важливо знати що у вас є можливість змінювати дані об’єкти.

У оголошених класів для тора виставляємо батьком resultEntity результат нашої функції. Для кожного з елементів настроюємо його змінні, про Qtransform та QphongMaterial говорилось раніше, а ось у QtorusMesh’у необхідно викликати 4 функції, для задання великого та малого радіусів, та для задання кількості кільців та граней.

Якщо усе зроблено правильно то при запуску програми ми отримаємо наступний результат:



Рисунок 10

Можна замітити, що хоча ми і не виставляли джерела світла, але наш тор всерівно освітлений. Це пояснюється тим, що Qt автоматично створює джерело світла, якщо його не були виставлено власноруч.

Тепер коли ми виставили наш примітив настав час подумати про реалізацію пересування камери. З цією метою був створений скрипт CameraController який містить у собі перелік подій, змінних та функцій для добавлення можливості керувати нашою камерою за допомогою клавіш клавіатури, та можливості її повороту за допомогою мишки. Скрипт використовує систему сигналів і слотів (SIGNALS & SLOTS), суть якої полягає у комунікації між об’єктами. Це ключова особливість Qt. Сигнали та слоти стали можливими завдяки системі метаоб’єктів Qt.

Для короткого пояснення, система метаоб’єктів грунтується на 3 речах:

  • Клас QObject надає базовий клас для об’єктів, які можуть використовувати переваги системи метаоб’єктів

  • Макрос Q_OBJECT у приватному розділі оголошення класу використовується для ввімкнення функцій метаоб’єкта, таких як динамічні властивості, сигнали та слоти.

  • Компілятор мета-об’єктів (moc) надає кожному підкласу QObject необхідний код для реалізації функцій мета-об’єктів

Повертаючись до системи сигналів, у Qt у нас є альтернатива техніці callback’у: ми використовуємо сигнали та слоти. Сигнал випромінюється, коли відбувається певна подія. Віджети Qt мають багато попередньо визначених сигналів, але ми завжди можемо створити підкласи віджетів, щоб додати до них власні сигнали. Слот — це функція, яка викликається у відповідь на певний сигнал. Віджети Qt мають багато попередньо визначених слотів, але звичайною практикою є створення підкласів віджетів і додавання власних слотів, щоб ви могли обробляти сигнали, які вас цікавлять. Приклад взаємодії об’єктів за допомогою сигналів зображено на рисунку 10.



Рисунок 11

Використовую цю особливість ми можемо створити клас, у якому у відповідь на нажимання певних клавіш будуть виконуватись певні функції, за допомогою цього я і реалізував можливість переміщення по віссях X, Y і Z в обох напрямках разом з можливістю повертати камеру.

Тепер у нашому проекту ми можемо выльно керувати камерою, декілька фото з різних кутів наведено на рисунках 12 та 13.



Рисунок 12



Рисунок 13

Тепер добавимо скайбокс, це об’єкт, який буде відігравати роль неба. Основною проблемою є правильне називання текстур, які ми будемо використовувати, оскільки кожна назва буде позначати позицію текстури у загальному скайбоксі. Для правильного використання нам потрібно мати 6 текстур любих розширень, у моєму випадку це розширення .tga. Далі нам необхідно створити ресурс файл, який буде зберігати наші текстури, таким чином ми зможемо використовувати їх у нашій програмі. Для цього треба нажати правою клавішою мишки на головну папку нашого проекту і вибрати ‘Add New…’



Рисунок 14

Та у з’явившомуся меню вибираємо варіант Qt, у якому вибираємо тип файлу Qt resource file.



Рисунок 15

Тепер коли ми маємо ресурс файл, ми повинні заповнити його текстурам, але зробити ми це повинні за одним правилом, назва файлу має закінчуватись одним з 6 назв (_posx|_posy|_posz|_negx|_negy|_negz), причому вони не можуть повторятись. Після правильного заповнення наш ресурс файл має виглядати наступним чином:



Рисунок 16

Тепер повторюємо процедуру добавляння об’єкту, як ми це робили з тором, але на цей раз нам також слід добавити розширення нашому скайбоксу, для цього у об’єкті skyboxTransform ми викликаємо функцію setScale3D.

Після запуску проекту ми маємо побачимо наш скайбокс:



Рисунок 17

Тепер залишилося добавити освітлення, для цього можна використовувати декілька заготовлених джерел світла, які знаходяться які знаходяться у бібліотеці Qt3Drender, я використав PointLight, який представляє собою точкове джерело світла. Створюємо його за вже продемонстрованими кроками та при наступному запуску побачимо наступне.



Рисунок 18

Тепер до нашого проекту лишилось добавити ще кілька примітивів, серед них буде QSphere, якого ми задамо за допомогою функцій SetRings(), SetSlices() і SetRadius(), QCone, який задається функціями SetSmallRadius(), SetBigRadius(), SetLength() та SetSlices(), Qcuboid, який задається функціями setXExtend(), setYExtend() setZExtend() та Qplain, який задається SetWidth() та SetHeigth().

Об’єднавши дані примітиви я зробив ‘підлогу’ з Qplain’а на якій знаходяться 2 композиції, куб у торі та морозиво. На цьому наш проекту повныстю завершений.

    1. Створення проекту на мові QML

Як і промовлялось раніше, QML є частиною QtQuick, а також заснована на JavaScript, тому процес написання та структура коду буде дуже подібною, якщо не ідентичною самому JavaScript’у.

Для початку при створені проекту нам потрібно вибрату заготовку, Qt Quick Application, далі вибрати мінімальну версію Qt, у моєму випадку це 5.15. Можна скачувати і більш ранні версії, доки вони належать до 5 версії Qt, але я не рекомендую опускатись нижче 5.12, оскільки починаючи з цієї версії виправили декілька помилок, які могли опинятись при роботі у QML.



Рисунок 19

Відкривши проект зразу замітимо відмінності, у нас було створено ресурс файл для наших .qml файлів і він уже заповнений одним, саме в ньому ми і будемо проводити більшість роботи, щоб потім просто підключити до головного cpp.

Але для початку потрібно підключити нові бібліотеки для роботи з Qt Quick



Рисунок 20

Тепер необхідно пояснити структуру нашого .qml, у відмінності від C++, ми майже не будемо використовувати функції для встановлення значень змінних, натомість ми будемо змінювати їх напряму, таким чином при створенні об’єкта ми зразу задаємо всі його властивості. Найголовнішою серед всіх, а також та яка зустрічається у кожному об’єкті, є id – індентифікатор за допомогою якого ми будемо звертатися до об’єкту. У результаті так буде виглядати наш об’єкт.



Рисунок 21

По даному принципу без проблем заповнюємо головний файл. Головне не забувати заповнювати всі елементи у об’єкт класу Entity, та помістити всі об’єкти усередину кореневої сутності. У результаті будемо мати основну сутність, у якій у властивості components розмішені всі інші об’єкти. Вигляд на прикладі об’єкта торуса

Рисунок 22

Більша різниця замітна, коли будемо створювати власну систему руху камери. У С++ нам доводилось створювати змінні під дію (Action), ввід (Input) та саму зміну стану (bool), що доволі сильно збільшувало розмір та складність читання нашого коду.

У цьому випадку все набагато простіше, нам досі потрібно декларувати кожну подію під кожну клавішу окремо, але тепер замість створення змінних ми можемо зразу добавляти їх у наш logicalDevice, вставляючи кожну подію як частину масиву компонентів. На практиці це буде мати такий вигляд:

Як можемо замітити у нашому пристрої зразу записані дії, кожна з яких містить у собі вектор клавіш, які будуть її викликати, пристрій з якого цю клавішу треба зчитати, та подію, яка буде при цьому викликатись. Таким чином ми уникаємо необхідності у зв’язуванні за допомогою функції connect, як ми це робили у С++. При цьому система слотів і сигналів всерівно розуміє зв’язки між подіями та самими діями.

Так само все працює і для осей повороту, ми записуємо кожну з них як елемент логічного пристрою, кожна вісь містить пристрій, подію та дію яка викликає її.

Таким чином ми значно полегшили чтруктуру нашого коду за рахунок вкладання об’єктів один в одного, можливості зробити таке у С++ у нас не було.

Далі повторюємо ці дії для інших примітивів і здобуваємо точну копію нашого минулого проекту, при цьому не змінюючи головний cpp файл.

Рисунок 23

  1.   1   2   3

    скачати

© Усі права захищені
написати до нас