OpenGL着色器。传递浮点数组

3
在我的场景中,我有许多对象需要同时旋转,但旋转的角度不同。
我有一个着色器来计算每个对象的位置,并绘制整个场景(将顶点数组传递到着色器中,并使用顶点数组绘制)。
    "uniform float uRotation;" +
    ...
    "   mat4 mz = mat4(1.0);" +
    "   mz[0][0] = cos(rotation);" +
    "   mz[0][1] = sin(rotation);" +
    "   mz[1][0] = -sin(rotation);" +
    "   mz[1][1] = cos(rotation);" +
    ...
    gl_Position = uMVPMatrix * (aPosition *mz);

我有所有的顶点、索引、颜色等信息存储在数组中(不是每个对象都有一个数组,而是有一个包含顶点偏移量、颜色偏移量等的数组)。
我想将浮点数数组(每个“对象”的角度)传递到一个float[]中,但没有任何反应。
    public void setRotations(float[] rotations)
    {
        GLES20.glUniform3fv(muRotation, rotations.length, rotations, 0);    
    }

如果只使用一个浮点数,那么一切都没问题。
如何为每个对象传递特定的浮点数(例如我想绘制20个矩形(我有一个顶点数组:float[20*3*4]),据我所知,我必须为每个顶点设置浮点数:rotations: float[20*4])?
更新:
我尝试将数组作为纹理传递。
当我为场景创建资源时 - 我尝试创建我的数组(称为mask):
    mask = new float[512*512*4];
    for (int i = 0; i < mask.length; i++)
    {
        mask[i] = 2f;
    }

    GLES20.glActiveTexture(GLES20.GL_TEXTURE1);
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 1029384756);
    GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 1, GLES20.GL_RGBA, 512, 512, 0, GLES20.GL_RGBA, GLES20.GL_FLOAT, FloatBuffer.wrap(mask));
    GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
    GLES20.glActiveTexture(GLES20.GL_TEXTURE0);

当我在场景中绘制新物品时,我使用着色器并尝试传递我的数组:

    setShaderProgram(ShaderProgram.getInstance());

    GLES20.glActiveTexture(GLES20.GL_TEXTURE1);
    GLES20.glUniform1i(ShaderProgram.sUniformMask, GLES20.GL_TEXTURE1);
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 1029384756);
    GLES20.glActiveTexture(GLES20.GL_TEXTURE0);

但是当我尝试检查数组中的任何值是否大于0.5时,每次计算都会返回 false 更新 片段着色器包含:
"uniform sampler2D " + ShaderProgramConstants.UNIFORM_TEXTURE_0 + ";\n" +
"uniform sampler2D " + ShaderProgramConstants.UNIFORM_TEXTURE_1 + ";\n" +
"varying mediump vec2 " + ShaderProgramConstants.VARYING_TEXTURECOORDINATES + ";\n" +

"void main() {\n" +
"vec4 color = texture2D(" + ShaderProgramConstants.UNIFORM_TEXTURE_0 + ", " + ShaderProgramConstants.VARYING_TEXTURECOORDINATES + ");\n" +
"vec4 mask = texture2D(" + ShaderProgramConstants.UNIFORM_TEXTURE_1 + ", " + ShaderProgramConstants.VARYING_TEXTURECOORDINATES + ");\n" +
"float maskVal = mask.r;\n" ...

颜色和遮罩纹理具有相同的尺寸。


你可以将数组作为一维纹理传递。你也可以将一块uniforms作为UBO传递,但如果你的数组很大,这并没有什么帮助。最好的方法是填充一个纹理并发送它。 - Michael IV
我已经为每个元素准备好了纹理,我不明白你的意思。也许你有一些好的教程链接吗?谢谢。 - dilix
实际上,您应该检查ES是否支持一维纹理。将您的数组值传递到glTexImage1D,并使用类型GL_TEXTURE_1D的目标。然后您可以在着色器中读取它。我是基于OpenGL桌面API编写的。请检查您是否可以在ES中完成此操作。 - Michael IV
你的着色器在做什么?你有一个Sampler2D和一个纹理坐标来采样纹理吗? - Tim
着色器非常简单(检查编辑) - dilix
我稍微尝试了一下你的代码。这个更改对我有效:GLES31.glTexImage2D(GLES20.GL_TEXTURE_2D,0,GLES31.GL_R32F,512,512,0,GLES31.GL_RED,GLES20.GL_FLOAT,FloatBuffer.wrap(mask))。 - neoexpert
1个回答

3

GLES20.glUniform1i(ShaderProgram.sUniformMask, GLES20.GL_TEXTURE1);

如果这是你的采样器统一变量,应该这样写:

GLES20.glUniform1i(ShaderProgram.sUniformMask, 1);(而不是GL_TEXTURE1)

对于采样器0也是类似的:

GLES20.glUniform1i(ShaderProgram.sUniformMask, 0);


也许需要类似于glGentexture的东西? - dilix
当我尝试使用GLES20.glUniform1i(ShaderProgram.sUniformMask, 1)时,出现错误1282(无效操作)。 - dilix
@dilix 你解决了这个错误吗?确保你的sUniformMask有一个有效的值,并且绑定了一个有效的着色器。有几个原因会导致无效操作,可以在此页面底部查看原因。 - Tim
是的,问题在于我在丢弃片段着色器之前尝试绑定我的统一变量,谢谢 =) - dilix

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接