OpenGL вид, проекции и ортогональное соотношение сторон
Есть много отличных уроков по матрицам проекции opengl для 3D, но я не занимаюсь 3D. Я действительно испытываю трудности с настройкой орфографической проекции по своему вкусу.
int width = 320; высота int = 480;
Я создаю матрицу проекции вида с этими настройками.
//eyex, eyey, eyez, centerx, centery, centerz, upx, upy, upz//
matrix view = (0, 0, -20, 0, 0, -1, 0, 1, 0);
matrix projection = (0, width, 0, height, 1, 100);
glViewport(0, width, 0, -height);
После создания этого вида и матрицы проекции и передачи их в GPU.
Затем я создаю квад -1,-1 to 1, 1
так что его происхождение находится в центре.
затем я делаю масштабную матрицу для четырехугольника, чтобы я мог видеть ее на экране. Он представляет собой идеальный квадрат, но, конечно, glViewport или перспективная матрица не должны быть квадратными. Это должен быть прямоугольник.
Как настроить glViewport, а также матрицу перспективы, чтобы поддерживать соотношение сторон.
например у меня теперь есть соотношение сторон, которое является шириной / высотой. Как мне использовать это с матрицей проекции и glviewport?
@ Reto, вероятно, правильно, что я обдумываю это, но интерфейс приложения opengl немного сложен для меня.
Я нарисовал изображение в надежде помочь прояснить ситуацию.
Допустим, я хочу, чтобы размер моего окна просмотра составлял 320х480 пикселей. Я хотел бы выбрать два разных режима масштабирования. Либо сохраняйте фиксированную высоту, где ширина будет увеличиваться, чтобы показать более горизонтальный вид, либо фиксированную ширину с растущей высотой, чтобы отображать более вертикально.
Допустим, я проектирую сцену размером около 320х480, я все выкладываю и знаю, что хотел бы увеличить ширину, но сохранить фиксированную высоту.
Как я могу добиться этого с помощью glViewport и матрицы ортографической проекции из моего соотношения сторон?
1 ответ
При использовании ортогональной проекции вы можете просто думать об ортогональной матрице как об определении некоторого выровненного по оси 2D-прямоугольника в плоскости XY, который описывает область сцены, которая отображается в области просмотра. Если пропорции этого прямоугольника не соответствуют пропорциям окна просмотра, изображение будет соответственно искажено.
Давайте использовать следующие определения:
V: aspect of the viewport:
V = viewport_width / viewport_height
P: aspect of the ortho projection:
P = (right - left) / (top - bottom)
O: aspect of some axis-aligned rectangle which is drawn
O = (x_max - x_min) / (y_max - y_min)
Когда преобразования будут применены, объект появится с соотношением сторон O / P * V
на экране.
Обычно, говоря о "сохранении пропорций", мы устанавливаем P == V
чтобы V / P
удаляет друг друга в вышеприведенной формуле, и объекты появляются именно с таким соотношением сторон, которое они рисуют в пространстве глаз.
И это уже именно то, что вы получаете с вашим кодом.:
Затем я создаю квад
-1,-1 to 1, 1
так что его происхождение находится в центре.
Это квадрат, и мне интересно, как вы можете ожидать, чтобы это получилось прямоугольником при сохранении соотношения сторон.
Из ваших изображений ясно, что интересующий вас объект представляет собой прямоугольник с соотношением сторон 2/3. Таким образом, вы должны также нарисовать его в виде прямоугольника с таким соотношением сторон. Есть несколько способов достичь этого. Так как размер области просмотра кажется заданным, вы можете настроить подоконник O
или же P
или оба.
Однако мне кажется, что вы слишком усложняете вещи. Если я правильно понял, у вас есть "пространство дизайна" размером 320x480 пикселей, которое является вашей "областью интересов", которую вы всегда хотите видеть на экране, независимо от размера области просмотра. Для этого вы можете сделать следующее:
float target_width = 320.f;
float target_height = 480.f;
float A = target_width / target_height; // target aspect ratio
// ... calculate V as above
if (V >= A) {
// wide viewport, use full height
ortho(-V/A * target_width/2.0f, V/A * target_width/2.0f, -target_height/2.0f, target_height/2.0f, ...);
} else {
// tall viewport, use full width
ortho(-target_width/2.0f, target_width/2.0f, -A/V*target_height/2.0f, A/V*target_height/2.0f, ...);
}
Теперь вы можете работать в "диапазоне дизайна" в пикселях. В этом примере всегда видимый диапазон будет от (-160, -240)
to (160, 240)`, и если вы нарисуете прямоугольник точно с этими координатами, он будет совпадать с синим прямоугольником на вашем изображении в любом из окон просмотра. Если вы не хотите, чтобы источник в центре, вы, конечно, можете перевести его.