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


本文针对与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下载地址:点击打开链接

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值