Android GlSurfaceView 入门教程 : 绘制一个三角形

这篇具有很好参考价值的文章主要介绍了Android GlSurfaceView 入门教程 : 绘制一个三角形。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1. GlSurfaceView是什么

GlSurfaceViewAndroid中的一个类,继承自SurfaceView,是用于显示OpenGL ES图形渲染的一个View
OpenGL ES是一种跨平台的图形API,用于渲染2D3D图形,也可以将相机的画面显示到GlSurfaceView上,从而实现滤镜的效果。
GlSurfaceView提供了一个可以在Android应用程序中绘制OpenGL ES图形的接口,允许开发者将复杂的3D图形、动画和视觉效果嵌入到应用程序中。
GlSurfaceView处理了OpenGL ES渲染环境的创建、维护和更新,以及与其他Android视图和事件系统的交互。

2. android中怎使用GlSurfaceview

2.1 添加OpenGL ES版本支持

新建Android项目,在AndroidManifest.xml文件中,添加 OpenGL ES 版本支持。例如,要使用 OpenGL ES 2.0,请添加以下代码:

<uses-feature android:glEsVersion="0x00020000" android:required="true" />

如果需要使用 OpenGL ES 3.0 则需要以下声明:0x00030000
如果需要使用 OpenGL ES 3.2 则需要以下声明:0x00030002

2.2 新建自定义的GlSurfaceView

新建一个MyGlSurfaceView类,继承自 GLSurfaceView,并进行初始化

import android.content.Context
import android.opengl.GLSurfaceView
import android.util.AttributeSet

class MyGLSurfaceView(context: Context, attrs: AttributeSet) : GLSurfaceView(context, attrs) {

    init {
        // 设置 OpenGL ES 版本
        setEGLContextClientVersion(2)

        // 设置渲染器
        val renderer = MyGLRenderer()
        setRenderer(renderer)
    }
}

2.3 新建自定义的Renderer

创建一个自定义的渲染器MyRenderer类,实现 GLSurfaceView.Renderer 接口,并实现其中的方法

class MyGLRenderer : GLSurfaceView.Renderer {
    override fun onSurfaceCreated(gl: GL10?, config: EGLConfig?) {
        //设置清除屏幕时使用的颜色
        GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f)
    }

    override fun onDrawFrame(gl: GL10?) {
        // 清除屏幕
        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT)
    }

    override fun onSurfaceChanged(gl: GL10?, width: Int, height: Int) {
        // 设置视口大小
        GLES20.glViewport(0, 0, width, height)
    }
}

2.4 使用MyGLSurfaceView

Activityxml中使用MyGLSurfaceView

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.heiko.myglsurfaceviewtest.MyGLSurfaceView
        android:id="@+id/gl_surface_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</FrameLayout>

2.5 运行看下效果

运行后,可以看到一个使用 OpenGL ES 绘制的黑色屏幕

Android GlSurfaceView 入门教程 : 绘制一个三角形,音视频开发,android,GLSurfaceView,OpenGL,入门,绘制三角形

3. 在自定义的MyGLRenderer中绘制三角形

3.1 添加顶点着色器和片段着色器的代码

MyGLRenderer 类中,添加顶点着色器和片段着色器的代码。在这里,我们创建一个简单的顶点着色器和片段着色器,它们将顶点位置传递给渲染管线并使用固定颜色进行渲染:

private val vertexShaderCode = "attribute vec4 vPosition;" +
        "void main() {" +
        "  gl_Position = vPosition;" +
        "}"

private val fragmentShaderCode = "precision mediump float;" +
        "uniform vec4 vColor;" +
        "void main() {" +
        "  gl_FragColor = vColor;" +
        "}"

3.2 添加编译和链接着色器的方法

MyGLRenderer 类中,添加一个方法来编译和链接着色器,然后返回着色器程序的 ID

private fun loadShaderProgram(vertexCode: String, fragmentCode: String): Int {
    // 编译顶点着色器
    val vertexShader = GLES20.glCreateShader(GLES20.GL_VERTEX_SHADER)
    GLES20.glShaderSource(vertexShader, vertexCode)
    GLES20.glCompileShader(vertexShader)

    // 编译片段着色器
    val fragmentShader = GLES20.glCreateShader(GLES20.GL_FRAGMENT_SHADER)
    GLES20.glShaderSource(fragmentShader, fragmentCode)
    GLES20.glCompileShader(fragmentShader)

    // 链接着色器程序
    val program = GLES20.glCreateProgram()
    GLES20.glAttachShader(program, vertexShader)
    GLES20.glAttachShader(program, fragmentShader)
    GLES20.glLinkProgram(program)
    return program
}

3.3 加载并创建着色器程序

MyGLRenderer 类中,添加成员变量来存储顶点数据、顶点缓冲区对象(VBO)和着色器程序 ID

private val vertexData = floatArrayOf(
    0.0f, 0.5f, 0.0f,
    -0.5f, -0.5f, 0.0f,
    0.5f, -0.5f, 0.0f
)

private var vertexBufferId = 0
private var shaderProgramId = 0

这里vertexData 为什么这么传,是和openGL的世界坐标系相关的
Android GlSurfaceView 入门教程 : 绘制一个三角形,音视频开发,android,GLSurfaceView,OpenGL,入门,绘制三角形
可以看到vertexData的第一个值0.0f,第二个值0.5f这个坐标点位于Y轴偏上的位置,第三个值0.0f我们不用管,这个是Z轴,在2D图形中我们不需要Z轴,所以这个统一传0.0f就好了。
同理,第四个值-0.5f、第五个值-0.5f位于X轴坐标的偏左侧,第六个值也是Z轴,我们不用管。
第七个值是0.5f,第八个值是-0.5f位于X轴坐标的偏右侧,第九个值也是Z轴,我们不用管。
具体如下图所示

Android GlSurfaceView 入门教程 : 绘制一个三角形,音视频开发,android,GLSurfaceView,OpenGL,入门,绘制三角形

然后,在 onSurfaceCreated 方法中初始化这些值,然后加载并创建着色器程序

override fun onSurfaceCreated(gl: GL10?, config: EGLConfig?) {
    // 设置清除屏幕时使用的颜色
    GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f)

    // 创建顶点缓冲区对象
    val buffers = IntArray(1)
    GLES20.glGenBuffers(1, buffers, 0)
    vertexBufferId = buffers[0]

    // 将顶点数据上传到缓冲区对象
    val vertexBuffer = ByteBuffer.allocateDirect(vertexData.size * 4)
        .order(ByteOrder.nativeOrder())
        .asFloatBuffer()
    vertexBuffer.put(vertexData)
    vertexBuffer.position(0)

    GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, vertexBufferId)
    GLES20.glBufferData(
        GLES20.GL_ARRAY_BUFFER,
        vertexData.size * 4,
        vertexBuffer,
        GLES20.GL_STATIC_DRAW
    )
    GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0)

    // 加载并创建着色器程序
    shaderProgramId = loadShaderProgram(vertexShaderCode, fragmentShaderCode);
}

3.4 绘制三角形

onDrawFrame 方法中,使用创建的着色器程序和顶点缓冲区对象来绘制三角形:

override fun onDrawFrame(gl: GL10?) {
    // 清除屏幕
    GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT)

    // 使用着色器程序
    GLES20.glUseProgram(shaderProgramId)

    // 绑定顶点缓冲区对象并启用顶点属性
    GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, vertexBufferId)
    val positionLocation = GLES20.glGetAttribLocation(shaderProgramId, "vPosition")
    GLES20.glEnableVertexAttribArray(positionLocation)
    GLES20.glVertexAttribPointer(positionLocation, 3, GLES20.GL_FLOAT, false, 0, 0)

    // 设置片段着色器的颜色
    val colorLocation = GLES20.glGetUniformLocation(shaderProgramId, "vColor")
    GLES20.glUniform4f(colorLocation, 1.0f, 0.0f, 0.0f, 1.0f)

    // 绘制三角形
    GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 3) // GL_TRIANGLES:三角形 GL_POINTS:点

    // 禁用顶点属性并解除顶点缓冲区对象的绑定
    GLES20.glDisableVertexAttribArray(positionLocation)
    GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0)
}

3.5 设置视口大小

onSurfaceChanged 方法中,还是一样,设置视口大小:

override fun onSurfaceChanged(gl: GL10?, width: Int, height: Int) {
    // 设置视口大小
    GLES20.glViewport(0, 0, width, height)
}

3.6 运行看下效果

Android GlSurfaceView 入门教程 : 绘制一个三角形,音视频开发,android,GLSurfaceView,OpenGL,入门,绘制三角形

4. Android中GLES20.java的API说明

上面我们已经实现了一个三角形的绘制,但是对于GLES20API还是不太了解,接下来再来看下常用的GLES20 API

4.1 Android中GLES20 API的一些主要功能说明

  • Shaders(着色器):GLES20使用可编程的着色器来渲染图形。顶点着色器处理顶点数据,片段着色器处理像素数据。着色器需要用GLSL(OpenGL Shading Language)编写。
  • Buffers(缓冲区):GLES20使用缓冲区来存储顶点数据和索引数据。顶点缓冲区对象(VBO)存储顶点数据,元素缓冲区对象(EBO)存储索引数据。
  • Textures(纹理):GLES20支持多种纹理类型,如2D纹理、立方体贴图等。纹理用于给3D对象添加详细的表面特征
  • Framebuffers(帧缓冲区):GLES20使用帧缓冲区对象(FBO)来存储渲染结果。你可以将渲染结果渲染到纹理中,然后将纹理应用到其他对象上,实现高级渲染效果。
  • Transformations(变换):GLES20支持多种变换操作,如平移、旋转、缩放等。变换矩阵用于在顶点着色器中处理顶点数据。
  • Lighting(光照):GLES20支持基本的光照计算,如环境光、漫反射光、镜面反射光等。光照计算通常在顶点着色器或片段着色器中进行。
  • Blending(混合):GLES20支持颜色混合,用于实现透明度、半透明等效果。混合操作可以根据源颜色和目标颜色按照指定的混合因子进行计算。
  • Culling(剔除):GLES20支持面剔除,可以剔除不可见的面,提高渲染性能。面剔除可以根据面的正面或反面进行。
  • Depth Testing(深度测试):GLES20支持深度测试,用于判断像素的可见性。深度测试可以根据像素的深度值进行比较,只渲染最前面的像素。
  • Stencil Testing(模板测试):GLES20支持模板测试,用于实现遮罩、镜子等效果。模板测试可以根据模板缓冲区的值对像素进行掩盖或者保留。

4.2 GLES20 API中一些主要方法的说明

  • glGenBuffers:生成缓冲区对象,如顶点缓冲区对象(VBO)和元素缓冲区对象(EBO)。
  • glBindBuffer:绑定缓冲区对象,使其成为当前活动的缓冲区。
  • glBufferData:将数据上传到缓冲区对象。
  • glVertexAttribPointer:定义顶点属性数组,指定顶点数据在缓冲区中的布局。
  • glEnableVertexAttribArray:启用顶点属性数组。
  • glDisableVertexAttribArray:禁用顶点属性数组。
  • glUseProgram:使用某个着色器程序进行渲染。
  • glGetUniformLocation:获取着色器程序中uniform变量的位置。
  • glUniformMatrix4fv:为uniform变量设置矩阵数据。
  • glCreateShader:创建着色器对象。
  • glShaderSource:为着色器对象设置源代码。
  • glCompileShader:编译着色器对象。
  • glGetShaderiv:获取着色器对象的编译状态。
  • glAttachShader:将着色器对象附加到着色器程序。
  • glLinkProgram:链接着色器程序。
  • glGetProgramiv:获取着色器程序的链接状态。
  • glDeleteShader:删除着色器对象。
  • glGenTextures:生成纹理对象。
  • glBindTexture:绑定纹理对象。
  • glTexParameteri:设置纹理参数,如过滤模式、环绕模式等。
  • glTexImage2D:上传纹理数据。
  • glGenFramebuffers:生成帧缓冲区对象。
  • glBindFramebuffer:绑定帧缓冲区对象。
  • glFramebufferTexture2D:将纹理对象附加到帧缓冲区对象。
  • glDrawArrays:绘制顶点数组,渲染图形。
  • glDrawElements:绘制索引数组,渲染图形。
  • glEnable:启用某个OpenGL功能,如深度测试、剔除、混合等。
  • glDisable:禁用某个OpenGL功能。
  • glBlendFunc:设置混合函数。
  • glCullFace:设置剔除面的模式。
  • glClearColor:设置清除颜色缓冲区时使用的颜色。
  • glClear:清除颜色缓冲区、深度缓冲区和/或模板缓冲区。

4.3 扩展 : EGL是什么

OpenGL是一个跨平台的操作GPUAPI,但OpenGL需要本地视窗系统进行交互,这就需要一个中间控制层。
EGL就是连接OpenGL ES和本地窗口系统的接口,引入EGL就是为了屏蔽不同平台上的区别。
EGL需要做一些环境配置,而GLSurfaceView就已经帮我们配置好了,从而让我们不了解EGL也可以调用OpenGL

当然,我们也可以不使用GLSurfaceView,而是自己通过EGL来和OpenGL进行交互,但这样就比较麻烦了。

5. 开启调试

GLSurfaceView.setDebugFlags() 方法可以激活 log或者错误检测,它们可以帮助调试 OpenGL ES 调用。具体使用时,在 GLSurfaceView 的构造函数中,调用 setRender() 之前调用GLSurfaceView.setDebugFlags()就可以了。下面是个例子:

class MyGLSurfaceView(context: Context, attrs: AttributeSet) : GLSurfaceView(context, attrs) {

    init {
        // 设置 OpenGL ES 版本
        setEGLContextClientVersion(2)
        //打开调试和日志
        setDebugFlags(DEBUG_CHECK_GL_ERROR or DEBUG_LOG_GL_CALLS)

        // 设置渲染器
        val renderer = MyGLRenderer()
        setRenderer(renderer)
    }
}

6. 源码下载

本文源码下载 : Android使用GlSurfaceView和OpenGL绘制三角形 Demo

7. 官方文档

GLSurfaceView | Android Developers (google.cn)
SurfaceView 和 GLSurfaceView | Android 开源项目 | Android Open Source Project (google.cn)
构建 OpenGL ES 环境 | Android 开发者 | Android Developers (google.cn)文章来源地址https://www.toymoban.com/news/detail-534418.html

到了这里,关于Android GlSurfaceView 入门教程 : 绘制一个三角形的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Android入门教程||Android 架构||Android 应用程序组件

    Android 操作系统是一个软件组件的栈,在架构图中它大致可以分为五个部分和四个主要层。 在所有层的最底下是 Linux - 包括大约115个补丁的 Linux 3.6。它提供了基本的系统功能,比如进程管理,内存管理,设备管理(如摄像头,键盘,显示器)。同时,内核处理所有 Linux 所擅

    2024年02月13日
    浏览(45)
  • Android 逆向入门保姆级教程

    作者:37手游移动客户端团队 前言 什么是 Android 逆向开发? Android 逆向开发是指对已发布的 Android 应用进行分析和破解,以了解应用程序的内部工作原理,获取应用程序的敏感信息,或者修改应用程序的行为。逆向开发可以帮助开发人员了解他人的代码实现,也可以帮助黑客

    2024年02月11日
    浏览(47)
  • Android入门教程 | ImageView 图片显示

    为了让App界面更美观生动,我们可以放上图片。 显示图片是“刚需”。不论是书籍,报纸,网站,都有显示图片的需求。毕竟“无图无真相”。 在 Android 应用开发中,我们通常使用 ImageView 来显示图片。 ImageView的主要属性 ImageView的使用 ImageView经常用来显示图片。例如直接显

    2024年02月03日
    浏览(61)
  • 掌握Linux指令和权限:一个入门教程

    语法格式 :ls [选项][目录或者文件] 功能 :对于目录,该命令列出该目录下的所有子目录与文件。对于文件,将列出文件名以及其他信息。 a 列出目录下的所有文件,包括以 . 开头的隐含文件。 -d 将目录象文件一样显示,而不是显示其下的文件。 如:ls –d 指定目录 -i 输出文

    2023年04月23日
    浏览(40)
  • Android基础教程——从入门到精通(上)

    本文是对B站教程 动脑学院 Android教程 学习过程中所做的笔记。 文章分为上下两部分,此文是上部分,下部分链接为:Android基础教程——从入门到精通(下) 源视频教程并没有录制全,本文还补充了 Service 和 网络通信 的内容 文章介绍详细,示例代码丰富,相信跟着本教程

    2024年02月02日
    浏览(50)
  • Android入门教程之Activity(生命周期,启动...)

    Activity 是一个应用组件,用户可与其提供的屏幕进行交互,以执行拨打电话、拍摄照片、发送电子邮件或查看地图等操作。 每个 Activity 都会获得一个用于绘制其用户界面的窗口。窗口通常会充满屏幕,但也可小于屏幕并浮动在其他窗口之上。 Activity 1. Activity 的使用 我们新建

    2024年02月04日
    浏览(65)
  • Android入门教程 | TextView简介(宽高、文字、间距)

    TextView简介 文字,是我们传达信息的一种常见方式。在安卓应用上显示文字,我们通常使用TextView。 之前我们已经知道如何获取到layout中的TextView,也知道 setText() 方法可以修改显示的文字。 结合我们实际的生活和学习经验,写字的时候,有哪些方面是可以由我们来控制的?

    2024年02月04日
    浏览(46)
  • android原生开发教程,安卓开发入门到精通

    建造者模式: 观察者模式: 代理模式: 门面模式: 单例模式: 生产者消费者模式: 这个通过对比来描述,比如面向对象和面向过程的对比,针对这两种思想的对比,还可以举个开发中的例子,比如播放器的实现,面向过程的实现方式就是将播放视频的这个功能分解成多个过

    2024年04月11日
    浏览(61)
  • Android入门教程 | UI布局之RelativeLayout 相对布局

    RelativeLayout 简述 RelativeLayout 继承于 android.widget.ViewGroup,按照子元素之间的位置关系完成布局,作为 Android 系统五大布局中最灵活也是最常用的一种布局方式,非常适合于一些比较复杂的界面设计。 RelativeLayout 和 LinearLayout 类似,都是 ViewGroup,能“容纳”多个子view。 Relativ

    2024年04月25日
    浏览(35)
  • OpenGL ES入门教程(一)编写第一个OpenGL程序

    从本文开始我将参考学习OpenGL ES应用开发实践指南 Android卷 [(美)KevinBrothaler著](提取码: 394m),并基于自己的理解以更加通俗易懂的方式讲解如何应用OpenGL ES。本系列教程的目标是应用OpenGL,所以不会涉及太多的理论知识,主要讲解方式是基于简单功能的代码拆解,学会对

    2024年02月06日
    浏览(48)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包