Урок 6 Клавиатура и мишка
Добре дошли в нашия шести урок!
Време е да научите как да използвате клавиатурата и мишката, за да местите камерата по същия начин, както в FPS игрите.
Тъй като кодът на този урок ще бъде използван по-късно, ние ще го поставим в отделен файл common/controls.cpp и ще декларираме необходимите функции в common/controls.hpp, така че tutorial06.cpp да ги вижда.
Кодът на този урок ще се различава малко от предишните. Основната разлика е, че сега ще изчислим MVP матрицата не веднъж, а във всеки кадър, така че нека да преминем към основния код на цикъла:
Този кодов фрагмент има 3 нови функции:
- computeMatricesFromInputs() изчислява матриците за проекция и изглед въз основа на текущия вход. Това е функцията, при която се извършва основната работа.
- getProjectionMatrix() просто връща изчислената проекционна матрица.
- getViewMatrix() просто връща изчислената View Matrix.
Разбира се, този метод е един от малкото, които можете да следвате.
Сега нека да преминем директно към controls.cpp
Основен код
Така че имаме нужда от няколко променливи:
FoV е „ниво на увеличение“. 80 = много широк зрителен ъгъл, тежка деформация. Стойност между 60 и 45 е стандартна. 20 е силно увеличение.
Първо, ще изчислим позицията, хоризонталните и вертикалните ъгли, както и FoV на базата на входа, след което ще изчислим View и проекционните матрици.
Разчитането на позицията на мишката е лесно:
за нас обаче е важно да не забравяме да преместим курсора обратно в центъра на екрана, така че да не излиза извън границите на прозореца:
Имайте предвид, че този код приема, че размерите на прозореца са 1024*768, което не винаги е така.ще бъде вярно, така че най-доброто решение е да използвате glfwGetWindowSize().
Сега можем да изчислим нашите ъгли:
Нека разбием този код отдясно наляво:
- 1024/2 - xpos означава колко далеч е мишката от центъра на прозореца. Колкото по-напред отивате, толкова по-голям ще бъде завоят.
- float(...) прехвърля стойността в скоби към реален тип.
- mouseSpeed е скоростта, с която ще се извърши въртенето (чувствителност на мишката).
- += : Ако не сте преместили мишката, тогава 1024/2 - xpos ще бъде 0, така че horizontalAngle+=0 няма да промени ъгъла.
Вече можем да изчислим вектор, който представя в Световното пространство посоката, в която гледаме
Сега трябва да изчислим вектор в световното пространство, който ще посочи посоката на гледане:
Това е стандартно изчисление, но ако не знаете за синус и косинус, ето малка илюстрация:

Сега трябва да изчислим вектора "нагоре". Тоест вектор, който показва посоката нагоре за камерата. Имайте предвид, че не винаги ще бъде +Y. Например, ако гледате надолу, векторът нагоре ще бъде хоризонтален.

В нашия случай единственото нещо, което остава същото, е векторът, който сочи вдясно от камерата.
И така, имаме десен вектор и има посока (вектор напред), тогава векторът „нагоре“ е вектор, който е перпендикулярен на тях и за да го получите, трябва да използвате кръстосаното произведение:
За да запомните какво прави векторен продукт, опитайте да си спомните правилото за дясната ръка от урок 3. Първият вектор е палецът; Вторият вектор е показалецът; Резултатът ще бъде вашият среден пръст.
Единственото странно нещо в този код е deltaTime. Ако ниепросто умножете вектора по скоростта, получаваме неприятни ефекти:
- Ако имате бърз компютър и приложението ви работи с 60 fps, ще се движите с 60 единици в секунда.
- Ако имате бавен компютър и честота на кадрите = 20, тогава ще се движите със скорост от 20 единици в секунда.
Така някой, който има бърз компютър, ще се движи по-бързо, затова въвеждаме променлива, в която въвеждаме времето, изминало от последния кадър. С GLFW се изчислява по следния начин:
За забавление можем също така да свържем колелото на мишката с променливата FoV и да променим полето на видимост по този начин, което в крайна сметка ще ни даде вид увеличение:
Вече сме използвали всички функции по-долу в предишните уроци, само сега използваме различни опции:
##Изрязване на задните лица
Сега можете свободно да се движите и трябва да сте забелязали, че ако влезете вътре в куба, полигоните все още се показват. Това изглежда нормално, но в същото време ни отваря възможност за оптимизиране, тъй като в нормалните приложения никога не сте вътре в куб.
За да не се показват невидими ръбове и съответно да се увеличи производителността, трябва да проверим къде се намира камерата спрямо полигона (отпред или отзад). Добрата новина е, че тази проверка е много лесна за изпълнение. Графичният процесор трябва да изчисли нормалата на многоъгълника (използвайки кръстосаното произведение, помните ли?) и да провери как нормалата е ориентирана по отношение на камерата.
Има обаче едно предупреждение. Векторното произведение не е комутативно. Това означава, че редът, в който умножавате векторите, е важен фактор за резултата. Тоест, ако объркате реда, ще получите грешен нормален, което означава, че неще можете да изчислите осветлението (по-късно) и изрязването на невидимите ръбове няма да работи правилно.
Активирането на изрязването на полигони се извършва само с една команда:
Упражнения
-
Направете го така, че да не можете да се движите нагоре или надолу
Създайте камера, която ще се върти около дадения обект. улика:
радиус на свързване, височина, време към клавиатурата