plsqlfor循环输出三角形_glium指南-03-移动我们的三角形
原地址: https://github.com/glium/glium/blob/master/book/tuto-03-animated-triangle.md
移動(dòng)我們的三角形
上一節(jié)我們畫了個(gè)三角形, 這一節(jié)我們打算試著讓它動(dòng)起來. 記住OpenGL不像繪畫軟件. 如果我們想改變屏幕上顯示的內(nèi)容, 我們必須再繪制一次, 然后用新繪制的內(nèi)容替換掉已經(jīng)存在的內(nèi)容. 還好我們已經(jīng)寫好了一個(gè) loop 循環(huán), 它正不斷地在窗口中重復(fù)繪制, 因此我們所寫的代碼幾乎會(huì)立即反映到窗口上.
比較naive的方法
第一個(gè)方法是創(chuàng)建一個(gè)名為 t 的變量并用它來表示移動(dòng)中的每一步. 我們將在每次循環(huán)時(shí)更新 t 的值, 然后把它加到三角形的坐標(biāo)值上:
let mut t: f32 = -0.5; let mut closed = false; while !closed {// 更新 `t`t += 0.0002;if t > 0.5 {t = -0.5;}// 創(chuàng)建形狀然后把 `t` 加到每個(gè)頂點(diǎn)的x坐標(biāo)上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,_ => ()},_ => (),}}); }如果你運(yùn)行這段代碼, 你就能看見我們的三角形從左邊移動(dòng)到右邊, 然后又跳回左邊.
在上個(gè)世紀(jì)90年代, 很多游戲開發(fā)者都是這樣做的. 在你的圖形比較簡(jiǎn)單時(shí)(例如一個(gè)三角形), 這個(gè)方法確實(shí)好用. 但是一旦你的圖形變得復(fù)雜, 例如某些有幾千個(gè)多邊形組成的3D模型, 這個(gè)方法的效率會(huì)變得特別低. 原因如下:
- 每次繪制時(shí), CPU都會(huì)花大量時(shí)間來計(jì)算坐標(biāo)(每個(gè)模型的每個(gè)頂點(diǎn)都進(jìn)行一次計(jì)算的話, 每次繪制你將進(jìn)行成百上千次計(jì)算).
- 將我們的形狀的頂點(diǎn)數(shù)據(jù)從內(nèi)存上傳到顯卡內(nèi)存也要花費(fèi)時(shí)間. GPU會(huì)等待所有數(shù)據(jù)上傳完畢再開始繪制工作, 而等待的這段時(shí)間都被浪費(fèi)掉了.
Uniform變量
還記得頂點(diǎn)著色器嗎? 頂點(diǎn)著色器輸入每個(gè)頂點(diǎn)的屬性, 輸出頂點(diǎn)在窗口中的位置. 之前, 我們?cè)诔绦蛑凶屓切雾旤c(diǎn)坐標(biāo)值增加然后將計(jì)算的結(jié)果上傳到GPU中, 現(xiàn)在我們把這件事交給GPU來做.
現(xiàn)在把程序改回上一節(jié)結(jié)束時(shí)的樣子, 不過依然保留 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,_ => ()},_ => (),}}); }然后, 我們稍微修改一下頂點(diǎn)著色器的代碼:
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上執(zhí)行的. 我們?cè)谥鞯拇a中添加了一個(gè)用 uniform 關(guān)鍵字聲明的變量. uniform變量是一個(gè)全局變量, 它的值是在繪制時(shí), 由 draw 函數(shù)傳遞給GPU. 現(xiàn)在, 我們可以用 uniform! 宏來實(shí)現(xiàn):
target.draw(&vertex_buffer, &indices, &program, &uniform! { t: t },&Default::default()).unwrap();使用uniform變量解決了之前第一種方法的兩個(gè)問題. CPU不必進(jìn)行任何計(jì)算, 而且不必上傳整個(gè)形狀的頂點(diǎn)的數(shù)據(jù)給GPU, 只需上傳 t 的值(一個(gè)單精度浮點(diǎn)數(shù))就行了.
總結(jié)
以上是生活随笔為你收集整理的plsqlfor循环输出三角形_glium指南-03-移动我们的三角形的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: php概率计算_php 抽奖概率算法
- 下一篇: 怪物行为树案例_Behavior Des