Рендеринг в текстуру OpenGL ES 2.0

Я пытаюсь использовать оптимизированную для аппаратного обеспечения 2D-библиотеку для увеличения и уменьшения изображения (масштабирование без интерполяции). Прямо сейчас я

  1. Загрузка исходного изображения
  2. Создание копии исходного изображения
  3. Использование 2D-библиотеки для «увеличения» копии
  4. Генерация текстур с помощью glTexImage2D из изображений
  5. Применение их к прямоугольникам, которые я нарисовал

Я не могу загружать изображения (пока), но вот ссылка на скриншот. http://img.photobucket.com/albums/v336/prankstar008/zoom.png

Я хотел бы увеличивать и уменьшать изображение справа на определенную величину в каждом кадре, и вместо того, чтобы убивать свою производительность, используя glTexImage2D каждый раз, я хотел бы отображать текстуру. Мои вопросы

  1. Является ли это допустимым применением рендеринга текстуры? Для пояснения: 2D-библиотека принимает указатель на буфер, заполненный необработанными данными RGB(A), и возвращает указатель на новые данные с примененной 2D-операцией.
  2. Я думаю, что большая часть моего замешательства связана с тем, как текстуры взаимодействуют с шейдерами. Может ли кто-нибудь объяснить самый простой способ применить текстуру к поверхности в GLES2? У меня явно что-то работает, и я могу опубликовать фрагменты кода, если это необходимо.
  3. Также для уточнения, хотя я не уверен, что это имеет значение, это выполняется на Android.

Спасибо.


person Josh A.    schedule 30.09.2011    source источник
comment
Зачем генерировать новые текстуры для разных уровней масштабирования? Нет нет нет! Измените координаты текстуры или даже просто измените матрицы проекции/вида. Одна текстура полного изображения выполняет свою работу.   -  person Steven Lu    schedule 17.01.2012
comment
Цель этого приложения — продемонстрировать возможности 2D-библиотеки. По сути, это черный ящик, где на входе — текстура (указатель на буфер), а на выходе — новая текстура (новый указатель). Я согласен, что есть гораздо лучшие способы масштабирования, но они не применимы к этому проекту.   -  person Josh A.    schedule 19.01.2012


Ответы (1)


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

2) Шейдеры - это программы, которые способны вычислять и преобразовывать координаты (что обычно делается в вершинных шейдерах) и могут использовать эти координаты для чтения из текстуры (что в то время можно было сделать только во фрагментном шейдере).

Я считаю, что ваши шейдеры могут выглядеть так:

precision mediump float;

uniform matrix4 modelviewProjectionMatrix; // input transformation matrix

attribute vec3 position;
attribute vec2 texcoord; // input coordinates of each vertex

varying vec2 _texcoord; // output coordinate for fragment shader

void main()
{
    gl_Position = modelviewProjectionMatrix * vec4(position, 1.0); // transform position
    _texcoord = texcoord; // copy texcoord
}

Это был вершинный шейдер, а теперь фрагментный шейдер:

precision mediump float;

varying vec2 _texcoord; // input coordinate from vertex shader

uniform sampler2D _sampler; // handle of a texturing unit (e.g. 0 for GL_TEXTURE0)

void main()
{
    gl_FragColor = glTexture2D(_sampler, _texcoord); // read texture
}

Что вы можете сделать, так это включить параметр масштабирования (так называемый юниформ) в вершинный шейдер:

precision mediump float;

uniform float zoom; // zoom
uniform matrix4 modelviewProjectionMatrix; // input transformation matrix

attribute vec3 position;
attribute vec2 texcoord; // input coordinates of each vertex

varying vec2 _texcoord; // output coordinate for fragment shader

void main()
{
    gl_Position = modelviewProjectionMatrix * vec4(position, 1.0); // transform position
    _texcoord = (texcoord - .5) * zoom + .5; // zoom texcoord
}

Во фрагментном шейдере изменений нет. Это просто вычисляет для него разные координаты, и вот как это просто. Чтобы установить масштаб, вам необходимо:

int zoomLocation = glGetUniformLocation(yourProgram, "zoom");
// this is done in init, where you call glGetUniformLocation(yourProgram, "modelviewProjectionMatrix")
// also, zoomLocation is not local variable, it needs to be stored somewhere to be used later when drawing

glUniform1f(zoomLocation, 1 + .5f * (float)Math.sin(System.nanotime() * 1e-8f));
// this will set zoom that will animatically zoom in and out of the texture (must be called after glUseProgram(yourProgram))

Теперь это приведет к увеличению и уменьшению масштаба обеих текстур. Чтобы исправить это (я предполагаю, что вы хотите, чтобы только правильная текстура была увеличена), вам необходимо:

// draw the second quad

glUniform1f(zoomLocation, 1);
// this will set no zoom (1:1 scale)

// draw the first quad

Надеюсь, это поможет ...

person the swine    schedule 20.01.2012