Как нарисовать текстуру в качестве 2D фона в OpenGL ES 2.0? - PullRequest
17 голосов
/ 27 октября 2010

Я только начинаю работать с OpenGL ES 2.0, и я хотел бы создать простой 2D-вывод.Учитывая разрешение 480x800, как я могу нарисовать текстуру фона?

[Моя среда разработки - Java / Android, так что примеры, непосредственно относящиеся к этому, были бы лучше, но другие языки были бы хороши.]

Ответы [ 2 ]

30 голосов
/ 19 ноября 2010

Несмотря на то, что вы работаете на Android, я создал пример приложения для iPhone, которое делает это для входящих видеокадров. Вы можете скачать код для этого примера с здесь .У меня есть запись об этом приложении, которое выполняет отслеживание объектов на основе цвета с использованием живого видео, которое вы можете прочитать здесь .

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

   static const GLfloat squareVertices[] = {
        -1.0f, -1.0f,
        1.0f, -1.0f,
        -1.0f,  1.0f,
        1.0f,  1.0f,
    };

    static const GLfloat textureVertices[] = {
        1.0f, 1.0f,
        1.0f, 0.0f,
        0.0f,  1.0f,
        0.0f,  0.0f,
    };

Чтобы пройти через видеокадр как текстуру, я использую простую программу со следующим вершинным шейдером:

attribute vec4 position;
attribute vec4 inputTextureCoordinate;

varying vec2 textureCoordinate;

void main()
{
    gl_Position = position;
    textureCoordinate = inputTextureCoordinate.xy;
}

и следующиеФрагмент шейдера:

varying highp vec2 textureCoordinate;

uniform sampler2D videoFrame;

void main()
{
    gl_FragColor = texture2D(videoFrame, textureCoordinate);
}

Рисование - это простое использование правильной программы:

glUseProgram(directDisplayProgram);

настройка формы текстуры:

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, videoFrameTexture);

glUniform1i(uniforms[UNIFORM_VIDEOFRAME], 0);   

установка атрибутов:

glVertexAttribPointer(ATTRIB_VERTEX, 2, GL_FLOAT, 0, 0, squareVertices);
glEnableVertexAttribArray(ATTRIB_VERTEX);
glVertexAttribPointer(ATTRIB_TEXTUREPOSITON, 2, GL_FLOAT, 0, 0, textureVertices);
glEnableVertexAttribArray(ATTRIB_TEXTUREPOSITON);

и затем рисуем треугольники:

glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
14 голосов
/ 10 декабря 2010

Вы на самом деле не рисуете фон, вместо этого вы рисуете прямоугольник (или, еще более правильно: два треугольника, образующие прямоугольник) и задаете для него текстуру. Это ничем не отличается от рисования любого другого объекта на экране.

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

Сложная задача - показать что-то перед или за чем-то другим. Чтобы это работало, вам нужно настроить буфер глубины и включить тестирование глубины (glEnable (GL_DEPTH_TEST)). И ваши вершины должны иметь координату Z (и сообщить glDrawElements, что ваши вершины состоят из трех значений, а не двух).

Если вы этого не сделаете, объекты будут отображаться в порядке вызова их функций glDrawElements () (то есть, в зависимости от того, что вы рисуете последним, все остальные будут скрыты).

Мой совет: не иметь фонового изображения или делать что-то необычное, пока вы не овладеете им. OpenGL ES 2.0 имеет вид крутой кривой обучения, и учебные пособия по ES 1.x на самом деле не помогают заставить 3D работать, потому что они могут использовать вспомогательные функции, такие как gluPerspective, которых 2.0 просто нет. Начните с создания треугольника на фоне ничего. Затем сделайте квадрат. Затем, если вы хотите стать более модным, добавьте текстуру. Играй с позициями. Посмотрите, что происходит, когда вы меняете значение Z ваших вершин. (Подсказка: не так много, если у вас не включено тестирование глубины. И даже тогда, если у вас нет перспективной проекции, объекты не станут меньше, чем дальше, так что все равно будет казаться, что ничего случилось)

Через несколько дней он перестает быть таким чертовски разочаровывающим, и вы, в основном, "получаете это", в основном.

...