<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                歡迎來到WebGL系列課程的第9課,基于NeHe OpenGL課程的[第9課](http://nehe.gamedev.net/data/lessons/lesson.asp?lesson=09)編寫而成。在這節課中,我們將使用JavaScript對象,以便在3D場景中,能夠支持許多的獨立運動物體。同時我們還會探討如何更改一個已加載紋理的顏色,以及將紋理混合在一起時將會發生什么。 以下是在支持WebGL的瀏覽器上運行程序的表現: https://youtu.be/Ti3jbuY4VlI [點擊這里可以看到demo演示](http://learningwebgl.com/lessons/lesson09/index.html),如果你的瀏覽器支持WebGL,將會看到大量的不同顏色的星星,在場景中盤旋。 你可以使用畫布下方的復選框,切換“閃爍”效果。同時你也可以使用上下方向鍵,使動畫繞X軸旋轉;還可以使用PageUp和PageDown鍵來縮放整個動畫。 下面是具體實現... >[info] 慣例聲明:本課程面向具有一定編程基礎,但在3D圖形學方面無實際經驗人群,目標是使學習者運行并了解WebGL代碼,以便快速構造自己的3D頁面。如果你還沒有閱讀之前的課程,建議先讀完它們 -- 這里只會講述和之前不同,以及新增的部分 >在教程中難免會有bug和錯誤,如果你發現了它,請告訴我,我會盡快改正它 本課的源碼可以查看:https://github.com/gracefung/webgl-codes/tree/master/lesson09 【這是繁體譯文對應的github源碼,感覺還不錯】 區分本課示例與第8課有哪些不同的最好方式是,從文件底部開始然后逐漸向上,首先是webGLStart()函數。如下是當前該函數代碼: ~~~ function webGLStart() { var canvas = document.getElementById("lesson09-canvas"); initGL(canvas); initShaders(); initTexture(); initBuffers(); initWorldObjects(); gl.clearColor(0.0, 0.0, 0.0, 1.0); document.onkeydown = handleKeyDown; document.onkeyup = handleKeyUp; tick(); } ~~~ 這里調用了一個新的函數initWorldObjects()。這個函數創建JavaScript對象來代表場景,我們待會再去看它,這里還有一個變更:之前幾課webGLStart()函數都會有一行設置深度測試的代碼: ~~~ gl.enable(gl.DEPTH_TEST); ~~~ 但在本課中被移除了。你應該還記得上節課說顏色混合與深度測試不能很好的兼容,而此課我們會一直使用顏色混合。在WebGL中深度測試是默認關閉的,所以我們在這里簡單移除這一行就行。 下一個重大變化是在animate()函數中。之前我們使用它來更新一些代表場景變化的全局變量 -- 比如,立方體在下一幀繪制之前需要旋轉的角度。這里的變更我們處理的很簡單,不再直接更新變量,而是遍歷場景中所有對象,然后告訴它們該作何處理。 ~~~ var lastTime = 0; function animate() { var timeNow = new Date().getTime(); if (lastTime != 0) { var elapsed = timeNow - lastTime; for (var i in stars) { stars[i].animate(elapsed); } } lastTime = timeNow; } ~~~ 繼續向上看,是drawScene()函數。這里面改變比較多,我們一點一點看。首先: ~~~ function drawScene() { gl.viewport(0, 0, gl.viewportWidth, gl.viewportHeight); gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); mat4.perspective(45, gl.viewportWidth / gl.viewportHeight, 0.1, 100.0, pMatrix); ~~~ 這些還是常用的初始化代碼,從第1課都沒有改動過。 ~~~ gl.blendFunc(gl.SRC_ALPHA, gl.ONE); gl.enable(gl.BLEND); ~~~ 接下來,我們開啟了顏色混合。使用的混合方式和上節課一樣;你應該記得這種方式允許物體間相互“通透”。還有,它還意味著物體黑色的部分被渲染的像是透明的效果;如果你不太記得這其中的原理了,可以翻看上節課的相關內容。也就是說,當我們繪制場景中的星星時,黑色部分看上去會是透明的;事實確實是這樣,星星中亮的部分越少,那么看上去就越透明。 我們繪制星星用的是如下的紋理貼圖: ![](https://box.kancloud.cn/7dbaac4bdeaf679e7be457e9e9628ff0_128x128.gif) 這個效果正是我們想要的 繼續看代碼: ~~~ mat4.identity(mvMatrix); mat4.translate(mvMatrix, [0.0, 0.0, zoom]); mat4.rotate(mvMatrix, degToRad(tilt), [1.0, 0.0, 0.0]); ~~~ 這里我們移動到場景中心,并且進行適當的縮放。同時我們還繞著X軸對場景做了一定傾斜;縮放值和傾斜度都還是全局變量,且通過鍵盤控制。現在我們已經準備好繪制場景了,首先檢查一下“閃爍”復選框是否被勾選: ~~~ var twinkle = document.getElementById("twinkle").checked; ~~~ 接著,類似于我們在animate()函數中所做的,我們遍歷星星列表,然后告訴它們把自己給繪制出來。傳入當前的傾斜值,和閃爍值。同時還告訴它當前的自轉角度是多少 -- 這個值是用來使星星在軌道上沿著場景中心公轉同時,還能夠環繞著自己的中心自轉。 ~~~ for (var i in stars) { stars[i].draw(tilt, spin, twinkle); spin += 0.1; } } ~~~ 以上就是drawScene()函數。我們現在可以看出,星星已經能夠自己繪制并且運動了;接下來的代碼用來創造它們: ~~~ var stars = []; function initWorldObjects() { var numStars = 50; for (var i=0; i < numStars; i++) { stars.push(new Star((i / numStars) * 5.0, i / numStars)); } } ~~~ 一個簡單的循環創建50顆星星(你可能會想試著調整這個數值)。每顆星星傳入的第一個參數是表示和場景中心的初始距離,第二個參數是表示環繞場景中心的公轉速度,這2個參數值都由它們在星星列表中的序號決定。 下面的代碼關注定義星星的類。如果你不太熟悉JavaScript,看上去會覺得很怪異。但如果你很懂JavaScript,可以略過直接看后續部分。 JavaScript的對象模型和其它語言有很大區別。我能找到最簡單易懂的解釋方式是,每個對象都是作為字典被創建(或者是哈希表,或者是關聯數組【即映射】),然后塞入各種值便成為一個成熟齊全的對象。對象的屬性就是字典中可以映射值的簡單條目【鍵】,對象的方法則是映射函數的條目。現在,我們就清楚了單詞鍵的真實含義,比如```foo.bar```語法是```foo["bar"]```的合法簡寫,你可以從這個截然不同的開端,看看如何找到與其它語言的相似處。 接下來,在每一個JavaScript方法內部,都有一個被稱做```this```的隱式綁定變量,它指向了方法的“所有者”。對于全局方法,```this```是每個頁面的“window”對象,但如果你在方法的前面放了關鍵字```new```,那么它就不再是一個方法,而是一個全新的對象。所以,如果你有一個方法A,其內部設置了```this.foo```為1, 以及```this.bar```為一個方法,并且你能保證每次調用方法A時,都會用```new```關鍵字,那么它基本上就和類定義中的構造函數是一樣的了。 后續我們可以看到如果一個方法,以類似于對象方法調用的語法被調用時(比如```foo.bar()```),那么該方法就會被綁定到這個方法的擁有者上(```foo```),就像我們希望的那樣,這樣對象的方法可以操作對象本身。 最后,有一個很特別的,與方法有關的屬性,```prototype```。這是一個與該方法```new```出來的每一個對象都相關的字典值;通過它可以很方便對這個“class”的每個對象都設置相同的值 -- 比如,類方法。 讓我們來看看對于場景中一顆星星對象的定義方法。 ~~~ function Star(startingDistance, rotationSpeed) { this.angle = 0; this.dist = startingDistance; this.rotationSpeed = rotationSpeed; // Set the colors to a starting value. this.randomiseColors(); } ~~~ 在構造方法中,使用提供的參數值和初始角度0來初始化對象,然后調用了一個方法。下一步是將一些方法綁定到Star()函數的```prototype```中,以便使所有新的Star對象都有同樣的方法,首先,綁定draw()方法: ~~~ Star.prototype.draw = function(tilt, spin, twinkle) { mvPushMatrix(); ~~~ draw()方法被定義為將我們傳入的參數,傳回到drawScene()函數中。首先將當前的模型視圖矩陣推入矩陣棧中,這樣我們就可以任意操作,而不需要擔心哪里有副作用的影響。 ~~~ // Move to the star's position mat4.rotate(mvMatrix, degToRad(this.angle), [0.0, 1.0, 0.0]); mat4.translate(mvMatrix, [this.dist, 0.0, 0.0]); ~~~ 緊接著,我們【這里的“我們”可以看做是繪制筆觸】繞Y軸,按照星星自己的角度旋轉;然后從場景中心向外移動星星的初始距離值。這樣我們就來到了繪制星星的正確位置。 ~~~ // Rotate back so that the star is facing the viewer mat4.rotate(mvMatrix, degToRad(-this.angle), [0.0, 1.0, 0.0]); mat4.rotate(mvMatrix, degToRad(-tilt), [1.0, 0.0, 0.0]); ~~~ 上面代碼都是必需的,這樣我們才可以使用方向鍵來改變場景的傾斜度時,星星的位置還能夠保持正確。星星是在一個方形上繪制2D紋理表現出來的,當我們垂直觀看時表現的很正常,但如果將場景傾斜,從邊上觀看時,就只能看到一條線。類似于這樣的原因,我們還要還原用戶指定的傾斜度,來放置星星。當你像這樣撤銷旋轉時,你需要按照之前做的順序,反向還原操作。所以首先我們在當前位置上做撤銷旋轉的操作,然后撤銷傾斜度(這些都是在drawScene()函數中完成的)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看