Камера - Част 1, Уроци по програмиране и примери
В поредицата от уроци "Камера" ще научим как да се движим в нашия свят, като управляваме клавиатурата, и по-късно мишката. Това, първият урок на камерата, ще постави основата за по-нататъшно развитие. Тук ще създадем клас за камера и ще научим как да се движим поне по някакъв начин.
Първоначалният код е взет от предишния урок, "FPS".
И така, първият файл, main.h. Ще добавим към него декларации за клас CVector и CCamera. Може да забележите, че тази заглавка е малко объркана - по-късно ще създадем друга заглавка и ще разделим данните.
Също така в заглавката ще добавим глобална инстанция на класа CCamera - gCamera. По този начин всеки файл има достъп до позицията и посоката на камерата.
// Добавяне на math.h към останалите включвания - ще бъде полезно. #включване
// *Векторен клас* // Това е началото на нашия "Векторен" клас. В началото ще бъде много просто, но с нарастването на класа // ще се увеличи функционалността, ще се появят повече типове данни. // От сега нататък ще го използваме за клас камера. // Засега просто трябва да запомним X,Y,Z. Засега това ще прилича повече на // структура, а не на клас.
public : // Няма да използваме контрол на достъпа и да избутваме всичко публично. float x, y, z; // Просто float за X,Y,Z > ;
// *Camera Class* // Ще се използва за съхраняване на позицията на камерата, нашия поглед и вертикалния вектор. // Сега имаме 3 CVector-а, които ще запомнят тази информация. // Също така, няколко помощни функции. Ние ще направим всички данни // публични, за да знаем нашата позиция по всяко време. // всички данни са публични, можете да използвате структура. // Но аз се опитвам да направя клас всичко, което съдържа методи.
CVector3 m_vPosition; // Позиция на камерата. CVector3 m_vView ; // Посока на камерата. CVector3 m_vUpVector ; // Вертикален вектор.
//В началото на променливите поставяме знак "m", т.к това са променливи "член". //"v" се добавя, защото те са членове на класа Vector (започва с V).
// Конструктор на клас камера CCamera ( ) ;
// Променете позиция, посока и вертикала тук. вектор на камерата. // Използва се основно по време на инициализация. void PositionCamera ( float positionX , float positionY , float positionZ , float viewX , float viewY , float viewZ , float upVectorX , float upVectorY , float upVectorZ ) ;
// Тази функция премества камерата напред/назад void MoveCamera ( float speed ) ; > ;
// И накрая, нека добавим глобална променлива за данни на камерата. външна CCamera g_Camera; // Глобални данни на камерата
// Всичко останало във файла остава непроменено.
Файлът Init.cpp остана непроменен.
Сега нека да преминем към файла camera.cpp, който ще опише изпълнението на класа камера. За начало ще приложим просто движение напред и назад, което ще усложним в следващите уроци. файл Camera.cpp:
// Включете нашия хедър #include "main.h"
CCamera :: CCamera() < //Инициализираме вектора на нашата позиция към нулеви координати CVector3 vZero = < 0.0, 0.0, 0.0 >; CVector3 vView = < 0.0, 1.0, 0.5 >; // В него. вектор на поглед CVector3 vUp = < 0.0, 0.0, 1.0 >; // Вертикален вектор
m_vPosition = vZero; m_vView = vView; m_vUpVector = vUp; >
GLvo >:: PositionCamera ( float positionX , float positionY , float positionZ , float viewX , float viewY , float viewZ , float upVectorX , float upVectorY , float upVectorZ ) < CVector3 vPosition = <позицияX, позицияY, позицияZ >; CVector3 vView = < viewX, viewY, viewZ >; CVector3 vUpVector = < upVectorX, upVectorY, upVectorZ >;
// Обширният код просто улеснява присвояването на променливи. //Можете просто незабавно да присвоите стойностите, предадени на функцията, на променливите на класа.
m_vPosition = vPosition; m_vView = vView; m_vUpVector = vUpVector; >
void CCamera :: MoveCamera (плаваща скорост) < CVector3 vVector = < 0 >; //В него. вектор на посоката на погледа
// Вземете вектора на посоката. За да получим вектор от 2x // точки, изваждаме първата точка от втората. // Това ни дава посоката, в която търсим. // По-късно ще напишем функция, която изчислява посоката // по различен начин.
//Получаване на посоката на изглед (напр. накъде сме обърнати) vVector. x = m_vView. x - m_vПозиция. х; //Посока X vВектор. y = m_vView. y - m_vПозиция. y; //Y посока vВектор. z = m_vView. z - m_vПозиция. z //Посока Z
// Следният код премества камерата напред или назад. // Добавяме към текущата позиция посоката на гледане, умножена по скоростта. // Може би смятате, че би било по-лесно просто да добавите скорост към позицията. Да, // това ще работи сега - гледате право надолу по оста X. Но веднага щом въртенето започне, // кодът вече няма да работи. Вярвай ми. // Така че, ако гледаме в посока от 45 градуса, ще отидем в тази посока. // Ако се движим назад, просто предаваме отрицателна скорост на f-та.
m_vПозиция. x += vВектор. x*скорост; m_vPosition. z += vВектор. z*скорост; m_vView. x += vВектор. x*скорост; m_vView. y += vВектор. z*скорост;
// Това е всичко. Изобщо не е сложен клас, който ни позволява поненякак се движи в света =)
Сега нека използваме нашия нов клас. файл main.cpp:
// Някъде в горната част на файла добавете: #define kSpeed0.03f //Колко бързо се движи камерата
// Деклариране на класа камера, дефиниран като extern в main.h : CCamera g_Camera ;
// Добавете дефиниция на камера към функцията Init(). // Сега функцията изглежда така: void Init ( HWND hWnd ) < g_hWnd = hWnd; GetClientRect ( g_hWnd , & g_rRect ) ; InitializeOpenGL (g_rRect. дясно, g_rRect. долу) ;
Шрифт = нов CFont ("arial.ttf", 16, 16); FPS = 0;
// По-долу инициализираме камерата. Задайте позицията, от която ще гледаме // цветния триъгълник. // Запомнете, тази инициализация е необходима само _веднъж_, // и ние няма да я извикаме отново.
// Позиция Посока верт. вектор g_Camera. Позиция на камерата (0, 0.5f, 6, 0, 0.5f, 0, 0, 1, 0); >
// Подаване на данни за OpenGL камера gluLookAt ( g_Camera. m_vPosition . x , g_Camera. m_vPosition . y , g_Camera. m_vPosition . z , g_Camera. m_vView . x , g_Camera. m_vView . y , g_Camera. m_vView . z , g_Camera.m_vUpVector.x , g_Camera.m_vUpVector.y , g_Camera.m_vUpVector.z );
// И начертайте триъгълник =) glBegin ( GL_TRIANGLES ) ; glColor3ub (255, 0, 0); glVertex3f (0, 1, 0);
glColor3ub (0, 255, 0); glVertex3f (-1, 0, 0);
glColor3ub (0, 0, 255); glVertex3f (1, 0, 0); glEnd();
// И накрая, нека направим промени във функцията WinProc, в секцията за обработка на ключове. // Сега кодът на case WM_KEYDOWN изглежда така: case WM_KEYDOWN : switch ( wParam ) < case VK_ESCAPE: PostQuitMessage (0); // Изход от break ;
случайVK_UP : // Ако сте натиснали "нагоре" // Придвижване напред - с положителна скорост g_Camera. MoveCamera (kSpeed ); RenderScene(); // Преначертайте сцената break ;
case VK_DOWN : // Ако е "надолу" // Движение назад - с отрицателна скорост g_Camera. MoveCamera(-kSpeed) ; RenderScene(); // Преначертайте сцената break ; > почивка ; //********************************************************************************
Това е всичко. Ако компилирате програмата, можете да се движите напред и назад около малкия триъгълник, начертан за ориентация. В бъдещите уроци ще разширим функционалността на камерата, ще добавим въртене, страйф и много други.