OpenGLES2.0绘制2D图片详解(附完整demo)

前段时间项目中有用到OpenGLES进行开发的部分,因此花了2周的时间研究了下OpenGLES,写了个绘制2D图片的Demo,OpenGLES提供了android访问OpenGL的接口,也就是我们熟知的GLSurfaceView的使用,他实际上也是封装了JNI规范进行调用OpenGL的代码.
下面附完整Demo的代码

MainActivity.java

package com.example.draw2dimagedemo;

import android.app.Activity;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.view.Window;
import android.view.WindowManager;
import android.widget.RelativeLayout;

public class MainActivity extends Activity {

    // Our OpenGL Surfaceview
    private GLSurfaceView glSurfaceView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        // Turn off the window's title bar
        requestWindowFeature(Window.FEATURE_NO_TITLE);

        // Super
        super.onCreate(savedInstanceState);

        // Fullscreen mode
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);

        // We create our Surfaceview for our OpenGL here.
        glSurfaceView = new GLSurf(this);

        // Set our view.    
        setContentView(R.layout.activity_main);

        // Retrieve our Relative layout from our main layout we just set to our view.
        RelativeLayout layout = (RelativeLayout) findViewById(R.id.gamelayout);



        // Attach our surfaceview to our relative layout from our main layout.
        RelativeLayout.LayoutParams glParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT);
        layout.addView(glSurfaceView, glParams);
    }

    @Override
    protected void onPause() {
        super.onPause();
        glSurfaceView.onPause();
    }

    @Override
    protected void onResume() {
        super.onResume();
        glSurfaceView.onResume();
    }

}

MainActivity中需要注意的就是保持GlSurfaceView的生命周期和Activity的生命周期保持同步,也就是重写onPause()和onResume()方法去调用glsurfaceView的onPause()和onResume()方法.

GLSurf.java

package com.example.draw2dimagedemo;

import android.content.Context;
import android.opengl.GLSurfaceView;

public class GLSurf extends GLSurfaceView {

    private final GLRenderer mRenderer;

    public GLSurf(Context context) {
        super(context);

        // Create an OpenGL ES 2.0 context.
        setEGLContextClientVersion(2);
        // Set the Renderer for drawing on the GLSurfaceView
        mRenderer = new GLRenderer(context);
        setRenderer(mRenderer);

        // Render the view only when there is a change in the drawing data
        setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);
    }

    @Override
    public void onPause() {
        super.onPause();
        mRenderer.onPause();
    }

    @Override
    public void onResume() {
        super.onResume();
        mRenderer.onResume();
    }

}

GLSurf中比较重要的一个方法是setRenderMode(),设置渲染模式,有两种模式
1.GLSurfaceView.RENDERMODE_CONTINUOUSLY GLSurfaceView以一定的时间不断渲染,这个是由GlsurfaceView内部控制的

2.GLSurfaceView.RENDERMODE_WHEN_DIRTY 当需要绘制的时候调用glSurfaceView.requestRender();去通知系统去更新渲染界面,实际上也就是去调用GLSurfaceView.Renderer中的onDrawFrame(GL10 gl10)方法.

GLRenderer.java

package com.example.draw2dimagedemo;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLES20;
import android.opengl.GLSurfaceView.Renderer;
import android.opengl.GLUtils;
import android.opengl.Matrix;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.ShortBuffer;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

public class GLRenderer implements Renderer {

    // Our matrices
    private final float[] mtrxProjection = new float[16];
    private final float[] mtrxView = new float[16];
    private final float[] mtrxProjectionAndView = new float[16];

    // Geometric variables
    //第一张图片所对应的位置数组
    public float vertices[] = new float[]

            //这里的适配问题需要dp和px的转化
            {
//                    0.0f, 600f, 0.0f,
//                    0.0f, 0f, 0.0f,
//                    600f, 0f, 0.0f,
//                    600f, 600f, 0.0f,
                    0.0f,1184f,0.0f,
                    0.0f,928f,0.0f,
                    256f,928f,0.0f,
                    256f,1184f,0.0f,
            };
    //第二张图片所对应的位置数组
    public static float vertices1[] = new float[]
            {
//                    350f, 1184f, 0.0f,
//                    350f, 700f, 0.0f,
//                    720f, 700f, 0.0f,
//                    720f, 1184f, 0.0f,
                    256f,1184f,0.0f,
                    256f,928f,0.0f,
                    512f,928f,0.0f,
                    512f,1184f,0.0f,
            };


    //第三张图片所对应的位置数组
    public static float vertices2[] = new float[]
            {
//                    0f,700f,0.0f,
//                   0f,0f,0f,
//                   240f,0f,0f,
//                   240f,700f,0f
                    512f,1184f,0.0f,
                    512f,928f,0.0f,
                    768f,928f,0.0f,
                    768f,1184f,0.0f,
            };


    //第四张图片所对应的位置数组
    public static float vertices3[] = new float[]
            {
                    0.0f,928f,0.0f,
                    0.0f,672f,0.0f,
                    256f,672f,0.0f,
                    256f,928f,0.0f,
            };


    //第五张图片所对应的位置数组
    public static float vertices4[] = new float[]
            {
                    256f,928f,0.0f,
                    256f,672f,0.0f,
                    512f,672f,0.0f,
                    512f,928f,0.0f,
            };

    //第六张图片所对应的位置数组
    public static float vertices5[] = new float[]
            {
                    512f,928f,0.0f,
                    512f,672f,0.0f,
                    768f,672f,0.0f,
                    768f,928f,0.0f,
            };

    //第7张图片所对应的位置数组
    public static float vertices6[] = new float[]
            {
                    0f,672f,0.0f,
                    0f,416f,0.0f,
                    256f,416f,0.0f,
                    256f,672f,0.0f,
            };

    //第8张图片所对应的位置数组
    public static float vertices7[] = new float[]
            {
                    256f,672f,0.0f,
                    256f,416f,0.0f,
                    512f,416f,0.0f,
                    512f,672f,0.0f,
            };

    //第9张图片所对应的位置数组
    public static float vertices8[] = new float[]
            {
                    512f,672f,0.0f,
                    512f,416f,0.0f,
                    768f,416f,0.0f,
                    768f,672f,0.0f,
            };

    //第10张图片所对应的位置数组
    public static float vertices9[] = new float[]
            {
                    0.0f,416f,0.0f,
                    0.0f,160f,0.0f,
                    256f,160f,0.0f,
                    256f,416f,0.0f,
            };

    //第11张图片所对应的位置数组
    public static float vertices10[] = new float[]
            {
                    256f,416f,0.0f,
                    256f,160f,0.0f,
                    512f,160f,0.0f,
                    512f,416f,0.0f,
            };

    //第12张图片所对应的位置数组
    public static float vertices11[] = new float[]
            {
                    512f,416f,0.0f,
                    512f,160f,0.0f,
                    768f,160f,0.0f,
                    768f,416f,0.0f,
            };

    //第13张图片所对应的位置数组
    public static float vertices12[] = new float[]
            {
                    0.0f,160f,0.0f,
                    0.0f,-96f,0.0f,
                    256f,-96f,0.0f,
                    256f,160f,0.0f,
            };

    //第14张图片所对应的位置数组
    public static float vertices13[] = new float[]
            {
                    256f,160f,0.0f,
                    256f,-96f,0.0f,
                    512f,-96f,0.0f,
                    512f,160f,0.0f,
            };

    //第15张图片所对应的位置数组
    public static float vertices14[] = new float[]
            {
                    512f,160f,0.0f,
                    512f,-96f,0.0f,
                    768f,-96f,0.0f,
                    768f,160f,0.0f,
            };





    public static short indices[];

    //    public static short indices1[];
//    public static float vertices1[];
    public static float uvs[];
    public FloatBuffer vertexBuffer;
    //    public FloatBuffer vertexBuffer1;
    public ShortBuffer drawListBuffer;
    //    public ShortBuffer drawListBuffer1;
    public FloatBuffer uvBuffer;
//    public FloatBuffer uvBuffer1;

//    private int program;
//    private int uColorLocation;
//    private int aPositionLocation;
//    private static final String U_COLOR = "u_Color";
//    private static final String A_POSITION = "a_Position";


    // Our screenresolution
    float mScreenWidth = 1280;
    float mScreenHeight = 768;

    // Misc
    Context mContext;
    long mLastTime;
    int mProgram;
    private FloatBuffer mUvBuffer1;
    private FloatBuffer mVerticeBuffer;

    public GLRenderer(Context c) {
        mContext = c;
        mLastTime = System.currentTimeMillis() + 100;
    }

    public void onPause() {
        /* Do stuff to pause the renderer */
    }

    public void onResume() {
        /* Do stuff to resume the renderer */
        mLastTime = System.currentTimeMillis();
    }

    @Override
    public void onDrawFrame(GL10 unused) {

        // Get the current time
        long now = System.currentTimeMillis();

        // We should make sure we are valid and sane
        if (mLastTime > now) return;

        // Get the amount of time the last frame took.
        long elapsed = now - mLastTime;

        // Update our example

        // Render our example
        Render(mtrxProjectionAndView);

        // Save the current time to see how long it took :).
        mLastTime = now;

    }

    private void Render(float[] m) {

        // clear Screen and Depth Buffer, we have set the clear color as black.
        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);

        //绘制第一张图片的所有操作

//        // get handle to vertex shader's vPosition member
        int mPositionHandle = GLES20.glGetAttribLocation(riGraphicTools.sp_Image, "vPosition");
//
//        // Enable generic vertex attribute array
//        GLES20.glEnableVertexAttribArray(mPositionHandle);
//
//        // Prepare the triangle coordinate data
//        GLES20.glVertexAttribPointer(mPositionHandle, 3,
//                GLES20.GL_FLOAT, false,
//                0, vertexBuffer);
//
//        // Get handle to texture coordinates location
        int mTexCoordLoc = GLES20.glGetAttribLocation(riGraphicTools.sp_Image, "a_texCoord");
//
//        // Enable generic vertex attribute array
//        GLES20.glEnableVertexAttribArray(mTexCoordLoc);
//
//        // Prepare the texturecoordinates
//        GLES20.glVertexAttribPointer(mTexCoordLoc, 2, GLES20.GL_FLOAT,
//                false,
//                0, mUvBuffer1);
//
//        // Get handle to shape's transformation matrix
//        int mtrxhandle = GLES20.glGetUniformLocation(riGraphicTools.sp_Image, "uMVPMatrix");
//
//        // Apply the projection and view transformation
//        GLES20.glUniformMatrix4fv(mtrxhandle, 1, false, m, 0);
//
//        // Get handle to textures locations
//        int mSamplerLoc = GLES20.glGetUniformLocation(riGraphicTools.sp_Image, "s_texture");


        // TODO
//        String vertexShaderSource = TextResourceReader
//                .readTextFileFromResource(mContext, R.raw.simple_vertex_shader);
//        String fragmentShaderSource = TextResourceReader
//                .readTextFileFromResource(mContext, R.raw.simple_fragment_shader);
//
//        int vertexShader = ShaderHelper.compileVertexShader(vertexShaderSource);
//        int fragmentShader = ShaderHelper.compileFragmentShader(fragmentShaderSource);
//
//        program = ShaderHelper.linkProgram(vertexShader, fragmentShader);
//
//        if (LoggerConfig.ON) {
//            ShaderHelper.validateProgram(program);
//        }
//
//        glUseProgram(program);
//
//        uColorLocation = glGetUniformLocation(program, U_COLOR);
//
//        aPositionLocation = glGetAttribLocation(program, A_POSITION);


        // Set the sampler texture unit to 0, where we have saved the texture.
//        GLES20.glUniform1i(mSamplerLoc, 0);

        //设置绘制平面图形的颜色
        //GLES20.glUniform4f(uColorLocation,1.0f,1.0f,1.0f,1.0f);

//        GLES20.glUniform4f(mtrxhandle,1.0f,1.0f,1.0f,1.0f);

        // Draw the triangle
//        GLES20.glDrawElements(GLES20.GL_TRIANGLES, indices.length,
//                GLES20.GL_UNSIGNED_SHORT, drawListBuffer);
//
//        // Disable vertex array
//        GLES20.glDisableVertexAttribArray(mPositionHandle);
//        GLES20.glDisableVertexAttribArray(mTexCoordLoc);

        //绘制第二张图片
        // get handle to vertex shader's vPosition member
        //拼接图片  one
        // Create the triangles
        mVerticeBuffer = setupTriangle(vertices);
        // Create the image information
        mUvBuffer1 = setupImage(R.drawable.mapa1);
        drawBitmap(m, mPositionHandle, mTexCoordLoc, mVerticeBuffer, mUvBuffer1, indices);

        FloatBuffer VertexPositionBuffer20 = setupTriangle(vertices);
        FloatBuffer uvBuffer20 = setupImage(R.drawable.mapb1);

        drawBitmap(m, mPositionHandle, mTexCoordLoc, VertexPositionBuffer20, uvBuffer20, indices);

        //拼接图片  two
        FloatBuffer VertexPositionBuffer1 = setupTriangle(vertices1);
        FloatBuffer uvBuffer1 = setupImage(R.drawable.mapa1);

        drawBitmap(m, mPositionHandle, mTexCoordLoc, VertexPositionBuffer1, uvBuffer1, indices);

        //拼接图片  three
        FloatBuffer VertexPositionBuffer2 = setupTriangle(vertices2);
        FloatBuffer uvBuffer2 = setupImage(R.drawable.mapa3);

        drawBitmap(m, mPositionHandle, mTexCoordLoc, VertexPositionBuffer2, uvBuffer2, indices);

        //拼接图片  four
        FloatBuffer VertexPositionBuffer3 = setupTriangle(vertices3);
        FloatBuffer uvBuffer3 = setupImage(R.drawable.mapa4);

        drawBitmap(m, mPositionHandle, mTexCoordLoc, VertexPositionBuffer3, uvBuffer3, indices);

        //拼接图片  five
        FloatBuffer VertexPositionBuffer4 = setupTriangle(vertices4);
        FloatBuffer uvBuffer4 = setupImage(R.drawable.mapa5);

        drawBitmap(m, mPositionHandle, mTexCoordLoc, VertexPositionBuffer4, uvBuffer4, indices);

        //拼接图片  six
        FloatBuffer VertexPositionBuffer5 = setupTriangle(vertices5);
        FloatBuffer uvBuffer5 = setupImage(R.drawable.mapa1);

        drawBitmap(m, mPositionHandle, mTexCoordLoc, VertexPositionBuffer5, uvBuffer5, indices);

        //拼接图片  7
        FloatBuffer VertexPositionBuffer6 = setupTriangle(vertices6);
        FloatBuffer uvBuffer6 = setupImage(R.drawable.mapa1);

        drawBitmap(m, mPositionHandle, mTexCoordLoc, VertexPositionBuffer6, uvBuffer6, indices);

        //拼接图片  8
        FloatBuffer VertexPositionBuffer7 = setupTriangle(vertices7);
        FloatBuffer uvBuffer7 = setupImage(R.drawable.mapa1);

        drawBitmap(m, mPositionHandle, mTexCoordLoc, VertexPositionBuffer7, uvBuffer7, indices);

        //拼接图片  9
        FloatBuffer VertexPositionBuffer8 = setupTriangle(vertices8);
        FloatBuffer uvBuffer8 = setupImage(R.drawable.mapa1);

        drawBitmap(m, mPositionHandle, mTexCoordLoc, VertexPositionBuffer8, uvBuffer8, indices);

        //拼接图片  10
        FloatBuffer VertexPositionBuffer9 = setupTriangle(vertices9);
        FloatBuffer uvBuffer9 = setupImage(R.drawable.mapa1);

        drawBitmap(m, mPositionHandle, mTexCoordLoc, VertexPositionBuffer9, uvBuffer9, indices);

        //拼接图片  11
        FloatBuffer VertexPositionBuffer10 = setupTriangle(vertices10);
        FloatBuffer uvBuffer10 = setupImage(R.drawable.mapa1);

        drawBitmap(m, mPositionHandle, mTexCoordLoc, VertexPositionBuffer10, uvBuffer10, indices);

        //拼接图片  12
        FloatBuffer VertexPositionBuffer11 = setupTriangle(vertices11);
        FloatBuffer uvBuffer11 = setupImage(R.drawable.mapa1);

        drawBitmap(m, mPositionHandle, mTexCoordLoc, VertexPositionBuffer11, uvBuffer11, indices);

        //拼接图片  13
        FloatBuffer VertexPositionBuffer12 = setupTriangle(vertices12);
        FloatBuffer uvBuffer12 = setupImage(R.drawable.mapb1);

        drawBitmap(m, mPositionHandle, mTexCoordLoc, VertexPositionBuffer12, uvBuffer12, indices);

        //拼接图片  14
        FloatBuffer VertexPositionBuffer13 = setupTriangle(vertices13);
        FloatBuffer uvBuffer13 = setupImage(R.drawable.mapb1);

        drawBitmap(m, mPositionHandle, mTexCoordLoc, VertexPositionBuffer13, uvBuffer13, indices);

        //拼接图片  15
        FloatBuffer VertexPositionBuffer14 = setupTriangle(vertices14);
        FloatBuffer uvBuffer14 = setupImage(R.drawable.mapb1);

        drawBitmap(m, mPositionHandle, mTexCoordLoc, VertexPositionBuffer14, uvBuffer14, indices);




    }

    private void drawBitmap(float[] m, int mPositionHandle, int mTexCoordLoc, FloatBuffer vertexBufferPosition, FloatBuffer uvBuffer1, short[] shortsIndices) {
        int mPositionHandle1 = GLES20.glGetAttribLocation(riGraphicTools.sp_Image, "vPosition");

        // Enable generic vertex attribute array
        GLES20.glEnableVertexAttribArray(mPositionHandle1);

        // Prepare the triangle coordinate data   绘制了两个三角形
        GLES20.glVertexAttribPointer(mPositionHandle, 3,
                GLES20.GL_FLOAT, false,
                0, vertexBufferPosition);

        // Get handle to texture coordinates location
        int mTexCoordLoc1 = GLES20.glGetAttribLocation(riGraphicTools.sp_Image, "a_texCoord");

        // Enable generic vertex attribute array
        GLES20.glEnableVertexAttribArray(mTexCoordLoc1);

        // Prepare the texturecoordinates
        GLES20.glVertexAttribPointer(mTexCoordLoc, 2, GLES20.GL_FLOAT,
                false,
                0, uvBuffer1);

        // Get handle to shape's transformation matrix
        int mtrxhandle1 = GLES20.glGetUniformLocation(riGraphicTools.sp_Image, "uMVPMatrix");

        // Apply the projection and view transformation
        GLES20.glUniformMatrix4fv(mtrxhandle1, 1, false, m, 0);

        // Get handle to textures locations
        int mSamplerLoc1 = GLES20.glGetUniformLocation(riGraphicTools.sp_Image, "s_texture");

        // Set the sampler texture unit to 0, where we have saved the texture.
        GLES20.glUniform1i(mSamplerLoc1, 0);

        // Draw the triangle
        GLES20.glDrawElements(GLES20.GL_TRIANGLES, shortsIndices.length,
                GLES20.GL_UNSIGNED_SHORT, drawListBuffer);

        // Disable vertex array
        GLES20.glDisableVertexAttribArray(mPositionHandle);
        GLES20.glDisableVertexAttribArray(mTexCoordLoc);
    }


    @Override
    public void onSurfaceChanged(GL10 gl, int width, int height) {

        // We need to know the current width and height.
        mScreenWidth = width;
        mScreenHeight = height;

        // Redo the Viewport, making it fullscreen.
        GLES20.glViewport(0, 0, (int) width, (int) height);

        // Clear our matrices
        for (int i = 0; i < 16; i++) {
            mtrxProjection[i] = 0.0f;
            mtrxView[i] = 0.0f;
            mtrxProjectionAndView[i] = 0.0f;
        }
        //矩阵的偏移
        // Setup our screen width and height for normal sprite translation.
        Matrix.orthoM(mtrxProjection, 0, 0f, mScreenWidth, 0.0f, mScreenHeight, 0, 50);
        // Set the camera position (View matrix)
        Matrix.setLookAtM(mtrxView, 0, 0f, 0f, 1f, 0f, 0f, 0f, 0f, 1.0f, 0.0f);

        // Calculate the projection and view transformation
        Matrix.multiplyMM(mtrxProjectionAndView, 0, mtrxProjection, 0, mtrxView, 0);

    }

    @Override
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {



        // Set the clear color to black
        GLES20.glClearColor(1.0f, 1.0f, 1.0f, 1);

        // Create the shaders, solid color
        int vertexShader = riGraphicTools.loadShader(GLES20.GL_VERTEX_SHADER, riGraphicTools.vs_SolidColor);
        int fragmentShader = riGraphicTools.loadShader(GLES20.GL_FRAGMENT_SHADER, riGraphicTools.fs_SolidColor);

        riGraphicTools.sp_SolidColor = GLES20.glCreateProgram();             // create empty OpenGL ES Program
        GLES20.glAttachShader(riGraphicTools.sp_SolidColor, vertexShader);   // add the vertex shader to program
        GLES20.glAttachShader(riGraphicTools.sp_SolidColor, fragmentShader); // add the fragment shader to program
        GLES20.glLinkProgram(riGraphicTools.sp_SolidColor);                  // creates OpenGL ES program executables

        // Create the shaders, images
        vertexShader = riGraphicTools.loadShader(GLES20.GL_VERTEX_SHADER, riGraphicTools.vs_Image);
        fragmentShader = riGraphicTools.loadShader(GLES20.GL_FRAGMENT_SHADER, riGraphicTools.fs_Image);

        riGraphicTools.sp_Image = GLES20.glCreateProgram();             // create empty OpenGL ES Program
        GLES20.glAttachShader(riGraphicTools.sp_Image, vertexShader);   // add the vertex shader to program
        GLES20.glAttachShader(riGraphicTools.sp_Image, fragmentShader); // add the fragment shader to program
        GLES20.glLinkProgram(riGraphicTools.sp_Image);                  // creates OpenGL ES program executables


        // Set our shader programm
        GLES20.glUseProgram(riGraphicTools.sp_Image);


    }

    public FloatBuffer setupImage(int id) {
        // Create our UV coordinates.
        //这里是干嘛的?  很关键
        uvs = new float[]{
                0.0f, 0.0f, 0.0f, 1.0f,
                1.0f, 1.0f, 1.0f, 0.0f
        };

        // The texture buffer
        ByteBuffer bb = ByteBuffer.allocateDirect(uvs.length * 4);
        bb.order(ByteOrder.nativeOrder());
        uvBuffer = bb.asFloatBuffer();
        uvBuffer.put(uvs);
        uvBuffer.position(0);

        // Generate Textures, if more needed, alter these numbers.
        int[] texturenames = new int[1];
        GLES20.glGenTextures(1, texturenames, 0);

        // Retrieve our image from resources.
//        int id = mContext.getResources().getIdentifier("drawable/mapa1", null, mContext.getPackageName());

        // Temporary create a bitmap
        //通过options改变图片的参数

        BitmapFactory.Options opts = new BitmapFactory.Options();
        opts.inPreferredConfig = Bitmap.Config.ARGB_8888;
        Bitmap bmp = BitmapFactory.decodeResource(mContext.getResources(), id,opts);

        // Bind texture to texturename
        GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
        GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texturenames[0]);

        // Set filtering
        GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
        GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);

        // Load the bitmap into the bound texture.
        GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bmp, 0);
        //开启gl的两个功能 使图片变成透明的
        GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA,GLES20.GL_ONE_MINUS_SRC_ALPHA);
        GLES20.glEnable(GLES20.GL_BLEND);

        // We are done using the bitmap so we should recycle it.
        bmp.recycle();

        return uvBuffer;

    }

    public FloatBuffer setupTriangle(float[] verticesPosition) {

        // We have to create the vertices of our triangle.
//        vertices = new float[]
//                {       400.0f, 300f, 0.0f,
//                        400.0f, 200f, 0.0f,
//                        500f, 200f, 0.0f,
//                        500f, 300f, 0.0f,
//                };

//                0.0f, 0.0f, 0.0f,
//                0f, 1280f, 0.0f,
//                720f, 1280f, 0.0f,
//                7200f, 0.0f, 0.0f,

        indices = new short[]{0, 1, 2, 0, 2, 3}; // The order of vertexrendering.

        // The vertex buffer.
        ByteBuffer bb = ByteBuffer.allocateDirect(verticesPosition.length * 4);
        bb.order(ByteOrder.nativeOrder());
        vertexBuffer = bb.asFloatBuffer();
        vertexBuffer.put(verticesPosition);
        vertexBuffer.position(0);

        // initialize byte buffer for the draw list
        ByteBuffer dlb = ByteBuffer.allocateDirect(indices.length * 2);
        dlb.order(ByteOrder.nativeOrder());
        drawListBuffer = dlb.asShortBuffer();
        drawListBuffer.put(indices);
        drawListBuffer.position(0);


        // We have to create the vertices of our triangle.
//        vertices1 = new float[]
//                {       600.0f, 200f, 0.0f,
//                        600.0f, 100f, 0.0f,
//                        700f, 100f, 0.0f,
//                        700f, 200f, 0.0f,
//                };
//
//        indices1 = new short[]{0, 1, 2, 0, 2, 3}; // The order of vertexrendering.
//
//        // The vertex buffer.
//        ByteBuffer bb1 = ByteBuffer.allocateDirect(vertices1.length * 4);
//        bb1.order(ByteOrder.nativeOrder());
//        vertexBuffer1 = bb1.asFloatBuffer();
//        vertexBuffer1.put(vertices1);
//        vertexBuffer1.position(0);
//
//        // initialize byte buffer for the draw list
//        ByteBuffer dlb1 = ByteBuffer.allocateDirect(indices1.length * 2);
//        dlb1.order(ByteOrder.nativeOrder());
//        drawListBuffer1 = dlb.asShortBuffer();
//        drawListBuffer1.put(indices1);
//        drawListBuffer1.position(0);
        return vertexBuffer;

    }
}

GLRenderer类中重要的方法有三个
1.onSurfaceChanged(),创建Render时调用的方法
2.onSurfaceChanged(),当Surface改变尺寸的时候
3.onDrawFrame(),渲染时调用的方法

其他重要方法代码中都有详细注释,自行查看

riGraphicTools.java

package com.example.draw2dimagedemo;

import android.opengl.GLES20;

public class riGraphicTools {

    // Program variables
    public static int sp_SolidColor;
    public static int sp_Image;


    /* SHADER Solid
     * 
     * This shader is for rendering a colored primitive.
     * 
     */
    public static final String vs_SolidColor =
        "uniform    mat4        uMVPMatrix;" +
        "attribute  vec4        vPosition;" +
        "void main() {" +
        "  gl_Position = uMVPMatrix * vPosition;" +
        "}";

    public static final String fs_SolidColor =
        "precision mediump float;" +
        "void main() {" +
        "  gl_FragColor = vec4(0.5,0,0,1);" +
        "}"; 

    /* SHADER Image
     * 
     * This shader is for rendering 2D images straight from a texture
     * No additional effects.
     * 
     */
    public static final String vs_Image =
        "uniform mat4 uMVPMatrix;" +
        "attribute vec4 vPosition;" +
        "attribute vec2 a_texCoord;" +
        "varying vec2 v_texCoord;" +
        "void main() {" +
        "  gl_Position = uMVPMatrix * vPosition;" +
        "  v_texCoord = a_texCoord;" +
        "}";

    public static final String fs_Image =
        "precision mediump float;" +
        "varying vec2 v_texCoord;" +
        "uniform sampler2D s_texture;" +
        "void main() {" +
        "  gl_FragColor = texture2D( s_texture, v_texCoord );" +
        "}"; 



    public static int loadShader(int type, String shaderCode){

        // create a vertex shader type (GLES20.GL_VERTEX_SHADER)
        // or a fragment shader type (GLES20.GL_FRAGMENT_SHADER)
        int shader = GLES20.glCreateShader(type);

        // add the source code to the shader and compile it
        GLES20.glShaderSource(shader, shaderCode);
        GLES20.glCompileShader(shader);

        // return the shader
        return shader;
    }
}

riGraphicTools这个类替代了shader着色语言的作用,当然你也可以自己写shader语句
另外两个重要的概念就是Position数组和color数组.根据代码注释可看出来这两个数组的重要性.代码中需要的图片资源可以自行替换.

如有不足之处请指正,谢谢!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值