openGL画三角形---openGL学习笔记(四)

在openGL中,所有面状图形的绘制都是使用画三角形方法,而针对不同需求,openGL给出三种不同的画三角形方法:

①traingles:画三角形集

openGL画三角形---openGL学习笔记(四)_第1张图片

②traingle_strip:画三角形带

openGL画三角形---openGL学习笔记(四)_第2张图片

③traingle_fan:画三角形扇面

openGL画三角形---openGL学习笔记(四)_第3张图片

画三角形集在笔记(一)中已经实现过,现在我们用三角形带渲染一个正方形,效果图如下。

openGL画三角形---openGL学习笔记(四)_第4张图片

onSurfaceCreated()和onSurfaceChanged()两个方法与之前一模一样,现在只看onDrawFrame()方法:

首先画三角形带的原理是,依次后推一位,比如:按逆时针顺序给定四个点,A、B、C、D,调用画三角形带方法后,openGL的绘制顺序是,ABCA(第一个三角形)--->BCDB(第二个三角形)以此类推,这样明显不是一个正方形。

所以,我们要用画三角形带的方式渲染一个正方形,那么点的顺序就是逆时针方向A-->B-->D-->C.

知道了点的顺序后就可以写onDrawFrame()方法了,同样的,还是先清除颜色缓冲区,设置绘图颜色,设置矩阵模式,加载单位矩阵,放置眼球位置,设置旋转角度(如需要)。

做好了这些工作之后,就要设置顶点坐标了,为方便起见,我们在Z=0的平面上绘制正方形,并且正方形与Y轴左右对称,那么四个点的Z轴坐标就都是0,设置XY轴坐标之前,我们先定义一个半径r=0.5f,那么A点坐标就为-r,r,0,相应的B点坐标为-r,-r,0,C点坐标为r,r,0,D点坐标为r,-r,0。

然后设置顶点指针,最后画矩阵的类型为GL10.GL_TRIANGLE_STRIP.

这样就用画三角形带的方法渲染出了一个正方形,附代码:

/**
 * 用三角形带渲染出正方形
 */

public class MyTriangleRenderer extends AbstractRenderer{

    public void onDrawFrame(GL10 gl) {

        //清除颜色缓冲区
        gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
        //设置绘图颜色
        gl.glColor4f(1f, 1f, 1f, 1f);
        //设置模型视图矩阵
        gl.glMatrixMode(GL10.GL_MODELVIEW);
        //载入单位矩阵
        gl.glLoadIdentity();
        //放置眼球位置
        GLU.gluLookAt(gl, 0f, 0f, 5f, 0f, 0f, 0f, 0f, 1f, 0f);
        //旋转角度,以便更直观查看
        gl.glRotatef(xRotate, 1, 0, 0);// x轴旋转 (openGL规定,顺时针旋转为负值)
        gl.glRotatef(yRotate,1,0,0);// y轴旋转

        /**
         * 计算点的坐标
         * @param r 半径
         * @param coordsList 坐标集合
         * @param x,y,z 每个点的坐标
         * @param alpha 角度
         *
         */

        float r = 0.5f;//半径
        float [] coords = {
                -r,r,0,
                -r,-r,0,
                r,r,0,
                r,-r,0,
        };

        gl.glVertexPointer(3,GL10.GL_FLOAT,0, BufferUtils.array2ByteBuffer(coords));//指定顶点指针

        gl.glDrawArrays( GL10.GL_TRIANGLE_STRIP,0,4 );


    }
}
接下来我们用画三角形扇面的方法绘制一个棱锥:

效果图如下

openGL画三角形---openGL学习笔记(四)_第5张图片

方便起见,我们设置平截头体的中心为坐标的原点,假定平截头体前后的距离0.5f,那么棱锥的顶点坐标为(0,0,0.5f),棱锥底面圆上的坐标为(x,y,-0.5f),而xy依旧用循环取到:

for( float alpha = 0f; alpha < Math.PI * 6;alpha = (float) (alpha+Math.PI / 8 )){
    x = (float) (Math.cos(alpha) * r);
    y = (float) (Math.sin(alpha) * r);
 
  
}

这样棱锥顶点和棱锥底面圆上的两点,就可以用画三角形扇面的方法绘制,而多个这样的扇面组合起来就是我们需要的棱锥。

这样绘制完之后我们发现,棱锥是单一颜色的,那么如何做到让棱锥出现交叉色呢?这就需要用到另一个缓冲区数据---颜色缓冲区。

我们可以设置一个布尔型变量flag,通过flag的值来添加颜色数据到颜色集合,然后将这个Float集合转换成字节缓冲区,最后设置顶点颜色指针。

boolean flag = false;
List colorList = new ArrayList();
if( flag = !flag ){
    //黄色
    colorList.add(1f);
    colorList.add(1f);
    colorList.add(0f);
    colorList.add(1f);

}else {
    //红色
    colorList.add(1f);
    colorList.add(0f);
    colorList.add(0f);
    colorList.add(1f);
}
ByteBuffer colorBuffer = BufferUtils.list2ByteBuffer(colorList);
gl.glColorPointer(4, GL10.GL_FLOAT, 0, colorBuffer );//顶点颜色指针
这样绘制完成之后,发现棱锥没有底面,那么同样,我们也可以通过画三角形扇面的方法也可以画一个棱锥的底面:

首先我们知道锥底的中心点坐标为(0,0,-0.5f),而底面圆上的坐标和上面画扇面所用到的循环一模一样,所以干脆直接添加进底面坐标的list:

/******************** 锥底 **********************/
float r = 0.5f;//半径
float x = 0f,y = 0f,z = -0.5f;//底面圆心点的坐标
List coordsConeBottomList = new ArrayList() ;coordsConeBottomList.add( 0f) ;coordsConeBottomList.add( 0f) ;coordsConeBottomList.add(- 0.5f) ;
for( float alpha = 0f; alpha < Math.PI * 6;alpha = (float) (alpha+Math.PI / 8 )){
    x = (float) (Math.cos(alpha) * r);
    y = (float) (Math.sin(alpha) * r);
    //锥面坐标
    coordsList.add(x);
    coordsList.add(y);
    coordsList.add(z);
    //锥底坐标
    coordsConeBottomList.add(x);
    coordsConeBottomList.add(y);
    coordsConeBottomList.add(z);
}

然后再次指定顶点指针,最后调用画三角形扇面方法即可。

最终效果图:

openGL画三角形---openGL学习笔记(四)_第6张图片

你可能感兴趣的:(openGL)