首页 > 其他分享 >OpenGL 学习系列---基本形状的绘制

OpenGL 学习系列---基本形状的绘制

时间:2022-10-08 22:03:46浏览次数:68  
标签:OpenGL float 0.5 --- 顶点 三角形 绘制 360

在之前的一篇博客中,讲述了 ​​OpenGL 基础绘制流程​​ 及相关的代码,其中关于 OpenGL 程序编译部分都是可以在其他项目中接着复用的,接下来会讲到如何去绘制其他的基本图元。

绘制直线

两点确定一条直线,显然绘制一条直线是需要两个顶点数据的。

定义如下顶点数据,绘制一条屏幕对角线的直线:

    float[] lineVertex = {
-0.5f, 0.5f,
0.5f, -0.5f
};

而我们的顶点着色器和片段着色器也会发生一些变化,最终还是绘制一条单一颜色的直线。

顶点着色器代码:

attribute vec4 a_Position;
void main(){
gl_Position = a_Position;
}

由于是绘制的直线,相比于绘制点,就没有了 ​​gl_PointSize​​变量来确定大小了。

片段着色器代码:

precision mediump float;
uniform vec4 u_Color;
void main()
{
gl_FragColor = u_Color;
}

依旧是纯色,目前还没有涉及到颜色的变化。

而在我们给着色器变量绑定数据时,依旧是通过​​glGetUniformLocation​​​和​​glGetAttribLocation​​​方法给​​uniform​​​和​​attribute​​​类型的​​u_Color​​​和​​a_Position​​变量赋值。

最后还是通过​​glDrawArrays​​方法执行绘制。

glDrawArrays(GL_LINES, 0, 2);

​GL_LINES​​​代表绘制的类型是直线,而​​0,2​​则是绘制的顶点范围。

绘制三角形

绘制三角形和绘制直线基本差不多,从两个点的直线变成了三个点的三角形。

顶点数据也发生了相应的改动,假设如下的数据,注意要以逆时针定义数据。

    float[] triangleVertex = {
-0.5f, 0.5f,
-0.5f, -0.5f,
0.5f, -0.5f
};

那么最后绘制时,绘制类型也会发生变化了,顶点个数范围也会变化。

 glDrawArrays(GL_TRIANGLES, 0, 3);

绘制三角形结果如图:

OpenGL 学习系列---基本形状的绘制_顶点着色器

绘制矩形

显然,OpenGL 是没有提供矩形这一基本图元的,但是我们可以用两个三角形来拼接成一个矩形。

OpenGL 中提供了一个绘制类型叫做​​三角形扇​​,如下图所示:

OpenGL 学习系列---基本形状的绘制_数据_02

在上图中,矩形的每一条边上的顶点都被两个三角形使用了,而且中心的顶点被所有四个三角形使用了。

我们不必输入四个三角形的顶点数据来绘制四个三角形从而组成矩形,可以告诉 OpenGL 重用那些顶点数据,把这些顶点作为一个三角形扇绘制。

一个三角形扇以一个中心顶点作为起始,使用相邻的两个顶点创建第一个三角形,接下来的每个顶点都会创建一个三角形,围绕起始的中心点按扇形展开,为了使扇形闭合,我们需要在最后重复第二个点。

所以,以三角形扇的形式绘制一个矩形,我们可以重新定义矩形的顶点数据:

   float[] rectangleVertex = {
// 第一个点就是三角形扇的中心点
0f, 0f,
-0.5f, -0.8f,
0.5f, -0.8f,
0.5f, 0.8f,
-0.5f, 0.8f,
-0.5f, -0.8f
// 重复第二个点,使三角形扇闭合
};

而着色器代码依旧不变,绘制一个纯色的矩形,绘制代码如下:

  glDrawArrays(GL_TRIANGLE_FAN, 0, 6);

绘制类型为​​GL_TRIANGLE_FAN​​,顶点数量也变成了 6 个。

那么问题来了,OpenGL 到底为我们提供哪些绘制方式呢?如下表所示:

OpenGL 学习系列---基本形状的绘制_着色器_03

绘制圆形

现在我们要绘制一个圆形,显然 OpenGL 是没有提供圆形的绘制类型的,这就要用到上面提供的绘制方式了。

以绘制一个实心的圆形为例子:

有了上面​​三角形扇绘​​制矩形的例子,我们按照同样的思想,把一个圆形分成多个三角形组成,如下图所示:

OpenGL 学习系列---基本形状的绘制_数据_04

我们分的三角形越多,三角形个数趋向于无限大的时候,整个图案也就越趋向于圆。

这样一来,顶点数据就不能再靠手写了。

    // 圆形分割的数量,分成 360 份,可由 360 个线段组成空心圆,也可以由 360 个三角形组成实心圆
public static final int VERTEX_DATA_NUM = 360;
// 360 个顶点的位置,因为有 x 和 y 坐标,所以 double 一下,再加上中心点 和 闭合的点
float[] circleVertex = new float[VERTEX_DATA_NUM * 2 + 4];
// 分成 360 份,每一份的弧度
float radian = (float) (2 * Math.PI / VERTEX_DATA_NUM);
// 绘制的半径
float radius = 0.8f;
// 初始化圆形的顶点数据
private void initVertexData() {
// 中心点
circleVertex[0] = 0f;
circleVertex[1] = 0f;
// 圆的 360 份的顶点数据
for (int i = 0; i < VERTEX_DATA_NUM; i++) {
circleVertex[2 * i + 2] = (float) (radius * Math.cos(radian * i));
circleVertex[2 * i + 1 + 2] = (float) (radius * Math.sin(radian * i));
}
// 闭合点
circleVertex[VERTEX_DATA_NUM * 2 + 2] = (float) (radius * Math.cos(radian));
circleVertex[VERTEX_DATA_NUM * 2 + 3] = (float) (radius * Math.sin(radian));
}

把圆分成了 360 份。圆形的顶点数据也分为了三部分了,以原心作为我们的中心点,中间的 360 个点用来绘制三角形,最后一个点使得我们的图形闭合。

在绘制时依旧使用三角形扇的形式来绘制。

    // 要把顶点数据个数对应上
glDrawArrays(GL_TRIANGLE_FAN, 0, VERTEX_DATA_NUM + 2);

当然,在绘制圆形时,我们也可以不单独定义原点和闭合点,直接使用圆形的 360 个顶点来绘制,最终的结果依旧会是一个圆形。

OpenGL 学习系列---基本形状的绘制_顶点着色器_05

当然,我们也可以使用其他的绘制类型,比如直线,来绘制一个空心的圆形。

还是上面定义的顶点数据,但是我们只用其中分割成 360 份的那部分顶点数据就好了,也就是去掉首位两个点,然后把这个 360 个点依次连接绘制成圆形。

        glDrawArrays(GL_LINE_LOOP, 1, VERTEX_DATA_NUM );


OpenGL 学习系列---基本形状的绘制_数据_06

这样就完成一个圆形的绘制。

正多边形的绘制

在绘制圆形的基础上,我们还可以进行拓展一下。

要知道,最后我们的圆形实际上是一个正多边形来趋近于圆形的,只是肉眼难以观察到了,毕竟它是一个正三百六十边形…

那么假设我们要绘制正五边形、正六边形、正七边形呢?

实际上也很简单,只要把圆分成五份、六份、七份就好了。

展示一些绘制图如下:

正五边形:

OpenGL 学习系列---基本形状的绘制_着色器_07

正六边形:

OpenGL 学习系列---基本形状的绘制_着色器_08

正七边形:

OpenGL 学习系列---基本形状的绘制_顶点着色器_09

小结

到此,基本讲述了 OpenGL 的绘制流程以及基本图形的绘制。

根据图形和绘制类型来采用以何种方式进行绘制,以及定义顶点数据,最后直接绘制对应图形即可。

但显然,这还是不够的,还是有很多问题的。

想要绘制一个圆形,结果却成了椭圆;想要绘制一个正五边形,却成了歪的;这到底是道德的沦丧还是人性的泯灭,一切的揭晓就在下一篇博客中了。

具体代码详情,可以参考我的 Github 项目:

​https://github.com/glumes/AndroidOpenGLTutorial​

参考


OpenGL 系列文章:

​OpenGL 基础绘制流程​

最后,如果觉得文章不错,欢迎关注微信公众号:【纸上浅谈】

OpenGL 学习系列---基本形状的绘制_数据_10


标签:OpenGL,float,0.5,---,顶点,三角形,绘制,360
From: https://blog.51cto.com/u_12127193/5738752

相关文章

  • ​OpenGL 学习系列---坐标系统
    在前面​​绘制基本图形​​中,遇到了很明显的问题,圆形不像圆形,正多边形不像正多边形?就像下面图形一样:不规则的形状好好的正五边形却东倒西歪的,这就是因为我们前面的绘制都是......
  • 基于python的基于Django工厂设备管理系统设计与实现-计算机毕业设计源码+LW文档
    caigoushenqing表注释:采购申请字段类型空默认注释id (主键)bigint(20)否主键addtimetimestamp否CURRENT_TIMESTAMP创建时间shebeimingchengvarchar(200)否设备名称shebeil......
  • Vue3组件库打包指南,一次生成esm、esm-bundle、commonjs、umd四种格式
    本文为Varlet组件库源码主题阅读系列第二篇,读完本篇,你可以了解到如何将一个Vue3组件库打包成各种格式上一篇里提到了启动服务前会先进行一下组件库的打包,运行的命令为:v......
  • Flink-动态表和持续查询
    在Flink中使用表和SQL基本上跟其他场景是一样的;不过对于表和流的转换,却稍显复杂。当我们将一个Table转换成DataStream时,有“仅插入流”(Insert-OnlyStreams)和“更新......
  • 推荐一个变量调试神器:go-spew
    今天给大家推荐的是一个可以将变量以一种非常友好的方式输出其完整的数据结构信息的工具:go-spew。 该包经过了全面的测试,测试覆盖率为100%。支持各种自定义配置,非常方便......
  • MYSQL-->存储过程与存储函数
    介绍存储过程是事先经过编译并且存储在数据库中的一段SQL语句的集合。调用存储过程可以简化应用开发人员的很多工作,减少数据在数据库和应用服务器之间的传输,有助于提高数......
  • ORA-39126: expdp
        Starting"SERVICEDESK"."SYS_EXPORT_SCHEMA_07": servicedesk/********@//11.32.18.110:1521/MOS7100directory=MOS7100_BACKUPDB_DIRdumpfile=servicedesk.......
  • ABC 271 F - XOR on Grid Path(搜索 meet in the mid)
    ABC271F-XORonGridPath题意:​ 给出20*20的地图,每个点上都有一个点权,保证为正整数。请问从(1,1)走到(n,n)且路径上所有点权异或和为0的路径有多少条。思路:​......
  • 2022-2023-1 20221425 《计算机基础与程序设计》第6周学习总结
    学期(如2022-2023-1)学号(如:20221300)《计算机基础与程序设计》第六周学习总结作业信息这个作业属于哪个课程<班级的链接>(如2022-2023-1-计算机基础与程序设计)这......
  • msf-地理位置获取
    相关内容一、GPS简介物理位置定位:根据IP的定位不准确,容易被欺骗,网上有很多IP伪造技术,所以定位肯定也不准确。GPS全球定位系统:(使用最广泛)GPS是英文GlobalPositioningSyst......