如何将Java数组赋值给片段着色器uniform vec2数组,GLES20.glUniform2fv用法
给OpenGL ES着色器uniform vec2数组传值的实现方法
你猜测的GLES20.glUniform2fv接口完全正确,具体操作按以下步骤进行:
操作步骤
- 第一步:获取uniform数组的起始位置
注意获取数组类型uniform的位置时,需要在变量名后加[0]后缀,指向数组第一个元素的地址:
如果返回值为-1,说明该uniform被GL优化(着色器中未实际使用),需要先检查着色器代码。int positionsLoc = GLES20.glGetUniformLocation(yourShaderProgram, "positions[0]"); - 第二步:准备Java侧的浮点数组
每个vec2对应2个float值,10个元素的数组总共需要20位的float数组,按[x0,y0,x1,y1,...,x9,y9]的顺序填充数值:float[] positionsArray = new float[2 * 10]; // 填充数值示例 positionsArray[0] = 0.5f; // 对应着色器positions[0].x positionsArray[1] = 0.5f; // 对应着色器positions[0].y positionsArray[2] = -0.5f; // 对应着色器positions[1].x positionsArray[3] = 0.5f; // 对应着色器positions[1].y // 后续依次填充剩下的元素 - 第三步:调用接口传值
确保当前已经调用GLES20.glUseProgram(yourShaderProgram)绑定了对应着色器程序后,执行传值:
各参数含义:GLES20.glUniform2fv(positionsLoc, 10, positionsArray, 0);- 第一个参数:刚才拿到的uniform起始位置
- 第二个参数:要传入的
vec2元素总数,此处填10,不要填总float数20,是高频错误点 - 第三个参数:填充好的Java float数组
- 第四个参数:数组读取的起始偏移位,从数组头部开始传填0即可
可选:使用FloatBuffer高效传值
如果需要频繁更新数组内容,推荐使用直接Native缓冲区减少内存拷贝开销:
// 缓冲区初始化只需要执行一次 FloatBuffer positionBuffer = ByteBuffer.allocateDirect(2 * 10 * 4) // 每个float占4字节 .order(ByteOrder.nativeOrder()) .asFloatBuffer(); // 每次更新数值时填充缓冲区 positionBuffer.put(positionsArray); positionBuffer.position(0); // 传值调用 GLES20.glUniform2fv(positionsLoc, 10, positionBuffer);
注意事项
- 所有GL操作必须在GL线程中执行
- 传值前必须先绑定对应着色器程序
- 传入的count值不能超过着色器中定义的数组长度(此处最多为10)
内容的提问来源于stack exchange,提问作者GoatPonny
相关产品推荐
相关产品推荐

