GL_REPEAT не работает для video.mp4, но хорошо для image.png - PullRequest
0 голосов
/ 03 июля 2018

GL_REPEAT работает нормально для изображения, использующего GL_TEXTURE_2D, но не для mp4, использующего GL_TEXTURE_EXTERNAL_OES. Мне это нужно для создания эффекта прокрутки бесконечного типа для сдвига пикселей и экспорта изменений.

В фрагментном шейдере эффект бесконечной горизонтальной прокрутки может быть достигнут:

uniform float scroll;
void main() {
    vec2 coord = vec2(v_TexCoordinate.x + scroll, v_TexCoordinate.y);
    gl_FragColor = texture2D(u_Texture, coord);
}

В моем GlSurface моя геометрия и начальные настройки gl определены ниже:

private static final float squareVertices[] = {
    -1.0f, 1.0f,    // top left
    -1.0f, -1.0f,   // bottom left
    1.0f, -1.0f,    // bottom right
    1.0f, 1.0f      // top right
};

private static final float textureVertices[] = {                // in counterclockwise order:
    0.0f, 0.0f,
    1.0f, 0.0f,
    1.0f, 1.0f,
    0.0f, 1.0f
};

private void glSetup() {
    final String vertexShader = Utils.readTextFileFromRawResource(mMainActivity,
            R.raw.media_vertex_shader);
    String fragmentShader = null;

    if (isVideo) {
        fragmentShader = Utils.readTextFileFromRawResource(mMainActivity,
                R.raw.media_fragment_shader_video);
    } else {
        fragmentShader = Utils.readTextFileFromRawResource(mMainActivity,
                R.raw.media_fragment_shader_image);
    }

    final int vertexShaderHandle = ShaderHelper.compileShader(GLES20.GL_VERTEX_SHADER,
            vertexShader);
    final int fragmentShaderHandle = ShaderHelper.compileShader(GLES20.GL_FRAGMENT_SHADER,
            fragmentShader);

    int[] textures = new int[1];
    GLES20.glGenTextures(1, textures, 0);
    mTextureId = textures[0];

    GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
    GLES20.glUniform1i(mTextureUniformHandle, 0);

    if (isVideo) {
        GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, mTextureId);
        GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MAG_FILTER,
                GLES20.GL_LINEAR);
        GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MIN_FILTER,
                GLES20.GL_LINEAR);
        GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_WRAP_S,
                GLES20.GL_REPEAT);
        GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_WRAP_T,
                GLES20.GL_REPEAT);

        mSurfaceTexture = new SurfaceTexture(mTextureId);
        mMediaPlayer.setSurface(mSurfaceTexture);
        mSurfaceTexture.setOnFrameAvailableListener(this);
    } else {                        //image
        GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureId);
        GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER,
                GLES20.GL_LINEAR);
        GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER,
                GLES20.GL_LINEAR);
        GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S,
                GLES20.GL_REPEAT);
        GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T,
                GLES20.GL_REPEAT);
    }

    mScrollHandle = GLES20.glGetUniformLocation(mProgramHandle, "scroll");

    Matrix.setIdentityM(mSTMatrix, 0);
}

И onDrawFame ():

@Override
public void onDrawFrame(GL10 gl) {
    if (isVideo) {
        GLES20.glUniformMatrix4fv(muSTMatrixHandle, 1, false, mSTMatrix, 0);
        GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, mTextureId);
        GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MAG_FILTER,
                GLES20.GL_LINEAR);
        GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MIN_FILTER,
                GLES20.GL_LINEAR);
        GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_WRAP_S,
                GLES20.GL_REPEAT);
        GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_WRAP_T,
                GLES20.GL_REPEAT);
        Log.d(TAG, GLES20.glGetError());
    } else {
        GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureId);

        GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureId);
        GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER,
                GLES20.GL_LINEAR);
        GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER,
                GLES20.GL_LINEAR);
        GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S,
                GLES20.GL_REPEAT);
        GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T,
                GLES20.GL_REPEAT);
        GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, mImage, 0);
    }
}

@Override  //only called for video
synchronized public void onFrameAvailable(SurfaceTexture surface) {
    mSurfaceTexture.updateTexImage();
    mSurfaceTexture.getTransformMatrix(stMatrix);;
}

Я вижу GL_INVALID_ENUM при входе в систему GLES20.glGetError ()

Что я пытался сделать:

  1. Изменение размера видео с помощью ffmpeg в POT (power-of-two, 2048 x 1024)
  2. Использование GLES30 / GLES31 / GLES32 для всех вызовов привязки, параметров и т. Д.
  3. Изменение текстурных и квадратных вершин на> 1.0f
  4. Печать ширины / высоты текстуры с помощью GL31.glGetTexLevelParameteriv (), который выводит 0 для ширины и высоты для видео, но правильные размеры для изображения

Не уверен, должен ли GL_Repeat работать с целевым GL_Texture_External_OES для файла mp4. Это звучит так, как будто оно должно быть повторяемым, согласно Разделу примечаний OpenGl

Любые другие предложения, которые можно попробовать, приветствуются!

1 Ответ

0 голосов
/ 09 июля 2018

Это не поддерживается. См. Спецификацию «Выпуск 2»:

https://www.khronos.org/registry/OpenGL/extensions/OES/OES_EGL_image_external.txt

В частности:

  1. Следует ли разрешить режиму обтекания внешней текстуры что-либо кроме CLAMP_TO_EDGE?

    RESOLVED: no
    
...