学习《Android3D游戏开发技术宝典:OpenGL.ES.2.0》一:初识OpenGL ES 2.0应用程序

来源:互联网 发布:淘宝市场容量分析 编辑:程序博客网 时间:2024/04/28 16:56

1.OpenGL ES 2.0 主要是用于嵌入式设备(主要就是手机及平板),与OpenGL 1.X的区别在于:1.X 使用的是固定渲染管线,而2.0使用的是可编程渲染管线,大大提高了渲染能力。

2.关于ShaderUtil的工具类:作用是将着色器(Shader)脚本加载进显卡并编译。

1>首先先从着色器sh 脚本中加载着色器内容的loadFromAssetsFile()以及检查每一步的是否有错误的checkGLError();


//检查每一步操作是否有错误的方法public static void checkGlError(String op){    int error;    while ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR)    {        Log.e("ES20_ERROR", op + ": glError " + error);        throw new RuntimeException(op + ": glError " + error);    }}

//从sh脚本中加载shader内容的方法public static String loadFromAssetsFile(String fname,Resources r){    String result=null;    try    {        InputStream in=r.getAssets().open(fname);        int ch=0;        ByteArrayOutputStream baos = new ByteArrayOutputStream();        while((ch=in.read())!=-1)        {            baos.write(ch);        }        byte[] buff=baos.toByteArray();        baos.close();        in.close();        result=new String(buff,"UTF-8");        result=result.replaceAll("\\r\\n","\n");    }    catch(Exception e)    {        e.printStackTrace();    }    return result;}

2>加载shader,因为有两种shader(一个是顶点,一个是片元)。

//加载制定shader的方法public static int loadShader(       int shaderType, //shader的类型  GLES20.GL_VERTEX_SHADER(顶点)   GLES20.GL_FRAGMENT_SHADER(片元)        String source   //shader的脚本字符串 ){    //创建一个新shader    int shader = GLES20.glCreateShader(shaderType);    //若创建成功则加载shader    if (shader != 0)    {        //加载shader的源代码        GLES20.glShaderSource(shader, source);        //编译shader        GLES20.glCompileShader(shader);        //存放编译成功shader数量的数组        int[] compiled = new int[1];        //获取Shader的编译情况        GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, compiled, 0);        if (compiled[0] == 0)        {//若编译失败则显示错误日志并删除此shader            Log.e("ES20_ERROR", "Could not compile shader " + shaderType + ":");            Log.e("ES20_ERROR", GLES20.glGetShaderInfoLog(shader));            GLES20.glDeleteShader(shader);            shader = 0;        }    }    return shader;}

3>创建Program的方法。

//创建shader程序的方法public static 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);        //存放链接成功program数量的数组        int[] linkStatus = new int[1];        //获取program的链接情况        GLES20.glGetProgramiv(program, GLES20.GL_LINK_STATUS, linkStatus, 0);        //若链接失败则报错并删除程序        if (linkStatus[0] != GLES20.GL_TRUE)        {            Log.e("ES20_ERROR", "Could not link program: ");            Log.e("ES20_ERROR", GLES20.glGetProgramInfoLog(program));            GLES20.glDeleteProgram(program);            program = 0;        }    }    return program;}

4>附上两个着色器:放在assets文件夹中

frag.sh

precision mediump float;varying  vec4 vColor; //接收从顶点着色器过来的参数void main()                         {                          gl_FragColor = vColor;//给此片元颜色值}
vertex.sh

uniform mat4 uMVPMatrix; //总变换矩阵attribute vec3 aPosition;  //顶点位置attribute vec4 aColor;    //顶点颜色varying  vec4 vColor;  //用于传递给片元着色器的变量void main()     {                                    gl_Position = uMVPMatrix * vec4(aPosition,1); //根据总变换矩阵计算此次绘制此顶点位置   vColor = aColor;//将接收的颜色传递给片元着色器 }                      

3.方法执行流程:<MyTDView是继承于GLSurfaceView>

//初始化shaderpublic void initShader(MyTDView mv){   
//加载顶点着色器的脚本内容String   mVertexShader=ShaderUtil.loadFromAssetsFile("vertex.sh", mv.getResources());//加载片元着色器的脚本内容String    mFragmentShader=ShaderUtil.loadFromAssetsFile("frag.sh", mv.getResources());//基于顶点着色器与片元着色器创建程序int   mProgram = ShaderUtil.createProgram(mVertexShader, mFragmentShader);//获取程序中顶点位置属性引用idint   maPositionHandle = GLES20.glGetAttribLocation(mProgram, "aPosition");//获取程序中顶点颜色属性引用idint   maColorHandle= GLES20.glGetAttribLocation(mProgram, "aColor");//获取程序中总变换矩阵引用idint  muMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
}


0 0
原创粉丝点击