Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2008.04.20;
Скачать: CL | DM;

Вниз

Организация камеры в 3D игре   Найти похожие ветки 

 
akaValerius ©   (2007-01-12 22:58) [0]

Вид от 1 лица. Вобщем я тут мучаюсь с камерой, исправлю одно ошибка в другом, исправлю то и ещё одно искожение. Помогите кто чем может. Небольшой исходник организации камеры именно главные формулы, функции а дальше я доработаю, исходник желательно с каментариями, а то глупо делать, не монимая, что творишь. Помогите please это у меня ед. проблема.OpenGL+Delphi не на WinApi а то кода много будет. И ещё былобы лучше без дополнительных модулей, а то ещё там рыться.


 
Samarik   (2007-01-12 23:07) [1]

Я бы мог те с glscen"ой помочь, но не с ОпенГЛ :)


 
XProger ©   (2007-01-12 23:39) [2]

Вот упрощённая часть кода камеры используемой мноюprocedure TCamera.Update;
const
 CAM_SPEED = 0.5;
 CAM_SENS = 0.1;
var
 Dir   : TVector;
 Speed : TVector;
begin
// осуществляем поворот головы мышью :)
 Angle.X := Angle.X + inp.MDelta.Y * CAM_SENS;
 Angle.Y := Angle.Y + inp.MDelta.X * CAM_SENS;
// ограничение угла поворота (вниз/вверх)
 if Angle.X < -90 then Angle.X := -90;
 if Angle.X >  90 then Angle.X :=  90;
// летим куда хотим
 Dir.X := sin(pi - Angle.Y * deg2rad) * cos(Angle.X * deg2rad);
 Dir.Y := -sin(Angle.X * deg2rad);
 Dir.Z := cos(pi - Angle.Y * deg2rad) * cos(Angle.X * deg2rad);
 Speed := Vector(0, 0, 0);
 if inp.Down(ord("W")) then Speed := Speed + Dir;
 if inp.Down(ord("S")) then Speed := Speed - Dir;
 if inp.Down(ord("D")) then Speed := Speed + Dir.Cross(Vector(0, 1, 0));
 if inp.Down(ord("A")) then Speed := Speed - Dir.Cross(Vector(0, 1, 0));
 Pos := Pos + Speed.Normal * CAM_SPEED;
end;

procedure TCamera.Setup;
begin
 glRotatef(Angle.Z, 0, 0, 1);
 glRotatef(Angle.X, 1, 0, 0);
 glRotatef(Angle.Y, 0, 1, 0);
 glTranslatef(-Pos.X, -Pos.Y, -Pos.Z);
end;


 
akaValerius ©   (2007-01-13 14:00) [3]

Опиши кто такие:
Dir.Cross(Vector(0, 1, 0));
Speed.Normal
а
glEnable(GL_DEPTH_TEST);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(90, ClientWidth/ClientHeight-1, 0.1, 100.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
procedure TCamera.Setup;
begin
glRotatef(Angle.Z, 0, 0, 1);
glRotatef(Angle.X, 1, 0, 0);
glRotatef(Angle.Y, 0, 1, 0);
glTranslatef(-Pos.X, -Pos.Y, -Pos.Z);
end;

В таком порядке иль glPop and Push Matrix"ы


 
akaValerius ©   (2007-01-13 15:24) [4]

deg2rad - это че за фитча, как она находится


 
DevilDevil ©   (2007-01-13 16:50) [5]


> akaValerius ©   (12.01.07 22:58)


Слушай, я тебе целый модуль с камерами прислал, что там непонятно-то?


 
akaValerius ©   (2007-01-13 17:40) [6]

>DevilDevil

Нет, там у тя находится, при этом беруца уже перменные заполненые другими функциями-процедурами, и пренести в мой код не получается, а просто подклучить его тоже, потомучто в нем ипользется еще один модуль которого у меня нет. Если не сложно пришли модуль покороче с основными функциями-процедурами, чтоб были процедуры углов(там посмотр. в верх, вниз, влево и т.д.). Please а то меня уже запарило "окно" игрока. И еще добавь туда пожайлуста коменнтарии.


 
DevilDevil ©   (2007-01-13 18:13) [7]

нет, я прорабатывал этот модуль долго и муторно, до сих пор не доработал.

Просто пишешь так:
var
 Camera : TCameraAction;

//OnCreate
Camera := TCameraAction.Create;

//OnDestroy
Camera.Free;

//OnDraw
Camera.SetProjection;
{прорисовка сцены}

//OnProcess
{здесь можно менять положение, углы поворотов и т.д. камеры}


А чтобы отвязаться от моего двига, нужно следующее:

1) модули OGL, DE_Select замени на свой модуль OpenGL
2) procedure IDENTITY_PROJECTION_MATRIX();
var
 vp   : Array [0..3] of GLint;
begin
 glMatrixMode(GL_PROJECTION);
 glLoadIdentity;

 if  Select_Mode then
 begin
    glGetIntegerv(GL_VIEWPORT, @vp);
    gluPickMatrix(SelectX, vp[3]-SelectY, 2, 2, @vp);
 end;
end;


Вот вроде и всё, должно работать! Там на самом деле куча фич! Если что, спрашивай


 
DevilDevil ©   (2007-01-13 18:16) [8]

сорри. В твоём случае:
procedure IDENTITY_PROJECTION_MATRIX();
begin
glMatrixMode(GL_PROJECTION);
glLoadIdentity;
end;


 
akaValerius ©   (2007-01-13 18:37) [9]

При компиляции такая ошибка:
[Ошибка] DE_Cameras.pas(381): Undeclared identifier: "GlobalEx"
[Фатальная Ошибка] Project1.dpr(5): Could not compile used unit "DE_Cameras.pas"


 
akaValerius ©   (2007-01-13 19:02) [10]

И еще вызываю  Camera.SetProjection. И вижу темноту, а если ее не вызывать то не че не пашет например:Camera.SetPosition; Кстати ту переменную "GlobalEx" я зделал как коментарий.


 
DevilDevil ©   (2007-01-13 20:14) [11]

> Кстати ту переменную "GlobalEx" я зделал как коментарий.

Правильно.


> И еще вызываю  Camera.SetProjection. И вижу темноту, а если
> ее не вызывать то не че не пашет например:Camera.SetPosition;


хм. Это абсолютно разные процедуры. Попробуй оставаться в нулевой точке (не вызывай SetPosition), а поворот вокруг своей оси привязать к мыши, почти так:
const
 Rad2Deg = 180/pi;
 MulAngle  : single = 0.0014;

//OnProcess****************************************
 Camera.RotateY(-MouseMoveX * MulAngle * Rad2Deg);
 Camera.RotateX( MouseMoveY * MulAngle * Rad2Deg);
//************************************************

<-- MouseMoveX, Y - это на сколько пикселей была передвинута мышь.

порядок поворотов в TCameraAction неважен. Не забудь, первой процедурой при отрисовке должно быть:
glMatrixMode(GL_MODELVIEW);
glLoadIdentity;
//<-- так ещё попробуй
Camera.SetProjection;

{сама отрисовка сцены}


 
XProger ©   (2007-01-14 15:57) [12]

Dir.Cross(Vector(0, 1, 0)); - векторное произведение Dir на (0, 1, 0)
Speed.Normal - единичный вектор вектора Speed
deg2rad = pi/180

порядок верный.


 
akaValerius ©   (2007-01-15 14:38) [13]

XProger
Поповоду TVector у меня не возможно зделать Dir.Cross происходит ошибка после того как ставлю точку. Пришли не большой исходник, если те не влом.


 
akaValerius ©   (2007-01-15 14:40) [14]

DevilDevil
Все равно не пашет, не знаю, как быть. Задолбался пиво пить. Мож пришлешь пример на работу с твоим модулем.


 
XProger ©   (2007-01-15 15:41) [15]

 TVector3f = record
   class function Create(X, Y, Z: Single): TVector3f; static; inline;
 public
   X, Y, Z : Single;
   class operator Equal(v1, v2: TVector3f): Boolean; inline;
   class operator Add(v1, v2: TVector3f): TVector3f; inline;
   class operator Subtract(v1, v2: TVector3f): TVector3f; inline;
   class operator Multiply(v: TVector3f; x: Single): TVector3f; inline;
   class operator Multiply(v1, v2: TVector3f): TVector3f; inline;
   function Lerp(v: TVector3f; t: Single): TVector3f; inline;
   function Dot(v: TVector3f): Single; inline;
   function Cross(v: TVector3f): TVector3f; inline;
   function Normal: TVector3f; inline;
   procedure Normalize; inline;
   function Length: Single; inline;
   function LengthQ: Single; inline;
 end;

 TVector = TVector3f;

...

function Vector(X, Y, Z: Single): TVector3f;
begin
 Result.X := X;
 Result.Y := Y;
 Result.Z := Z;
end;

class function TVector3f.Create;
begin
 Result := Vector(X, Y, Z);
end;

class operator TVector3f.Equal(v1, v2: TVector3f): Boolean;
begin
 Result := (v1.X = v2.X) and (v1.Y = v2.Y) and (v1.Z = v2.Z);
end;

class operator TVector3f.Add(v1, v2: TVector3f): TVector3f;
begin
 Result.X := v1.X + v2.X;
 Result.Y := v1.Y + v2.Y;
 Result.Z := v1.Z + v2.Z;
end;

class operator TVector3f.Subtract(v1, v2: TVector3f): TVector3f;
begin
 Result.X := v1.X - v2.X;
 Result.Y := v1.Y - v2.Y;
 Result.Z := v1.Z - v2.Z;
end;

class operator TVector3f.Multiply(v: TVector3f; x: Single): TVector3f;
begin
 Result.X := v.X * x;
 Result.Y := v.Y * x;
 Result.Z := v.Z * x;
end;

class operator TVector3f.Multiply(v1, v2: TVector3f): TVector3f;
begin
 Result.X := v1.Y * v2.Z - v1.Z * v2.Y;
 Result.Y := v1.Z * v2.X - v1.X * v2.Z;
 Result.Z := v1.X * v2.Y - v1.Y * v2.X;
end;

function TVector3f.Lerp(v: TVector3f; t: Single): TVector3f;
begin
 Result := Self + (v - Self) * t;
end;

function TVector3f.Dot(v: TVector3f): Single;
begin
 Result := X * v.X + Y * v.Y + Z * v.Z;
end;

function TVector3f.Cross(v: TVector3f): TVector3f;
begin
 Result.X := Y * v.Z - Z * v.Y;
 Result.Y := Z * v.X - X * v.Z;
 Result.Z := X * v.Y - Y * v.X;
end;

function TVector3f.Normal: TVector3f;
var
 len : Single;
begin
 len := Length;
 if len <> 0 then
   Result := Self * (1/len)
 else
   Result := Vector(0, 0, 0);
end;

procedure TVector3f.Normalize;
begin
 Self := Normal;
end;

function TVector3f.Length: Single;
begin
 Result := sqrt(LengthQ);
end;

function TVector3f.LengthQ: Single;
begin
 Result := sqr(X) + sqr(Y) + sqr(Z);
end;


 
DevilDevil ©   (2007-01-15 19:27) [16]

Высылаю стрёмный пристрёмный модуль в котором чёрт ногу сломит, повезёт, если разберёшься.

Главное:
1) смени камеру на TCameraAction :)
2) вся обработка действий (OnProcess) происходит по событию OnIdle

P.S. ничего-ничего, ещё одна-две бутылки пива и разберёшься ;)


 
akaValerius ©   (2007-01-21 00:05) [17]

DevilDevil вообщем тут такая тема вот такая вот и тема вообщем не обращай внимание это все пиво. Так вот я зделал выводы что лучше все креатить самому иначе не какой практики ведь мы прогеры тем и отличаемся от простых смертных умением не стандартно мыслить а gamedav"ы темболее.



Страницы: 1 вся ветка

Текущий архив: 2008.04.20;
Скачать: CL | DM;

Наверх




Память: 0.52 MB
Время: 0.018 c
2-1206038360
Nicky000
2008-03-20 21:39
2008.04.20
SQL


11-1184206425
danger
2007-07-12 06:13
2008.04.20
Компонент TKOLQProgressBar


2-1206682211
dumka
2008-03-28 08:30
2008.04.20
QReport


2-1206773311
nw
2008-03-29 09:48
2008.04.20
Можно установить и использовать компонент без *.dcu ?


2-1206460637
QAT
2008-03-25 18:57
2008.04.20
Битовые флаги