![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Организация камеры в 3D игре [Delphi, Windows]
akaValerius © (2007-01-12 22:58:00)Вид от 1 лица. Вобщем я тут мучаюсь с камерой, исправлю одно ошибка в другом, исправлю то и ещё одно искожение. Помогите кто чем может. Небольшой исходник организации камеры именно главные формулы, функции а дальше я доработаю, исходник желательно с каментариями, а то глупо делать, не монимая, что творишь. Помогите please это у меня ед. проблема.OpenGL+Delphi не на WinApi а то кода много будет. И ещё былобы лучше без дополнительных модулей, а то ещё там рыться.
akaValerius (2007-01-21 00:05:00) [1]DevilDevil вообщем тут такая тема вот такая вот и тема вообщем не обращай внимание это все пиво. Так вот я зделал выводы что лучше все креатить самому иначе не какой практики ведь мы прогеры тем и отличаемся от простых смертных умением не стандартно мыслить а gamedav'ы темболее.
DevilDevil (2007-01-15 19:27:00) [2]Высылаю стрёмный пристрёмный модуль в котором чёрт ногу сломит, повезёт, если разберёшься.
Главное:
1) смени камеру на TCameraAction :)
2) вся обработка действий (OnProcess) происходит по событию OnIdle
P.S. ничего-ничего, ещё одна-две бутылки пива и разберёшься ;)
XProger (2007-01-15 15:41:00) [3]
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;
akaValerius (2007-01-15 14:40:00) [4]DevilDevil
Все равно не пашет, не знаю, как быть. Задолбался пиво пить. Мож пришлешь пример на работу с твоим модулем.
akaValerius (2007-01-15 14:38:00) [5]XProger
Поповоду TVector у меня не возможно зделать Dir.Cross происходит ошибка после того как ставлю точку. Пришли не большой исходник, если те не влом.
XProger (2007-01-14 15:57:00) [6]Dir.Cross(Vector(0, 1, 0)); - векторное произведение Dir на (0, 1, 0)
Speed.Normal - единичный вектор вектора Speed
deg2rad = pi/180
порядок верный.
DevilDevil (2007-01-13 20:14:00) [7]> Кстати ту переменную '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;
{сама отрисовка сцены}
akaValerius (2007-01-13 19:02:00) [8]И еще вызываю Camera.SetProjection. И вижу темноту, а если ее не вызывать то не че не пашет например:Camera.SetPosition; Кстати ту переменную 'GlobalEx' я зделал как коментарий.
akaValerius (2007-01-13 18:37:00) [9]При компиляции такая ошибка:
[Ошибка] DE_Cameras.pas(381): Undeclared identifier: 'GlobalEx'
[Фатальная Ошибка] Project1.dpr(5): Could not compile used unit 'DE_Cameras.pas'
DevilDevil (2007-01-13 18:16:00) [10]сорри. В твоём случае:
procedure IDENTITY_PROJECTION_MATRIX();
begin
glMatrixMode(GL_PROJECTION);
glLoadIdentity;
end;
DevilDevil (2007-01-13 18:13:00) [11]нет, я прорабатывал этот модуль долго и муторно, до сих пор не доработал.
Просто пишешь так:
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;
Вот вроде и всё, должно работать! Там на самом деле куча фич! Если что, спрашивай
akaValerius (2007-01-13 17:40:00) [12]>DevilDevil
Нет, там у тя находится, при этом беруца уже перменные заполненые другими функциями-процедурами, и пренести в мой код не получается, а просто подклучить его тоже, потомучто в нем ипользется еще один модуль которого у меня нет. Если не сложно пришли модуль покороче с основными функциями-процедурами, чтоб были процедуры углов(там посмотр. в верх, вниз, влево и т.д.). Please а то меня уже запарило "окно" игрока. И еще добавь туда пожайлуста коменнтарии.
DevilDevil (2007-01-13 16:50:00) [13]
> akaValerius © (12.01.07 22:58)
Слушай, я тебе целый модуль с камерами прислал, что там непонятно-то?
akaValerius (2007-01-13 15:24:00) [14]deg2rad - это че за фитча, как она находится
akaValerius (2007-01-13 14:00:00) [15]Опиши кто такие:
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'ы
XProger (2007-01-12 23:39:00) [16]Вот упрощённая часть кода камеры используемой мною
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;
Samarik (2007-01-12 23:07:00) [17]Я бы мог те с glscen'ой помочь, но не с ОпенГЛ :)