Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/219.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 无法使用OpenGL ES着色器,是否每帧调用glLinkProgram?_Android_Opengl Es_Opengl Es 2.0_Glsl - Fatal编程技术网

Android 无法使用OpenGL ES着色器,是否每帧调用glLinkProgram?

Android 无法使用OpenGL ES着色器,是否每帧调用glLinkProgram?,android,opengl-es,opengl-es-2.0,glsl,Android,Opengl Es,Opengl Es 2.0,Glsl,我正在尝试在OpenGLES2.0中创建透明对象。这是一个实时壁纸,我使用GLWallperService作为基类。我以这种方式设置OpenGL: GLES20.glEnable(GLES20.GL_DEPTH_TEST); GLES20.glDepthFunc(GLES20.GL_GEQUAL); GLES20.glClearDepthf(0.0f); GLES20.glClearColor(0.0f, 0.0f, 1.0f, 1.0f); 我使用的着色器来自PowerVR样本OGLES2A

我正在尝试在OpenGLES2.0中创建透明对象。这是一个实时壁纸,我使用GLWallperService作为基类。我以这种方式设置OpenGL:

GLES20.glEnable(GLES20.GL_DEPTH_TEST);
GLES20.glDepthFunc(GLES20.GL_GEQUAL);
GLES20.glClearDepthf(0.0f);
GLES20.glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
我使用的着色器来自PowerVR样本OGLES2AlphaTest,用于alpha测试,在我的HTC Desire设备上运行良好。 以下是着色器的代码:

private final String mVertexShader = "uniform highp mat4 uMVPMatrix;\n" +
        "attribute highp vec4 aPosition;\n" +
        "attribute highp vec2 aTextureCoord;\n" +
        "varying mediump vec2 vTextureCoord;\n" +
        "void main() {\n" +
        "  gl_Position = uMVPMatrix * aPosition;\n" +
        "  vTextureCoord = aTextureCoord;\n" +
        "}\n";

private final String mFragmentShader = "precision mediump float;\n" +
        "varying mediump vec2 vTextureCoord;\n" +
        "uniform sampler2D sTexture;\n" +
        "void main() {\n" +
        "  vec4 base = texture2D(sTexture, vTextureCoord);\n" +
        "  if(base.a < 0.5){ discard; }\n" +
        "  gl_FragColor = base;\n" +
        "}\n";

private int createProgram(String vertexSource, String fragmentSource) {
    int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexSource);
    if (vertexShader == 0) {
        return 0;
    }

    int pixelShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentSource);
    if (pixelShader == 0) {
        return 0;
    }

    int program = GLES20.glCreateProgram();
    if (program != 0) {
        GLES20.glAttachShader(program, vertexShader);
        checkGlError("glAttachShader");
        GLES20.glAttachShader(program, pixelShader);
        checkGlError("glAttachShader");
        GLES20.glLinkProgram(program);
        int[] linkStatus = new int[1];
        GLES20.glGetProgramiv(program, GLES20.GL_LINK_STATUS, linkStatus, 0);
        if (linkStatus[0] != GLES20.GL_TRUE) {
            Log.e(TAG, "Could not link program: ");
            Log.e(TAG, GLES20.glGetProgramInfoLog(program));
            GLES20.glDeleteProgram(program);
            program = 0;
        }
    }
    return program;
}

private int loadShader(int shaderType, String source) {
    int shader = GLES20.glCreateShader(shaderType);
    if (shader != 0) {
        GLES20.glShaderSource(shader, source);
        GLES20.glCompileShader(shader);
        int[] compiled = new int[1];
        GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, compiled, 0);
        if (compiled[0] == 0) {
            Log.e(TAG, "Could not compile shader " + shaderType + ":");
            Log.e(TAG, GLES20.glGetShaderInfoLog(shader));
            GLES20.glDeleteShader(shader);
            shader = 0;
        }
    }
    return shader;
}
GLES20.glLinkProgram(mProgram)
在onDrawFrame()的开头,我得到了不正确的结果(透明度不正确):

当我添加
GLES20.glLinkProgram(mProgram)时
onDrawFrame()
的开始部分,它正确渲染,但性能很差,
glLinkProgram()
是一个耗时的函数。以下是正确渲染的屏幕截图:


请解释我做错了什么,显然我不必在每一帧重新绘制时调用
glLinkProgram()

此错误行为的原因与
glLinkProgram()
无关。我已经修改了一些其他GL init参数(现在记不起是哪个参数),现在它工作得很好。

您不需要将程序链接到每一帧,链接一次并将其id存储在某处。然后调用
GLES20.glUseProgram(\u programmaid)


检查一下已经实现的方法:(bindProgram方法就是你想要的)。

你从哪里获得属性/统一位置?特别是MappositionHandle、MatExtralHandle和muMVPMatrixHandle?请将代码张贴在您指定的位置。每次重新链接时,都需要重新分配这些任务。在上面的代码中,我看不出您在哪里指定了这些,以及它们是否准确。检查这些位置句柄以确保它们不是-1(只需检查它们是否有效)。
public void onDrawFrame(GL10 glUnused) {
    //GLES20.glLinkProgram(mProgram);

    GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
    GLES20.glUseProgram(mProgram);
    checkGlError("glUseProgram");

    GLES20.glDisable(GLES20.GL_BLEND);

    GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureID);

    mTriangleVertices.position(TRIANGLE_VERTICES_DATA_POS_OFFSET);
    GLES20.glVertexAttribPointer(maPositionHandle, 3, GLES20.GL_FLOAT, false, TRIANGLE_VERTICES_DATA_STRIDE_BYTES, mTriangleVertices);
    checkGlError("glVertexAttribPointer maPosition");
    mTriangleVertices.position(TRIANGLE_VERTICES_DATA_UV_OFFSET);
    GLES20.glEnableVertexAttribArray(maPositionHandle);
    checkGlError("glEnableVertexAttribArray maPositionHandle");
    GLES20.glVertexAttribPointer(maTextureHandle, 2, GLES20.GL_FLOAT, false, TRIANGLE_VERTICES_DATA_STRIDE_BYTES, mTriangleVertices);
    checkGlError("glVertexAttribPointer maTextureHandle");
    GLES20.glEnableVertexAttribArray(maTextureHandle);
    checkGlError("glEnableVertexAttribArray maTextureHandle");

    long time = SystemClock.uptimeMillis() % 4000L;
    float angle = 0.090f * ((int) time);
    time = SystemClock.uptimeMillis();// % 4000L;
    angle = 0.030f * ((int) time);
    // Matrix.setRotateM(mMMatrix, 0, angle, 0, 0, 1.0f);
    Matrix.setRotateM(mMMatrix, 0, angle, 0, 1.0f, 0);
    Matrix.scaleM(mMMatrix, 0, 0.075f, 0.075f, 0.075f);
    Matrix.multiplyMM(mMVPMatrix, 0, mVMatrix, 0, mMMatrix, 0);
    Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mMVPMatrix, 0);

    GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, mMVPMatrix, 0);
    GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, numPolys);
    checkGlError("glDrawArrays");
}