【Android学习系列】OpenGL开发教程二

来源:互联网 发布:highcharts ng.js 编辑:程序博客网 时间:2024/04/27 09:01

【第三部分】3D模型

3D动画,主要在于如何建模,比如金字塔,正方体,搞清楚它们顶点的坐标,然后绘制就可以了。

需要注意的是,这些模型,是一个个面去画,坐标存放在数组中。


具体参见: http://gongziya.com/834/android%E7%9A%84opengl%E6%95%99%E7%A8%8B%E7%AC%AC%E4%BA%94%E8%AF%BE%EF%BC%9A3d%E6%A8%A1%E5%9E%8B/


【第四部分】纹理

纹理映射就是用一个独立的图片文件来覆盖3D物体

(1) 在onSurfaceCreated方法中,进行配置

//允许2D贴图,纹理gl.glEnable(GL10.GL_TEXTURE_2D);// 创建纹理IntBuffer intBuffer = IntBuffer.allocate(1);gl.glGenTextures(1, intBuffer);texture = intBuffer.get();// 设置要使用的纹理gl.glBindTexture(GL10.GL_TEXTURE_2D, texture);//生成纹理,函数的第三个参数GLImage.mBitmap告诉OpenGL纹理数据的来源,GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, GLImage.mBitmap, 0);gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR);gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);

当它比放大得原始的纹理大 (GL_TEXTURE_MAG_FILTER)或缩小得比原始得纹理小(GL_TEXTURE_MIN_FILTER)时OpenGL采用的滤波方式。第三个参数GL10.GL_LINEAR表明是采用线性方式。使用 GL_LINEAR 需要CPU和显卡做更多的运算,也可以考虑采用 GL_NEAREST 。

(2) 设定纹理坐标

纹理坐标的X坐标, 0.0f代表着纹理的左侧。 0.5f表示纹理的中点, 1.0f 是纹理的右侧。 对于纹理的Y坐标。 0.0f 是纹理的底部。 0.5f 是纹理的中点, 1.0f 是纹理的顶部。

比如正方体的例子中,顶点(-1.0f,-1.0f,1.0f)代表了四边形的左下角坐标,而相应的纹理坐标是(0.0f,0.0f)也代表着纹理的左下角。(1.0f,-1.0f,1.0f)代表着四边形的右下角,而相应的纹理坐标(0.0f,1.0f)代表着纹理的右下角。

同样需要将纹理坐标加载到字符缓存对象中(在Render的构造函数中完成)。

private float texvertices[] ={    0.0f,0.0f,    0.0f,1.0f,    1.0f,1.0f,    1.0f,0.0f,    .........}

(3) 纹理应用,在onDrawFrame中进行

public void onDrawFrame(GL10 gl){// 清除屏幕和深度缓存gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);// 重置当前的模型观察矩阵gl.glLoadIdentity();// 并移入屏幕 4.0gl.glTranslatef(0.0f, 0.0f, -4.0f);//设置旋转gl.glRotatef(xrot, 1.0f, 0.0f, 0.0f);gl.glRotatef(yrot, 0.0f, 1.0f, 0.0f);gl.glRotatef(zrot, 0.0f, 0.0f, 1.0f); // 绑定纹理,可以不绑定,初始化已经绑定了gl.glBindTexture(GL10.GL_TEXTURE_2D, texture);//启用顶点数组和纹理数组功能gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);//指定顶点数组和纹理数组中的数据,纹理和四边形对应的顶点gl.glVertexPointer(3, GL10.GL_FLOAT, 0, QuaterBuffer);gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, TexCoordBuffer);//循环绘制for(int i=0; i<6; i++){    gl.glDrawArrays(GL10.GL_TRIANGLE_FAN, i*4, 4);}//关闭定点数组和纹理数组,并改变旋转值变量gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);xrot += 0.5f;yrot += 0.6f;zrot += 0.4f;}


【注意】1. 在gongziya的文章中,绑定纹理操作了两次,在(1)中已经绑定好了,又在(3)中进行绑定;经过测试,(3)中是可以不绑定的。

             2.纹理的坐标跟图形的坐标对应,这个也是需要注意的,不然会出现图形不对的情况。


【绘制多边形】

GL_TRIANGLE_FAN与GL_TRIANGLE_STRIP 区别

四个顶点分别v1,v2,v3,v4

在跳过开始的2个顶点,然后遍历每个顶点,让OpenGL将这些顶点和它前一个,以及数组的第一个顶点一起组成一个三角形。
先v1,v2,v3再v1,v3,v4这样可以形成一个扇形状得图形。


OpenGL的使用将最开始的两个顶点出发,然后遍历每个顶点,这些顶点将和他的前2个顶点一起组成一个三角形。
先v1, v2, v3, 再 v3, v2, v4 并且确定这些顶点可以形成某个多边形

可见,采用不同的绘制模式,顶点的坐标值也应该是不同的。(在OpenGL ES中,取消了绘制四边形的模式GL_QUADS和GL_QUAD_STRIP。那么要想绘制多边形,就要通过绘制多个三角形的方法‘拼成’多边形。)


OpenGL ES中支持的顶点绘制模式如下:
    GL_PONITS
    GL_LINES
    GL_LINE_STRIP
    GL_LINE_LOOP
    GL_TRIANGLES
    GL_TRIANGLE_STRIP
    GL_TRIANGLE_FAN

GL_POINTS模式是绘制一个个的点,

GL_LINES根据每一对点绘制一条条直线,

GL_LINE_STRIP绘制一系列连接的直线,

GL_LINE_LOOP也是绘制一系列连接的直线,只不过第一个顶点和最后一个顶点要彼此相连


【触屏事件】

想要实现按键和触屏事件的处理,只需要重载Activity类的onKeyUp(),onKeyDown()和onTouchEvent()这三个方法就可以了,在这三个方法中调用render类中的方法,达到控制图形状态改变的目的。