Android OpenGL ES 3.0 纹理应用

转载自:http://www.cnblogs.com/gaofengworking/p/4941774.html


文主要演示OpenGL ES 3.0 纹理演示。接口大部分和2.0没什么区别,脚本稍微有了点变化而已。

扩展GLSurfaceView

package com.example.gles300;

 

import android.app.ActivityManager;

import android.content.Context;

import android.content.pm.ConfigurationInfo;

import android.opengl.GLSurfaceView;

import android.util.AttributeSet;

import android.util.Log;

 

/**

 *

 * @author gaofeng

 *

 */

public class MyGLSurfaceView extends GLSurfaceView {

     

    private GLRenderer renderer;

 

    /**

     * @param context

     */

    public MyGLSurfaceView(Context context) {

        super(context);

        init();

    }

 

    /**

     * @param context

     * @param attrs

     */

    public MyGLSurfaceView(Context context, AttributeSet attrs) {

        super(context, attrs);

        init();

    }

     

    private void init() {

        ActivityManager am = (ActivityManager) getContext().getSystemService(Context.ACTIVITY_SERVICE);

        ConfigurationInfo info = am.getDeviceConfigurationInfo();

        String v = info.getGlEsVersion(); //判断是否为3.0 ,一般4.4就开始支持3.0版本了。

        if (v.equalsIgnoreCase("3.0")) {

            setEGLContextClientVersion(3);

        } else {

            setEGLContextClientVersion(2);

        }

        renderer = new GLRenderer();

        renderer.setContext(getContext());

        setRenderer(renderer);

        setRenderMode(RENDERMODE_CONTINUOUSLY);

    }

}

package com.example.gles300;

 

import java.io.IOException;

import java.io.InputStream;

 

import javax.microedition.khronos.egl.EGLConfig;

import javax.microedition.khronos.opengles.GL10;

 

import android.content.Context;

import android.graphics.Bitmap;

import android.graphics.BitmapFactory;

import android.opengl.GLES30;

import android.opengl.GLSurfaceView.Renderer;

import android.opengl.GLUtils;

import android.opengl.Matrix;

import android.util.Log;

 

/**

 * @author gaofeng

 *

 */

public class GLRenderer implements Renderer {

     

       

    public static float[] projMatrix = new float[16];// 投影  

    public static float[] viewMatrix = new float[16];// 相机  

    public static float[] mViewPjMatrix;// 总变换矩阵  

    public static float[] matrixs = new float[16];  

    public static int textureId = -1;  

    Context context;  

    MyDrawModel drawModel;  

 

    public void setContext(Context context) {

        this.context = context;

    }

     

    public GLRenderer() {

    }

 

      @Override 

        public void onDrawFrame(GL10 arg0) {  

            GLES30.glClear( GLES30.GL_DEPTH_BUFFER_BIT | GLES30.GL_COLOR_BUFFER_BIT);  

            Log.e("", "textureId:" + textureId);  

            drawModel.drawFrame(textureId);  

        }  

       

        @Override 

        public void onSurfaceChanged(GL10 arg0, int w, int h) {  

            GLES30.glViewport(0, 0, w, h);  

            float ratio = (float) w / h;  

            Matrix.frustumM(projMatrix, 0, -ratio, ratio, -1, 1, 1, 10);//投影矩阵设置  

            Matrix.setLookAtM(viewMatrix, 0, 0, 0, 3, 0, 0, 0, 0.0f, 1.0f, 0.0f);//摄像机坐标设置  

        }  

       

        @Override 

        public void onSurfaceCreated(GL10 g, EGLConfig eglConfig) {  

            GLES30.glClearColor(0.5f,0.5f,0.5f, 1.0f);    

            GLES30.glEnable(GLES30.GL_DEPTH_TEST);  

            InputStream ins = null;  

            drawModel = new MyDrawModel();  

            drawModel.init();  

            try {  

                ins = context.getAssets().open("girl4.jpg");  

                textureId = createTexture(ins);  

                Log.e("", "textureId:" + textureId);  

            } catch (IOException e) {  

                e.printStackTrace();  

            } finally {  

                try {  

                    if (ins != null) {

                        ins.close();  

                    }

                } catch (IOException e) {  

                    e.printStackTrace();  

                }  

            }  

            GLES30.glDisable(GLES30.GL_CULL_FACE);  

        } 

         

        public static int createTexture(InputStream ins) {  

            int[] textures = new int[1];  

            GLES30.glGenTextures(1, textures, 0);

            int textureId = textures[0];  

            GLES30.glBindTexture(GLES30.GL_TEXTURE_2D, textureId);  

            GLES30.glTexParameterf(GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_MIN_FILTER,GLES30.GL_NEAREST);   

            GLES30.glTexParameterf(GLES30.GL_TEXTURE_2D,GLES30.GL_TEXTURE_MAG_FILTER,GLES30.GL_LINEAR);  

            GLES30.glTexParameterf(GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_WRAP_S,GLES30.GL_CLAMP_TO_EDGE);  

            GLES30.glTexParameterf(GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_WRAP_T,GLES30.GL_CLAMP_TO_EDGE);  

            //上面是纹理贴图的取样方式,包括拉伸方式,取临近值和线性值  

            Bitmap bitmap = BitmapFactory.decodeStream(ins);  

            GLUtils.texImage2D(GLES30.GL_TEXTURE_2D, 0, bitmap, 0);//让图片和纹理关联起来,加载到OpenGl空间中  

            Log.d("OPENGL","bitmap:" + bitmap);  

            bitmap.recycle();//不需要,可以释放  

            return textureId;  

        }  

}

package com.example.gles300;

 

import java.nio.ByteBuffer;

import java.nio.ByteOrder;

import java.nio.FloatBuffer;

 

import android.opengl.GLES30;

import android.opengl.Matrix;

import android.util.Log;

 

/**

 * @author gaofeng

 *

 */

public class MyDrawModel {

    <br>    private int programId;  

    private int mVPMatrixHandle; 

    private FloatBuffer vertexBuffer;  

    private FloatBuffer texCoorBuffer;  

   

    public MyDrawModel() {  

    }  

   

    public void init() {  

        initData();  

        int vertexsharder = GLHelper.compileScript(GLES30.GL_VERTEX_SHADER,  GLScript.vertex3);  

        int fragmentsharder = GLHelper.compileScript(GLES30.GL_FRAGMENT_SHADER,  GLScript.fragment3);  

        programId = GLHelper.linkAttach(vertexsharder, fragmentsharder);  

        boolean isOK = GLHelper.checkProgram(programId);  

        mVPMatrixHandle = GLES30.glGetUniformLocation(programId, "uMVPMatrix");  

    }  

   

    private void initData() {  

        //X,Y,Z 顶点  

        float vertices[] = new float[] {  

                   0,     0, 0,  

               -1.8f, -1f, 0,  

               1.8f, -1f, 0,  

               1.8f,  1f, 0,  

               -1.8f,  1f, 0,  

               -1.8f, -1f, 0 

           };  

   

        ByteBuffer vb = ByteBuffer.allocateDirect(vertices.length * 4);  

        vb.order(ByteOrder.nativeOrder());  

        vertexBuffer = vb.asFloatBuffer();  

        vertexBuffer.put(vertices);  

        vertexBuffer.position(0);  

   

        //纹理空间坐标UV

        float texCoor[] = new float[] {   

                0.5f, 0.5f,  

                0f,     1f,  

                1f,     1f,  

                1f,     0f,  

                0f,     0f,  

                0f,     1f   

            };  

   

        ByteBuffer cb = ByteBuffer.allocateDirect(texCoor.length * 4);  

        cb.order(ByteOrder.nativeOrder());  

        texCoorBuffer = cb.asFloatBuffer();  

        texCoorBuffer.put(texCoor);  

        texCoorBuffer.position(0);  

    }  

   

    public void drawFrame(int textureId) {  

           

         GLES30.glUseProgram(programId);  

            

         // // 初始化矩阵  

         Matrix.setRotateM(GLRenderer.matrixs, 0, 0, 1, 0, 0);  

         Matrix.translateM(GLRenderer.matrixs, 0, 0, 0, 1);  

            

         //矩阵转换 ,投影矩阵,摄像机矩阵,模型矩阵  

         GLRenderer.mViewPjMatrix = new float[16];  

         Matrix.multiplyMM(GLRenderer.mViewPjMatrix, 0, GLRenderer.viewMatrix,0, GLRenderer.matrixs, 0);  

         Matrix.multiplyMM(GLRenderer.mViewPjMatrix, 0, GLRenderer.projMatrix,0, GLRenderer.mViewPjMatrix, 0);  

         GLES30.glUniformMatrix4fv(mVPMatrixHandle, 1, false, GLRenderer.mViewPjMatrix, 0);  

          

         GLES30.glVertexAttribPointer(0, 3, GLES30.GL_FLOAT, false, 3 * 4, vertexBuffer);  

         GLES30.glVertexAttribPointer(1,  2, GLES30.GL_FLOAT, false, 2 * 4, texCoorBuffer);  

           

         GLES30.glEnableVertexAttribArray(0);  

         GLES30.glEnableVertexAttribArray(1);  

           

         GLES30.glActiveTexture(GLES30.GL_TEXTURE0);  

         GLES30.glBindTexture(GLES30.GL_TEXTURE_2D, textureId);  

         GLES30.glDrawArrays(GLES30.GL_TRIANGLE_FAN, 0, 6);//六个定点,绘制三角形  

   

    }  

 

}

package com.example.gles300;

 

/**

 * @author gaofeng

 *

 */

public class GLScript {

 

       

    public GLScript() {  

    }  

     

    public static final String vertex3 =

            "#version 300 es \n" +

            "uniform mat4 uMVPMatrix;\n" 

            + "layout(location = 0) in vec3 aPosition;\n" 

            + "layout(location = 1) in vec2 aTexCoor;\n" 

            + "out vec2 vTextureCoord;\n"  

            + "void main() { \n" 

            + "gl_Position = uMVPMatrix * vec4(aPosition,1);\n" 

            + "vTextureCoord = aTexCoor;\n"  

            + "}\n" 

           ;  

      

   public static final String fragment3 = "#version 300 es \n" + 

            "precision mediump float;\n" 

           + "in vec2 vTextureCoord;\n" 

           + "uniform sampler2D sTexture;\n" 

           + "out vec4 v_color;\n"

           + "void main() { \n" 

           + "vec2 coord =  vTextureCoord;\n" 

           + "coord.s =  coord.s * 0.5;\n"

           + "v_color = texture(sTexture, coord); \n" 

           + "}\n" 

           ;  

 

}

layout(location=0) in vec3 aPosition;定义个输入,location定义了这个数据的位置,相对于2.0 不需要进行attribute查找。

     3.0中内置变量gl_FragColor 也被 out 颜色输出修改了。

     3.0脚本前面需要添加 #version 300 es 版本声明


最后是脚本编译和链接工具类.

package com.example.gles300;

 

import android.opengl.GLES30;

import android.util.Log;

 

/**

 * @author gaofeng

 *

 */

public class GLHelper {

 

    /**

     * 

     */

    public GLHelper() {

        // TODO Auto-generated constructor stub

    }

     

    public static int linkGL(){  

        int programId = GLES30.glCreateProgram();//创建一个程序  

        if (programId == 0) {  

           Log.e("OPENGL", "Error Create Link Program");  

           return 0;  

        }  

        return programId;  

    }  

       

    public static int linkAttach(int vertexsharder,int fragmentsharder){  

        int programId = linkGL();  

        GLES30.glAttachShader(programId, vertexsharder); //和着色器进行关联  

        GLES30.glAttachShader(programId, fragmentsharder);//和着色器进行关联  

        GLES30.glLinkProgram(programId); //把program链接起来  

        int status[] = new int[1];  

        GLES30.glGetProgramiv(programId, GLES30.GL_LINK_STATUS, status, 0); //这地方一样是检查是否有错误发生。  

        Log.d("OPENGL","linkAttach link status is " + GLES30.glGetProgramInfoLog(programId));  

        if (status[0] == 0) {  

            Log.e("OPENGL","link status is error.");  

            GLES30.glDeleteProgram(programId);  

            return 0;  

        }  

        return programId;  

    } 

     

    public static boolean checkProgram(int programId){  

        GLES30.glValidateProgram(programId);  

        int status[] = new int[1];  

        GLES30.glGetProgramiv(programId,GLES30.GL_VALIDATE_STATUS, status,0);  

        if (status[0] == 0) {  

            Log.e("OPENGL","program is error");  

            return false;  

        }  

        return true;  

    }  

     

    public static int compileScript(int type, String script){  

        int objID  = GLES30.glCreateShader(type); //创建一个着色器对象,TYPE表示顶点着色器和片段着色器  

        if (objID == 0) { //0表示有错误  

            return 0;  

        }  

        GLES30.glShaderSource(objID, script); //把脚本代码传给OpenGL 引擎  

        GLES30.glCompileShader(objID); //开始编译  

        int[] status = new int[1];  

        GLES30.glGetShaderiv(objID, GLES30.GL_COMPILE_STATUS, status, 0); //看看编译结果是否有错误。  

        Log.d("OPENGL","compileScript status info:" + GLES30.glGetShaderInfoLog(objID));  

        if (status[0] == 0) {  

            GLES30.glDeleteShader(objID);//有错误我们删除这个对象。  

            Log.e("OPENGL", "Error Compile Script:" + script);  

            return 0;  

        }  

        return objID;  

    }  

 

}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值