plsqlfor循环输出三角形_glium指南-03-移动我们的三角形
原地址: 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-移动我们的三角形的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: php概率计算_php 抽奖概率算法
- 下一篇: 怪物行为树案例_Behavior Des