Делать рендеринг с высоким разрешением с 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