Как настроить GLCamera, чтобы показать весь GLScene
У меня есть объект GLScene различного (но известного) размера. Он полностью окружен TGLDummyCube
,
Я хочу расположить GLCamera
(с CameraStyle: glPerspective
), чтобы объект был полностью виден на экране. Я запустил это в основном - объект виден, но расстояние иногда слишком велико, или объект больше экрана и обрезается.
Как я могу это сделать? Я полагаю, что это может быть сделано с помощью умного сочетания расстояния между камерой и фокусного расстояния, но я пока не добился успеха.
Похоже, что это отличается от GLScene по сравнению с OpenGL. Я использую GLScene и Delphi 2007.
2 ответа
Хотя изменение расстояния от камеры и фокусного расстояния приведет к изменению визуального размера объекта, у него также есть недостаток, заключающийся в изменении перспективы, что приводит к несколько искаженному виду. Я предлагаю использовать камеры SceneScale
собственность вместо
Увы, у меня нет действительных шагов, чтобы вычислить правильное значение для этого. В моем случае я должен масштабироваться до куба с переменным размером, в то время как размер окна зрителя является постоянным. Таким образом, я поместил два фиктивных куба в позицию целевого куба, каждый из которых должен соответствовать ширине или высоте зрителя с соответствующими значениями для SceneScale
, расстояние до камеры и FocalLength
, Во время выполнения я вычисляю новый SceneScale
отношением размера целевого куба к размеру фиктивного куба. Это работает довольно хорошо в моем случае.
Редактировать: вот код, который я делаю для расчетов.
ZoomRefX
а такжеZoomRefY
это DummyCubesTargetDimX
а такжеTargetDimY
дать размер текущего объектаDesignWidth
а такжеDesignHeight
размерMyGLView
во время разработкиDesignSceneScale
это камераSceneScale
во время разработки
Код расчета:
ScaleX := (ZoomRefX.CubeSize*MyGLView.Width)/(DesignWidth*TargetDimX);
ScaleY := (ZoomRefY.CubeSize*MyGLView.Height)/(DesignHeight*TargetDimY);
NewSceneScale := Min(ScaleX, ScaleY)*DesignSceneScale;
Манекены ZoomRefX
а также ZoomRefY
имеют такие размеры, чтобы иметь небольшой запас по левому, правому или верхнему нижнему краям окна просмотра. Оба расположены так, чтобы передние грани совпадали. Также целевой объект позиционируется так, чтобы его лицевая поверхность совпадала с таковой этих DummyCubes.
Приведенные выше формулы позволяют размеру окна отличаться от времени разработки, но я на самом деле не тестировал эту функцию.
@Andreas, если вы играли с SceneScale (как вы упомянули в комментариях), это означает, что вы ищете правильный способ размещения объекта в поле зрения камеры, изменяя расстояние / фокусное расстояние камеры или изменяя размеры объекта. Если это так, самый простой способ изменить размер одного объекта по размеру экрана - использовать его свойство BoundingSphereRadius, например:
ResizeMultiplier := 2; //play with it, it depends on your camera params
GLFreeForm1.Scale.Scale(ResizeMultiplier / GLFreeForm1.BoundingSphereRadius);
Вы можете добавить GLDummyCube в качестве корневого объекта для всех других объектов сцены, а затем изменить размер GLDummyCube с помощью метода, упомянутого выше.