OpenGL ES 2.0 for Android

来源:互联网 发布:淘宝退货金额怎么改 编辑:程序博客网 时间:2024/05/17 22:28

1、了解OpenGL着色语言(OpenGL Shading Language)中的三种变量(uniform,attribute和varying) 

①、uniform:是由程序传入给(vertex和fragment)shader的变量,只能使用,不能修改。
            如果uniform变量在vertex和fragment两者之间声明方式完全一样,则它可以在vertex和fragment共享使用。(相当于一个被vertex和fragment shader共享的全局变量)。
            通过函数glUniform**()来赋值。
uniform变量一般用来表示:变换矩阵(viewProjMatrix),材质(material),光照参数(light)和颜色(color)等信息。
②、attribute: 只在vertex shader,不在fragment shader
                        通过函数glBindAttribLocation()、glVertexAttribPointer()来绑定数据和赋值。
attribute变量一般用来表示:一些顶点的数据,如:顶点坐标(vertex),法线(normal),纹理坐标(texcoord),顶点颜色(vertex color)等。
③、varying: vertex和fragment shader之间传递数据。vertex改变,fragment变换。
                        varying变量在vertex和fragment shader二者之间的声明必须是一致。

2、解读ShaderHelper(着色器助手类)  

    编译(compileVertexShader和compileFragmentShader)--->链接(linkProgram)--->验证(validateProgram)

编译

/**           * 编译着色器           * @param type                          着色器类型           * @param shaderCode                     着色器代码           * @return           */          private static int compileShader(int type, String shaderCode){                   int shaderObjectId = glCreateShader(type);                                      if(shaderObjectId == 0){                              if(LoggerConfig.ON){                                        Log.w(TAG, "Coult not create new Shader");                              }                              return 0;                   }                                      glShaderSource(shaderObjectId, shaderCode);                                      glCompileShader(shaderObjectId);                                      int[] compileStatus = new int[1];                   glGetShaderiv(shaderObjectId, GL_COMPILE_STATUS, compileStatus, 0);                                      if(LoggerConfig.ON){                              Log.v(TAG, "Result of compiling source:"+"\n"+shaderCode+"\n"+glGetShaderInfoLog(shaderObjectId));                   }                                      if(compileStatus[0] == 0){                              glDeleteShader(shaderObjectId);                              if(LoggerConfig.ON){                                        Log.w(TAG, "Compilation of shader failed");                              }                              return 0;                   }                                      return shaderObjectId;          }


 

链接

/**           * 链接程序           * @param vertexShaderId                                     顶点着色器Id           * @param fragmentShaderId                         碎片着色器Id           * @return           */          public static int linkProgram(int vertexShaderId, int fragmentShaderId){                   int programObjectId = glCreateProgram();                                      if(programObjectId == 0){                              if(LoggerConfig.ON){                                        Log.w(TAG, "Could not create new Program");                              }                                        return 0;                   }                                      // 附上着色器                   glAttachShader(programObjectId, vertexShaderId);                   glAttachShader(programObjectId, fragmentShaderId);                                      // 链接                   glLinkProgram(programObjectId);                                      int[] linkStatus = new int[1];                   glGetProgramiv(programObjectId, GL_LINK_STATUS, linkStatus, 0);                                      if(LoggerConfig.ON){                              Log.v(TAG, "Results of linking program:\n"+glGetProgramInfoLog(programObjectId));                   }                                      if(linkStatus[0] == 0){                              glDeleteProgram(programObjectId);                              if(LoggerConfig.ON){                                        Log.v(TAG, "Linking of program failed");                              }                              return 0;                   }                                      return programObjectId;          }



验证

/**           * 验证程序           * @param programObjectId                          链接后的程序Id           * @return           */          public static boolean validateProgram(int programObjectId){                   glValidateProgram(programObjectId);                                      int[] validateSatus = new int[1];                   glGetProgramiv(programObjectId, GL_VALIDATE_STATUS, validateSatus, 0);                   Log.v(TAG, "Result of validating program:\n"+glGetProgramInfoLog(programObjectId));                                      return validateSatus[0] != 0;          }





3、开始使用opengl es程序

。。。

4、添加细节纹理(loadTexture

、创建纹理助手类(TextureHelper

/**         * 加载纹理信息         * @param context                                            上下文对象         * @param resourceId                                  资源Id         * @return         */        public static int loadTexture(Context context, int resourceId){               int[] textureObjectId = new int[1];                             // 分配一个纹理对象Id               glGenTextures(1, textureObjectId, 0);                             if(textureObjectId[0] == 0){                       if(LoggerConfig.ON){                               Log.w(TAG, "Could not generate a new OpenGL Texture Object");                       }                       return 0;               }                             // 加载图片资源  绑定纹理数据               BitmapFactory.Options o = new BitmapFactory.Options();               o.inScaled = false;                             Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), resourceId, o);                             if(bitmap == null){                       glDeleteTextures(resourceId, textureObjectId, 0);                       if(LoggerConfig.ON){                               Log.w(TAG, "Resource ID "+resourceId+" could not be decoded");                       }                       return 0;               }                             // 绑定 纹理号 到 纹理目标               glBindTexture(GL_TEXTURE_2D, textureObjectId[0]);                             // 设置纹理参数               glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);               glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);                             // 生成纹理               texImage2D(GL_TEXTURE_2D, 0, bitmap, 0);                             bitmap.recycle();                                           glGenerateMipmap(GL_TEXTURE_2D);                             // 解除绑定               glBindTexture(GL_TEXTURE_2D, 0);                             // 返回纹理对象标识               return textureObjectId[0];        }



②、编写texture_vertex_shader.glsl

uniform mat4 u_Matrix;attribute vec4 a_Position;attribute vec2 a_TextureCoordinates;varying vec2 v_TextureCoordinates;void main(){        v_TextureCoordinates = a_TextureCoordinates;        gl_Position = u_Matrix * a_Position;}



③、编写texture_fragment_shader.glsl

precision mediump float;uniform sampler2D u_TextureUnit;varying vec2 v_TextureCoordinates;void main(){        gl_FragColor = texture2D(u_TextureUnit, v_TextureCoordinates);}


 

④、创建VertexArray类

public class VertexArray extends Constants{               private final FloatBuffer floatBuffer;               public VertexArray(float[] vertexData) {               // TODO Auto-generated constructor stub               floatBuffer = ByteBuffer                               .allocateDirect(vertexData.length * BYTES_PER_FLOAT)                               .order(ByteOrder.nativeOrder())                               .asFloatBuffer()                               .put(vertexData);        }               public void setVertexAttribPointer( int dataOffset, int attributeLocation, int componentCount, int stride) {                       floatBuffer.position(dataOffset);                      glVertexAttribPointer(attributeLocation, componentCount, GL_FLOAT, false, stride, floatBuffer);                       glEnableVertexAttribArray(attributeLocation);                       floatBuffer.position(0);        } }



⑤、准备工作(数据,绑定,绘制)

package com.opengles.android.objects; import static android.opengl.GLES20.*; import com.opengles.android.Constants;import com.opengles.android.data.VertexArray;import com.opengles.android.programs.TextureShaderProgram; public class Table extends Constants{               private static final int POSITION_COMPONENT_COUNT = 2;        private static final int TEXTURE_COORDINATES_COMPONENT_COUNT = 2;        private static final int STRIDE = (POSITION_COMPONENT_COUNT        + TEXTURE_COORDINATES_COMPONENT_COUNT) * BYTES_PER_FLOAT;               private static final float[] VERTEX_DATA = {               // Order of coordinates: X, Y, S, T               // Triangle Fan               0f, 0f, 0.5f, 0.5f,               -0.5f, -0.8f, 0f, 0.9f,               0.5f, -0.8f, 1f, 0.9f,               0.5f, 0.8f, 1f, 0.1f,               -0.5f, 0.8f, 0f, 0.1f,               -0.5f, -0.8f, 0f, 0.9f };               private VertexArray vertexArray;         public Table() {               vertexArray = new VertexArray(VERTEX_DATA);        }               public void bindData(TextureShaderProgram textureProgram) {               vertexArray.setVertexAttribPointer(0,        textureProgram.getPositionAttributeLocation(), POSITION_COMPONENT_COUNT, STRIDE);               vertexArray.setVertexAttribPointer(POSITION_COMPONENT_COUNT, textureProgram.getTextureCoordinatesAttributeLocation(), TEXTURE_COORDINATES_COMPONENT_COUNT, STRIDE);        }               public void draw() {               glDrawArrays(GL_TRIANGLE_FAN, 0, 6);        }       }



⑥、添加纹理着色器程序

package com.opengles.android.programs; import static android.opengl.GLES20.*; import com.opengles.android.R; import android.content.Context; public class TextureShaderProgram extends ShaderProgram {         // Uniform locations        private final int uMatrixLocation;        private final int uTextureUnitLocation;        // Attribute locations        private final int aPositionLocation;        private final int aTextureCoordinatesLocation;         public TextureShaderProgram(Context context) {               super(context, R.raw.texture_vertex_shader,                               R.raw.texture_fragment_shader);               // Retrieve uniform locations for the shader program.               uMatrixLocation = glGetUniformLocation(program, U_MATRIX);               uTextureUnitLocation = glGetUniformLocation(program, U_TEXTURE_UNIT);               // Retrieve attribute locations for the shader program.               aPositionLocation = glGetAttribLocation(program, A_POSITION);               aTextureCoordinatesLocation = glGetAttribLocation(program,                               A_TEXTURE_COORDINATES);        }         public void setUniforms(float[] matrix, int textureId) {               // Pass the matrix into the shader program.               glUniformMatrix4fv(uMatrixLocation, 1, false, matrix, 0);               // Set the active texture unit to texture unit 0.               glActiveTexture(GL_TEXTURE0);               // Bind the texture to this unit.               glBindTexture(GL_TEXTURE_2D, textureId);               // Tell the texture uniform sampler to use this texture in the shader by               // telling it to read from texture unit 0.               glUniform1i(uTextureUnitLocation, 0);        }               public int getPositionAttributeLocation() {               return aPositionLocation;        }         public int getTextureCoordinatesAttributeLocation() {               return aTextureCoordinatesLocation;        } }



⑦、真正绘制纹理

// 加载纹理程序textureProgram = new TextureShaderProgram(context);// 加载纹理数据texture = TextureHelper.loadTexture(context, R.drawable.air_hockey_surface);// 设置纹理程序,并使用textureProgram.useProgram();textureProgram.setUniforms(projectionMatrix, texture);// 绑定纹理程序,并绘制table.bindData(textureProgram);table.draw();


 

 

 

0 0
原创粉丝点击