Сделайте снимок окна OpenGL с очень большим разрешением изображения - PullRequest
4 голосов
/ 27 июня 2011

В настоящее время я пытаюсь сделать снимки трехмерного мира рендеринга OpenGL при различных положениях камеры и различном разрешении изображения с помощью glReadPixels. У меня есть два варианта библиотеки GUI, которая реализует программу Windows OpenGL: Qt и freeglut. После нескольких экспериментов с обоими я понимаю, что Qt не ограничивает разрешение изображения своих снимков QGLWidget размером рабочего стола, но я не мог сделать то же самое для freeglut.

Хотелось бы использовать Qt для этой программы захвата снимков, но я ограничен в избытке, потому что мой напарник по проекту, который работает над другим модулем той же программы, не может позволить себе время на изучение новой библиотеки и IDE (Qt Creator) , Он использует Visual Studio 2008.

Могу ли я в любом случае создать перенасыщенное окно, которое не ограничено размером рабочего стола и может достигать 4000 x 2000?

Ответы [ 2 ]

9 голосов
/ 27 июня 2011

Делать рендеринг с высоким разрешением с OpenGL немного сложно. Одна проблема заключается в том, что мешают тесты владения пикселями. Другой - это максимальный размер кадрового буфера (объекта). Первая проблема может быть преодолена с помощью объекта framebuffer или PBuffer.

Второе требует некоторой хитрости: допустим, мы хотим визуализировать изображение размером W × H, где W и H превышают максимальный размер кадрового буфера; glGetInteger из токенов GL_MAX_VIEWPORT_SIZE, GL_MAX_TEXTURE_SIZE, GL_MAX_RENDERBUFFER_SIZE дает вам эти ограничения. Итак, вам нужно разбить целевое изображение на листы, размер которых меньше этих пределов, визуализировать эти листы и затем рекомбинировать их. Скажем, W_t и H_t - размеры тайлов, W_t := W / N, H_t := H / M, и у нас есть объект PBuffer или Framebuffer соответствующего размера. Затем мы можем визуализировать эти плитки с помощью 2-петлевого:

for m in 0 to M: for n in 0 to N:
    render_tile(n, m)

Так как же render_tile(n,m) выглядит?

render_tile(n,m):

Очевидно, что мы используем всю плитку в качестве рендеринга буфера, поэтому

    glViewport(0, 0, W_t, H_t)

так что меняется, это проекция. Каким-то образом мы должны сместить проекцию вместе с плиткой в ​​плоскости проекции. Плоскость проекции также известна как «ближняя» плоскость. Экстентами ближней плоскости являются right - left и top - bottom, поэтому мы разбиваем ближнюю плоскость на плитки размером (right - left) / N × (top - bottom) / M, поэтому нам необходимо использовать размер шага сдвига:

    shift_X = (right - left) / N
    shift_Y = (top - bottom) / M

    glMatrixMode(GL_PROJECTION)
    glLoadIdentity()
    switch Projection:
         case Ortho:
             glOrtho( left + shift_X * n, left + shift_X * (n+1), 
                      bottom + shift_Y * m, bottom + shift_Y * (n+1),
                      near, far)
         case Perspective:
             glFrustum( left + shift_X * n, left + shift_X * (n+1), 
                      bottom + shift_Y * m, bottom + shift_Y * (n+1),
                      near, far)

    render_scene()

И на всякий случай, как мы получим left, right, top, bottom для перспективы:

right = -0.5 * tan(fov) * near
left = -right;
top = aspect * right
bottom = -top
4 голосов
/ 27 июня 2011

После нескольких экспериментов с обоими я понял, что Qt не ограничивает разрешение изображения своих снимков QGLWidget размером рабочего стола, но я не мог сделать то же самое для freeglut.

Имейте в виду: если вы создаете окно, которое больше рабочего стола, те пиксели, которые не отображаются, не проходят проверку владения пикселями. Следовательно, содержимое этих пикселей равно undefined . Они могут содержать то, что вы хотите, но не могут.

Это верно для любых пикселей, которые не видны, независимо от того, находится ли окно рядом с рабочим столом или закрыто другим окном.

В любом случае, вам не следует создавать окно размером с рабочий стол. Вы должны создать обычное окно и создать объект framebuffer , который содержит большой цвет и глубину renderbuffer . Сделайте весь свой рендеринг в эти закадровые буферы. Тогда вам не придется беспокоиться об ограничениях размера вашего окна.

...