Android openGL中的GLES20.glCreateShader(type)始终返回0

时间:2015-03-19 14:45:25

标签: android opengl-es shader

我正在使用openGL 2.0开发Android应用程序。我必须使用着色器将位图图像显示为纹理。 从很多Internet教程中,我创建了一个GlRenderer.java类。在那里,位图图像成功显示为纹理。但要检查着色器的工作情况,当我替换" gl_FragColor = texture2D(sTexture,vTextureCoord);"在片段着色器中,对于" gl_FragColor = vec4(0.0,1.0,0.0,0.0);",输出屏幕上没有发生任何变化。实际上" vec4(0.0,1.0,0.0,0.0)"我猜应该显示绿屏。 为什么会这样?

下面的代码是我的变量和着色器代码。

    private Square      square;     // the square
private Context     context;
private int mTextureUniformHandle ;
private int mTextureCoordinateHandle;
private int mTextureDataHandle;

private FloatBuffer vertexBuffer;   // buffer holding the vertices
private float vertices[] = {
        -1.0f, -1.0f,  1.0f,        // V1 - bottom left
        -1.0f,  1.0f,  1.0f,        // V2 - top left
         1.0f, -1.0f,  1.0f,        // V3 - bottom right
         1.0f,  1.0f,  1.0f         // V4 - top right
};

private FloatBuffer textureBuffer;  // buffer holding the texture coordinates
private float texture[] = {         
        // Mapping coordinates for the vertices
        0.0f, 1.0f,     // top left     (V2)
        0.0f, 0.0f,     // bottom left  (V1)
        1.0f, 1.0f,     // top right    (V4)
        1.0f, 0.0f      // bottom right (V3)
};



/** The texture pointer */
private int[] textures = new int[1];

private final String vertexShaderCode =
        "uniform mat4 uMVPMatrix; " +
        "uniform mat4 uSTMatrix; " +
        "attribute vec4 aPosition; " +
        "attribute vec4 aTextureCoord; " +
        "varying vec2 vTextureCoord; " +

        "void main() { " +
        "  gl_Position = uMVPMatrix * aPosition; " +
        "  vTextureCoord = (uSTMatrix * aTextureCoord).xy; " +
        "} ";

private final String fragmentShaderCode =

        "#extension GL_OES_EGL_image_external : require \n" +

                    "precision mediump float; " +
                    "varying vec2 vTextureCoord; " +
                    "uniform samplerExternalOES sTexture; " +
                    "void main() {" +
                    " ivec2 uv = ivec2(gl_FragCoord.xy) / ivec2(20); "+
                    "vec4 bg; "+
                    "if(mod(float(uv.x + uv.y),2.0)>0.0) {"+

                    "  bg = vec4(0.3,0.3,0.3,1.0);"+
                    " }else{"+
                    " bg = vec4(1.0,1.0,1.0,1.0);"+
                    " }"+
                    "gl_FragColor = bg;"+
                "}";
        private int mProgram;
        private int maPositionHandle;
    private int muMVPMatrixHandle;
    private float[] mProjMatrix = new float[16];
    private float[] mVMatrix = new float[16];
    public float mAngle;
    private float[] mMMatrix = new float[16];
    private float[] mMVPMatrix = new float[16];

以下是onSurfaceCreated():

    @Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
    // TODO Auto-generated method stub

    System.out.println("inside onSurfaceCreated");

    // a float has 4 bytes so we allocate for each coordinate 4 bytes
    ByteBuffer byteBuffer = ByteBuffer.allocateDirect(vertices.length * 4);
    byteBuffer.order(ByteOrder.nativeOrder());

    // allocates the memory from the byte buffer
    vertexBuffer = byteBuffer.asFloatBuffer();

    // fill the vertexBuffer with the vertices
    vertexBuffer.put(vertices);

    // set the cursor position to the beginning of the buffer
    vertexBuffer.position(0);

    byteBuffer = ByteBuffer.allocateDirect(texture.length * 4);
    byteBuffer.order(ByteOrder.nativeOrder());
    textureBuffer = byteBuffer.asFloatBuffer();
    textureBuffer.put(texture);
    textureBuffer.position(0);
    ThisAppGlobals.textureBuffer=textureBuffer;
    // Load the texture for the square
    mTextureDataHandle=loadGLTexture(gl);

            gl.glEnable(GLES20.GL_TEXTURE_2D);          //Enable Texture Mapping ( NEW )
            gl.glClearColor(0.0f, 0.0f, 0.0f, 0.5f);    //Black Background



            // Load/Compile shaders from shader source
               int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode);
               int fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode);
               System.out.println("vertexShader value : " +vertexShader);
               System.out.println("fragmentShader value : " +fragmentShader);
           // Create shader program object
               mProgram = GLES20.glCreateProgram();
               System.out.println("mProgram value : " +mProgram);
               // Attach vertex and fragment shader to program
               GLES20.glAttachShader(mProgram, vertexShader);
               GLES20.glAttachShader(mProgram, fragmentShader);

               // Link shaders to create shader program
               GLES20.glLinkProgram(mProgram);

               // Get vertex shader variable reference
               maPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");
               muMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");


}

loadGLTexture()函数是:

    private int loadGLTexture(GL10 gl) {
    // TODO Auto-generated method stub

    Bitmap tempBitmap = null;
    if(ThisAppGlobals.created3DImage!=null)
    {
        System.out.println("Created3Dimage not null");
    }
    else
    {
        System.out.println("Created3Dimage is null");
    }
    try{
 tempBitmap=ImageResizetoPO2(ThisAppGlobals.created3DImage);
    }catch(NullPointerException e){
        e.printStackTrace();
    }
    // generate one texture pointer
    gl.glGenTextures(1, textures, 0);
    // ...and bind it to our array
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textures[0]);

    // create nearest filtered texture
    gl.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST);
    gl.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);

    try{
         GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0,tempBitmap, 0);
    }catch(NullPointerException e){
        e.printStackTrace();
    }
    return textures[0];
    }

其他使用的功能是:

    private Bitmap ImageResizetoPO2(Bitmap created3dImage) {
    // TODO Auto-generated method stub

            int powWidth = getNextHighestPO2( ThisAppGlobals.screenWidth );
            int powHeight = getNextHighestPO2( ThisAppGlobals.screenHeight );
            Bitmap tempBitmap2 = null;
            try{
            tempBitmap2=Bitmap.createScaledBitmap(created3dImage, powWidth, powHeight, true);
            }catch(NullPointerException e){
                e.printStackTrace();
            }

            return tempBitmap2;
        }

        private int getNextHighestPO2(int n) {
            // TODO Auto-generated method stub
             n -= 1;
                n = n | (n >> 1);
                n = n | (n >> 2);
                n = n | (n >> 4);
                n = n | (n >> 8);
                n = n | (n >> 16);
                n = n | (n >> 32);
                return n + 1;

        }

loadShader()函数是:

    private int loadShader(int type, String shaderCode) {
    // TODO Auto-generated method stub
             // Create shader object of appropriate type
               int shader = GLES20.glCreateShader(type);
               System.out.println("shader value : " +shader);
               // Compile shader source
               GLES20.glShaderSource(shader, shaderCode);
               GLES20.glCompileShader(shader);

               return shader;
}
In the above code shader= GLES20.glCreateShader(type) is always returning zero.

onSurfaceChanged funstion是:

    @Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
    // TODO Auto-generated method stub


         // Set viewport to new extents
           GLES20.glViewport(0, 0, width, height);

       // Compute aspect ratio for proper scaling
           float ratio = (float) width / height;

           // Create perspective projection matrix
           Matrix.frustumM(mProjMatrix, 0, -ratio, ratio, -1, 1, 3, 7);

           // Set camera modelview matrix
           Matrix.setLookAtM(mVMatrix, 0, 0, 0, -3, 0f, 0f, 0f, 0f, 1.0f, 0.0f);


            mTextureUniformHandle = GLES20.glGetUniformLocation(mProgram, "u_Texture");
           mTextureCoordinateHandle = GLES20.glGetAttribLocation(mProgram, "a_TexCoordinate");

           // Set the active texture unit to texture unit 0.
           GLES20.glActiveTexture(GLES20.GL_TEXTURE0);

           // Bind the texture to this unit.
           GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureDataHandle);

           // Tell the texture uniform sampler to use this texture in the shader by binding to texture unit 0.
           GLES20.glUniform1i(mTextureUniformHandle, 0);
 }

onDraw()函数是:

    @Override
public void onDrawFrame(GL10 gl) {
    // TODO Auto-generated method stub


     // Clear frame and depth buffers
       GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);

       // Select shader program
       GLES20.glUseProgram(mProgram);

       // Attaches vertex buffer to shader
       GLES20.glVertexAttribPointer(maPositionHandle, 3, GLES20.GL_FLOAT, false, 12, ThisAppGlobals.textureBuffer);
       GLES20.glEnableVertexAttribArray(maPositionHandle);

       // Compute local transformation (rotation) matrix
       Matrix.setRotateM(mMMatrix, 0, mAngle, 0, 0, 1.0f);

       // Add local transformation into modelview matrix
       Matrix.multiplyMM(mMVPMatrix, 0, mVMatrix, 0, mMMatrix, 0);

       // Add modelview matrix to projection matrix
       Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mMVPMatrix, 0);

       // Pass modelview-projection matrix to shader
       GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, mMVPMatrix, 0);

       draw(gl);

}


private void draw(GL10 gl) {
    // TODO Auto-generated method stub

    // bind the previously generated texture
            gl.glBindTexture(GLES20.GL_TEXTURE_2D, textures[0]);

            // Point to our buffers
            gl.glEnableClientState(GL11.GL_VERTEX_ARRAY);
            gl.glEnableClientState(GL11.GL_TEXTURE_COORD_ARRAY);

            // Set the face rotation
            gl.glFrontFace(GLES20.GL_CW);

            // Point to our vertex buffer
            gl.glVertexPointer(3, GLES20.GL_FLOAT, 0, vertexBuffer);
            gl.glTexCoordPointer(2, GLES20.GL_FLOAT, 0, textureBuffer);

            // Draw the vertices as triangle strip
            gl.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, vertices.length / 3);

            //Disable the client state before leaving
            gl.glDisableClientState(GL11.GL_VERTEX_ARRAY);
            gl.glDisableClientState(GL11.GL_TEXTURE_COORD_ARRAY);

}

0 个答案:

没有答案