用户登录
用户注册

分享至

opengl es 绘制

  • 作者: 用户121108023
  • 来源: 51数据库
  • 2020-10-04
如何在Android使用OpenGL ES 2.0绘制点,看上去并不是一个复杂的问题,但是上网一搜,满眼都是绘制点的代码。

如果你看到类似如下代码,基本上你已经掉坑里了。
··· c
glBeging();
...
glDrawPoint(...);
...
glEnd();
```
如上是使用OpenGL ES 1.0绘制点的代码。因为架构不同,在OPENGL ES 2.0的世界里,这一套已经彻底不管用了。

在OpenGL ES 2.0里绘制点,要使用Shader,使用Shader,用Shader。。。。。。

具体怎么绘制呢,首先你要搞清楚,如何用Shader绘制一个普通带颜色的三角形。我这里假设你已经会了。

三角形显示出来的那一刻,你一定会有这样的代码:
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertexCount);

那么,只显示三角形的三个顶点该怎么办,说来简单,这行代码改成
GLES20.glDrawArrays(GLES20.GL_POINTS, 0, vertexCount);
即可。

但是,理想和现实的差距总是很大,改完后三角形消失了但是顶点没有出现。正常OpenGL 2.0环境下应该怎么做呢?
1)首先调用 GL20.glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); 这样在Shader中可以访问glPointSize;
2)然后类似准备每个顶点色彩那样准备顶点的大小的数值,三角形是三个顶点,就准备3个float。把顶点数据像色彩数据那样,绑定到VOB,再绑定到Shader的参数中。基本上就是照准备色彩那样准备顶点大小数据,不同之处在于每个色彩4个float,每个顶点尺寸1个float。
3)最后,把你的顶点Shader文件改好,增加顶点大小的输入参数和gl_PointSize赋值。
4)另外,如果你打算显示圆形顶点,而不是方形的,还要用GL20.glEnable()函数设置其他参数,具体可查OpenGL官网。
比如:
uniform mat4 matrix;
attribute vec4 aVertex;
attribute vec4 aColor;
attribute float aPointSize;
varying vec4 vColor;
void main(){
vColor = aColor;
gl_Position = matrix * aVertex;
gl_PointSize = aPointSize;
}
这样,基本上就搞定了。

现在,坑爹的问题来了,在Android上你找不到GLES20.GL_VERTEX_PROGRAM_POINT_SIZE的常量,谷歌似乎认为在手机的3D环境下绘制点没多大必要性,所以并没有加上这个参数,好在缺省情况下,模拟器中Shader中的gl_PointSize是打开的(Android 4.4.x)。所以你可以跳过第一步,直接传递点大小的参数,并把Shader改好就成。

那么,为什么你不写gl_PointSize = aPointSize,点就显示不出来呢。我估计缺省情况下,gl_PointSize = 0.0f,所以显示不出来。

如果你显示点的大小总是固定不变的,你甚至可以把传递顶点大小数值的步骤也省略掉,直接在Shader中写上gl_PointSize = 10.0f;即可。

阅读本文,当你打算在Android上用OPENGL ES 2.0显示点时,即可跳过谷歌的那些坑了。我想,手机GPU硬件厂商的开发包应该对OpenGL ES 2.0支持的更好些,比如高通的AdrenoSDK,建议大家下载尝试。



  完成工具的安装以后,继续在eclipse中创建一个新的android项目。项目名称虽然不重要,但是该节将与主要活动有关,因此应认真学习掌握。

首先看一段代码:

/** 新建一个glsurfaceview对象 */
private glsurfaceview mglsurfaceview;
glsurfaceview是一个特殊的视图,它为我们管理opengl表面并将其绘制到android视图系统中。它还添加许多可以简化opengl使用的功能,包括但并不局限于:

它为opengl提供一个专用的渲染线程,使主线程得以继续。

它支持连续或按需渲染,维护屏幕设置以及opengl和底层窗口系统之间的接口。代码如下:

@override
public void oncreate(bundle savedinstancestate)
{
super.oncreate(savedinstancestate);

mglsurfaceview = new glsurfaceview(this);

// 检测系统是否支持 opengl es 2.0
final activitymanager activitymanager = (activitymanager) getsystemservice(context. activity_service);
final configurationinfo configurationinfo = activitymanager.getdeviceconfigurationinfo();
final boolean supportses2 = configurationinfo.reqglesversion >= 0x20000;

if (supportses2)
{

mglsurfaceview.seteglcontextclientversion(2);


mglsurfaceview.setrenderer(new lessononerenderer());
}
else
{

return;
}

setcontentview(mglsurfaceview);
}
在oncreate()方法里面主要是创建opengl es 2.0上下文以及做一些初始化工作。在oncreate()中,调用超类之后的第一件事情就是创建glsurfaceview。然后确定系统是否支持 opengl es 2.0。因此,我们需要一个可以与全局系统状态相交互的activitymanager实例,以及使用这个实例来得到设备配置信息,该信息将通知我们设备 是否支持opengl es 2.0。

一旦确定设备是否支持opengl es 2.0后,就会通知表面视图需要一个与opengl es 2.0相兼容的视图,然后传递一个自定义渲染。这个渲染将在任何需要调整表面或者绘制一个新的帧的时候被系统调用。我们还通过传递一个不同的渲染来支持 opengl es 1.x,尽管可能由于apis的不同,导致我们需要编写不同的代码,但在这一节中,我们将只关注opengl es 2.0。

最后,我们为glsurfaceview设置内容视图,它通知android活动内容应该填补opengl表面,代码如下:

@override
protected void onresume()
{
super.onresume();
mglsurfaceview.onresume();
}

@override
protected void onpause()
{
super.onpause();
mglsurfaceview.onpause();
}
glsurfaceview要求我们在任何父activity的onresume()和onpause()方法被调用的时候调用onresume()和onpause()方法。
软件
前端设计
程序设计
Java相关