openGL ES 2.0 点与点之间的绘制方式(III)

来源:互联网 发布:三国志11自制武将数据 编辑:程序博客网 时间:2024/04/29 18:27

ShaderUtil.java文件:

package com.example.sample_5_5_mine;import java.io.ByteArrayOutputStream;import java.io.InputStream;import android.content.res.Resources;import android.opengl.GLES20;import android.util.Log;//加载顶点Shader与片元Shader的工具类public class ShaderUtil {   //加载制定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;    }       //创建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;    }       //检查每一步操作是否有错误的方法    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;   }}

Constant.java文件:

package com.example.sample_5_5_mine;public class Constant {public static float UNIT_SIZE = 1f;public static float ratio;public static final int GL_POINTS = 0;public static final int GL_LINES = 1;public static final int GL_STRIP = 2;public static final int GL_LINE_LOOP = 3;public static int CURR_DRAW_MODE = 0;}

MatrixState.java文件:

package com.example.sample_5_5_mine;import java.nio.ByteBuffer;import android.opengl.Matrix;public class MatrixState {private static float[] mProjMatrix = new float[16];private static float[] mVMatrix = new float[16];private static float[] currMatrix;static float[][] mStack = new float[10][16];static int stackTop = -1;public static void setInitStack(){currMatrix = new float[16];Matrix.setRotateM(currMatrix, 0, 0, 1, 0, 0);}public static void pushMatrix(){stackTop++;for(int i=0;i<16;i++){mStack[stackTop][i] = currMatrix[i];}}public static void popMatrix(){for(int i=0;i<16;i++){currMatrix[i] = mStack[stackTop][i];}stackTop--;}public static void translate(float x, float y, float z){Matrix.translateM(currMatrix, 0, x, y, z);}static ByteBuffer llbb = ByteBuffer.allocateDirect(3*4);static float[] cameraLocation = new float[3];public static void setCamera(float cx,float cy, float cz,float tx, float ty, float tz,float upx, float upy, float upz){Matrix.setLookAtM(mVMatrix, 0, cx, cy, cz, tx, ty, tz, upx, upy, upz);}public static void setProjectionFrustum(float left,float right, float bottom, float top,float near, float far){Matrix.frustumM(mProjMatrix, 0, left, right, bottom, top, near, far);}public static void setProjectionOrtho(float left,float right, float bottom, float top, float near, float far){Matrix.orthoM(mProjMatrix, 0, left, right, bottom, top, near, far);}static float[] mMVPMatrix = new float[16];public static float[] getFinalMatrix(){Matrix.multiplyMM(mMVPMatrix, 0, mVMatrix, 0, currMatrix, 0);        Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mMVPMatrix, 0);                return mMVPMatrix;}public static float[] getMMatrix()    {               return currMatrix;    }}

PontsOrLines.java文件:

package com.example.sample_5_5_mine;import java.nio.ByteBuffer;import java.nio.ByteOrder;import java.nio.FloatBuffer;import android.opengl.GLES20;public class PointsOrLines {int mProgram;String mVertexShader;String mFragmentShader;int muMVPMatrixHandle;int maPositionHandle;int maColorHandle;FloatBuffer mVertexBuffer;FloatBuffer mColorBuffer;int vCount = 0;public PointsOrLines(MySurfaceView mv){initVertexData();initShader(mv);}public void initVertexData(){vCount = 5;float vertices[] = new float[]{0, 0, 0, Constant.UNIT_SIZE, Constant.UNIT_SIZE, 0,-Constant.UNIT_SIZE, Constant.UNIT_SIZE, 0,-Constant.UNIT_SIZE, -Constant.UNIT_SIZE, 0,Constant.UNIT_SIZE, -Constant.UNIT_SIZE, 0, };ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length*4);vbb.order(ByteOrder.nativeOrder());mVertexBuffer = vbb.asFloatBuffer();mVertexBuffer.put(vertices);mVertexBuffer.position(0);float colors[] = new float[]{1, 1, 0, 0,// 黄1, 1, 1, 0,// 白0, 1, 0, 0,// 绿1, 1, 1, 0,// 白1, 1, 0, 0,// 黄};ByteBuffer cbb = ByteBuffer.allocateDirect(colors.length*4);cbb.order(ByteOrder.nativeOrder());mColorBuffer = cbb.asFloatBuffer();mColorBuffer.put(colors);mColorBuffer.position(0);}public void initShader(MySurfaceView mv){mVertexShader =   ShaderUtil.loadFromAssetsFile("vertex.sh", mv.getResources());mFragmentShader = ShaderUtil.loadFromAssetsFile("frag.sh",mv.getResources());mProgram = ShaderUtil.createProgram(mVertexShader, mFragmentShader);maPositionHandle = GLES20.glGetAttribLocation(mProgram, "aPosition");maColorHandle = GLES20.glGetAttribLocation(mProgram, "aColor");muMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram,"uMVPMatrix");}public void drawSelf(){GLES20.glUseProgram(mProgram);GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, MatrixState.getFinalMatrix(),0);GLES20.glVertexAttribPointer(maPositionHandle, 3, GLES20.GL_FLOAT, false, 4*4, mColorBuffer);GLES20.glEnableVertexAttribArray(maPositionHandle);GLES20.glEnableVertexAttribArray(maColorHandle);GLES20.glLineWidth(10);switch(Constant.CURR_DRAW_MODE){case Constant.GL_POINTS:GLES20.glDrawArrays(GLES20.GL_POINTS, 0, vCount);break;case Constant.GL_LINES:GLES20.glDrawArrays(GLES20.GL_LINES, 0, vCount);break;case Constant.GL_STRIP:GLES20.glDrawArrays(GLES20.GL_LINE_STRIP, 0, vCount);break;case Constant.GL_LINE_LOOP:GLES20.glDrawArrays(GLES20.GL_LINE_LOOP, 0, vCount);break;}}}

MySurfaceView.java文件:

package com.example.sample_5_5_mine;import javax.microedition.khronos.egl.EGLConfig;import javax.microedition.khronos.opengles.GL10;import android.content.Context;import android.opengl.GLES20;import android.opengl.GLSurfaceView;public class MySurfaceView extends GLSurfaceView{private SceneRenderer mRenderer;public MySurfaceView(Context context) {super(context);// TODO 自动生成的构造函数存根this.setEGLContextClientVersion(2);mRenderer = new SceneRenderer();setRenderer(mRenderer);Constant.CURR_DRAW_MODE = Constant.GL_POINTS;}private class SceneRenderer implements GLSurfaceView.Renderer{PointsOrLines PointsOrLines;@Overridepublic void onDrawFrame(GL10 arg0) {// TODO 自动生成的方法存根GLES20.glClear(GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);MatrixState.pushMatrix();MatrixState.pushMatrix();PointsOrLines.drawSelf();MatrixState.popMatrix();MatrixState.popMatrix();}@Overridepublic void onSurfaceChanged(GL10 gl, int width, int height) {// TODO 自动生成的方法存根GLES20.glViewport(0, 0, width, height);Constant.ratio = (float) width / height;MatrixState.setProjectionFrustum(-Constant.ratio, Constant.ratio, -1, 1, 20, 100);MatrixState.setCamera(0, 8f, 30, 0f, 0f, 0f, 0f, 1.0f, 0.0f);MatrixState.setInitStack();}@Overridepublic void onSurfaceCreated(GL10 arg0, EGLConfig arg1) {// TODO 自动生成的方法存根GLES20.glClearColor(0, 0, 0, 1.0f);PointsOrLines = new PointsOrLines(MySurfaceView.this);GLES20.glEnable(GLES20.GL_DEPTH_TEST);GLES20.glEnable(GLES20.GL_CULL_FACE);}}}

MainActivity.java文件:

package com.example.sample_5_5_mine;import javax.microedition.khronos.egl.EGLConfig;import javax.microedition.khronos.opengles.GL10;import android.content.Context;import android.opengl.GLES20;import android.opengl.GLSurfaceView;public class MySurfaceView extends GLSurfaceView{private SceneRenderer mRenderer;public MySurfaceView(Context context) {super(context);// TODO 自动生成的构造函数存根this.setEGLContextClientVersion(2);mRenderer = new SceneRenderer();setRenderer(mRenderer);Constant.CURR_DRAW_MODE = Constant.GL_POINTS;}private class SceneRenderer implements GLSurfaceView.Renderer{PointsOrLines PointsOrLines;@Overridepublic void onDrawFrame(GL10 arg0) {// TODO 自动生成的方法存根GLES20.glClear(GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);MatrixState.pushMatrix();MatrixState.pushMatrix();PointsOrLines.drawSelf();MatrixState.popMatrix();MatrixState.popMatrix();}@Overridepublic void onSurfaceChanged(GL10 gl, int width, int height) {// TODO 自动生成的方法存根GLES20.glViewport(0, 0, width, height);Constant.ratio = (float) width / height;MatrixState.setProjectionFrustum(-Constant.ratio, Constant.ratio, -1, 1, 20, 100);MatrixState.setCamera(0, 8f, 30, 0f, 0f, 0f, 0f, 1.0f, 0.0f);MatrixState.setInitStack();}@Overridepublic void onSurfaceCreated(GL10 arg0, EGLConfig arg1) {// TODO 自动生成的方法存根GLES20.glClearColor(0, 0, 0, 1.0f);PointsOrLines = new PointsOrLines(MySurfaceView.this);GLES20.glEnable(GLES20.GL_DEPTH_TEST);GLES20.glEnable(GLES20.GL_CULL_FACE);}}}

activity_main.xml文件:

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:orientation="vertical"    android:layout_width="fill_parent"    android:layout_height="fill_parent"    android:id="@+id/main_liner"    ><RadioGroup android:id="@+id/RadioGroup01" android:layout_width="wrap_content" android:layout_height="wrap_content"android:orientation="horizontal"><LinearLayout android:id="@+id/LinearLayout01" android:layout_width="wrap_content" android:layout_height="wrap_content"android:orientation="vertical"><RadioButton android:text="GL_POINTS" android:id="@+id/RadioButton00" android:layout_width="wrap_content" android:layout_height="wrap_content"android:checked="true"></RadioButton><RadioButton android:text="GL_LINES" android:id="@+id/RadioButton01" android:layout_width="wrap_content" android:layout_height="wrap_content"></RadioButton></LinearLayout><LinearLayout android:id="@+id/LinearLayout02" android:layout_width="wrap_content" android:layout_height="wrap_content"android:orientation="vertical"><RadioButton android:text="GL_LINE_STRIP" android:id="@+id/RadioButton02" android:layout_width="wrap_content" android:layout_height="wrap_content"></RadioButton><RadioButton android:text="GL_LINE_LOOP" android:id="@+id/RadioButton03" android:layout_width="wrap_content" android:layout_height="wrap_content"></RadioButton></LinearLayout></RadioGroup></LinearLayout>

frag.sh文件:

precision mediump float;varying  vec4 vColor; //接收从顶点着色器过来的参数varying vec3 vPosition;//接收从顶点着色器过来的顶点位置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); //根据总变换矩阵计算此次绘制此顶点位置   gl_PointSize=10.0;   vColor = aColor;//将接收的颜色传递给片元着色器}                      




0 0
原创粉丝点击