目前使用Android Studio,用Java和GLES3编写移动应用程序。我试图在我的程序中获取多个纹理,似乎我的着色器只会绘制 GL_TEXTURE0 中的内容,无论我是否将其设置不同。 这是我正在使用的纹理类:
public class Texture {
private int[] id;
byte tex[];
int slot;
private void loadImageBytes(Bitmap bm) {
// ...
}
public Texture(Context context, String filename, int textureslot) {
id = new int[1]; slot = textureslot;
GLES30.glGenTextures(1, id, 0);
GLES30.glActiveTexture(GLES30.GL_TEXTURE0 + textureslot);
GLES30.glBindTexture(GLES30.GL_TEXTURE_2D, id[0]);
GLES30.glTexParameteri(GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_WRAP_S, GLES30.GL_CLAMP_TO_EDGE);
GLES30.glTexParameteri(GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_WRAP_T, GLES30.GL_CLAMP_TO_EDGE);
//GLES30.glTexParameteri(GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_MIN_FILTER, GLES30.GL_LINEAR_MIPMAP_LINEAR);
//GLES30.glTexParameteri(GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_MAG_FILTER, GLES30.GL_LINEAR);
GLES30.glTexParameteri(GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_MAG_FILTER, GLES30.GL_NEAREST);
int height = 0;
int width = 0;
try {
Bitmap bm = BitmapFactory.decodeStream(context.getAssets().open(filename));
height = bm.getHeight();
width = bm.getWidth();
tex = new byte[height * width * 4];
loadImageBytes(bm);
}
catch (IOException e) {
Log.e("MYAPP", "exception", e);
}
GLES30.glTexImage2D(GLES30.GL_TEXTURE_2D, 0, GLES30.GL_RGBA, width, height, 0, GLES30.GL_RGBA,
GLES30.GL_UNSIGNED_BYTE, ByteBuffer.wrap(tex));
GLES30.glGenerateMipmap(GLES30.GL_TEXTURE_2D);
}
public void activeToShader(ShaderProgram sp, String nume){
GLES30.glActiveTexture(GLES30.GL_TEXTURE0 + slot);
sp.setUniform1ui(nume, slot);
}
/* This is the function that is called here
void setUniform1ui(String name, int data) {
int locc = GLES30.glGetUniformLocation(id, name);
if (locc == -1){
Log.e("UniformError", "Uniform not found: " + name);
}
GLES30.glUniform1ui(locc, data);
}
*/
}
我只使用了 1 个着色器程序和 1 个初始化一次的纹理。
ts2 = new Texture(getBaseContext(), "apple.png", 1); // I will call this line A
//shader.setUniform1ui("m_texture", ts2.slot);
int locc = GLES30.glGetUniformLocation(shader.getId(), "m_texture");
if (locc == -1) Log.e("PROGRAM", "Location not found");
GLES30.glUniform1ui(locc, 1); // I will call this line B
int locc = GLES30.glGetUniformLocation(shader.getId(), "thing");
//GLES30.glUniform1f(locc, 1.0f);
shader.setUniform1ui("thing", 1.0f);
A 行和 B 行中有 2 个整数参数。在 A 行中,如果我输入 0,无论我在 B 行中输入什么,它都会绘制苹果。如果我输入 0 以外的任何内容,它都不会绘制苹果苹果,不管 B 行是什么。 另外,我知道它会找到制服并向其写入一些内容,因为我没有收到任何错误。另外,我测试了统一的“东西”,它工作得很好。
这是片段着色器:
"#version 300 es \n" +
"precision mediump float;\n" +
"out vec4 fragColor;\n" +
"uniform sampler2D m_texture;\n" +
"uniform float thing;\n" +
"in vec2 texUV;\n" +
"void main() {\n" +
" fragColor = vec4(1.0,0.0,1.0,1.0);\n" +
" fragColor = texture(m_texture, vec2(texUV.x, 1.0 - texUV.y) );\n" +
" if (fragColor.a == 0.0) fragColor = vec4(0, 0, 255, 255);\n" + // modifying the background color into something, works as expected if the texture is in slot 0
" //fragColor = vec4(0.0f, 1.0f, thing, 1.0f);\n" +
"}";
(将纹理绑定到插槽 1 时)程序不显示背景,但很可能来自空纹理 0 插槽的黑屏。 我还尝试每帧更新sampler2d(不起作用),每帧修改“东西”(工作正常),使用另一个纹理(相同的结果)。另外,我的设备上的最大纹理数是 32。我正在运行带有 api 28 的 Pixel 2 模拟器。任何帮助将不胜感激。
更新:我尝试使用 glGetError 并发现导致问题的行是 GLES30.glUniform1ui(locc, 1)。我仍然不知道为什么也不知道如何解决。
看来统一的sampler2D应该接受一个int,而不是一个无符号的int,我通过简单地使用
GLES30.glUniform1i(locc, 1);
解决了它。我将把它留在这里给其他有同样问题的人。