java - 在 java androidgles20 api 中将纹理单元上传到采样器时出现错误 1281(错误值)

标签 java android 3d glsl opengl-es-2.0

我正在做自己的游戏框架,我发现了一个非常奇怪的行为。当调用 GLES20.glUniform1i(samplerLocation, GLES20.GL_TEXTURE0) 并检查 GLES20.glGetError() 是否发现任何错误时,如果在模拟 Nexus 6 设备的 Genymotion 中执行,我会收到 1281 错误(错误值)。如果我对我的 moto g(2014 版)尝试同样的操作,我不会在 GLES20.glUniform1i 中收到任何错误,但在调用 drawElements 时却收到另一个错误:

03-20 15:09:23.087    9260-9692/com.manu.juegos.half_hero V/GLSurfaceView﹕ glGetString(7937) returns Adreno (TM) 305;
03-20 15:10:15.727    9260-9692/com.manu.juegos.half_hero W/Adreno-ES20﹕ <validate_samplers:252>: GL_INVALID_OPERATION
03-20 15:10:16.628    9260-9692/com.manu.juegos.half_hero E/framework.GLProg error:﹕ post Vertices3D.draw(): glError 1282

你认为我可能做错了什么?

编辑:

这就是我将纹理单元上传到采样器制服的方法:

public void uploadUniformData(String uniformName, Object value){
    // triplet: locator, dataType, dataValue
    Map<String, Triplet<Integer, Integer, Object>> mapa_programa = GlProgram.m_Uniform_Cache_Store.get(m_GL_Program_ID);
    if (mapa_programa == null){
        throw new RuntimeException("GlProgram.uploadUniformData: mapa de programa no inicializado");
    }
    Triplet<Integer, Integer, Object> uniform_data = mapa_programa.get(uniformName);

    if (uniform_data == null){
        return; // por ejemplo normal texture no está implementado y no estará declarado en el shader
    }

    uniform_data.m_Z = value;
    Integer dataType = uniform_data.m_Y;
    Integer location = uniform_data.m_X;

    int[] intValArr = null;
    float[] floatValArr = null;
    int matrixCounterToUpload = 1;
    Integer intVal = null;

    switch (dataType) { // tipo de dato del uniform
        case GLES20.GL_INT:
            intVal = (Integer) value;
            GLES20.glUniform1i(location, intVal);
            break;
        case GLES20.GL_INT_VEC2:
            intValArr = (int[]) value;
            GLES20.glUniform2i(location, intValArr[0], intValArr[1]);
            break;
        case GLES20.GL_INT_VEC3:
            intValArr = (int[]) value;
            GLES20.glUniform3i(location, intValArr[0], intValArr[1], intValArr[2]);
            break;
        case GLES20.GL_INT_VEC4:
            intValArr = (int[]) value;
            GLES20.glUniform4i(location, intValArr[0], intValArr[1], intValArr[2], intValArr[3]);
            break;
        case GLES20.GL_FLOAT:
            Float floatVal = (Float) value;
            GLES20.glUniform1f(location, floatVal);
            break;
        case GLES20.GL_FLOAT_VEC2:
            floatValArr = (float[]) value;
            GLES20.glUniform2f(location, floatValArr[0], floatValArr[1]);
            break;
        case GLES20.GL_FLOAT_VEC3:
            floatValArr = (float[]) value;
            GLES20.glUniform3f(location, floatValArr[0], floatValArr[1], floatValArr[2]);
            break;
        case GLES20.GL_FLOAT_VEC4:
            floatValArr = (float[]) value;
            GLES20.glUniform4f(location, floatValArr[0], floatValArr[1], floatValArr[2], floatValArr[3]);
            break;
        case GLES20.GL_FLOAT_MAT2:
            floatValArr = (float[]) value;
            matrixCounterToUpload = 1; // no subimos array de matrices sino solo una matriz, al menos aquí
            GLES20.glUniformMatrix2fv(location, matrixCounterToUpload, false, floatValArr, 0);
            break;
        case GLES20.GL_FLOAT_MAT3:
            floatValArr = (float[]) value;
            matrixCounterToUpload = 1; // no subimos array de matrices sino solo una matriz, al menos aquí
            GLES20.glUniformMatrix3fv(location, matrixCounterToUpload, false, floatValArr, 0);
            break;
        case GLES20.GL_FLOAT_MAT4:
            floatValArr = (float[]) value;
            matrixCounterToUpload = 1; // no subimos array de matrices sino solo una matriz, al menos aquí
            GLES20.glUniformMatrix4fv(location, matrixCounterToUpload, false, floatValArr, 0);
            break;
        case GLES20.GL_BOOL:
            intVal = (Integer) value;
            GLES20.glUniform1i(location, intVal);
            break;
        case GLES20.GL_BOOL_VEC2:
            intValArr = (int[]) value;
            GLES20.glUniform2i(location, intValArr[0], intValArr[1]);
            break;
        case GLES20.GL_BOOL_VEC3:
            intValArr = (int[]) value;
            GLES20.glUniform3i(location, intValArr[0], intValArr[1], intValArr[2]);
            break;
        case GLES20.GL_BOOL_VEC4:
            intValArr = (int[]) value;
            GLES20.glUniform4i(location, intValArr[0], intValArr[1], intValArr[2], intValArr[3]);
            break;
        case GLES20.GL_SAMPLER_2D:
            GLES20.glUseProgram(this.m_GL_Program_ID);
            intVal = (Integer) value;
            int intvalue = intVal.intValue();

            GLES20.glUniform1i(location, intvalue);
            break;
    }
    this.checkGLError("- error uploading uniform -" + uniformName);
}

最佳答案

此调用未传递正确的值:

GLES20.glUniform1i(samplerLocation, GLES20.GL_TEXTURE0);

采样器制服的值是纹理单元的索引,而不是相应的枚举。因此纹理单元 GL_TEXTURE0 的值为 0GL_TEXTURE1 的值为 1,依此类推。

在此示例中:

GLES20.glUniform1i(samplerLocation, 0);

或者,如果您的枚举值是 GL_TEXTUREn 值之一:

GLES20.glUniform1i(samplerLocation, enumVal - GLES20.GL_TEXTURE0);

关于java - 在 java androidgles20 api 中将纹理单元上传到采样器时出现错误 1281(错误值),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29168639/

相关文章:

java - 为什么 Java 不提示模棱两可的调用?

JAVA递归距离伪代码帮助

android - 拍摄整个屏幕的android屏幕截图

ios - 如何在谷歌或 iOS map 上叠加 3D 模型?

c# - 如何计算 3D 折线拉伸(stretch)的顶点?

java - 将 Web 应用程序移植到 Tomcat : javax. naming.NameNotFoundException:

java - 保存前验证电话号码

android - YouTube API : com. google.api.client.googleapis.json.GoogleJsonResponseException: 403 禁止访问

java - 如何为包含的布局设置java文件?

swift - GLKit 与 Metal 透视矩阵的区别