Как предотвратить масштабирование Texture_2D больше, чем область просмотра, в область просмотра в openGL - PullRequest
0 голосов
/ 08 сентября 2011

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

В основном у меня есть VBO, который отображает 2D-изображение в GL. Тем не менее, поскольку размер моего окна просмотра составляет 800x600, а изображение - 1024x1024, изображение уменьшается в соответствии с размером окна просмотра. Я очень долго гуглял по этой проблеме, и все, что я могу найти, - это ссылки на такие вещи, как учебные пособия NeHe, в которых говорится, что это произойдет, но без объяснения причин и способов предотвращения этого. Я думаю, что нашел один форум, который сказал, что это можно предотвратить, но опять же, никаких подробностей.

Итак, мне любопытно, как это можно сделать? Я просто изучаю GL, так что я в значительной степени новичок в этой области. Если это помогает, я делаю 2D-игру и пытаюсь использовать это VBO для отображения фонового изображения для уровня, так что при перемещении камеры влево и вправо, вверх и вниз вы, по сути, прокручиваете это фоновое изображение. , Любая помощь будет принята с благодарностью и благодарностью. :)

P.S. Кроме того, я понимаю, что это, вероятно, должно быть в отдельном вопросе, но любые объяснения или ссылки для объяснения системы координат для карт вершин / текстур также будут оценены. Я не совсем понимаю, как можно отображать текстуры с 0-1 и преобразовывать их в пиксельные координаты в пространстве.

UPDATE

Хорошо, после еще одного приближения к поиску ЕДИНСТВЕННОЕ решение, которое я нашел, состоит в том, чтобы временно настроить область просмотра по крайней мере на размер вашей 2D-текстуры, затем нарисовать 2D-текстуру, а затем вернуть область просмотра обратно к размеру окна (или каким бы оно ни было). Вот так:

//Set viewport so size of the current texture - note this is using a VBO
glViewport(0, 0, 1024, 1024);
glBindTexture(GL_TEXTURE_2D, texture);

glDrawArrays(GL_QUADS, 0, 4 );

glPopAttrib();

glBindBuffer(GL_ARRAY_BUFFER, 0);

glBindTexture(GL_TEXTURE_2D, 0);

//Set the viewport back to the window size
glViewport(0, 0, 800, 600);

Единственное, это похоже на ОСНОВНОЙ взлом. Это официальное или приемлемое решение?

Ответы [ 2 ]

1 голос
/ 08 сентября 2011

Думайте текстуры как резиновые листы.Нижний левый угол (не пиксель) текстуры находится в (0, 0), верхний правый угол в (1, 1).При рисовании треугольника на экране - точное положение на экране не имеет значения - текстура «резинового листа» «вырезана» в соответствии с координатами текстуры и растянута на треугольник, как указано в координатах текстуры. Нет никакого взаимодействия между размерами области просмотра и текстурированием!

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

void display()
{
    glViewport(0, 0, viewport_width, viewport_height);
    /* ... */

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    /* By using a orthographic projection with limits matching the viewport
       we're effectively getting viewport pixel coordinates for the vertices. */
    glOrtho(0, viewport_width, 0, viewport_height, -1, 1);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    /* I'm using immediate mode here for clarity – not
       recommended for new applications, use Vertex Arrays */
    glBegin(GL_QUADS);

    glTexCoord2f(0.0f, 0.0f); glVertex2f(0, 0);
    glTexCoord2f(1.0f, 0.0f); glVertex2f(texture_width, 0.0f);
    glTexCoord2f(1.0f, 1.0f); glVertex2f(texture_width, texture_height);
    glTexCoord2f(0.0f, 1.0f); glVertex2f(0, texture_height);

    glEnd();
}

Ключ в том, чтобы изменить проекцию по мере необходимости.Матрица проекции OpenGL не является частью священных данных, которые не должны касаться.На самом деле вы должны изменить его, когда вы видите, что это необходимо, чтобы сделать вещи проще.Менять матрицы - это дешево.То же самое относится и к окну просмотра.Это просто набор регистров (с точки зрения шейдеров они называются униформами), которые можно установить практически бесплатно.

0 голосов
/ 08 сентября 2011

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

Например, чтобы нарисовать блок 10 на 10 пикселей (игнорировать устаревшие API).

glBegin( GL_QUADS );
glVertex2d(0.0                    ,0.0);
glVertex2d(10.0/viewportWidth * 2,0.0);
glVertex2d(10.0/viewportWidth * 2,10.0/viewportHeight * 2);
glVertex2d(0.0                    ,10.0/viewportHeight * 2);
glEnd();

Вы можете сделать это в шейдере или на процессоре.

Изменение окна просмотра выглядит как еще одно из этих дорогостоящих изменений состояния OpenGL.

ПРИМЕЧАНИЕ. Это может усложниться сболее сложная матрица проекции. (я принимаю значение по умолчанию от -1 до 1)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...