понедельник, 7 мая 2012 г.

Fire Monkey: Camera Test

Захотелось мне сделать такую вещь: пользователь смотрит на 3D-сцену и с ней взаимодействует мышкой. Но при этом где-нибудь на панельке сбоку я хочу показать эту же сцену, но под другим углом,  т.е. с другой камеры. По идее, это должно решаться как-то довольно просто: создаём вторую камеру и для неё говорим, мол рисуй что видишь на такую-то панель. Но не тут-то было…

У камеры есть свойство Target. Попробовал я его – не получилось. Попробовал ещё много всяких способов – всё как-то не то. В итоге получилось не очень красиво… но получилось. Вот картинка:

image

В левом-верхнем углу – TViewPort3D – сама сцена. В ней несколько объектов крутятся и реагируют на мышь. В остальных углах – это то, что видят другие камеры. Камера 3, при этом, ещё и вращается вокруг основной сцены. Для интереса, я эту камеру нарисовал жёлтым шаром с красным глазом :с)

Код, по захвату того, что видет камера, и сохранение этого на TImage, выглядит примерно так:

  procedure MakeIt(Camera: TCamera; Image: TImage);
  var
    Bmp: TBitmap;
  begin
    Viewport3D1.Camera := Camera;
    Bmp := Viewport3D1.MakeScreenshot;
    try
      Image.Bitmap := Bmp;
    finally
      Bmp.Free;
    end;
  end;
begin
    Viewport3D1.UsingDesignCamera := False;

    MakeIt(Camera1, Image1);
    MakeIt(Camera2, Image2);
    MakeIt(Camera3, Image3);

    Viewport3D1.Camera := nil;
    Viewport3D1.UsingDesignCamera := True;
end;

Этот код вызывается сразу, после того как закончилась прорисовка ViewPort3D (на событии OnPaint), и чтобы он не вызывался во время скриншотов там ещё добавлена проверка. Ну и почему-то обновление TImage не вызывает перерисовку себя на форме (вернее оно вызывает, но отрисовывается всего один раз). Поэтому я там ещё добавил таймер, по которому говорю форме Invalidate.

Есть ещё одна особенность: TViewport3D.MakeScreenshot – создаёт TBitmap, который уничтожать нужно самому…

Скачать: исходник (zip-архив, 1 Мб), исполняемый файл (zip-архив, 3,9 Мб)

5 коммент.:

Всеволод Леонов комментирует...

Очень интересный пост!
Краткий, лаконичный, но очень понятный и (что главное) содержит оригинальную идею!

Переключение между камерами - ну это все держат в голове. А вот так - однорвеменно - очень свежо.

У меня, кстати, есть личные переживания по этому вопросу :) Но пока такой подход вызывает более позитивные эмоции.

Спасибо!

Unknown комментирует...

Thanks, thanks, thanks a lot from Spain!!

Анонимный комментирует...

У меня не работает. Как откомпилировать исходник?

Анонимный комментирует...

Ошибка в Viewport3D1

Николай Зверев комментирует...

Анонимный, представленный код создавался в Delphi XE2. С выходом Delphi XE3, библиотека FireMonkey немного изменилась и вполне возможно, что данный код в ней работать не будет.

Извините, но у меня нет возможности это проверить/исправить.

Отправить комментарий

.

.