OpenGL ES 2.0 for Android

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();


 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qiuchenlong

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值