Подтвердить что ты не робот

Как нарисовать текстуру как 2D-фон в OpenGL ES 2.0?

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

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

4b9b3361

Ответ 1

Даже если вы на 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);

Ответ 2

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

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

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

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

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

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