Skip to content
Snippets Groups Projects
Commit d84f5973 authored by PARK Sanghyuk's avatar PARK Sanghyuk
Browse files

Initial Commit

parent 76641f12
No related branches found
No related tags found
No related merge requests found
LICENSE 0 → 100644
MIT License
Copyright (c) 2021 PARK Sanghyuk
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
\ No newline at end of file
# WebGL Tutorial
Project for 2021-Spring Computer Graphics final assignment
# Overview
This document is to describe the basic method of changing the WebGL1-based document to WebGL2.
WebGL2 is nearly 100% back compatible with WebGL1. In this document, there will be description of very basic way to change the WebGL1 script to WebGL2.
Very brief comments are here, so read the source code to see the details.
# Initializing
<img src=img/InitializeGL.png width=50%>
First, you use "webgl2" instead of "webgl", on initializing canvas.
Note that there is no "experimental-webgl2". Many WebGL1 extensions are a standard part of WebGL2.
# Switching the Shader Version to GLSL 3.00 ES
Add "#version 300 es" to the very first line of the shader source code.
CAUTION: NO BLANKS AND LINES ARE ALLOWED BEFORE THIS DECLARATION.
# Some Changes in Shader Code
Add "#version 300 es" to the very first line of the shader source code.
CAUTION: NO BLANKS AND LINES ARE ALLOWED BEFORE THIS DECLARATION.
No more gl_fragColor. In WebGL1, your fragment shader would set the specific variable gl_fragColor" to set the output value.
You can now use any name for the output, except for those starting with "gl_".
Change "varying" to "in" or "out", and "attribute" to "in".
The output of the vertex shader would be the input of the fragment shader. We call them varying" values.
Simply change them to "out" in the vertex shader, and "in" in the fragment shader.
# Shader Code Example
<img src=img/FragmentShader.png width=50%>
Fragment shader
<img src=img/VertexShader.png width=50%>
Vertex shader
# References
* This page is modified from Lab 06 of the Computer Graphics course.
* WebGL1 to WebGL2: https://webgl2fundamentals.org/webgl/lessons/webgl1-to-webgl2.html
* WebGL2 Fundamentals: https://webgl2fundamentals.org/webgl/lessons/ko/webgl-fundamentals.html
\ No newline at end of file
Script.js 0 → 100644
// Change WebGL 1 based document to WebGL 2
// Reference: https://webgl2fundamentals.org/webgl/lessons/webgl1-to-webgl2.html
// https://webgl2fundamentals.org/webgl/lessons/ko/webgl-fundamentals.html
var gl;
const {mat2, mat3, mat4, vec2, vec3, vec4} = glMatrix;
// Now we can use function without glMatrix.~~~
function testGLError(functionLastCalled) {
/* gl.getError returns the last error that occurred using WebGL for debugging */
var lastError = gl.getError();
if (lastError != gl.NO_ERROR) {
alert(functionLastCalled + " failed (" + lastError + ")");
return false;
}
return true;
}
function initialiseGL(canvas) {
try {
// Try to grab the standard context. If it fails, fallback to experimental
// gl = canvas.getContext("webgl") || canvas.getContext("experimental-webgl"); // in WebGL1
gl = canvas.getContext("webgl2");
// No experimental-webgl2
gl.viewport(0, 0, canvas.width, canvas.height);
}
catch (e) {
}
if (!gl) {
alert("Unable to initialise WebGL. Your browser may not support it");
return false;
}
return true;
}
var shaderProgram;
var vertexData = [
// Backface (RED/WHITE) -> z = 0.5
// x y z r g b a
-0.5, -0.5, -0.5, 1.0, 0.0, 0.0, 1.0,
0.5, 0.5, -0.5, 1.0, 0.0, 0.0, 1.0,
0.5, -0.5, -0.5, 1.0, 0.0, 0.0, 1.0,
-0.5, -0.5, -0.5, 1.0, 0.0, 0.0, 1.0,
-0.5, 0.5, -0.5, 1.0, 0.0, 0.0, 1.0,
0.5, 0.5, -0.5, 1.0, 1.0, 1.0, 1.0,
// Front (BLUE/WHITE) -> z = 0.5
-0.5, -0.5, 0.5, 0.0, 0.0, 1.0, 1.0,
0.5, 0.5, 0.5, 0.0, 0.0, 1.0, 1.0,
0.5, -0.5, 0.5, 0.0, 0.0, 1.0, 1.0,
-0.5, -0.5, 0.5, 0.0, 0.0, 1.0, 1.0,
-0.5, 0.5, 0.5, 0.0, 0.0, 1.0, 1.0,
0.5, 0.5, 0.5, 1.0, 1.0, 1.0, 1.0,
// LEFT (GREEN/WHITE) -> z = 0.5
-0.5, -0.5, -0.5, 0.0, 1.0, 0.0, 1.0,
-0.5, 0.5, 0.5, 0.0, 1.0, 0.0, 1.0,
-0.5, 0.5, -0.5, 0.0, 1.0, 0.0, 1.0,
-0.5, -0.5, -0.5, 0.0, 1.0, 0.0, 1.0,
-0.5, -0.5, 0.5, 0.0, 1.0, 0.0, 1.0,
-0.5, 0.5, 0.5, 0.0, 1.0, 1.0, 1.0,
// RIGHT (YELLOW/WHITE) -> z = 0.5
0.5, -0.5, -0.5, 1.0, 1.0, 0.0, 1.0,
0.5, 0.5, 0.5, 1.0, 1.0, 0.0, 1.0,
0.5, 0.5, -0.5, 1.0, 1.0, 0.0, 1.0,
0.5, -0.5, -0.5, 1.0, 1.0, 0.0, 1.0,
0.5, -0.5, 0.5, 1.0, 1.0, 0.0, 1.0,
0.5, 0.5, 0.5, 1.0, 1.0, 1.0, 1.0,
// BOTTON (MAGENTA/WHITE) -> z = 0.5
-0.5, -0.5, -0.5, 1.0, 0.0, 1.0, 1.0,
0.5, -0.5, 0.5, 1.0, 0.0, 1.0, 1.0,
0.5, -0.5, -0.5, 1.0, 0.0, 1.0, 1.0,
-0.5, -0.5, -0.5, 1.0, 0.0, 1.0, 1.0,
-0.5, -0.5, 0.5, 1.0, 0.0, 1.0, 1.0,
0.5, -0.5, 0.5, 1.0, 1.0, 1.0, 1.0,
// TOP (CYAN/WHITE) -> z = 0.5
-0.5, 0.5, -0.5, 0.0, 1.0, 1.0, 1.0,
0.5, 0.5, 0.5, 0.0, 1.0, 1.0, 1.0,
0.5, 0.5, -0.5, 0.0, 1.0, 1.0, 1.0,
-0.5, 0.5, -0.5, 0.0, 1.0, 1.0, 1.0,
-0.5, 0.5, 0.5, 0.0, 1.0, 1.0, 1.0,
0.5, 0.5, 0.5, 1.0, 1.0, 1.0, 1.0
];
function initialiseBuffer() {
gl.vertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, gl.vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertexData), gl.STATIC_DRAW);
return testGLError("initialiseBuffers");
}
function initialiseShaders() {
// Define "#version 300 es" at the very first line of the shader code
// Neither blanks nor lines before this context are allowed.
// No more gl_fragColor
// Change "varying" to "in" or "out", and "attribute" to "in".
// You can make any name except for those starting with "gl_".
var fragmentShaderSource = `#version 300 es
// varying highp vec4 col; // in WebGL1
// You cannot use the name starting with "gl_"
in highp vec4 col;
out highp vec4 outFragColor;
void main(void)
{
outFragColor = col;
}`;
gl.fragShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(gl.fragShader, fragmentShaderSource);
gl.compileShader(gl.fragShader);
// Check if compilation succeeded
if (!gl.getShaderParameter(gl.fragShader, gl.COMPILE_STATUS)) {
alert("Failed to compile the fragment shader.\n" + gl.getShaderInfoLog(gl.fragShader));
return false;
}
// Vertex shader code
var vertexShaderSource = `#version 300 es
// change attribute to in
in highp vec4 myVertex;
in highp vec4 myColor;
uniform mediump mat4 transformationMatrix;
out highp vec4 col;
void main(void)
{
gl_Position = transformationMatrix * myVertex;
gl_PointSize = 5.0;
col = myColor;
}`;
gl.vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(gl.vertexShader, vertexShaderSource);
gl.compileShader(gl.vertexShader);
// Check if compilation succeeded
if (!gl.getShaderParameter(gl.vertexShader, gl.COMPILE_STATUS)) {
alert("Failed to compile the vertex shader.\n" + gl.getShaderInfoLog(gl.vertexShader));
return false;
}
// Create the shader program
gl.programObject = gl.createProgram();
// Attach the fragment and vertex shaders to it
gl.attachShader(gl.programObject, gl.fragShader);
gl.attachShader(gl.programObject, gl.vertexShader);
// Bind the custom vertex attribute "myVertex" to location 0
gl.bindAttribLocation(gl.programObject, 0, "myVertex");
gl.bindAttribLocation(gl.programObject, 1, "myColor");
// Link the program
gl.linkProgram(gl.programObject);
// Check if linking succeeded in a similar way we checked for compilation errors
if (!gl.getProgramParameter(gl.programObject, gl.LINK_STATUS)) {
alert("Failed to link the program.\n" + gl.getProgramInfoLog(gl.programObject));
return false;
}
gl.useProgram(gl.programObject);
return testGLError("initialiseShaders");
}
var xRot = 0.0;
var yRot = 0.0;
var zRot = 0.0;
var speedRot = 0.01;
flag_animation = 0;
function toggleAnimation()
{
flag_animation ^= 1;
console.log("flag_animation=", flag_animation);
}
function speed_plus(){
speedRot *= 1.1;
}
function speed_minus(){
speedRot /= 1.1;
}
var draw_mode = 4;
function draw_mode_change(a){
draw_mode = a;
}
function renderScene() {
gl.clearColor(0.0, 0.0, 0.0, 1.0);
gl.clearDepth(1.0); // Added for depth Test
gl.clear(gl.COLOR_BUFFER_BIT);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); // Added for depth Test
gl.enable(gl.DEPTH_TEST); // Added for depth Test
var matrixLocation = gl.getUniformLocation(gl.programObject, "transformationMatrix");
var transformationMatrix = mat4.create();
mat4.rotateX(transformationMatrix, transformationMatrix, xRot);
mat4.rotateY(transformationMatrix, transformationMatrix, yRot);
mat4.rotateZ(transformationMatrix, transformationMatrix, zRot);
xRot += (speedRot * flag_animation);
yRot += (speedRot * flag_animation);
zRot += (speedRot * flag_animation);
gl.uniformMatrix4fv(matrixLocation, gl.FALSE, transformationMatrix );
if (!testGLError("gl.uniformMatrix4fv")) {
return false;
}
gl.bindBuffer(gl.ARRAY_BUFFER, gl.vertexBuffer);
gl.enableVertexAttribArray(0);
gl.vertexAttribPointer(0, 3, gl.FLOAT, gl.FALSE, 28, 0);
gl.enableVertexAttribArray(1);
gl.vertexAttribPointer(1, 4, gl.FLOAT, gl.FALSE, 28, 12);
if (!testGLError("gl.vertexAttribPointer")) {
return false;
}
//gl.drawArrays(gl.TRIANGLES, 0, 36);
//gl.drawArrays(gl.LINE_STRIP, 0, 36);
// Draw Mode
// 0: points
// 2: lines
// 4: triangles
gl.drawArrays(draw_mode, 0, 36);
if (!testGLError("gl.drawArrays")) {
return false;
}
return true;
}
function main() {
var canvas = document.getElementById("helloapicanvas");
if (!initialiseGL(canvas)) {
return;
}
if (!initialiseBuffer()) {
return;
}
if (!initialiseShaders()) {
return;
}
// renderScene();
// Render loop
requestAnimFrame = (function () {
return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame ||
function (callback) {
window.setTimeout(callback, 1000, 60);
};
})();
(function renderLoop() {
if (renderScene()) {
// Everything was successful, request that we redraw our scene again in the future
requestAnimFrame(renderLoop);
}
})();
}
This diff is collapsed.
img/FragmentShader.png

11.7 KiB

img/InitializeGL.png

25.8 KiB

img/VertexShader.png

14.5 KiB

<html>
<head>
<title>WebGL1.0 to WebGL2.0</title>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
<script type="text/javascript" src="gl-matrix.js"> </script>
<script type="text/javascript" src="Script.js"> </script>
</head>
<body onload="main()">
<div>
<header>
<h1>WebGL Tutorial</h1>
<h2>How to change WebGL1-based documents to WebGL2</h2>
</header>
</div>
<canvas id="helloapicanvas" style="border: none;" width="600" height="600"></canvas>
<br/> <br/>
<button onclick="toggleAnimation()">Toggle Animation</button>
<button onclick="speed_plus()"> + </button>
<button onclick="speed_minus()"> - </button>
<button onclick="draw_mode_change(2)"> Lines </button>
<button onclick="draw_mode_change(4)"> Triangles </button>
<button onclick="draw_mode_change(0)"> Points </button>
<hr>
<div>
<h3>Description</h3>
<div>This document is to describe the basic method of changing the WebGL1-based document to WebGL2.</div>
<div>WebGL2 is nearly 100% back compatible with WebGL1. In this document, there will be description of very basic way to change the WebGL1 script to WebGL2.</div>
<div>Very brief comments are here, so read the source code to see the details.</div>
</div>
<hr>
<div>
<h3>Initializing</h3>
<div>First, you use "webgl2" instead of "webgl", on initializing canvas.</div>
<div>Note that there is no "experimental-webgl2". Many WebGL1 extensions are a standard part of WebGL2.</div>
</div>
<hr>
<div>
<h3>Switching the Shader Version to GLSL 3.00 ES</h3>
<div>Add "#version 300 es" to the very first line of the shader source code.</div>
<div>CAUTION: NO BLANKS AND LINES ARE ALLOWED BEFORE THIS DECLARATION.</div>
</div>
<hr>
<div>
<h3>Some Changes in Shader Code</h3>
<div>Add "#version 300 es" to the very first line of the shader source code.</div>
<div>CAUTION: NO BLANKS AND LINES ARE ALLOWED BEFORE THIS DECLARATION.</div>
<br>
<div>No more gl_fragColor. In WebGL1, your fragment shader would set the specific variable "gl_fragColor" to set the output value.</div>
<div>You can now use any name for the output, except for those starting with "gl_".</div>
<br>
<div>Change "varying" to "in" or "out", and "attribute" to "in".</div>
<div>The output of the vertex shader would be the input of the fragment shader. We call them "varying" values.</div>
<div>Simply change them to "out" in the vertex shader, and "in" in the fragment shader.</div>
</div>
<hr>
<div>
<h3>References</h3>
<div>This page is modified from Lab 06 of the Computer Graphics course.</div>
<div>Additional information is from WebGL2 Fundamentals.</div>
<div> <a href="https://webgl2fundamentals.org/webgl/lessons/webgl1-to-webgl2.html">WebGL1 to WebGL2</a> / <a href="https://webgl2fundamentals.org/webgl/lessons/ko/webgl-fundamentals.html">WebGL2 Fundamentals</a></div>
</div>
</body>
</html>
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment