本文介绍了不工作的OpenGL ES着色器,调用glLinkProgram每一帧?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图让透明物体的OpenGL ES 2.0。这是一个动态壁纸,我使用GLWallpaperService作为这个基类。我设立的OpenGL是这样的:

I'm trying to make transparent object in OpenGL ES 2.0. It's a live wallpaper, I'm using GLWallpaperService as a base class for this. I'm setting up OpenGL in this way:

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为阿尔法测试,我的HTC Desire设备上正常工作。
这里是code为着色器:

Shaders I use are taken from PowerVR sample OGLES2AlphaTest for alpha testing, which works fine on my HTC Desire device.Here is the code for shaders:

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;
}

code渲染帧:

Code for rendering frame:

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");
}

没有 GLES20.glLinkProgram(mProgram); onDrawFrame的开始()我得到不正确的结果(用不正确透明度):

Without GLES20.glLinkProgram(mProgram); in the start of onDrawFrame() I get incorrect result (with incorrect transparency): http://imgur.com/kESeO

当我加入 GLES20.glLinkProgram(mProgram);在 onDrawFrame开始()它呈现正确,但性能差, glLinkProgram()是耗时的功能。这里是正确的渲染截图:

When I add GLES20.glLinkProgram(mProgram); in the start of onDrawFrame() it renders correctly, but the performance is bad, glLinkProgram() is time-consuming function. Here is screenshot of correct rendering: http://imgur.com/sw83z

请解释一下我做错了,显然我没有打电话给 glLinkProgram()在每一帧重绘。

Please explain what am I doing wrong, apparently I don't have to call glLinkProgram() on every frame redraw.

推荐答案

这不端行为的原因是不相关的 glLinkProgram()。我已经修改了一些其他的GL初始化参数(不记得这在目前),现在它工作得很好。

The cause of this misbehavior was not related to glLinkProgram(). I've modified some other GL init parameters (can't recall which at the moment) and now it works just fine.

这篇关于不工作的OpenGL ES着色器,调用glLinkProgram每一帧?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-21 13:03