Android 如何将图形调用和采样值的更改与单个着色器程序正确混合?
我试图在OpenGL ES 2.0 for Android中使用一个着色器程序,使用两种不同的纹理绘制两个对象。第一个对象应该具有Android 如何将图形调用和采样值的更改与单个着色器程序正确混合?,android,opengl-es,opengl-es-2.0,Android,Opengl Es,Opengl Es 2.0,我试图在OpenGL ES 2.0 for Android中使用一个着色器程序,使用两种不同的纹理绘制两个对象。第一个对象应该具有texture0,第二个对象应该具有texture1 在片段着色器中,我有: uniform sampler2D tex; 在java代码中: int tiu0=0; int tiu1=1; int-texLoc=glGetUniformLocation(程序,“tex”); glUseProgram(程序); //将纹理0绑定到纹理图像单元0 玻璃结构(GL_纹理
texture0
,第二个对象应该具有texture1
在片段着色器中,我有:
uniform sampler2D tex;
在java代码中:
int tiu0=0;
int tiu1=1;
int-texLoc=glGetUniformLocation(程序,“tex”);
glUseProgram(程序);
//将纹理0绑定到纹理图像单元0
玻璃结构(GL_纹理0+tiu0);
glBindTexture(GL_TEXTURE_2D,texture0);
//将纹理1绑定到纹理图像单元1
玻璃结构(GL_纹理0+tiu1);
glBindTexture(GL_TEXTURE_2D,texture1);
glUniform1i(texLoc,tiu0);
//成功:glGetError返回GL_NO_错误,glGetUniformiv为texLoc返回0
drawFirstObject();//应该有纹理0
glUniform1i(texLoc,tiu1);
//成功:glGetError返回GL_NO_ERROR,glGetUniformiv为texLoc返回1
drawSecondObject();//应该有纹理1
在三星Galaxy Ace和Android 2.3.3上运行,两个对象具有相同的texture0
。类似的代码在我的桌面计算机上的OpenGL 2.0中正确运行
如果删除drawFirstObject
,则第二个对象将具有texture1
如果删除drawSecondObject
,第一个对象将具有texture0
如果在drawFirstObject
和drawSecondObject
之间的某个位置,我会更改程序一段时间:
glUseProgram(0);//也可以是除下一次调用的程序之外的任何有效程序
glUseProgram(程序);
然后两个对象都将具有纹理1
始终正确设置与sampler2D
不同的制服值
我知道我可以只使用一个纹理图像单元绘制具有不同纹理的两个对象,并在绘制对象之前将适当的纹理绑定到该纹理图像单元,但我也想知道这里发生了什么
我的代码有问题吗?在OpenGL ES 2.0中,是否可以仅通过在纹理图像单元之间切换来绘制具有不同纹理的对象,如我在代码中所示?如果这是不可能的,那么OpenGL2.0(如果可能的话)和OpenGLES2.0之间的差异是否在任何地方都有记录?我找不到它。经过数小时的进一步研究,我发现这个问题是我的三星Galaxy Ace(GT-S5830)中使用的Adreno 200 GPU特有的。似乎在第一次调用绘图函数时,Adreno 200驱动程序会将纹理指定给采样器,之后它会忽略采样器值的任何更改(
glUniform1i(采样器位置,textureImageUnit)
),直到出现以下两种情况之一:
使用不同的着色器程序调用glUseProgram
- 不同的纹理绑定到着色器程序使用的任何纹理图像单元
glUseProgram(0);glUseProgram(您的绘图程序)代码>在每个绘图功能之前
我不认为您的代码在概念上有任何问题,而且您似乎有正确的想法。你在检查代码中的错误吗?是的。在这个程序中,glGetError在每次调用任何OpenGL函数后都返回GL_NO_ERROR。将一个纹理单元(比如0)重新绑定到不同的纹理是否有效?是的,重新绑定有效。问题出在GPU驱动程序上,我发布了答案。谢谢你,我自己也不知道如何缩小问题的范围。