2017-01-19 6 views
0

Предположим, что я воспроизвожу видео на GLSurfaceView с помощью специального средства визуализации, а в упомянутом рендерере я использую фрагментарный шейдер, который использует дополнительную текстуру для фильтрации поиска. Указанный фрагмент шейдер выглядит следующим образом:GLES20 Texturing - do glUniform1i (uniformLoc, txtUnit) до или после glActiveTexture() + glBindTexture()?

#extension GL_OES_EGL_image_external : require 
precision mediump float; 

uniform samplerExternalOES u_Texture; 
uniform sampler2D inputImageTexture2; 

varying highp vec2 v_TexCoordinate; 

void main() 
{ 
    vec3 texel = texture2D(u_Texture, v_TexCoordinate).rgb; 
    texel = vec3(
     texture2D(inputImageTexture2, vec2(texel.r, .16666)).r, 
     texture2D(inputImageTexture2, vec2(texel.g, .5)).g, 
     texture2D(inputImageTexture2, vec2(texel.b, .83333)).b 
    ); 

    gl_FragColor = vec4(texel, 1.0); 
} 

В функции onDrawFrame() после glUseProgram() вызова, у меня есть функция, которая в основном onPreDrawFrame() связывающейся текстурная в форму шейдера. В настоящее время она выглядит следующим образом:

public void onPreDrawFrame() 
{ 
    if (filterSourceTexture2 != -1 && filterInputTextureUniform2 != -1) { 
     GLES20.glActiveTexture(GLES20.GL_TEXTURE2); 
     GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, filterSourceTexture2); 
     GLES20.glUniform1i(filterInputTextureUniform2, 2); 
    } 
} 

filterSourceTexture2 является текстурным блоком, соответствующий дополнительной текстура.

Что я запутался в том, что если я ставлю glUniform1i() вызов до glActiveTexture(), он все еще работает хорошо, но большинство из учебников я видел поставить glUniform1i() вызов, как приведенный выше код.

Итак, какой из них рекомендуется?

ответ

0

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

Теперь в большинстве случаев вы увидите ту же последовательность, что уже упоминалось: active, bind, set uniform. Но когда дело доходит до оптимизации кода, это изменится:

Поскольку вы можете уменьшить трафик на GPU, вы захотите уменьшить избыточные звонки в униформу. Единый единообразный вызов вам не принесет много пользы, но все же ... Вы инициализируете шейдер, а затем устанавливаете все униформы по умолчанию, поэтому вы не будете устанавливать их при каждом обращении кадра кадра. В вашем случае это означает, что у вас будет 2 текстуры, а для первого это всегда будет активная текстура 0, а вторая - всегда активная текстура 1. Поэтому сначала установите 2 формы, а затем, когда вам нужно привязать новые текстуры, просто выполните что, предпочтительно, не в каждом розыгрыше.

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

if(this.myUniform != newValue) { 
    this.myUniform = newValue; 
    GLES20.glUniform1i(filterInputTextureUniform2, newValue); 
} 

Но проблема эта система может в конец будет медленнее, если вы на самом деле просто установите форму снова.

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

И просто замечание о «большинстве учебников»:

Большинство учебников вы найдете предназначены, чтобы показать вам, как API работает. Они предназначены для того, чтобы вы могли легко определить, какие вызовы должны быть сделаны и в каком порядке (если таковые имеются). Это приводит к обычному коду в одном исходном файле, который не должен выполняться для реальных приложений. Не забудьте создать свои инструменты по своему усмотрению и разделить их на разные классы.В конце ваш метод «на рисование» должен иметь не более 50 строк независимо от размера проекта или сцен, которые вы рисуете.