Начиная с OpenGL ES. Рисование с использованием пикселей - PullRequest
2 голосов
/ 19 февраля 2012

Я начинаю изучать открытый GL в Android (GL10), используя Java, и я следовал некоторым урокам, чтобы рисовать квадраты, треугольники и т. Д.

Теперь я начинаю рисовать некоторые идеи, которые у меня есть, но яЯ действительно запутался с рисованием вершин экрана.Когда я рисую что-то, используя openGL ES, мне нужно указать ту часть экрана, которую я хочу нарисовать, и то же самое для текстуры ...

Итак, я начал делать несколько тестов и печатал полноэкранную текстуру сэти вершины:

(-1, -1, //top left
 -1, 1, //bottom left
 1, -1, //top right
 1, 1); //bottom right

Почему это полноэкранный режим?Разве центр OpenGL не находится сверху слева (0, 0)?Почему с этими вершинами ничья верна?Кажется, что центр действительно является реальным центром экрана, а ширина и высота от -1 ... 1, но я не совсем понимаю, потому что я думал, что центр был в верхнем левом углу ...

Другой вопрос ... Я прочитал много кода на С ++, где они печатают с использованием пикселей.Это кажется действительно необходимым в видеоиграх, использующих пиксели, потому что нужно точное положение вещей, а с -1 ... 1 я не могу быть действительно точным.Как я могу использовать пиксели вместо -1 ... 1?

Действительно спасибо и извините за мой плохой английский.Спасибо

Ответы [ 3 ]

9 голосов
/ 19 февраля 2012

Почему это полноэкранный режим? Разве центр OpenGL не находится сверху слева (0, 0)? Почему с этими вершинами ничья верна? Кажется, что центр действительно является реальным центром экрана, а ширина и высота от -1 ... 1, но я не совсем понимаю, потому что я думал, что центр был в верхнем левом углу ...

Есть 3 вещи, которые собираются вместе. Так называемая область просмотра , так называемые нормализованные координаты устройства (NDC) и проекция из пространства модели в пространство глаза для отсечения пространства в пространство NDC.

Окно просмотра выбирает часть вашего окна, в которую входит диапазон NDC

[-1…1]×[-1…1]

отображается на. Сигнатура функции glViewport(x, y, width, height). OpenGL предполагает, что система координат с восходящими x-координатами NDC направлена ​​вправо, а восходящие y-координаты NDC повышается.

Таким образом, если вы вызываете glViewport(0, 0, window_width, window_height), который также является значением по умолчанию после того, как контекст OpenGL впервые привязан к окну, координата NDC (-1, -1) будет в левом нижнем углу, а координата NDC ( 1,1) в верхнем правом углу окна.

OpenGL начинается со всех преобразований, устанавливаемых в идентичность, что означает, что координаты вершины, которые вы проходите, проходят прямо в пространство NDC и интерпретируются следующим образом. Однако большую часть времени в OpenGL вы применяете к последовательным преобразованиям:

  • * 1023 вида модели *

и

Преобразование вида модели используется для перемещения по всему миру перед неподвижным глазом / камерой (которая всегда находится в (0,0,0)). Размещение камеры просто означает добавление дополнительной трансформации всего мира (просмотр трансформации), это полная противоположность тому, как вы поместите камеру в мире. Фиксированная функция OpenGL называет эту матрицу MODELVIEW , доступной, если для режима матрицы установлено значение GL_MODELVIEW.

Проекционное преобразование является своего рода объективом OpenGL. Вы используете его, чтобы установить, является ли он широким или небольшим углом (в случае перспективы) или краями кубоида (ортопроекция) или даже чем-то другим. Фиксированная функция OpenGL называет эту матрицу PROJECTION , доступной, если для режима матрицы установлено значение GL_PROJECTION.

После того, как примитивы проекции обрезаны, а затем применено так называемое однородное деление , которое создает фактический эффект перспективы, если была применена перспективная проекция.

В этот момент вершины были преобразованы в пространство NDC, которое затем отображается в окне просмотра, как объяснено в начале.


Относительно вашей проблемы: вам нужна проекция , которая отображает координаты вершин 1: 1 в пикселях области просмотра. Достаточно просто:

glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if( origin_lower_left ) {
    glOrtho(0, width, height, 0, -1, 1);
} else {
    glOrtho(0, width, 0, height, -1, 1);
}
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

Теперь координаты вершин отображаются в пикселях области просмотра.


Обновление: рисование текстурированного квадрата полного видового экрана треугольниками:

OpenGL-2.1 и OpenGL ES-1

void fullscreenquad(int width, int height, GLuint texture)
{
    GLfloat vtcs[] = {
      0, 0,
      1, 0,
      1, 1,
      0, 1
    };

    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);

    glVertexPointer(2, GL_FLOAT, 0, vtcs);
    glTexCoordPointer(2, GL_FLOAT, 0, vtcs);

    glViewport(0, 0, width, height);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(0, 1, 0, 1, -1, 1);

    glMatrixMode(GL_MODELVIEW);
    glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, texture);
    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
}
2 голосов
/ 19 февраля 2012

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

2 голосов
/ 19 февраля 2012

По умолчанию камера opengl располагается в начале координат, указывая на отрицательную ось Z.Все, что проецируется на камеру рядом с плоскостью, - это то, что видно на вашем экране.Таким образом, центр экрана соответствует (0,0)

В зависимости от того, что вы хотите нарисовать, у вас есть возможность использовать GL_POINT, GL_LINE и GL_TRIANGLE для рисования.

Вы можете использовать GL_POINTSЧтобы выделить некоторые пиксели на экране, но в случае, если вам нужно нарисовать объекты / сетки, такие как чайник, куб и т. д., чем вы должны пойти для треугольников.

...