Урок 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 и да променим полето на видимост по този начин, което в крайна сметка ще ни даде вид увеличение:

Вече сме използвали всички функции по-долу в предишните уроци, само сега използваме различни опции:

##Изрязване на задните лица

Сега можете свободно да се движите и трябва да сте забелязали, че ако влезете вътре в куба, полигоните все още се показват. Това изглежда нормално, но в същото време ни отваря възможност за оптимизиране, тъй като в нормалните приложения никога не сте вътре в куб.

За да не се показват невидими ръбове и съответно да се увеличи производителността, трябва да проверим къде се намира камерата спрямо полигона (отпред или отзад). Добрата новина е, че тази проверка е много лесна за изпълнение. Графичният процесор трябва да изчисли нормалата на многоъгълника (използвайки кръстосаното произведение, помните ли?) и да провери как нормалата е ориентирана по отношение на камерата.

Има обаче едно предупреждение. Векторното произведение не е комутативно. Това означава, че редът, в който умножавате векторите, е важен фактор за резултата. Тоест, ако объркате реда, ще получите грешен нормален, което означава, че неще можете да изчислите осветлението (по-късно) и изрязването на невидимите ръбове няма да работи правилно.

Активирането на изрязването на полигони се извършва само с една команда:

Упражнения

    Направете го така, че да не можете да се движите нагоре или надолу

Създайте камера, която ще се върти около дадения обект. улика:

радиус на свързване, височина, време към клавиатурата