OpenGL 绘制一个三角型解析

一、如图

OpenGL 绘制一个三角型解析_第1张图片

二、坐标图

OpenGL 绘制一个三角型解析_第2张图片

三、眼睛观测图

OpenGL 绘制一个三角型解析_第3张图片

四、绘制步骤:

1)创建GLSurfaceView对象
2)创建GLSurfaceView.renderer实现类.
3)设置activity的contentView,以及设置view的render对象.
4)实现render类

五、实现render类的过程

1)a.onSurfaceCreate()方法
//设置清屏的颜色和启用顶点缓冲区
//设置清屏色
gl.glClearColor(0, 0, 0, 1);
//启用顶点缓冲区.
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
2)b.onSurfaceChanged()方法
1.设置viewport(视口)
gl.glViewport(0, 0, width, height);
2.操纵投影矩阵,设置平截头体(比例通常和视口比例相同,否则输出画面会走样)
//矩阵模式,投影矩阵,openGL基于状态机
gl.glMatrixMode(GL10.GL_PROJECTION);
//加载单位矩阵
gl.glLoadIdentity();
//平截头体
gl.glFrustumf(-1f, 1f, -ratio, ratio, 3, 7);
3)c.onDrawFrame()方法
1.清除颜色缓冲区
gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
2.操纵模型视图矩阵,设置眼球的参数
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity();//加载单位矩阵
GLU.gluLookAt(gl, 0, 0, 5, 0, 0, 0, 0, 1, 0);
3.定义图形顶点坐标值数组
float[] coords = {
0f,0.5f,0f,
-0.5f,-0.5f,0f,
0.5f,-0.5f,0f
};
4.将顶点坐标转换成缓冲区数据
//分配字节缓存区空间,存放顶点坐标数据
ByteBuffer ibb = ByteBuffer.allocateDirect(coords.length * 4);
//设置的顺序(本地顺序)
ibb.order(ByteOrder.nativeOrder());
//放置顶点坐标数组
FloatBuffer fbb = ibb.asFloatBuffer();
fbb.put(coords);
//定位指针的位置,从该位置开始读取顶点数据
ibb.position(0);
5.设置绘图颜色
gl.glColor4f(1f, 0f, 0f, 1f);
6.指定顶点缓冲区指针
//3:3维点,使用三个坐标值表示一个点
//type:每个点的数据类型
//stride:0,跨度.
//ibb:指定顶点缓冲区
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, ibb);
7.绘图
//0:起始点:
//3:绘制点的数量
gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 3);

六、内容说明:

viewPort:视口,输出画面的区域.

openGL:matrix,矩阵.

投影:
透视投影:有深度,越远越小.
正投影:没有深度,相同大小.

GLSurfaceView:GL表层视图,输出openGL画面的控件.
GLSurfaceView.Renderer:openGL渲染器,绘制openGL的类.

gl.glMatrixMode(int n);
矩阵模式,openGL基于状态的,操纵很多矩阵,通过该函数指定使用哪个矩阵.
常用的矩阵有:
GL10.GL_PROJECTION:投影矩阵.
GL10.GL_MODELVIEW:模型视图矩阵.
指定使用哪个矩阵之后,需要先加载单位矩阵(使用gl.loadIdentity()方法,类似于矩阵归零.

frustum:平截头体,拍摄画面的一个区域,是一个棱台,对投影矩阵进行操纵.
参数:
left:左侧距离
right:右侧距离
bottom:下方距离
top:上方距离
zNear:近平面距离
zFar:远平面距离
gl.glFrustum(,,,,,,);

设置眼睛的位置.
//涉及到眼球的坐标,观察的点,向上的向量
//操纵的是模型视图矩阵,因此需要先设置gl.glMatrixMode(Gl_modelview);
GLU.gluLookat(gl,eyex,eyey,eyez,centerx,centery,centerz,upx,upy,upz);

七、具体代码实现

/**
 * @描述         使用opengl绘制三角形
 * @项目名称      App_OpenGL
 * @包名         com.android.opengl
 * @类名         MainActivity
 * @author      chenlin
 * @date        2014年5月12日 下午10:57:20
 * @version     1.0
 */

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        MyGlSurfaceView surfaceView = new MyGlSurfaceView(this);
        surfaceView.setRenderer(new MyRender());
        setContentView(surfaceView);
    }

    private class MyGlSurfaceView extends GLSurfaceView{
        public MyGlSurfaceView(Context context, AttributeSet attrs) {
            super(context, attrs);
        }

        public MyGlSurfaceView(Context context) {
            super(context);
        }
    }

    private class MyRender implements Renderer{

        //绘图
        @Override
        public void onDrawFrame(GL10 gl) {
            //清楚颜色缓存
            gl.glClear(GL10.GL_COLOR_BUFFER_BIT);

            gl.glMatrixMode(GL10.GL_MODELVIEW);
            gl.glLoadIdentity();
            //眼睛的位置,眼睛的观测点,眼睛向上的量
            GLU.gluLookAt(gl, 0, 0, 5, 0, 0, 0, 0, 1, 0);

            //绘制数组
            float coords[] = {
                    0f,0.5f,0f,
                    -0.5f,-0.5f,0f,
                    0.5f,-0.5f,0f
            };
            //创建缓存区,存放顶点坐标
            ByteBuffer bb = ByteBuffer.allocateDirect(coords.length * 4);
            //设置循序
            bb.order(ByteOrder.nativeOrder());
            FloatBuffer floatBuffer = bb.asFloatBuffer();
            floatBuffer.put(coords);
            //指向0
            bb.position(0);

            //设置颜色
            gl.glColor4f(1f, 0f, 0f, 1f);
            //3:3维点,使用三个坐标表示一个点,type类型
            gl.glVertexPointer(3, GL10.GL_FLOAT, 0, bb);

            //画三角形
            gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 3);
        }

        //表层size时
        @Override
        public void onSurfaceChanged(GL10 gl, int width, int height) {
            gl.glViewport(0, 0, width, height);
            float ratio = width*1.0f / height;
            //投影矩阵
            gl.glMatrixMode(GL10.GL_PROJECTION);
            gl.glLoadIdentity();
            //平杰头体
            gl.glFrustumf(-1f, 1f, -ratio, ratio, 3, 7);

        }

        //表层创建时
        @Override
        public void onSurfaceCreated(GL10 gl, EGLConfig config) {
            gl.glClearColor(0, 0, 0, 1);
            gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
        }


    }
}

你可能感兴趣的:(android,高级技术,OpenGL)