![]() |
|
![]() |
![]() |
Новости | Конференция | Чат | База данных | Творчество | Сообщество | О сайте | English |
![]() |
Помощь сайту |
![]() |
![]() |
![]() |
![]() |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Глава 5. Камера и спрайт Для того чтобы отображать сцену нужны камеры. Вынесем их в отдельный класс. Создайте новый юнит. type JLCamera=class(JLSceneObj) объявляем потомком класса JLSceneObj v1,v2,v3,v4:TDotVector3; просто объявите, зачем скажу позже. Fov:integer; угол обзора constructor Create; override; destructor Destroy; override; procedure Bind; procedure Render; override; procedure Update; override; procedure LoadFromFile(var f:file); override; procedure SaveToFile(var f:file); override; procedure Assign(a:JLSceneObj); override; end; Эта процедура делает данную камеру активной. Для этого нужно завести глобальные переменные, хранящие имя активной камеры (у меня это JL_ACTIVE_CAM) и еще текущий угол обзора (JL_SCR_FOV). JLResize-вызов gluPerspective, который устанавливает угол обзора. procedure JLCamera.Bind; begin JL_ACTIVE_CAM:=IdName; JL_SCR_FOV:=Fov; JLResize; end; Просто отладочная процедура в «жизни» не понадобится, а в отладке легко видеть камеру. procedure JLCamera.Render; begin glPushMatrix; Trans.DoTransform; glPointSize(10); glBegin(GL_POINTS); glVertex3d(0,0,0); glEnd; glPopMatrix; if WithChild then RenderChildren; end; Теперь я расскажу зачем нужны v1,v2,v3,v4. Дело в том, что есть такое понятие как спрайт. Спрайт (он же биллборд) – прямоугольник всегда направленный на камеру. Создается впечатление объемности. Спрайтами делают много эффектов, начиная со свечения из дюз корабля, заканчивая системами частиц. Итак, как же повернуть спрайт к камере? Спрайт – это четырехугольник, значит, нам нужно узнать 4 координаты. Допустим, у нас есть положение спрайта в пространстве. Значит, нам нужно к этому положению прибавить вектора для получения 4 вершин. Вот v1,v2,v3,v4 – это и есть эти вектора. Для всех спрайтов эти вектора одинаковые, они изменяются только в зависимости от камеры, значит, поместим их в неё. Как и где высчитать эти вектора? Будем считать их по Update. procedure JLCamera.Update; var modl:tdotMatrix16; VR,VU:TDotVector3; begin это DEBUG команда if Trans=nil then raise Exception.Create('Trans = nil at <'+IdName+'>'); glGetFloatv( GL_MODELVIEW_MATRIX, @ modl ); VR:=dotVector3(modl[0], modl[4], modl[8]); VU:=dotVector3(modl[1], modl[5], modl[9]); V1:=dotVector3(-VR.X-VU.X,-VR.Y-VU.Y,-VR.Z-VU.Z); V2:=dotVector3(VR.X-VU.X,VR.Y-VU.Y,VR.Z-VU.Z); V3:=dotVector3(VR.X+VU.X,VR.Y+VU.Y,VR.Z+VU.Z); V4:=dotVector3(-VR.X+VU.X,-VR.Y+VU.Y,-VR.Z+VU.Z); end; glGetFloatv( GL_MODELVIEW_MATRIX, @ modl ); этой командой мы берем матрицу трансформации в переменную modl. Кстати, modl является не стандартным типом математической библиотеки dot. type TDotMatrix16 = array [0..15] of Single; Почему именно так? Стандартный формат dot матрицы – 4х4, а нужно 1х16-это формат OpenGL. Потом идут расчеты этих четырех векторов. Вариантом оптимизации является пересчитывать эти вектора только в случае поворота камеры и не пересчитывать вообще, если в сцене нет спрайтов. Теперь обозначим класс спрайта. type JLSprite=class(JLSceneObj) Color:TDotVector4; цвет TexID:string; имя текстуры size:single; размер спрайта constructor Create; override; destructor Destroy; override; procedure Render; override; procedure Update; override; procedure LoadFromFile(var f:file); override; procedure SaveToFile(var f:file); override; procedure Assign(a:JLSceneObj); override; end; Текстуры.. Пока о них не будем говорить, это будет в следующей главе. В принципе, все процедуры понятны, кроме Render. procedure JLSprite.Render(WithChild:boolean); var v1,v2,v3,v4:TDotVector3; const Tex1:TDotVector2=(x:0;y:0); Tex2:TDotVector2=(x:1;y:0); Tex3:TDotVector2=(x:1;y:1); Tex4:TDotVector2=(x:0;y:1); begin v1:=dotVecAdd3(JLGetActiveCamera.V1,trans.pos); v2:=dotVecAdd3(JLGetActiveCamera.V2,trans.pos); v3:=dotVecAdd3(JLGetActiveCamera.V3,trans.pos); v4:=dotVecAdd3(JLGetActiveCamera.V4,trans.pos); if TexID<>'' then textures.GetObjByName(TexID).Bind; glColor3fv(@ color); glBegin(GL_QUADS); glTexCoord2fv(@ tex1); glVertex3fv(@ v1); glTexCoord2fv(@ tex2); glVertex3fv(@ v2); glTexCoord2fv(@ tex3); glVertex3fv(@ v3); glTexCoord2fv(@ tex4); glVertex3fv(@ v4); glEnd; end; JLGetActiveCamera – глобальная функция, возвращающая указатель на активную камеру (имя которой хранится в JL_ACTIVE_CAM). У меня выглядит так: function JLGetActiveCamera:JLCamera; begin result:=JLCamera(scene.Objects.GetObjByName(JL_ACTIVE_CAM)); end; textures – некий класс-хранитель текстур. Очевидно, что по textures.GetObjByName(TexID) возвращается указатель на текстуру с именем TexID. Подробнее об этом классе – в следующей главе. Вот, у нас уже есть каркасы для камеры, спрайта и геометрии. Они легко расширяемы. В следующих главах мы переделаем расчет координат спрайта на шейдеры и встроим поддержку VBO в геометрию. Но вначале текстуры.
|
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
![]() |
![]() |
![]() |
![]() |
Дизайн Elite Games V5 beta.18 EGM Elite Games Manager v5.17 02.05.2010 |
![]() |