GLES Sampler2d 只会绘制第一个纹理槽中的内容

问题描述 投票:0回答:1

目前使用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)。我仍然不知道为什么也不知道如何解决。

java opengl-es glsl
1个回答
0
投票

看来统一的sampler2D应该接受一个int,而不是一个无符号的int,我通过简单地使用

GLES30.glUniform1i(locc, 1);
解决了它。我将把它留在这里给其他有同样问题的人。

© www.soinside.com 2019 - 2024. All rights reserved.