美文网首页
OpenGL ES 2.0中绘制三角形(三)

OpenGL ES 2.0中绘制三角形(三)

作者: 冉冉升起的小太阳 | 来源:发表于2017-04-26 18:50 被阅读39次

    前面已经简单框架搭好了,现在进行封装下一边以后更好的学习

    1.我们都知道OpenGLES 呈现方式是依靠GLSurfaceView 来绘制出来的的那我们就从GLSurfaceView入手

    
    public class FGLView extends GLSurfaceView {
    
        private FGLRender renderer;
    
        /*构造方法*/
        public FGLView(Context context, AttributeSet attrs) {
            super(context, attrs);
            init();
        }
    
        /*初始化*/
        private void init(){
            /*OpenGL的版本 当前是OpenGL2*/
            setEGLContextClientVersion(2);
            /*这行代码是最重要的 渲染主要是Render来负责的*/
            setRenderer(renderer=new FGLRender(this));
            /*渲染的模式*/
            /** setRenderMode(Model)
             *public static final int RENDERMODE_CONTINUOUSLY = 1; 自动渲染模式
             * public static final int RENDERMODE_WHEN_DIRTY = 0; 脏模式 需要渲染才进行渲染
             */
            setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
        }
    
        /*适用于多个页面切换*/
        public void setShape(Class<? extends Shape> clazz){
            try {
                renderer.setShape(clazz);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
    }
    
    

    2。第一步就相当于xml 布局文件写完了,那么现在开始写 GLSurfaceView.Renderer 里面有三个 方法

    //每一帧都会去绘制
        @Override
        public void onDrawFrame(GL10 gl) {}
    //页面有改变的时候 例如生命周期改变的时候
            @Override
        public void onSurfaceChanged(GL10 gl, int width, int height) {}
    //开始创建
            @Override
        public void onSurfaceCreated(GL10 gl, EGLConfig config) {}
    

    开始封装FGLRender

    
    public class FGLRender extends Shape {
        private static final String TAG = "zhangxin";
        private Shape shape;
        private Class<? extends Shape> clazz = Triangle.class;
    
        /*构造方法*/
        public FGLRender(View mView) {
            super(mView);
        }
    
        public void setShape(Class<? extends Shape> shape) {
            this.clazz = shape;
        }
    
        @Override
        public void onSurfaceCreated(GL10 gl, EGLConfig config) {
          //清屏让屏幕显示的颜色
            GLES20.glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
            Log.e(TAG, "输出信息-->: onSurfaceCreated"  );
            try {
                //不知道,抄的
                Constructor constructor = clazz.getDeclaredConstructor(View.class);
                constructor.setAccessible(true);
                shape = (Shape) constructor.newInstance(mView);
            } catch (Exception e) {
                e.printStackTrace();
                shape = new Triangle(mView);
            }
            shape.onSurfaceCreated(gl, config);
        }
    
        @Override
        public void onSurfaceChanged(GL10 gl, int width, int height) {
    
            Log.e(TAG, "输出信息-->: onSurfaceChanged" );
            //获取屏幕的大小
            GLES20.glViewport(0, 0, width, height);
    
            shape.onSurfaceChanged(gl, width, height);
        }
    
        @Override
        public void onDrawFrame(GL10 gl) {
            Log.e(TAG, "输出信息-->: onDrawFrame" );
            //清楚深度和颜色
            GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
            shape.onDrawFrame(gl);
        }
    }
    
    

    加载顶点着色器和片元着色器

    public abstract class Shape implements GLSurfaceView.Renderer {
    
        protected View mView;
        public Shape(View mView){
            this.mView = mView;
        }
    
        public int loadShader (int type ,String shaderCode){
            /*根据type创建顶点着色器或者片元着色器*/
            int shader = GLES20.glCreateShader(type);
            /*将资源加入着色器中编译*/
            GLES20.glShaderSource(shader,shaderCode);
            GLES20.glCompileShader(shader);
            return shader;
    
        }
    }
    

    现在开始绘制三角形 主要呈现的就在Model3D

    public class Triangle extends Shape {
        private FloatBuffer vertexBuffer;
        private final String vertexShaderCode = 
                "attribute vec4 vPosition;"          + 
                        "void main() {"              + 
                        "  gl_Position = vPosition;" + 
                        "}";
    
        private final String fragmentShaderCode = 
                "precision mediump float;"           + 
                        "uniform vec4 vColor;"       +
                        "void main() {"              + 
                        "  gl_FragColor = vColor;"   +
                        "}";
    
        private int mProgram;
    
        static final int COORDS_PER_VERTEX = 3;
        
        static float triangleCoords[] = {
                0.5f,  0.5f, 0.0f, // top
                -0.5f, -0.5f, 0.0f, // bottom left
                0.5f, -0.5f, 0.0f  // bottom right
        };
    
        private int mPositionHandle;
        
        private int mColorHandle;
    
        private float[] mViewMatrix=new float[16];
    
        //顶点个数
        private final int vertexCount = triangleCoords.length / COORDS_PER_VERTEX;
        //顶点之间的偏移量
        private final int vertexStride = COORDS_PER_VERTEX * 4; // 每个顶点四个字节
    
        private int mMatrixHandler;
    
        //设置颜色,依次为红绿蓝和透明通道
        float color[] = { 1.0f, 1.0f, 1.0f, 1.0f };
    
        public Triangle(View mView) {
            super(mView);
            ByteBuffer bb = ByteBuffer.allocateDirect(triangleCoords.length * 4);
            bb.order(ByteOrder.nativeOrder());
    
            vertexBuffer = bb.asFloatBuffer();
            vertexBuffer.put(triangleCoords);
            vertexBuffer.position(0);
            int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode);
            int fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode);
    
            //创建一个空的OpenGLES程序
            mProgram = GLES20.glCreateProgram();
            //将顶点着色器加入到程序
            GLES20.glAttachShader(mProgram, vertexShader);
            //将片元着色器加入到程序中
            GLES20.glAttachShader(mProgram, fragmentShader);
            //连接到着色器程序
            GLES20.glLinkProgram(mProgram);
        }
    
        @Override
        public void onSurfaceCreated(GL10 gl, EGLConfig config) {
    
        }
    
        @Override
        public void onSurfaceChanged(GL10 gl, int width, int height) {
    
        }
    
        @Override
        public void onDrawFrame(GL10 gl) {
    
            //将程序加入到OpenGLES2.0环境
            GLES20.glUseProgram(mProgram);
    
            //获取顶点着色器的vPosition成员句柄
            mPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");
            //启用三角形顶点的句柄
            GLES20.glEnableVertexAttribArray(mPositionHandle);
            //准备三角形的坐标数据
            GLES20.glVertexAttribPointer(mPositionHandle, COORDS_PER_VERTEX, GLES20.GL_FLOAT, false, vertexStride, vertexBuffer);
            //获取片元着色器的vColor成员的句柄
            mColorHandle = GLES20.glGetUniformLocation(mProgram, "vColor");
            //设置绘制三角形的颜色
            GLES20.glUniform4fv(mColorHandle, 1, color, 0);
            //绘制三角形
            GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertexCount);
            //禁止顶点数组的句柄
            GLES20.glDisableVertexAttribArray(mPositionHandle);
        }
    }
    
    

    Activity代码

    public class Load3DActivity extends AppCompatActivity {
        private static final String TAG = "zhangxin";
        private FGLView fglView;
    
        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.loadopengl);
            init();
        }
    
        private void init() {
            fglView = (FGLView) findViewById(R.id.fglView);
        }
    
        @Override
        protected void onResume() {
            super.onResume();
            fglView.onResume();
        }
    
        @Override
        protected void onPause() {
            super.onPause();
            fglView.onPause();
        }
    }
    
    

    xml文件

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/activity_main"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
     >
    
        <com.alvasystems.openGLes.loadshader.FGLView
            android:id="@+id/fglView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
     />
    </RelativeLayout>
    
    

    相关文章

      网友评论

          本文标题:OpenGL ES 2.0中绘制三角形(三)

          本文链接:https://www.haomeiwen.com/subject/acsizttx.html