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)`, и если вы нарисуете прямоугольник точно с этими координатами, он будет совпадать с синим прямоугольником на вашем изображении в любом из окон просмотра. Если вы не хотите, чтобы источник в центре, вы, конечно, можете перевести его.

Другие вопросы по тегам