原地址: https://github.com/glium/glium/blob/master/book/tuto-03-animated-triangle.md

移动我们的三角形

上一节我们画了个三角形, 这一节我们打算试着让它动起来. 记住OpenGL不像绘画软件. 如果我们想改变屏幕上显示的内容, 我们必须再绘制一次, 然后用新绘制的内容替换掉已经存在的内容. 还好我们已经写好了一个 loop 循环, 它正不断地在窗口中重复绘制, 因此我们所写的代码几乎会立即反映到窗口上.

比较naive的方法

第一个方法是创建一个名为 t 的变量并用它来表示移动中的每一步. 我们将在每次循环时更新 t 的值, 然后把它加到三角形的坐标值上:

let mut t: f32 = -0.5;
let mut closed = false;
while !closed {// 更新 `t`t += 0.0002;if t > 0.5 {t = -0.5;}// 创建形状然后把 `t` 加到每个顶点的x坐标上let vertex1 = Vertex { position: [-0.5 + t, -0.5] };let vertex2 = Vertex { position: [ 0.0 + t,  0.5] };let vertex3 = Vertex { position: [ 0.5 + t, -0.25] };let shape = vec![vertex1, vertex2, vertex3];let vertex_buffer = glium::VertexBuffer::new(&display, &shape).unwrap();// 绘制let mut target = display.draw();target.clear_color(0.0, 0.0, 1.0, 1.0);target.draw(&vertex_buffer, &indices, &program, &glium::uniforms::EmptyUniforms,&Default::default()).unwrap();target.finish().unwrap();events_loop.poll_events(|event| {match event {glutin::Event::WindowEvent { event, .. } => match event {glutin::WindowEvent::CloseRequested => closed = true,_ => ()},_ => (),}});
}

如果你运行这段代码, 你就能看见我们的三角形从左边移动到右边, 然后又跳回左边.

在上个世纪90年代, 很多游戏开发者都是这样做的. 在你的图形比较简单时(例如一个三角形), 这个方法确实好用. 但是一旦你的图形变得复杂, 例如某些有几千个多边形组成的3D模型, 这个方法的效率会变得特别低. 原因如下:

  • 每次绘制时, CPU都会花大量时间来计算坐标(每个模型的每个顶点都进行一次计算的话, 每次绘制你将进行成百上千次计算).
  • 将我们的形状的顶点数据从内存上传到显卡内存也要花费时间. GPU会等待所有数据上传完毕再开始绘制工作, 而等待的这段时间都被浪费掉了.

Uniform变量

还记得顶点着色器吗? 顶点着色器输入每个顶点的属性, 输出顶点在窗口中的位置. 之前, 我们在程序中让三角形顶点坐标值增加然后将计算的结果上传到GPU中, 现在我们把这件事交给GPU来做.

现在把程序改回上一节结束时的样子, 不过依然保留 t :

let vertex1 = Vertex { position: [-0.5, -0.5] };
let vertex2 = Vertex { position: [ 0.0,  0.5] };
let vertex3 = Vertex { position: [ 0.5, -0.25] };
let shape = vec![vertex1, vertex2, vertex3];let vertex_buffer = glium::VertexBuffer::new(&display, &shape).unwrap();let mut t: f32 = -0.5;
let mut closed = false;
while !closed {// 更新 `t`t += 0.0002;if t > 0.5 {t = -0.5;}// 绘制let mut target = display.draw();target.clear_color(0.0, 0.0, 1.0, 1.0);target.draw(&vertex_buffer, &indices, &program, &glium::uniforms::EmptyUniforms,&Default::default()).unwrap();target.finish().unwrap();events_loop.poll_events(|event| {match event {glutin::Event::WindowEvent { event, .. } => match event {glutin::WindowEvent::CloseRequested => closed = true,_ => ()},_ => (),}});
}

然后, 我们稍微修改一下顶点着色器的代码:

let vertex_shader_src = r#"#version 140in vec2 position;uniform float t;void main() {vec2 pos = position;pos.x += t;gl_Position = vec4(pos, 0.0, 1.0);}
"#;

你也许注意到了, 这不就是我们之前在rust代码里写的操作吗, 只不过这次这段代码是在GPU上执行的. 我们在着色器的代码中添加了一个用 uniform 关键字声明的变量. uniform变量是一个全局变量, 它的值是在绘制时, 由 draw 函数传递给GPU. 现在, 我们可以用 uniform! 宏来实现:

target.draw(&vertex_buffer, &indices, &program, &uniform! { t: t },&Default::default()).unwrap();

使用uniform变量解决了之前第一种方法的两个问题. CPU不必进行任何计算, 而且不必上传整个形状的顶点的数据给GPU, 只需上传 t 的值(一个单精度浮点数)就行了.

plsqlfor循环输出三角形_glium指南-03-移动我们的三角形相关推荐

  1. php实现 三角形_PHP使用for循环输出三角形

    在PHP面试过程中,关于for循环的基础知识考点是必不可少的.如通过for循环构造输出三角形的形状.那么实现三角形的效果,我们就需要通过嵌套for循环的思路. 下面我们就给大家结合简单的代码示例,给大 ...

  2. python编程*三角形图形创意图片_python循环输出三角形图案的例子

    我就废话不多说了,直接上代码吧! #Copyright (c)2017, 东北大学软件学院学生 # All rightsreserved #文件名称:a.py #作 者:孔云 #问题描述:编写程序,使 ...

  3. python循环语句打印三角形_python循环输出三角形图案的例子

    python循环输出三角形图案的例子 我就废话不多说了,直接上代码吧! #Copyright (c)2017, 东北大学软件学院学生 # All rightsreserved #文件名称:a.py # ...

  4. java利用循环输出*三角形

    1.在控制台输出五行五列*: for (int i =1; i <=5; i++) {for(int j=1;j<=5;j++){System.out.print("*" ...

  5. python循环输出00-59

    python循环输出00-59 for i in range(0,60):print("%02d"%i) ------------------------------------- ...

  6. python基础——while循环(九九乘法表,阶乘计算器,三角形图案打印输出)

    python基础--while循环(九九乘法表,阶乘计算器,三角形图案打印输出) 一.目的 本人最近在学习python的基础语法,此文章用来记录学习过程所用,本文章讲述的是while循环的一些基础实例 ...

  7. ThinkPHP 模板循环输出 Volist 标签

    2019独角兽企业重金招聘Python工程师标准>>> volist 标签用于在模板中循环输出数据集或者多维数组. volist 标签 在模块操作中,select() 方法返回的是一 ...

  8. 成功解决for循环语句中,后几次循环输出数据一直全部为空

    成功解决for循环语句中,后几次循环输出数据一直全部为空 目录 解决问题 解决思路 解决方法 解决问题 for循环语句中,后几次循环输出数据一直全部为空

  9. python中while语句的用法_python 使用while循环输出*组成的菱形实例

    一,python输出*组成的菱形(实心): python代码: x = int(input('请输入最长行的*的个数:')) y = int(input('请输入每个*之间的间隔:')) i = 1 ...

最新文章

  1. WPF绘制自定义窗口
  2. 1005 Spell It Right (20 分)——13行代码Ac
  3. 中文字符频率统计python_python统计字符串出现最多的字母及其出现次数
  4. 医生c语言测试卷b卷的答案,合肥工业大学C语言期中测试题_B卷
  5. 【Docker】Docker 启动prometheus报错 parsing YAML file /etc/prometheus/prometheus.yml: yaml: unmarshal
  6. Java CyclicBarrier介绍
  7. 为什么建议使用count(*)来统计数据行数
  8. 三维点云学习(5)5-实现Deeplearning-PointNet-2-classfication
  9. 将文件保存到数据库中
  10. 异步保存数据到mysql或mssql 学习笔记
  11. 给Hexo主题博客加入百度站点统计
  12. Matlab如何多行添加注释和取消注释
  13. 软件架构设计说明书该怎么写?
  14. 求伴随矩阵和逆矩阵C++
  15. png转icon java_原创 | Java图片处理:ico格式转 PNG/JPG等格式
  16. 《大道至简-软件工程实践者的思想》读书笔记
  17. linux vnc登陆,vnc登陆,4个步骤教你vnc登陆Linux
  18. Fortran学习3:控制流2:循环
  19. 【openMP并行计算】计算π
  20. 音视频开发中常见基础问题总结

热门文章

  1. html %3c 不给转义,八个无法利用XSS漏洞的场景
  2. html制作选择题题库,HTML与网页制作测试题库
  3. lisp 绘制立体感的五角星_几何作图的方法、例子、解答及札记
  4. 判断当前界面是该fragment_学不动也要学!探究Fragment延迟加载的前世今生
  5. 2019数据安装勾选_万能的XY数据标签插件,柱形图也可以呈现变化率
  6. 13-爬虫之js加密,解密,混淆,逆向破解思路
  7. 09-百度ai图片识别
  8. Linux上用Jenkins执行shell
  9. NodeJS Web模块
  10. javascript中==和===的区别