เริ่มต้นใช้งาน WebGL2

A. สถาปัตยกรรม OpenGL ทั่วไป


OpenGL เป็นไลบรารี 3D ข้ามแพลตฟอร์มที่ชัดเจน มันมีประวัติอันยาวนาน เป็นแรงบันดาลใจให้ Direct3D (D3D) API ของ Microsoft และทั้งสองได้พัฒนาร่วมกันจากการสนับสนุนตัวเร่งกราฟิกฟังก์ชันคงที่ไปจนถึงการสนับสนุนฮาร์ดแวร์ที่ตั้งโปรแกรมได้ที่ทันสมัย สไตล์ OpenGL ที่ทันสมัยและ D3D เวอร์ชันล่าสุดเรียกว่า Core Profile ชุดคุณลักษณะที่คล้ายกันมีให้ในอุปกรณ์เคลื่อนที่เช่น OpenGL ES OpenGL ES 3.0 ใช้เป็นพื้นฐานสำหรับ WebGL 2

ด้วยการเรียนรู้ WebGL2 คุณจะได้เรียนรู้รูปแบบการเขียนโปรแกรมกราฟิกระดับต่ำซึ่งเป็นเรื่องปกติสำหรับ OpenGL สมัยใหม่ทั้งหมด โดยเฉพาะอย่างยิ่งหากคุณใช้ภาษาการเขียนโปรแกรมเดียวกัน การสลับระหว่างเวอร์ชันต่างๆ นั้นไม่ยากเกินไป และโค้ดพอร์ตก็สามารถทำได้ง่ายหากคุณปรับให้เป็นโมดูลอย่างเหมาะสม

การไปยังจุดที่คุณสามารถเริ่มเขียนโค้ด OpenGL นั้นค่อนข้างจะยุ่งยากกว่าเล็กน้อย เนื่องจากกระบวนการนี้แตกต่างจากระบบปฏิบัติการไปยังระบบปฏิบัติการ โชคดีที่มีไลบรารีข้ามแพลตฟอร์มที่สามารถทำให้โค้ดของคุณง่ายต่อการพอร์ต แผนภาพด้านบนแสดงกรณีทั่วไปสำหรับการรับสภาพแวดล้อม OpenGL “Core” ที่ทันสมัย ไม่ว่าคุณจะเลือกตั้งค่าอย่างไร :

  • โมดูล แอปพลิเคชันได้รับการพัฒนาโดย โปรแกรมเมอร์
  • ฟังก์ชัน Windowing API ที่พัฒนาขึ้นโดยเฉพาะเพื่อรองรับ OpenGL ใช้เพื่อตั้งค่า ปิด และจัดการ สัญญาณ เหตุการณ์สำหรับพื้นที่วาดภาพ OpenGL ที่เรียกว่า Rendering Context (RC) ในหน้าต่างหรือส่วนประกอบ ฟังก์ชันเหล่านี้อาจถูกกำหนดโดยระบบปฏิบัติการ ชุดวิดเจ็ตของบุคคลที่สาม หรือโดยไลบรารี OpenGL ข้ามแพลตฟอร์ม
    • ไลบรารีที่กำหนดโดยระบบปฏิบัติการ:
      • Windows: ฟังก์ชัน WGL
      • XWindows (Linux, UNIX ส่วนใหญ่): ฟังก์ชัน GLX
      • Mac OS X: คลาส NSOpenGL (ปกติ)
    • APIs ข้ามแพลตฟอร์มและสภาพแวดล้อมที่โดดเด่นเต็มรูปแบบพร้อมการสนับสนุน OpenGL
      • wxWidgets
      • fltk
      • tcl/tk
      • Qt
      • HTML 5 (ผ่าน canvas WebGL)
        • นี่คือ API สำหรับคลาสนี้ มีทุกสิ่งที่คุณต้องการในตัว รวมถึงการเลือกไดรเวอร์ที่ดีที่สุดสำหรับแพลตฟอร์มของคุณโดยอัตโนมัติ 
    • ไลบรารี OpenGL ข้ามแพลตฟอร์ม
      • SDL
      • GLFW
      • GLUT
        • GLUTเป็น API ที่ ใช้ในหลักสูตร OpenGL ส่วนใหญ่เป็น เวลาหลายปีรวมถึงหลักสูตรนี้ด้วย บทเรียนเก่าใช้ OpenGL ฟังก์ชันคงที่แบบคลาสสิกกับ GLUT 3.7 ในขณะที่บทเรียนที่ใหม่กว่าใช้ freeglut หรือ Apple GLUT เพื่อเข้าถึงฟังก์ชัน Core Profile 

  • ฟังก์ชัน OpenGL API ที่กำหนดใน gl.h และจัดเตรียมโดยไดรเวอร์ OpenGL ที่ใช้งานอยู่ (ระบุโดย RC) จะถูกใช้ในการวาด 
  • GLEW เป็นยูทิลิตี้ยอดนิยมที่ใช้เพื่อแสดงคุณสมบัติ OpenGL ใหม่ได้อย่างง่ายดาย สิ่งนี้สำคัญมากสำหรับโปรแกรม Windows เนื่องจาก Microsoft หยุดดูแล OpenGL ที่เวอร์ชัน 1.1 (เวอร์ชันปัจจุบันคือ 4.5) นอกจากนี้ยังเป็นประโยชน์สำหรับการตรวจสอบความสามารถและส่วนขยายของ OpenGL บนระบบปฏิบัติการอื่นๆ
  • ไดรเวอร์ OpenGLใช้รายละเอียดของฟังก์ชัน OpenGL โดยส่งข้อมูลโดยตรงไปยังฮาร์ดแวร์ 3D ดำเนินการคำนวณบน CPU หลัก หรือทั้งสองอย่างรวมกัน

เมื่อคุณเขียนโปรแกรม WebGL รายละเอียดเหล่านี้จำนวนมากจะถูกซ่อนจากคุณ อันที่จริง การเรียก WebGL ของคุณอาจไม่สามารถดำเนินการโดยไดรเวอร์ OpenGL ด้วยซ้ำ บน Macs ซึ่งรองรับ OpenGL ในตัว OS การเรียก WebGL จะถูกแปลโดยตรงเป็น OpenGL ที่เทียบเท่ากัน บน Windows DirectX/D3D 9 หรือดีกว่านั้นได้รับการติดตั้งในระบบปฏิบัติการตั้งแต่ Vista ดังนั้นเลเยอร์พิเศษที่เรียกว่า ANGLE ซึ่งพัฒนาโดย Google โดยเฉพาะสำหรับ WebGL และใช้โดย Chrome, Firefox, IE11 และ Edge – ใช้เพื่อแปล WebGL API คำสั่งเป็นคำสั่ง D3D9 หรือ D3D11 ที่เทียบเท่า บน Linux การสนับสนุนไดรเวอร์มีความสำคัญอย่างยิ่ง — เบราว์เซอร์ส่วนใหญ่รองรับเฉพาะไดรเวอร์อย่างเป็นทางการของ nVidia เท่านั้น



แอปพลิเคชัน WebGL “ในอุดมคติ” / การโต้ตอบ OpenGL / OS


แอปพลิเคชัน Windows WebGL / การโต้ตอบ “OpenGL” / OS


การแปลของ ANGLE จาก WebGL เป็น D3D นั้นดี แต่ไม่สมบูรณ์แบบ หากคุณต้องการประสบการณ์ OpenGL ที่ “บริสุทธิ์” บน Windows และคุณคิดว่าไดรเวอร์กราฟิกของคุณใช้งานได้แล้ว ให้ เรียนรู้วิธีปิดใช้งาน ANGLE จาก wiki ของนักพัฒนาของ three.js


B. ภาพรวมของโปรแกรมเชิงโต้ตอบ


สถาปัตยกรรม Model-View-Controller


การออกแบบโปรแกรมเชิงโต้ตอบแบ่งโปรแกรมออกเป็นสามส่วน:

  • Model โมเดล:ข้อมูลทั้งหมดที่ไม่ซ้ำกันสำหรับโปรแกรมของคุณอยู่ที่นั่น นี่อาจเป็นสถานะของเกม เนื้อหาของไฟล์ข้อความ หรือตารางในฐานข้อมูล
  • View มุมมอง:เป็นวิธีการแสดงข้อมูลของโมเดลบางส่วนหรือทั้งหมดแก่ผู้ใช้ วัตถุในสถานะเกมอาจถูกวาดในแบบ 3 มิติ ข้อความในไฟล์อาจถูกวาดไปที่หน้าจอด้วยการจัดรูปแบบ หรือข้อความค้นหาในฐานข้อมูลอาจถูกห่อด้วย HTML และส่งไปยังเว็บเบราว์เซอร์
  • Controller ตัวควบคุม:วิธีการสำหรับผู้ใช้ในการจัดการโมเดลหรือมุมมอง การกระทำของเมาส์และการกดแป้นอาจเปลี่ยนสถานะของเกม เลือกข้อความ หรือกรอกและส่งแบบฟอร์มสำหรับการสืบค้นใหม่

การเขียนโปรแกรมเชิงวัตถุได้รับการพัฒนาในบางส่วนเพื่อช่วยในการปรับส่วนประกอบต่างๆ ของโปรแกรม Model-View-Architecture API อินเทอร์เฟซผู้ใช้ส่วนใหญ่เขียนด้วยภาษาเชิงวัตถุคุณจะจัดโครงสร้างโปรแกรมของคุณเพื่อรองรับทั้งสามด้านของโปรแกรมแบบโต้ตอบ กราฟิก 3 มิติ:

  • Model โมเดล ประกอบด้วยคำอธิบายของเรขาคณิต การวางตำแหน่ง ลักษณะที่ปรากฏ และการจัดแสงในฉากของคุณ ตามหลักการแล้วสิ่งเหล่านี้สามารถบันทึกและโหลดจากไฟล์ได้ แต่เราจะไม่ทำอะไรมากในแล็บนี้
  • View มุมมอง ประกอบด้วยการเรียกการแสดงผล OpenGL ที่ตั้งค่าบริบทการเรนเดอร์ของคุณ ตีความโมเดล และส่งสิ่งต่าง ๆ ที่จะวาด
  • Controller ตัวควบคุม มักจะเป็นชุดของฟังก์ชันที่คุณเขียนซึ่งตอบสนองต่อ สัญญาณ เหตุการณ์ที่ส่งไปยังโปรแกรมของคุณผ่าน Windowing API

ในโปรแกรมที่ง่ายที่สุด โมเดลและมุมมองของคุณจะถูกเชื่อมโยงเข้าด้วยกันอย่างแนบแน่น คุณอาจมีหนึ่งหรือสองตัวแปรที่ตั้งค่าไว้ซึ่งควบคุมบางสิ่งในฉากของคุณ และฉากนั้นอาจอธิบายได้ด้วยการโทรแบบฮาร์ดโค้ดที่ทำขึ้นโดยตรงไปยัง WebGL โดยมีองค์ประกอบไดนามิกเพียงไม่กี่รายการ ในที่สุด คุณจะได้เรียนรู้การจัดเก็บฉากในโครงสร้างข้อมูลที่แยกจากกัน

เหตุการณ์หลัก


โปรแกรม OpenGL ทั้งหมดควรตอบสนองต่อเหตุการณ์อย่างน้อยสองเหตุการณ์:

  • Setup ตั้งค่า – มีอย่างน้อยสองสิ่งที่ต้องทำที่นี่
    • Acquire Rendering Context รับบริบทการแสดงผล:วิธีที่คุณทำขั้นตอนนี้ถูกกำหนดโดย Windowing API ของคุณ
    • Set initial OpenGL scene settings ตั้งค่าเริ่มต้นของฉาก OpenGL: การตั้งค่าเริ่มต้นของ OpenGL นั้นไร้ประโยชน์ ส่วนสำคัญของไปป์ไลน์การวาดไม่มีโปรแกรม shader คุณจะต้องโหลด คอมไพล์ และเปิดใช้งาน นอกจากนี้ยังควรโหลดวัตถุบางอย่างที่คุณต้องการวาดลงในบัฟเฟอร์ข้อมูลล่วงหน้าและเชื่อมต่อกับโปรแกรม shader ของคุณ คุณอาจต้องเปิดใช้งาน ปิดใช้งาน หรือกำหนดการตั้งค่า OpenGL ต่างๆ เพื่อให้เหมาะกับความต้องการในการเรนเดอร์ของคุณ
  • Rendering การแสดงผล – ฟังก์ชันที่ทำสิ่งนี้เป็นแบบเฉพาะของ Windowing API แต่โค้ด OpenGL จะเป็นแบบทั่วไปทั้งหมด และควรคัดลอก/วางแบบพกพาได้

มีกิจกรรมอื่น ๆ ที่คุณมักจะจัดการเช่นกัน หากคุณวางโปรแกรมของคุณในหน้าต่างที่ปรับขนาดได้ การตอบสนองต่อเหตุการณ์การเปลี่ยนแปลงขนาดเป็นสิ่งสำคัญมาก ถ้าคุณไม่ทำ ผลลัพธ์ที่แสดงผลของคุณจะบิดเบี้ยวหรือไม่ถูกต้องเมื่อมีการปรับขนาดหน้าต่าง คุณอาจต้องการตอบสนองต่อการเคลื่อนไหวของเมาส์ การคลิก การกดแป้น และการควบคุม HTML


C. โปรแกรม WebGL แรกของคุณ


ก่อนเริ่มคำแนะนำเหล่านี้ ตรวจสอบให้แน่ใจว่าเบราว์เซอร์ของคุณรองรับ WebGL ฉันชอบ Chrome สำหรับแล็บนี้ แต่ Firefox จะทำ นอกจากนี้ ตรวจสอบให้แน่ใจว่าคุณคุ้นเคยกับตัวแก้ไขซอร์ส HTML และ Javascript บนคอมพิวเตอร์ของคุณ หากคุณต้องการเริ่มต้นง่ายๆ ฉันขอแนะนำ TextWrangler บน Mac หรือ Notepad++ บน Windows หากคุณเลือกวิธีนี้ คุณจะต้องโฮสต์โค้ดของคุณบนเว็บเซิร์ฟเวอร์จริง เช่น Hercules หรือทำตามขั้นตอนบางอย่างเพื่ออนุญาตให้ไฟล์ในเครื่องสามารถ bel

Lab Editor และ Code Tester:เราจะใช้ Visual Studio Code ซึ่งเป็นสิ่งที่เราจะใช้ในแล็บ เพราะมีส่วนขยาย “Live Server” ในเครื่องโดย Ritwick Dey ที่ให้คุณดูตัวอย่างการเปลี่ยนแปลงทุกครั้งที่บันทึก และอนุญาตให้คุณ ใช้คำขอ AJAX เพื่อโหลดเฉดสี พื้นผิว และโมเดล 3 มิติแบบไดนามิก

1. ตั้งค่าโฟลเดอร์ของคุณ

  • สร้างโฟลเดอร์รูทสำหรับแล็บทั้งหมดของคุณ ตั้งชื่อให้มีความหมาย เช่น “WebGL_Labs”
  • สร้างโฟลเดอร์ภายในชื่อ “Common”
  • สร้างโฟลเดอร์ ตั้งชื่อให้มีความหมาย เช่น “Lab1”
  • ใช้เว็บเบราว์เซอร์ที่คุณชื่นชอบเพื่อเปิดไฟล์ HTML ที่คุณบันทึกไว้ มันควรจะ “ทำงาน”


2. สร้างไฟล์ HTML


ไฟล์ HTML สำหรับแอปพลิเคชัน WebGL จะลิงก์ในไฟล์จาวาสคริปต์และทรัพยากรที่จำเป็น ทรัพยากรบางอย่าง เช่น ตัวแรเงา สามารถกำหนดแบบอินไลน์ได้ ต่อไปนี้คือไฟล์ HTML ขั้นต่ำที่มีความคิดเห็นสำหรับแอปพลิเคชัน WebGL สไตล์ textbook :

สร้างไฟล์ HTML ใหม่ชื่อ Lab1Demo.html ในโฟลเดอร์ Lab1 แล้ววางโค้ดด้านล่างลงไป

<!DOCTYPE html>
<html>
<head>
   <title>WebGL Template</title>

   <!-- This in-line script is a vertex shader resource
      Shaders can be linked from an external file as well.
      First line must be shader language version, no spaces before.
      (Actually textbook's shader loader strips leading spaces...)
      -->
   <script id="vertex-shader" type="x-shader/x-vertex">
      #version 300 es

      // All vertex shaders require a position input.
      // The name can be changed.
      // Other inputs can be added as desired for colors and other features.
      in vec4 vPosition;

      void main()
      {
         // gl_Position is a built-in vertex shader output.
         // Its value should always be set by the vertex shader.
         // The simplest shaders just copy the position attribute straight to
         // gl_Position
         gl_Position = vPosition;
      }
   </script>

   <!-- This in-line script is a vertex shader resource
      Shaders can be linked from an external file as well.
      First line must be shader language version, no spaces before.
      (Actually textbook's shader loader strips the spaces...) -->
   <script id="fragment-shader" type="x-shader/x-fragment">
      #version 300 es

      // Sets default precision for floats.
      // Since fragment shaders have no default precision, you must either:
      //   - set a default before declaring types that use floating point OR
      //   - specify the precision before each floating point declaration
      // Choices are lowp, mediump, and highp.
      precision mediump float;

      // The output of a fragment shader is sent to draw buffers,
      // which might be an array or the screen. The default is
      out vec4 fragColor;

      void main()
      {
         // In general, the fragment shader output should be set,
         //     but this is not required.
         // If an output is not set,
         //    there will be no output to the corresponding draw buffer.
         fragColor = vec4(0.0, 0.0, 0.0, 1.0);
      }
   </script>

   <!-- These are external javascript files.
      The first three are the textbook libraries.
      The last one is your own javascript code. Make sure to change the name
      to match your javascript file. -->
   <script type="text/javascript" src="../Common/utility.js"></script>
   <script type="text/javascript" src="../Common/initShaders.js"></script>
   <script type="text/javascript" src="../Common/MVnew.js"></script>
   <script type="text/javascript" src="../Common/flatten.js"></script>
   <script type="text/javascript" src="Lab1Demo.js"></script>
</head>

<body>
   <!-- This is the canvas - the only HTML element that can render WebGL
      graphics. You can have more than one WebGL canvas on a web page, but
      that gets tricky. Stick to one per page for now. -->
   <canvas id="gl-canvas" width="512" height="512">
      Oops ... your browser doesn't support the HTML5 canvas element
   </canvas>
</body>
</html>


3. สร้างไฟล์ Javascript


ไฟล์จาวาสคริปต์จะเติมชีวิตชีวาให้กับแอปพลิเคชัน WebGL ของคุณ มันตั้งค่าบริบทการเรนเดอร์ WebGL ทำการวาดภาพและกำหนดการตอบสนองต่อเหตุการณ์ต่างๆ โปรแกรมจาวาสคริปต์ WebGL ที่ง่ายที่สุดจะตั้งค่าบริบทการเรนเดอร์หลังจากโหลด HTML โดยกำหนดการดำเนินการสำหรับเหตุการณ์ window.onload นอกจากนี้ยังสามารถวาดได้หากไม่ต้องการแอนิเมชั่น

จาวาสคริปต์ต่อไปนี้กำหนดโปรแกรม WebGL เทมเพลตที่เรียบง่ายมาก:

สร้างไฟล์จาวาสคริปต์ใหม่ชื่อ Lab1Demo.js ในโฟลเดอร์ Lab1 แล้ววางโค้ดด้านล่างลงไป

// This variable will store the WebGL rendering context
var gl;

window.addEventListener("load", init);
function init() {
   // Set up a WebGL Rendering Context in an HTML5 Canvas
   var canvas = document.getElementById("gl-canvas");
   gl = canvas.getContext('webgl2');
   if (!gl) alert("WebGL 2.0 isn't available");

   //  Configure WebGL
   //  eg. - set a clear color
   //      - turn on depth testing

   //  Load shaders and initialize attribute buffers
   var program = initShaders(gl, "vertex-shader", "fragment-shader");
   gl.useProgram(program);

   // Set up data to draw

   // Load the data into GPU data buffers

   // Associate shader attributes with corresponding data buffers

   // Get addresses of shader uniforms

   // Either draw as part of initialization
   //render();

   // Or draw just before the next repaint event
   //requestAnimationFrame(render);
};


function render() {
   // clear the screen
   // draw
}


เปิดไฟล์ Lab1Demo.html ในเว็บเบราว์เซอร์ที่รองรับ WebGL คุณจะไม่เห็นอะไรเลย นี่คือพฤติกรรมที่ถูกต้อง 

4. เพิ่มโค้ดเพิ่มเติมเพื่อวาดรูปสามเหลี่ยมสี


มาเพิ่มโค้ดไฟล์ Lab1Demo.js เพื่อวาดรูปสามเหลี่ยมสีผสมกัน โดยเริ่มจากจาวาสคริปต์ที่จำเป็น และโค้ดที่เพิ่ม


// This variable will store the WebGL rendering context
var gl;

window.onload = function init() {
   // Set up a WebGL Rendering Context in an HTML5 Canvas
   var canvas = document.getElementById("gl-canvas");
   gl = canvas.getContext('webgl2');
   if (!gl) alert("WebGL 2.0 isn't available");

   //  Configure WebGL
   //  eg. - set a clear color
   //      - turn on depth testing
   // This light gray clear colour will help you see your canvas
   gl.clearColor(0.9, 0.9, 0.9, 1.0);

   //  Load shaders and initialize attribute buffers
   var program = initShaders(gl, "vertex-shader", "fragment-shader");
   gl.useProgram(program);

   // Set up data to draw
   // Here, 2D vertex positions and RGB colours are loaded into arrays.
   var positions = [
         -0.5, -0.5, // point 1
         0.5, -0.5, // point 2
         0.0,  0.5   // point 2
      ];
   var colors = [
         1, 0, 0, // red
         0, 1, 0, // green
         0, 0, 1  // blue
      ];

   // Load the data into GPU data buffers
   // The vertex positions are copied into one buffer
   var vertex_buffer = gl.createBuffer();
   gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);
   gl.bufferData(gl.ARRAY_BUFFER, flatten(positions), gl.STATIC_DRAW);

   // The colours are copied into another buffer
   var color_buffer = gl.createBuffer();
   gl.bindBuffer(gl.ARRAY_BUFFER, color_buffer);
   gl.bufferData(gl.ARRAY_BUFFER, flatten(colors), gl.STATIC_DRAW);

   // Associate shader attributes with corresponding data buffers
   // Create a connection manager for the data, a Vertex Array Object
   // These are typically made global so you can swap what you draw in the
   //    render function.
   var triangleVAO = gl.createVertexArray();
   gl.bindVertexArray(triangleVAO);

   //Here we prepare the "vPosition" shader attribute entry point to
   //receive 2D float vertex positions from the vertex buffer
   var vPosition = gl.getAttribLocation(program, "vPosition");
   gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);
   gl.vertexAttribPointer(vPosition, 2, gl.FLOAT, false, 0, 0);
   gl.enableVertexAttribArray(vPosition);

   //Here we prepare the "vColor" shader attribute entry point to
   //receive RGB float colours from the colour buffer
   var vColor = gl.getAttribLocation(program, "vColor");
   gl.bindBuffer(gl.ARRAY_BUFFER, color_buffer);
   gl.vertexAttribPointer(vColor, 3, gl.FLOAT, false, 0, 0);
   gl.enableVertexAttribArray(vColor);


   // Get addresses of shader uniforms
   // None in this program...

   //Either draw once as part of initialization
  render();

   //Or schedule a draw just before the next repaint event
   //requestAnimationFrame(render);
};


function render() {
   // clear the screen
   // Actually, the  WebGL automatically clears the screen before drawing.
   // This command will clear the screen to the clear color instead of white.
   gl.clear(gl.COLOR_BUFFER_BIT);

   // draw
   // Draw the data from the buffers currently associated with shader variables
   // Our triangle has three vertices that start at the beginning of the buffer.
   gl.drawArrays(gl.TRIANGLES, 0, 3);
}


โหลดหน้า HTML ซ้ำ ผลลัพธ์ควรมีลักษณะดังนี้:

ตอนนี้เรากำลังจะไปที่ไหนสักแห่ง เหตุผลที่รูปสามเหลี่ยมเป็นสีดำก็คือตัวแรเงาในไฟล์ HTML นั้นถูกฮาร์ดโค้ดไว้เพื่อทำให้ทุกอย่างเป็นสีดำ ตรวจสอบคอนโซลข้อผิดพลาดของเว็บเบราว์เซอร์ ออบเจ็กต์ WebGL ของคุณอาจรายงานข้อผิดพลาดเมื่อคุณเรียก vertexAttribPointer() และ enableVertexAttribArray() ด้วย vColor ที่ไม่ถูกต้อง ส่งคืนโดย getAttribLocation() เราจำเป็นต้องปรับเปลี่ยนเฉดสีเพื่อให้ทราบถึงบัฟเฟอร์สี ทำการเปลี่ยนแปลงต่อไปนี้กับจุดยอดและส่วนแรเงา:


โค้ดไฟล์ Lab1Demo.html

<!DOCTYPE html>
<html>
  <head>
    <title>WebGL Template</title>

    <!-- This in-line script is a vertex shader resource
      Shaders can be linked from an external file as well.
      First line must be shader language version, no spaces before.
      (Actually textbook's shader loader strips leading spaces...)
      -->
    <script id="vertex-shader" type="x-shader/x-vertex">
      #version 300 es

      // All vertex shaders require a position input.
      // The name can be changed.
      // Other inputs can be added as desired for colors and other features.
      in vec4 vPosition;
      in vec4 vColor;

      // This varying output is interpolated between the vertices in the
      // primitive we are drawing before being sent to an input with
      // matching name and type in the fragment shader
      out vec4 varColor;

      void main()
      {
         // gl_Position is a built-in vertex shader output.
         // Its value should always be set by the vertex shader.
         // The simplest shaders just copy the position attribute straight to
         // gl_Position
         gl_Position = vPosition;
         varColor = vColor;
      }
    </script>

    <!-- This in-line script is a vertex shader resource
      Shaders can be linked from an external file as well.
      First line must be shader language version, no spaces before.
      (Actually textbook's shader loader strips the spaces...) -->
    <script id="fragment-shader" type="x-shader/x-fragment">
      #version 300 es

      // Sets default precision for floats.
      // Since fragment shaders have no default precision, you must either:
      //   - set a default before declaring types that use floating point OR
      //   - specify the precision before each floating point declaration
      // Choices are lowp, mediump, and highp.
      precision mediump float;

      in vec4 varColor;

      // The output of a fragment shader is sent to draw buffers,
      // which might be an array or the screen. The default is
      out vec4 fragColor;

      void main()
      {
         // In general, the fragment shader output should be set,
         //     but this is not required.
         // If an output is not set,
         //    there will be no output to the corresponding draw buffer.
         fragColor = varColor;
      }
    </script>

    <!-- These are external javascript files.
      The first three are the textbook libraries.
      The last one is your own javascript code. Make sure to change the name
      to match your javascript file. -->
    <script type="text/javascript" src="../Common/utility.js"></script>
    <script type="text/javascript" src="../Common/initShaders.js"></script>
    <script type="text/javascript" src="../Common/MVnew.js"></script>
    <script type="text/javascript" src="../Common/flatten.js"></script>
    <script type="text/javascript" src="Lab1Demo.js"></script>
  </head>

  <body>
    <!-- This is the canvas - the only HTML element that can render WebGL
      graphics. You can have more than one WebGL canvas on a web page, but
      that gets tricky. Stick to one per page for now. -->
    <canvas id="gl-canvas" width="512" height="512">
      Oops ... your browser doesn't support the HTML5 canvas element
    </canvas>
  </body>
</html>



เมื่อคุณโหลดหน้า HTML ใหม่ คุณควรเห็นสิ่งนี้:

Leave a Reply

Your email address will not be published. Required fields are marked *