OpenGL ES 2.0(二)实战绘制一个三角形

网络空间安全

  这是我们绘制的第一个图形,选择三角形,点、线、三角形是OpenGL ES世界的图形基础。无论多么复杂的几何物体,在OpenGL ES的世界里都可以用三角形拼成。关于Android OpenGL ES 三角形的绘制,在Android官方文档中也是优先详细介绍三角形,这边也是根据官方文档来绘制。

  一、流程

  在AndroidManifest.xml文件中设置使用的OpenGL ES的版本创建显示三角形的Activity,利用GLSurfaceView作为显示三角形的View,图形的具体渲染工作都是在Rer中完成的。实现GLSurfaceView的Rer,在Rer中完成三角形的绘制,具体行为有: 加载顶点和片元着色器。 确定需要绘制图形的坐标和颜色数据。 创建program对象(着色器程序),连接顶点和片元着色器,链接program对象。 设置视图窗口(viewport)。 将坐标数据传入OpenGL ES程序中。 使颜色缓冲区的内容显示到屏幕上。二、实现

  1、在清单中声明 OpenGL ES 的使用:

  OpenGL ES 1.0 和 1.1 - 此 API 规范受 Android 1.0 及更高版本的。OpenGL ES 2.0 - 此 API 规范受 Android 2.2(API 级别 8)及更高版本的。OpenGL ES 3.0 - 此 API 规范受 Android 4.3(API 级别 18)及更高版本的。OpenGL ES 3.1 - 此 API 规范受 Android 5.0(API 级别 21)及更高版本的。//为了让您的应用使用 OpenGL ES 2.0 API,您必须将以下声明添加到清单中: //假如:OpenGL ES 3.1配置 0x00030001<uses-feature android:glEsVersion="0x00020000" android:required="true" />2、 创建Activity,自定义GLSurfaceView 作为主要视图的 Activity 的最低实现:

  public class Mai nActivity exts Activity { private GLSurfaceView gLView; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //创建一个自定义的GLSurfaceView gLView = new MyGLSurfaceView(this); setContentView(gLView); } }创建GLSurfaceView 是一种专用视图,您可以在其中绘制 OpenGL ES 图形。它本身并没有很大的作用。对象的实际绘制由您在此视图中设置的 GLSurfaceView.Rerer 控制

   import android.content.Context; import android.opengl.GLSurfaceView; class MyGLSurfaceView exts GLSurfaceView { private final MyGLRerer rerer; public MyGLSurfaceView(Context context){ super(context); //设置opengl版本 setEGLContextClientVersion(2); //创建自定义渲染器 rerer = new MyGLRerer(); // Set the Rerer for drawing on the GLSurfaceView setRerer(rerer); //性能有关。安卓默认使用这个按需渲染 //该设置可防止系统在您调用 requestRer() 之前重新绘制 GLSurfaceView 帧,这对于此示例应用而言更为高效。 setRerMode(GLSurfaceView.RERMODE_WHEN_DIRTY); } }【相关学习资料推荐,点击下方链接免费报名,先码住不迷路~】

  【免费】FFmpeg/WebRTC/RTMP/NDK/Android音视频流媒体高级开发-学习视频教程-腾讯课堂

  C++音视频配套学习资料:点击莬费领取→音视频开发(资料文档+视频教程+面试题)(FFmpeg+WebRTC+RTMP+RTSP+HLS+RTP)

  3、具体Rer渲染器的实现:

  基本着色器编写:顶点着色器: attribute vec4 vPosition; void main() { gl_Position = vPosition; }片元着色器: precision mediump float;//uniform vec4 vColor;void main() { //系统默认颜色字段:gl_FragColor gl_FragColor = vec4(0.9, 0.5, 0.7, 1.0);}定义三角形和创建program对象(着色器程序)

   private final int mProgram; private final FloatBuffer mVertexBuffer; private int vertexCount; private final int vertexStride = 3 * 4; // 4 bytes per vertex public Triangle(Context context) { String vertex = OpenGLUtils.readRawTextFile(context, R.raw.triangle_vert); String frag = OpenGLUtils.readRawTextFile(context, R.raw.triangle_frag); //顶点着色器id int vertexId = loadShader(GLES20.GL_VERTEX_SHADER, vertex); //片元着色器id int fragId = loadShader(GLES20.GL_FRAGMENT_SHADER, frag); //OpenGL ES渲染程序 mProgram = GLES20.glCreateProgram(); GLES20.glAttachShader(mProgram, vertexId); GLES20.glAttachShader(mProgram, fragId); //link一下。激活 GLES20.glLinkProgram(mProgram); GLES20.glDeleteShader(vertexId); GLES20.glDeleteShader(fragId); //世界坐标 float squareCoords[] = { -0.5f, -0.5f, 0f, 0.5f, -0.5f, 0f, -0.5f, 0.5f, 0f, 0.5f, 0.5f, 0f}; mVertexBuffer = ByteBuffer.allocateDirect(squareCoords.length * 4).order(ByteOrder.nativeOrder()).asFloatBuffer(); mVertexBuffer.clear(); mVertexBuffer.put(squareCoords); vertexCount = squareCoords.length / 3; } private int loadShader(int type, String shaderCode) { //获取着色器 int shader = GLES20.glCreateShader(type); //添加对于代码 GLES20.glShaderSource(shader, shaderCode); //编译着色器 GLES20.glCompileShader(shader); return shader; } public void draw() { //创建程序。链接到GPU GLES20.glUseProgram(mProgram); //获取顶点着色器坐标 int vPosition = GLES20.glGetAttribLocation(mProgram, "vPosition"); mVertexBuffer.position(0); //第二个参数是坐标个数:x,y,z GLES20.glVertexAttribPointer(vPosition, 3, GLES20.GL_FLOAT, false, vertexStride, mVertexBuffer); GLES20.glEnableVertexAttribArray(vPosition); GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertexCount); }绘制渲染

  public class MyRerer implements GLSurfaceView.Rerer { private MyGLSurfaceView myGLSurfaceView; private Triangle mTriangle; public MyRerer(MyGLSurfaceView myGLSurfaceView) { this.myGLSurfaceView = myGLSurfaceView; } @Override public void onSurfaceCreated(GL10 gl10, EGLConfig eglConfig) { //设置要清空窗体为指定的颜色 GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f); mTriangle = new Triangle(myGLSurfaceView.getContext()); } @Override public void onSurfaceChanged(GL10 gl10, int i, int i1) { //设置窗口大小 GLES20.glViewport(0,0,i,i1); } @Override public void onDrawFrame(GL10 gl10) { //执行清空窗体 GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT); mTriangle.draw(); }}三、效果

  如果你对音视频开发感兴趣,或者对本文的一些阐述有自己的看法,可以在下方的留言框,一起探讨。

标签: 网络空间安全