3D开发学习-初始openGL ES应用程序

来源:互联网 发布:arm-linux-gnueabi 编辑:程序博客网 时间:2024/06/08 17:27

本文针对与OpenGL ES2.0开发一个小程序,实现一个三角形在空间位置上的旋转.

运行效果图如下:


开始之前,我们需要做一个工具类的封装,该工具类有如下几个方法:

/**     * 加载指定的着色器方法     * @param shaderType 着色器类型     * @param source 着色器脚本字符串源码     * @return     */    public static int loadShader(int shaderType, String source) {    }    /**     * 创建着色器程序的方法     * @param vertexSource 顶点源码     * @param fragmentSource 片元着色器     * @return     */    public static int createProgram(String vertexSource, String fragmentSource) {    }    /**     * 检查每一步操作是否有误     * @param op 操作     */    public static void checkGlError(String op) {    }    /**     * 从资产目录加载     * @param fName 文件名字 着色器代码     * @param resources 资源     * @return 结果     */    public static String loadFromAeertsFile(String fName, Resources resources) {    }

工具类方法中有详细代码注释,接下来开始开发主控显示类MainActivity,其中代码如下:

@Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);        mTriangleSurfaceView = new TriangleSurfaceView(this);        /**         * 设置获取焦点         * 设置接收触摸事件         */        mTriangleSurfaceView.requestFocus();        mTriangleSurfaceView.setFocusableInTouchMode(true);        setContentView(mTriangleSurfaceView);    }    @Override    protected void onResume() {        super.onResume();        mTriangleSurfaceView.onResume();    }    @Override    protected void onPause() {        super.onPause();        mTriangleSurfaceView.onPause();    }

代码中TriangleSurfaceView是用于显示三角形旋转的控制控件.代码如下:


public class TriangleSurfaceView        extends GLSurfaceView {    //三角形一次旋转的角度    final float ANGLE_SPAN = 0.375f;    RotateThread mRotateThread;    //渲染器引用    SceneRenderer mSceneRenderer;    public TriangleSurfaceView(Context context) {        this(context , null);    }    public TriangleSurfaceView(Context context, AttributeSet attrs) {        super(context, attrs);        init();    }    /**     * 初始化     */    private void init() {        setEGLContextClientVersion(2);        mSceneRenderer = new SceneRenderer();        //设置渲染器        setRenderer(mSceneRenderer);        setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);    }    /**     * 渲染器     */    private class SceneRenderer implements GLSurfaceView.Renderer{        Triangle mTriangle;        @Override        public void onSurfaceCreated(GL10 gl, EGLConfig config) {            //设置背景颜色            GLES20.glClearColor( 0 , 0 , 0 , 1.0f);            //创建Triangle对象            mTriangle = new Triangle(TriangleSurfaceView.this);            //深度测试            GLES20.glEnable(GLES20.GL_DEPTH_TEST);            mRotateThread = new RotateThread();            mRotateThread.start();        }        @Override        public void onSurfaceChanged(GL10 gl, int width, int height) {            //设置视窗            GLES20.glViewport(0 , 0 , width , height);            //计算屏幕的宽高比例            float ratio = (float) width / height;            //设置透视投影            Matrix.frustumM(Triangle.mProjMatrix , 0 , -ratio , ratio , -1 , 1 , 1 , 10);            //设置摄像机            Matrix.setLookAtM(Triangle.mVMatrix , 0 , 0 , 0 , 3 , 0.0f , 0.0f , 0.0f , 0.0f , 1.0f , 0.0f );        }        @Override        public void onDrawFrame(GL10 gl) {            /**             * 清除深度和颜色缓存             */            GLES20.glClear(GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);            //绘制三角形            mTriangle.drawSelf();        }    }    private class RotateThread extends Thread{        public boolean mFlag = true;        @Override        public void run() {            super.run();            while (mFlag){                /**                 * 改变角度 以达到旋转                 */                mSceneRenderer.mTriangle.mXAngle = mSceneRenderer.mTriangle.mXAngle + ANGLE_SPAN;                try {                    Thread.sleep(20);                } catch (InterruptedException e) {                    e.printStackTrace();                }            }        }    }}



主控制类完成之后,需要开发一个用于绘制三角形的类,该类中主要实现三角形的绘制:Triangle的代码如下:

public Triangle(TriangleSurfaceView triangleSurfaceView){        //初始化顶点数据        initVertexData();        //初始化着色器        initShader(triangleSurfaceView);    }    /**     * 初始化着色器     * @param triangleSurfaceView 显示用     */    private void initShader(TriangleSurfaceView triangleSurfaceView) {            }    /**     * 初始化顶点数据     */    private void initVertexData() {            }    /**     * 绘制自己     */    public void drawSelf(){        GLES20.glUseProgram(mProgram);        //初始化变换矩阵        Matrix.setRotateM(mMMatrix , 0 , 0 , 0 , 1 , 0);        //设置沿X轴正方向位移        Matrix.translateM(mMMatrix , 0 , 0 , 0 , 1);        //设置绕X轴旋转        Matrix.rotateM(mMMatrix , 0 , mXAngle , 1 , 0 , 0);        GLES20.glUniformMatrix4fv(muMVPMatrixHandle , 1 , false , Triangle.getFinalMatrix(mMMatrix) , 0);        //把顶点位置传送进渲染管线        GLES20.glVertexAttribPointer(maPositionHandle , 3 , GLES20.GL_FLOAT , false , 3 * 4 , mVertexBuffer);        //把颜色数据传送进渲染管线        GLES20.glVertexAttribPointer(maColorHandle , 4 , GLES20.GL_FLOAT , false , 4 * 4 , mColorBuffer);        //启用顶点位置数据和颜色数据        GLES20.glEnableVertexAttribArray(maPositionHandle);        GLES20.glEnableVertexAttribArray(maColorHandle);        //开始绘制        GLES20.glDrawArrays(GLES20.GL_TRIANGLES , 0 , mVCount);    }    /**     * 产生最终变换矩阵的方法     * @param spec     * @return     */    public static float[] getFinalMatrix(float[] spec){        mMVPMatrix = new float[16];        mMVPMatrix=new float[16];        Matrix.multiplyMM(mMVPMatrix , 0 , mVMatrix , 0 , spec , 0);        Matrix.multiplyMM(mMVPMatrix , 0 , mProjMatrix , 0 , mMVPMatrix , 0);        return mMVPMatrix;    }


由于代码中注释比较详细了,所以此处代码注释会比较少.demo下载地址:点击打开链接

2 0