位置: 编程技术 - 正文

Android OpenGL ES(九)----构建几何物体

编辑:rootadmin
1.三角形扇

推荐整理分享Android OpenGL ES(九)----构建几何物体,希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:,内容如对您有帮助,希望把文章链接给更多的朋友!

一个三角形扇以一个中心顶点作为起始,使用相邻的两个顶点创建第一个三角形,接下来的每个顶点都会创建一个三角形,围绕起始的中心点按扇形展开。为了使这个扇形闭合,我们只需要在最后重复第二个点。(以长方形为例)

构建三角形扇的步骤,如下图所示:

要使用OpenGL绘制这个三角形扇,需要在渲染类的onDrawFrame()中,使用如下方法:

GLES.glDrawArray(GLES.GL_TRIANGLE_FAN,0,6);

第一个参数是告诉OpenGL要绘制一个三角形扇,第二参数是告诉OpenGL从本地顶点数据的第几个位置开始取顶点坐标,第三个参数是告诉OpenGL要取多少个顶点坐标。

根据上面的6个点,就可以绘制一个长方形了。

三角形扇在OpenGL的应用:长方形,正方形,圆等。

2.三角形带

一个三角形带的前三个顶点定义了第一个三角形。这之后的每个额外的顶点都定义了另外的一个三角形。

构建三角形带的步骤,如下图所示:

要使用OpenGL绘制这个三角形带,需要在渲染类的onDrawFrame()中,使用如下方法:

GLES.glDrawArray(GLES.GL_TRIANGLE_STRIP,0,6);

第一个参数是告诉OpenGL要绘制一个三角形带,第二参数是告诉OpenGL从本地顶点数据的第几个位置开始取顶点坐标,第三个参数是告诉OpenGL要取多少个顶点坐标。

三角形带在OpenGL的应用:长方形,圆柱的侧面等。

3.圆柱体

想象一下在自己的手机上构建的圆柱体,并且以一个角度观察它,假如我们把圆柱放在桌面上,从侧面观察它,你会发现,圆柱体是一个由一个顶部的圆加上侧面卷起来的长方形构成。结合本文前2节的讲解,就可以知道其实就是一个三角形带和三角形扇构建一个圆柱体。

要构建三角形扇,我们首先定义一个圆心顶点,接着,我们围绕圆心的点按扇形展开,并把第一个点绕圆周重复两次使其圆闭合。我们接下来使用三角函数和单位圆的概念生成那个点。

为了生成沿一个圆周边的点,我们首先需要一个循环,它的覆盖范围从0到度的整个圆,或者0到2π弧度。要找到圆周上的一个点的X的位置,我们需要调用cos(angle),如果你是放在Z-X平面那么,Z的位置我们就需要调用sin(angle);我们用圆的半径缩放这两个位置。这是圆柱上的圆的绘画过程。

如果是圆柱的侧面,我们就需要看图了解一下,我们假设圆柱垂直方向以Y为中心,圆柱高height,得到如下图:

我们该怎么用程序绘画出来这个圆柱体呢?其实在OpenGL如果想绘制的图像越清晰,那么它绘制的点就会越多越密集,所以由我们自己决定绘制这个圆柱体需要多少个顶点。

我们要计算圆柱体顶部顶点数量的方法作为开始,我们定义一个求圆柱体上面圆的顶点数的方法,如下:

private static int sizeOfCricleInVertices(int numPoint){

return 1&#;(numPoint&#;1);

}

一个圆柱体的顶部是一个用三角形扇构造的圆;它有一个顶点在圆心,围着圆的每个顶点点都有一个顶点,并且围着圆的顶点要重复两次,才能使圆闭合。

下面是计算圆柱体侧面顶点的数量:

private static int sizeOfOpenCylinderInVertices(int numPoint){

return (numPoints&#;1)*2;

}

一个圆柱体侧面是一个卷起来的长方形,由一个三角形带构造,围着顶部圆的每个点都需要两个顶点,并且前两个顶点要重复两次才能使这个管闭合。看三角形带,我们直指定了上面的点的数量,自然下面的点也要计算进去,所以都需要两个顶点。

添加几何图形的类

我们要构建几何物体,其实可以分解成几个类,这样便于管理和重用。创建一个新的类,为Geometry,在该类的内部我们定义一个坐标类,也就是点类:

public static class Point(){

public final float x,y,z;

public Point(float x,float y,float z){

this.x=x;

this.y=y;

this.z=z;

}

public Point translateY(float distance){

return new Point(x,y&#;distance,z);

}

}

其中有一个辅助函数用于把这个点沿着Y轴平移。我们也需要给,下面我们也给圆一个定义,如下,也为Geometry的内部类:

public static class Circle{

private final Point center;

private final float radius;

public Circle(Point center,float radius){

this.center=center;

this.radius=radius;

}

public Circle scale(float scale){

return new Circle(center,radius*scale);

}

}

我们同样在圆的类里面定义了一个辅助函数,用于缩放圆的半径,最后是给圆柱一个定义,如下:

public static class Cylinder{

public final Point center;

public final float radius;

public finla float height;

public Cylinder(Point center,float radius,float height){

this.center=center;

this.radius=radius;

this.height=height;

}

}

一个圆柱体就像一个扩展的圆,它有一个中心,一个半径和一个高度。

你可能注意到了我们已经把这几个几何物体定义的类定义为不可变的;无论什么时候改动它,都会返回一个新的对象。这有助于使代码更容易使用和理解。但是当你需要提高性能时,你也许想一直用简单的浮点数组,并用静态函数改变它们。

添加物体构建器

我们现在可以开始写物体构建器了,在你的objects包中创建一个名为“ObjectBuilder”的类,在类的内部,以下面的代码作为开始:

Android OpenGL ES(九)----构建几何物体

private static final int FLOATS_PER_VERTEX=3;

private final float[] vertexData;

private int offset=0;

private ObjectBuilder(int sizeInVertices){

this.vertexData=new float[sizeInVertices*FLOATS_PER_VERTEX];

}

我们定义了一个常量用来保存椒一个顶点需要多少浮点数,一个数组用于保存这些顶点,以及一个变量用于记录数组中下一个顶点的位置。这个构造函数基于需要的顶点数量初始化数组。

用三角形扇构建圆

在ObjectBuilder类中创建一个名为appendCircle的新方法,并加入如下代码:

private void appendCircle(Circle circle,int numPoint){

final int startVertex=offset/FLOATS_PER_VERTEX;

final int numVertices=sizeOfCircleInVertices(numPoint);

this.vertexData[offset&#;&#;]=circle.center.x;

this.vertexData[offset&#;&#;]=circle.center.y;

this.vertexData{offset&#;&#;}=circle.center.z;

for(i=0;i<numPoint;i&#;&#;){

float angleInRadians=(float)i/(float numPoints)*((float)Math.PI*2f);

this.vertexData[offset&#;&#;]=circle.center.x&#;circle.radius*FloatMath.cos(angleInRadians);

this.vertexData[offset&#;&#;]=circle.center.y;

this.vertexData[offset&#;&#;]=circle.center.z&#;circle.radius*FloatMath.sin(angleInRadians);

}

}

我们知道我们想要使用本地存储的顶点,必须设置偏移量,也就是多少个顶点才是正确的坐标,比如我们现在在绘画一个圆柱体,把圆的顶点和侧面的顶点都存储在本地,如果我们开始绘画圆,那么自然偏移是0,但是圆的顶点都绘完后,我们总不能还是从开始的顶点开始取&#;把,所以跳过取顶点,跳过的就是偏移&#;startVertex。而numVertices就是要取顶点的长度。

接着我们在ObjectBuilder类的开始处定义一个绘画的接口,顺便也加入一个变量,如下:

static interface DrawCommand{

void draw();

}

private final List<DrawCommand> drawList=new ArrayList<DrawCommand>();

这个常量用于保存绘画命令,如下:

this.drawList.add(new Command(){

public void draw(){

GLES.glDrawArrays(GLES.GL_TRIANGLE_FAN,startVertex,numVertices);

}

});

用三角形带构造圆柱体的侧面,为了代码的重用,我们额外定义了一个绘制侧面的方法appendOpenCylinder(),它也需要偏移量和长度,而且,看第二节的图片,你发现没有,上面一排和下面一排的顶点Y&#;是一样的,所以首先我们在appendOpenCylinder()加入下面四个常量:

private void appendOpenCylinder(Cylinder cylinder,int numPoints){

final int startVertex=offset/FLOATS_PER_VERTEX;

final int numVertices=sizeOfOpenCylinderInVertices(numPoints);

final float yStart=cylinder.center.y-(cylinder.height/2f);

final float yEnd=cylinder.center.y&#;(cylinder.height/2f);

}

然后加入如下代码生成实际的三角形带:

for(int i=0;i<=numPoints;i&#;&#;){

float angleInRadians=(float)i/(float numPoints)*((float)Math.PI*2F);

float xPosition=cylinder.center.x&#;cylinder.radius*FloatMath.cos(angleInRadians);

float zPosition=cylinder.center.z&#;cylinder.radius*FloatMath.sin(angleInRadians);

this.vertexData[offset&#;&#;]=xPosition;

this.vertexData[offset&#;&#;]=yStart;

this.vertexData[offset&#;&#;]=zPosition;

this.vertexData[offset&#;&#;]=xPosition;

this.vertexData[offset&#;&#;]=yEnd;

this.vertexData[offset&#;&#;]=zPosition;

}

最后在该方法中加入如下代码完成:

this.drawList.add(new Command(){

public void draw(){

GLES.glDrawArrays(GLES.GL_TRIANGLE_STRIP,startVertex,numVertices);

}

});

我们在ObjectBuilder类中实现了构造圆和圆柱侧面的方法。是不是还少了什么,没错,你获得的顶点和数据怎么传递给其他的类呢?所以我们在ObjectBuilder里面定义了一个包装类,将存储的绘制命令和顶点数据都传递给它,如下:

static class GenerateData{

final float[] vertexData;

final List<Command> drawList;

GenerateData(float[] vertexData,List<DrawCommand> drawList){

this.drawList=drawList;

this.vertexData=vertexData;

}

}

最后就是将圆和侧面叠加成一个圆柱体,我们ObjectBuilder加入如下的代码:

static GeneratedData createCylindrical(Cylinder cylinder,int numPoints){

int size=sizeOfCricleInVertices()&#;sizeOfOpenCylinderInVertices(numPoints);//计算总的顶点数

ObjectBuilder builder=new ObjectBuilder(size);//根据顶点数实例化vertexData;

Circle circle=new Circle(cylinder.center.translateY(cylinder.height/2f),cylinder.radius);

builder.appendCircle(circle,numPoints);

builder.appendOpenCylinder(cylinder,numPoints);

return builder.build();

}

private GenerateData build(){

return new GenerateData(this.vertexData,this.drawList);

}

这样一个圆柱体绘制类就完成了。

源代码如下:

版权声明:本文为博主原创文章,未经博主允许不得转载。

转载与收集的布局属性详解 收集备用第一类:属性为true或falseandroid:layout_centerHrizontal水平居中android:layout_centerVertical垂直居中android:layout_centerInparent相对于父元素完全居中android:layout_

LinearLayout设置 weight 无法绘制的问题 项目地址:ChildLayout一.问题起因:新项目中首页有这么一个需求:看布局:主要就是大牌专场这个栏目的布局问题,呈现一个,左——右上——右下的形

要看的书 《第一行代码》android基本知识《HeadFirstjava》java基本知识《TCP/IP协议》网络《算法》数据结构,算法,排序算法《HeadFirst设计模式》软件测试,android开

标签: Android OpenGL ES(九)----构建几何物体

本文链接地址:https://www.jiuchutong.com/biancheng/379601.html 转载请保留说明!

上一篇:android 背景音乐的播放(android 设置背景)

下一篇:LinearLayout设置 weight 无法绘制的问题(linearlayout addview)

  • 浙江税务网上办税大厅官网
  • 支付给员工的工资属于什么科目
  • 非金融单位贷款利息收入列示什么科目
  • 代收款有手续费怎么做账
  • 出售已使用固定资产增值税申报表
  • 支付外币投资会计处理
  • 投资性房地产转换日公允价值大于账面价值
  • 企业没有收入怎么办
  • 广告制作需要交文化建设费吗
  • 新公司成立前期人员配置
  • 免税和应税无法划分
  • 进项票已认证忘记开票
  • 水利建设专项收入税率
  • 承包学校的食堂如何纳税
  • 公司买回来做样衣的服装怎么做会计分录?
  • 固定资产折旧计算方法
  • 历年亏损企业开什么发票
  • 申报附加专项扣除
  • 餐饮店工装
  • 居民小区人防设施主要是什么
  • 租入房屋修缮费用谁承担
  • 理财公司收到客户投资款怎么处理
  • 资产负债表的资产总额怎么看
  • 上缴财政的收入 企业所得税
  • 公司购买基金怎样入账
  • windows10更新会丢失数据吗
  • 腾讯地图js api
  • 二年级祖先的摇篮教学视频
  • 控制器code是什么意思
  • 应交增值税转入营业外收入摘要怎么写
  • 完成认证后开具什么证明
  • 购买其他权益工具
  • 将时间序列转化为图像
  • 个人独资企业都需要交什么税
  • 企业亏损企业汇算清缴怎么处理
  • 在税务局怎么查补缴的社保
  • 增值税申报流程大全(附图文详解)
  • 物流小规模企业有哪些
  • 借款利息收入发票
  • java变量初始化的两种方式
  • 车改补贴算工资吗
  • 经营性应收项目的减少调增 为什么是减
  • 废旧物资处理的税金
  • 应收应付款会计分录
  • 电子承兑没到期兑换手多少手续费
  • 实收资本入账需要算设备安装费吗
  • 查补以前年度所得税
  • 已使用的存货,计价方式不允许修改
  • 电费发票开据后如何入帐?
  • 外派国外的员工享受国内法定假期吗
  • 结算本月职工工资,其中生产甲产品
  • 固定资金管理内容包括哪些
  • 收到代收款需要开票吗
  • 融资租入固定资产计提折旧吗
  • 生育津贴与员工有关吗
  • 对公账户提取备用金怎么做账
  • 中小企业两账合一怎么办
  • mysql数据存在内存还是硬盘
  • java连接sqlserver数据库对象名无效
  • sql server的mdf文件怎么导入数据库
  • w7系统ip地址
  • mse windows defender
  • windows无法打开此文件
  • windows10玩lol有延迟怎么办
  • windows10预览版怎么样
  • win7 设置
  • 手机连接电脑win11
  • win8小键盘怎么打开
  • unity de
  • 一个简单的灵魂
  • javascript运行环境有哪些
  • jQuery插件能输出到控制台
  • php守护进程的应用场景
  • 刮刮奖软件下载
  • aiclod
  • 浙江职称评审网址官网
  • 税务局纳税服务中心
  • 河南省地方税务局公告2011年第10号
  • 深圳关内停车场收费标准
  • 城镇土地使用税税率
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设