Android基于OpenGL在GLSurfaceView上绘制三角形及使用投影和相机视图方法示例
作者:pku_android 发布时间:2023-06-08 03:59:42
本文实例讲述了Android基于OpenGL在GLSurfaceView上绘制三角形及使用投影和相机视图方法。分享给大家供大家参考,具体如下:
定义三角形
OpenGL 允许我们使用三维坐标来定义物体。在绘制三角形前,我们需要定义它各个点的坐标。我们一般使用数组来存储各个顶点的坐标。
OpenGL ES 默认 [0,0,0] (X,Y,Z) 在GLSurfaceView的中心,[1,1,0]在右上角,[-1,-1,0]在左下角。
绘制三角形
在绘制三角形之前,我们必须告诉OpenGL我们正在使用顶点数组。然后我们才使用绘制函数画出三角形。
实验步骤:
1. 添加新的类Triangle
代码如下:
public class Triangle {
public Triangle()
{
float triangleCoords[] = {
// X, Y, Z 这是一个等边三角形
-0.5f, -0.25f, 0,
0.5f, -0.25f, 0,
0.0f, 0.559016994f, 0
};
// 初始化三角形的顶点缓存
ByteBuffer vbb = ByteBuffer.allocateDirect(
// (# of coordinate values * 4 bytes per float)
triangleCoords.length * 4);
vbb.order(ByteOrder.nativeOrder());// 使用设备硬件本身的字节序
triangleVB = vbb.asFloatBuffer(); // 从ByteBuffer中创建一个浮点缓存
triangleVB.put(triangleCoords); // 向浮点缓存中添加顶点坐标
triangleVB.position(0); // 使缓存读第一个坐标
}
public void draw(GL10 gl)
{
gl.glColor4f(0.63671875f, 0.76953125f, 0.22265625f, 0.0f); //设置当前颜色
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, triangleVB);//设置顶点
gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 3);//绘制三角形
}
private FloatBuffer triangleVB;
}
2. 在myGLRenderer类中添加成员privateTriangle mTriangle并在构造函数中初始化。
代码如下:
public myGLRenderer()
{
mTriangle = new Triangle();
}
3. 在myGLRenderer类的onSurfaceCreated()函数最后添加glEnableClientState()方法来启用顶点数组。
代码如下:
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
// TODO Auto-generated method stub
gl.glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
}
4. 在myGLRenderer类的onDrawFrame()函数最后添加三角形绘制方法。
代码如下:
@Override
public void onDrawFrame(GL10 gl) {
// TODO Auto-generated method stub
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
mTriangle.draw(gl);
}
这样,我们便完成了一个平面三角形的绘制。但我们发现这个三角形并不像我们定义的那样是一个等边三角形,这是由于OpenGL总假设我们的屏幕是一个正方形,这样在绘制的时候最终图形会随着屏幕长宽比例的不同而被拉伸。为了得到正确的显示,我们需要将图形投影到正确的位置。这一功能我们在下一节进行实现。
Android设备屏幕通常不是正方形的,而OpenGL总是默认地将正方形坐标系投影到这一设备上,这就导致图形无法按真实比例显示。要解决这一问题,我们可以使用OpenGL 的投影模式和相机视图将图形的坐标进行转换以适应不同的设备显示。
实验步骤:
1. 修改myGLRenderer类的onSurfaceCreated()函数来启用GL10.GL_PROJECTION模式,计算屏幕的长宽比并使用这一比例来转换物体的坐标。
代码如下:
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
// TODO Auto-generated method stub
gl.glViewport(0, 0, width, height);
float ratio = (float) width / height;
gl.glMatrixMode(GL10.GL_PROJECTION); // 设置当前矩阵为投影矩阵
gl.glLoadIdentity(); // 重置矩阵为初始值
gl.glFrustumf(-ratio, ratio, -1, 1, 3, 7); // 根据长宽比设置投影矩阵
}
2. 修改myGLRenderer的onDrawFrame()方法,启用MODELVIEW模式,并使用GLU.gluLookAt()来设置视点。
代码如下:
@Override
public void onDrawFrame(GL10 gl) {
// TODO Auto-generated method stub
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
// 设置当前矩阵为模型视图模式
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity(); // reset the matrix to its default state
// 设置视点
GLU.gluLookAt(gl, 0, 0, -5, 0f, 0f, 0f, 0f, 1.0f, 0.0f);
mTriangle.draw(gl);
}
这样,我们绘制的图形比例就总是正确的,不再受设备的影响而被拉伸变形了。
希望本文所述对大家Android程序设计有所帮助。
猜你喜欢
- JVM之方法返回地址JVM运行时数据区的虚拟机栈的栈帧中包含了返回地址当一个方法开始执行后,只有两种方式可以退出这个方法。第一种方式是执行引
- spring针对Bean之间的循环依赖,有自己的处理方案。关键点就是 * 缓存。当然这种方案不能解决所有的问题,他只能解决Bean单例模式下非
- 前言今天遇到一个问题,我们有个ip.dat二进制文件,通过里面内容可以解析ip所在的地域信息,本地单元测试都是OK的,部署到测试环境后,发现
- 前言面向切面(AOP)Aspect Oriented Programming是一种编程范式,与语言无关,是一种程序设计思想,它也是sprin
- java 中的instanceof 运算符是用来在运行时指出对象是否是特定类的一个实例。instanceof通过返回一个布尔值来指出,这个对
- 前言任何一个服务如果没有监控,那就是两眼一抹黑,无法知道当前服务的运行情况,也就无法对可能出现的异常状况进行很好的处理,所以对任意一个服务来
- 本文实例为大家分享了java实现多个文件压缩的具体代码,供大家参考,具体内容如下需要用到的ant.jarpackage util;impor
- 1. 效果图展示2. 工程目录结构注意: webapp下的resources目录放置easyui和js(jQuery文件是另外的) 
- 一、获取企业微信群机器人 Webhook 地址业务需要在企业微信推送告警监控或者定时提醒业务,就可以使用企业微信自带的机器人工具Webhoo
- 提示:建议一定要看后面的@RequestBody的核心逻辑源码以及六个重要结论!本文前半部分的内容都是一些基本知识常识,可选择性跳过。声明:
- 概述ConcurrentHashMap(CHM)是日常开发中使用频率非常高的一种数据结构,想对于普通的HashMap,CHM提供了线程安全的
- 一:背景1. 讲故事每次项目预交付的时候,总会遇到各种奇葩的坑,我觉得有必要梳理一下以及如何快速解决的,让后来人避避坑,这篇就聊聊自己的所闻
- java中的final关键字详解final的作用随着所修饰的类型而不同  
- 在项目的实际开发和应用中,常常需要用到将对象转为String这一基本功能。本文将对常用的转换方法进行一个总结。常用的方法有Object.to
- RestTemplate未设置超时时间,导致RabbitMQ队列大量堆积,消费者假死,不进行消费,类似线程堵塞。排查:从日志排查问题,在从进
- 这篇文章主要介绍了java操作elasticsearch的案例解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价
- 一、什么是重量级锁当有大量的线程都在竞争同一把锁的时候,这个时候加的锁,就是重量级锁。这个重量级锁其实指的就是JVM内部的ObjectMon
- 1 前言敏感词过滤就是你在项目中输入某些字(比如输入xxoo相关的文字时)时要能检测出来,很多项目中都会有一个敏感词管理模块,在敏感词管理模
- 前言:什么是多数据源?最常见的单一应用中最多涉及到一个数据库,即是一个数据源(Datasource)。那么顾名思义,多数据源就是在一个单一应
- 这篇文章主要介绍了Java等待唤醒机制线程通信原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋