《OpenGL ES应用开发实践指南:Android卷》—— 3.4 做最后的拼接

简介:

本节书摘来自华章出版社《OpenGL ES应用开发实践指南:Android卷》一 书中的第3章,第3.4节,作者:(美)Kevin Brothaler ,更多章节内容可以访问云栖社区“华章计算机”公众号查看。

3.4 做最后的拼接

我们在前两章中用了很大篇幅为这个应用打下了很好的基础:我们学习了如何使用属性数组定义一个物体的结构,也学习了如何创建着色器、加载并编译它们,以及把它们链接起来形成一个OpenGL的程序。
现在是时候在这个基础上开始构建并把它们拼接起来了。在下面的几个步骤里,我们就要把这些部分拼在一起,并准备好把第一个版本的空气曲棍球桌子画到屏幕上。

3.4.1 验证OpenGL程序的对象

在开始使用OpenGL的程序之前,我们首先应该验证一下它,看看这个程序对于当前的OpenGL状态是不是有效的。根据OpenGL ES 2.0的文档,它也给OpenGL提供了一种方法让我们知道为什么当前的程序可能是低效率的、无法运行,等等。
让我们在ShaderHelper中加入如下代码:
screenshot

我们调用glValidateProgram()来验证这个程序,然后用GL_VALIDATA_STATUS作为参数调用glGetProramiv()方法检查其结果。如果OpenGL有什么有用的信息要透露,这些信息会显示在程序日志里,因此我们也用glGetProgramInfoLog () 把日志打印出来。
在开始使用这个程序之前,我们应该验证它,并且我们应该只有在开发或调试应用的时候才去验证它。让我们在onSurfaceCreated()的结尾处加入如下代码:
screenshot

只有日志需要打开时,它才会调用我们早前定义的验证代码。下一步我们应该做的就是使用曾花费了很大力气创建的OpenGL程序。在onSurfaceCreated()结尾处加入如下代码:
screenshot

调用glUseProgram()告诉OpenGL在绘制任何东西到屏幕上的时候要使用这里定义的程序。

3.4.2 获得一个uniform的位置

下一步是获得我们早前在着色器中定义的uniform的位置。当OpenGL把着色器链接成一个程序的时候,它实际上用一个位置编号把片段着色器中定义的每个uniform都关联起来了。这些位置编号用来给着色器发送数据,并且我们需要u_Color的位置,以便我们可以在要绘画的时候设置颜色。
让我们快速看一下片段着色器:
screenshot
screenshot

在这个着色器里,我们已经定义了一个称为u_Color的uniform,并在main()中把这个uniform的值赋给了gl_FragColor。我们要使用这个uniform设置将要绘制的东西的颜色;我们要绘制一张桌子、一个中间分隔线和两个木槌,并且我们要使用不同的颜色绘制它们。
让我们在AirHockeyRenderer的顶部加入如下定义:
screenshot

我们已经为这个uniform的名字创建了一个常量和一个用来容纳它在OpenGL程序对象中的位置的变量。uniform的位置并不是事先指定的,因此,一旦程序链接成功了,我们就要查询这个位置。一个uniform的位置在一个程序对象中是唯一的:即使在两个不同的程序中使用了相同的uniform名字,也不意味着它们使用相同的位置。
在onSurfaceCreated()结尾处加入如下代码:
screenshot

我们调用glGetUniformLocation()获取uniform的位置,并把这个位置存入uColorLocation;当我们稍后要更新这个uniform值的时候,我们会使用它。

3.4.3 获取属性的位置

像uniform一样,在使用属性之前我们也要获得它们的位置。我们可以让OpenGL自动给这些属性分配位置编号,或者在着色器被链接到一起之前,可以通过调用glBindAttribLocation()由我们自己给它们分配位置编号。我们要让OpenGL自动分配这些属性位置,因为它使代码更容易管理。
让我们在AirHockeyRender顶部加入如下定义:
screenshot

一旦着色器被链接在一起了,我们就只需要加入一些代码去获取属性位置。在onSurfaceCreated()结尾处加入如下代码:
screenshot

调用glGetAttribLocation()获取属性的位置。有了这个位置,就能告诉OpenGL到哪里去找到这个属性对应的数据了。

3.4.4 关联属性与顶点数据的数组

下一步是要告诉OpenGL到哪里找到属性a_Position对应的数据。
在onSurfaceCreated()的结尾处加入如下代码:
screenshot

回到本章的开始处,我们创建了一个浮点数数组,这些浮点数表示组成空气曲棍球桌子的顶点的位置;我们在本地内存中创建了一个缓冲区,称为vertexData,并把这些位置复制到这个缓冲区内。
在我们告诉OpenGL从这个缓冲区中读取数据之前,需要确保它会从开头处开始读取数据,而不是中间或者结尾处。每个缓冲区都有一个内部的指针,可以通过调用position(int)移动它,并且当OpenGL从缓冲区中读取时,它会从这个位置开始读取。为了保证它一定从最开头处开始读取,我们调用position(0)把位置设在数据的开头处。
然后我们调用glVertexAttribPointer()告诉OpenGL,它可以在缓冲区vertexData中找到a_Position对应的数据。这是一个非常重要的函数,因此,让我们仔细看一下每个参数传递了什么(见表3-1)。
screenshot

传递不正确的参数给glVertexAttribPointer()会导致奇怪的结果,甚至导致程序崩溃。这种崩溃还很难跟踪,因此,我不是言过其实,获得正确的参数是非常重要的。
调用了glVertexAttribPointer()之后,OpenGL就知道在哪里读取属性a_Position的数据了。

3.4.5 使能顶点数组

尽管我们已经把数据属性链接起来了,在开始绘制之前,我们还需要调用glEnableVertexAttribArray()使能这个属性。在glVertexAttribPointer()调用之后加入如下代码:
screenshot

通过这最后一个调用,OpenGL现在就知道去哪里寻找它所需要的数据了。
在这一节里,我们取得了u_Color(uniform)及a_Position(属性)的位置;每个变量都有一个位置,并且OpenGL将使用这些位置,而不是直接使用这些变量的名字;之后,我们调用glVertexAttribPointer()告诉OpenGL,它可以从vertexData找到属性a_Position的数据。

相关文章
|
开发框架 前端开发 Android开发
Flutter 与原生模块(Android 和 iOS)之间的通信机制,包括方法调用、事件传递等,分析了通信的必要性、主要方式、数据传递、性能优化及错误处理,并通过实际案例展示了其应用效果,展望了未来的发展趋势
本文深入探讨了 Flutter 与原生模块(Android 和 iOS)之间的通信机制,包括方法调用、事件传递等,分析了通信的必要性、主要方式、数据传递、性能优化及错误处理,并通过实际案例展示了其应用效果,展望了未来的发展趋势。这对于实现高效的跨平台移动应用开发具有重要指导意义。
1408 4
|
11月前
|
存储 Android开发
如何查看Flutter应用在Android设备上已被撤销的权限?
如何查看Flutter应用在Android设备上已被撤销的权限?
566 64
|
存储 XML 开发工具
探索安卓应用开发:从基础到进阶
在这篇文章中,我们将一起踏上安卓应用开发的旅程。不论你是编程新手还是希望提升技能的开发者,这里都有你需要的东西。我们会从最基础的概念开始,逐步深入到更复杂的主题。文章将涵盖开发环境设置、用户界面设计、数据处理以及性能优化等方面。通过理论与实践的结合,你将能够构建出既美观又高效的安卓应用。让我们一起开启这段技术之旅吧!
|
Android开发 Swift iOS开发
深入探索iOS与Android操作系统的架构差异及其对应用开发的影响
在当今数字化时代,移动设备已经成为我们日常生活和工作不可或缺的一部分。其中,iOS和Android作为全球最流行的两大移动操作系统,各自拥有独特的系统架构和设计理念。本文将深入探讨iOS与Android的系统架构差异,并分析这些差异如何影响应用开发者的开发策略和用户体验设计。通过对两者的比较,我们可以更好地理解它们各自的优势和局限性,从而为开发者提供有价值的见解,帮助他们在这两个平台上开发出更高效、更符合用户需求的应用。
|
算法 Java 数据库
Android 应用的主线程在什么情况下会被阻塞?
【10月更文挑战第20天】为了避免主线程阻塞,我们需要合理地设计和优化应用的代码。将耗时操作移到后台线程执行,使用异步任务、线程池等技术来提高应用的并发处理能力。同时,要注意避免出现死循环、不合理的锁使用等问题。通过这些措施,可以确保主线程能够高效地运行,提供流畅的用户体验。
984 156
|
前端开发 Java Shell
【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
846 20
【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
|
Dart 前端开发 Android开发
【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
417 4
【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
|
JSON Java API
探索安卓开发:打造你的首个天气应用
在这篇技术指南中,我们将一起潜入安卓开发的海洋,学习如何从零开始构建一个简单的天气应用。通过这个实践项目,你将掌握安卓开发的核心概念、界面设计、网络编程以及数据解析等技能。无论你是初学者还是有一定基础的开发者,这篇文章都将为你提供一个清晰的路线图和实用的代码示例,帮助你在安卓开发的道路上迈出坚实的一步。让我们一起开始这段旅程,打造属于你自己的第一个安卓应用吧!
377 14
|
Java Linux 数据库
探索安卓开发:打造你的第一款应用
在数字时代的浪潮中,每个人都有机会成为创意的实现者。本文将带你走进安卓开发的奇妙世界,通过浅显易懂的语言和实际代码示例,引导你从零开始构建自己的第一款安卓应用。无论你是编程新手还是希望拓展技术的开发者,这篇文章都将为你打开一扇门,让你的创意和技术一起飞扬。
277 13
|
搜索推荐 前端开发 测试技术
打造个性化安卓应用:从设计到开发的全面指南
在这个数字时代,拥有一个定制的移动应用不仅是一种趋势,更是个人或企业品牌的重要延伸。本文将引导你通过一系列简单易懂的步骤,从构思你的应用理念开始,直至实现一个功能齐全的安卓应用。无论你是编程新手还是希望拓展技能的开发者,这篇文章都将为你提供必要的工具和知识,帮助你将创意转化为现实。