GLES20纹理 - 在glActiveTexture()+ glBindTexture()之前或之后我是glUniform1i(uniformLoc,txtUnit)吗?

时间:2017-01-19 06:42:25

标签: android opengl-es

假设我使用自定义渲染器在function updateMapLive(positions) { for (i = 0; i < positions.length; i++) { console.log(positions[i].longitude + "," + positions[i].latitude); var latlong = positions[i].longitude + "," + positions[i].latitude; var deviceid = positions[i].deviceId; var Q = new Queue(); Q.enqueue(latlong); arr.push(latlong); console.log(deviceid); } } function Queue() { this.stac = new Array(); this.dequeue = function () { return this.stac.pop(); } this.enqueue = function (item) { this.stac.unshift(item); } } 上播放视频,并在所述渲染器中使用片段着色器,该片段着色器采用额外的纹理进行查找过滤。所述片段着色器如下所示:

GLSurfaceView

#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()像上面的代码一样。

那么推荐哪个?

1 个答案:

答案 0 :(得分:0)

2没有区别。穿过制服的是在片段着色器中应该使用哪个活动纹理。接下来,您需要将纹理id绑定到实际的活动纹理。因此,您将在此处看到的唯一顺序是必须在绑定之前调用活动纹理。

现在在大多数情况下,您将看到与已经提到的相同的序列:active,bind,set uniform。但是当谈到优化代码时,这将改变:

由于您可能希望减少GPU的流量,因此您需要减少对制服的冗余调用。单一的统一调用对你没什么好处,但仍然......你将初始化着色器,然后设置所有默认的制服,这样你就不会在每个并条机调用上设置它们。在你的情况下,这意味着你将有2个纹理,对于第一个,这将始终是活动纹理0,而第二个总是活动纹理1.所以首先设置2个制服,然后一旦你需要绑定新纹理,只需做那,最好不是每次抽奖。

其他一些实现包括您有一个自定义着色器对象,它会记住您之前的设置,因此它不会再次向着色器发送相同的值:

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

但问题是如果你真的只是再次设置制服,这个系统最终可能会慢一些。

所以推荐的实际答案是:如果可能的话,我建议先在一些初始化中设置制服,这意味着序列甚至不在同一个方法中。但是如果他们使用相同的方法,我建议你最后设置制服,因为可读性,但这意味着先设置两个纹理(主动加上绑定),然后依次设置2个制服。

只是关于&#34;大多数教程&#34;

的说明

您将找到的大多数教程旨在向您展示API的工作原理。它们旨在让您能够轻松识别必须进行的呼叫以及以何种顺序(如果有)。这导致通常将所有代码放在单个源文件中,而不应该为实际应用程序完成。请记住根据需要构建工具并将它们分成不同的类。最后你的'#34;平局&#34;无论项目的大小或绘制的场景如何,方法都不应超过50行。