LINUX.ORG.RU

[opengl] Отмасштабировать изображение, чтобы оно занимало большую часть экрана

 


0

0

Есть набор точек (координаты х и у). Я рисую их (в плоскости ху), соединяя линиями. Получается некий график.

Нужно подогнать позицию камеры (перспектива) так, чтобы график занимал максимально возможное пространство на экране. Как это сделать?

★★

Использовать ортографическую проекцию вместо перспективной не катит?

Deleted
()
Ответ на: комментарий от Booster

Не, суть не в этом.

Это курсовик, не реальная задача. Пробовал в орто, но, что и логично, при вращении все выглядит неестественно.

Уже написал костыль, который пытается делать то, что мне надо в перспективе, но работает плохо: неправильно считает координаты точек, определяющих видимый прямоугольник камеры на плоскости ху.

Если кто-то может подсказать что-нибудь, код на Common Lisp здесь - функция center-camera.

bk_ ★★
() автор топика
Ответ на: комментарий от bk_

В лиспе не силён, но думаю проблем быть не должно. Угол обзора камеры и нормаль известны, осталось применить элементарную математику.

Booster ★★
()
Ответ на: комментарий от unnamed

Верно, но кроме этого нужно выровнять камеру так (подогнать z-координату), чтобы крайние точки были как можно ближе к краю изображения на камере.

bk_ ★★
() автор топика

Обьясните это, не понятно.

Пробовал в орто, но, что и логично, при вращении все выглядит неестественно.

Если нужен график поверх 3Д изображения, то саме простое - это стереть буфер глубины и переключиться на орто. Потом нарисовать нормально график. Это обычная удобная техника.

Другой вариант - рисовать 3Д и 2Д в разные FBO, а потом просто в орто рисовать 2 quad'а. Фактически вы получаете просто две текстуры - в первой 3Д картинка, во второй график. Делайте с ними что хотите.

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

vertexua ★★★★★
()
Ответ на: комментарий от vertexua

У меня нет никаких шейдеров и тому подобных наворотов :) Просто в плоскости ху рисую график по точкам, хранящимся в списке.

Искомая задача - пододвинуть камеру по оси z так, чтобы крайние точки графика располагались как можно ближе к краю экрана -> то есть, приблизить камеру по максимуму.

Я сделал это следующим образом: нашел среднюю точку в графике (среднее арифметическое по х и у). Поставил камеру в эту точку с z=0.

Далее в цикле проверяю, все ли точки графика видимы сейчас. Если все, то стоп. Если не все, то отодвигаю камеру на 0.5 по оси z. Перехожу в начало цикла, и так далее.

Проблема сейчас в том, что я неправильно (не знаю, почему) считаю границы видимости плоскости ху с текущего положения камеры. В результате, камера отодвигается дальше, чем надо было бы.

bk_ ★★
() автор топика
Ответ на: комментарий от bk_

Скиньте ваш gluPerspective gluLookAt. График у вас квадратом?

А как насчет идеи нарисовать белый QUAD, отмасштабировать его идеально, пускай методом тыка, а потом в точности на месте квада рисовать график? Соотношение сторон и размер квада сделать таким же, как и у области графика.

vertexua ★★★★★
()
Ответ на: комментарий от vertexua

зачем вам перспектива

Такая постановка задачи.

Код я выкладывал здесь.

График задается массивом точек, который может быть абсолютно любой.

bk_ ★★
() автор топика
Ответ на: комментарий от bk_

>Далее в цикле проверяю, все ли точки графика видимы сейчас. Если все, то стоп. Если не все, то отодвигаю камеру на 0.5 по оси z. Перехожу в начало цикла, и так далее.
Ужос. Почитайте про объём видимости, картинную плоскость.

Booster ★★
()
Ответ на: комментарий от shty

Спасибо всем, решил проблему так:

(defun center-camera ()
  (setf *camera-angle-x* 0 
	*camera-angle-y* 0
	*camera-angle-z* 0)
  (let ((min-x (nth 0 (nth 0 *points*)))
	(max-x (nth 0 (nth 0 *points*)))
	(min-y (nth 1 (nth 0 *points*)))
	(max-y (nth 1 (nth 0 *points*)))
	(mid-x 0) (mid-y 0))
    (dolist (point *points*)
      (setf min-x (min min-x (nth 0 point)))
      (setf max-x (max max-x (nth 0 point)))
      (setf min-y (min min-y (nth 1 point)))
      (setf max-y (max max-y (nth 1 point))))
    (setf mid-x (/ (+ min-x max-x) 2))
    (setf mid-y (/ (+ min-y max-y) 2))
;    (format t "min-x=~a max-x=~a min-y=~a max-y=~a mid-x=~a~%" min-x max-x min-y max-y mid-x)
    (setf *camera-x* (- mid-x))
    (setf *camera-y* (- mid-y))
    (let ((camera-z-by-x (- (/ (- mid-x min-x)
			       0.466307658)))
	  (camera-z-by-y (- (/ (- mid-y min-y)
			       0.466307658))))
      (setf *camera-z* (/ (min camera-z-by-x camera-z-by-y)
			  (/ *window-width* *window-height*))))))

P.S. Лор пожмакал выравнивание.

bk_ ★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.