着色器脚本的加载及编译

来源:互联网 发布:java 异步io 框架 编辑:程序博客网 时间:2024/05/17 23:44

要使用着色器对图像进行渲染则需要将着色器内容加载并编译

  • 首先加载着色器脚本内容
 public static String loadFromAssetsFile(String fname,Resources r)    {        String result=null;        try        {            InputStream in=r.getAssets().open(fname);            ByteArrayOutputStream baos = new ByteArrayOutputStream();            int ch;            while((ch=in.read())!=-1)            {                baos.write(ch);            }            byte[] buff=baos.toByteArray();            baos.close();            in.close();            result=new String(buff,"GBK");            result=result.replaceAll("\\r\\n","\n");        }        catch(Exception e)        {            e.printStackTrace();        }        Log.e(fname,result);        return result;    }
本段的作用为将fname文件中的脚本内容读取到字符串result中,并返回result
 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);            //若编译失败则显示错误日志并删除此shader            if (compiled[0] == 0)            {                Log.e("ES20_ERROR", "Could not compile shader " + shaderType + ":");                Log.e("ES20_ERROR", GLES20.glGetShaderInfoLog(shader));                GLES20.glDeleteShader(shader);                shader = 0;            }        }        return shader;    }
本段的作用为创建一个着色器,加载源码并编译,若成功则返回此着色器的id,其中source为上段读取到的字符串result。
 //创建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);            //向程序中加入片元着色器            GLES20.glAttachShader(program, pixelShader);            //链接程序            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;    }
本段的作用为创建着色器程序,将顶点着色器与片元着色器(通过id)加进程序链接程序,若成功则返回程序id

当我们使用着色器进行渲染时,只需拿到此着色器的id即可判断使用哪套着色器进行渲染以及数据的初始化

最后还可对每一步操作进行检查,方便调试
//检查每一步操作是否有错误的方法    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);        }    }

原创粉丝点击