Skip to content
Snippets Groups Projects
Commit 3051ac0a authored by KimKwangho's avatar KimKwangho
Browse files

.

parents
Branches
No related tags found
No related merge requests found
Pipeline #1940 canceled
<!-- (CC-NC-BY) Kim Kwangho 2019 -->
<!-- Reference : https://www.tutorialspoint.com/webgl/webgl_interactive_cube.htm -->
<html>
<head>
<title>WebGL Tutorial with mouse and keyboard interaction</title>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
<script type="text/javascript" src="gl-matrix.js"></script>
</head>
<body>
<!-- set the canvas -->
<canvas style="border: none;" width="500" height="500" id="my_Canvas"></canvas>
<br>If you want to rotate the cube, drag the cube.<br>
If you want to change color of cube , press c.<br>
If you want to move the cube, press m and drag the cube.<br>
If you want to zoom the cube, wheel the mouse.<br><br>
(CC-NC-BY) Kim Kwangho 2019<br>
Reference : https://www.tutorialspoint.com/webgl/webgl_interactive_cube.htm
<script>
/*============= Creating a canvas ======================*/
var canvas = document.getElementById('my_Canvas');
gl = canvas.getContext('experimental-webgl');
/*========== Defining and storing the geometry ==========*/
//location of vertices.
var vertices = [
-1,-1,-1, 1,-1,-1, 1, 1,-1, -1, 1,-1,
-1,-1, 1, 1,-1, 1, 1, 1, 1, -1, 1, 1,
-1,-1,-1, -1, 1,-1, -1, 1, 1, -1,-1, 1,
1,-1,-1, 1, 1,-1, 1, 1, 1, 1,-1, 1,
-1,-1,-1, -1,-1, 1, 1,-1, 1, 1,-1,-1,
-1, 1,-1, -1, 1, 1, 1, 1, 1, 1, 1,-1,
];
//color per vertices.
var colors = [
1,1,1, 1,1,1, 1,1,1, 1,1,1,
1,1,1, 1,1,1, 1,1,1, 1,1,1,
0,0,1, 0,0,1, 0,0,1, 0,0,1,
1,0,0, 1,0,0, 1,0,0, 1,0,0,
1,1,0, 1,1,0, 1,1,0, 1,1,0,
0,1,0, 0,1,0, 0,1,0, 0,1,0
];
//direction of vertices.
var indices = [
0,1,2, 0,2,3, 4,5,6, 4,6,7,
8,9,10, 8,10,11, 12,13,14, 12,14,15,
16,17,18, 16,18,19, 20,21,22, 20,22,23
];
// Create and store data into vertex buffer
var vertex_buffer = gl.createBuffer ();
gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
// Create and store data into color buffer
var color_buffer = gl.createBuffer ();
gl.bindBuffer(gl.ARRAY_BUFFER, color_buffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW);
// Create and store data into index buffer
var index_buffer = gl.createBuffer ();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, index_buffer);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW);
/*=================== SHADERS =================== */
var vertCode = 'attribute vec3 position;'+
'uniform mat4 Pmatrix;'+
'uniform mat4 Vmatrix;'+
'uniform mat4 Mmatrix;'+
'attribute vec3 color;'+
'varying vec3 vColor;'+
'void main(void) { '+
'gl_Position = Pmatrix*Vmatrix*Mmatrix*vec4(position, 1.);'+
'vColor = color;'+
'}';
var fragCode = 'precision mediump float;'+
'varying vec3 vColor;'+
'void main(void) {'+
'gl_FragColor = vec4(vColor, 1.);'+
'}';
//make vertex shader and compile
var vertShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertShader, vertCode);
gl.compileShader(vertShader);
//make fragment shader and compile
var fragShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragShader, fragCode);
gl.compileShader(fragShader);
//attach these 2 shader to shader program and link.
var shaderprogram = gl.createProgram();
gl.attachShader(shaderprogram, vertShader);
gl.attachShader(shaderprogram, fragShader);
gl.linkProgram(shaderprogram);
/*======== Associating attributes to vertex shader =====*/
var _Pmatrix = gl.getUniformLocation(shaderprogram, "Pmatrix"); //these matrices are all used in vertex shader
var _Vmatrix = gl.getUniformLocation(shaderprogram, "Vmatrix");
var _Mmatrix = gl.getUniformLocation(shaderprogram, "Mmatrix");
gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);
var _position = gl.getAttribLocation(shaderprogram, "position");
gl.vertexAttribPointer(_position, 3, gl.FLOAT, false,0,0);
gl.enableVertexAttribArray(_position);
gl.bindBuffer(gl.ARRAY_BUFFER, color_buffer);
var _color = gl.getAttribLocation(shaderprogram, "color");
gl.vertexAttribPointer(_color, 3, gl.FLOAT, false,0,0) ;
gl.enableVertexAttribArray(_color);
gl.useProgram(shaderprogram);
/*==================== MATRIX ====================== */
var proj_matrix = glMatrix.mat4.create();
glMatrix.mat4.perspective(proj_matrix,40/180*Math.PI,canvas.width/canvas.height,1,100);
var mo_matrix = glMatrix.mat4.create();
var view_matrix = glMatrix.mat4.create();
console.log(view_matrix);
view_matrix[14] = view_matrix[14]-8;
/*================= Mouse events ======================*/
var AMORTIZATION = 0.95;
var drag = false;
var old_x, old_y;
var dX = 0, dY = 0, mX = 0.0, mY = 0.0;
var sv = glMatrix.vec3.create(),old_sv = glMatrix.vec3.create();
//when mouse is pressed.
var mouseDown = function(e) {
drag = true;
old_x = e.pageX, old_y = e.pageY;
e.preventDefault();
return false;
};
//when mouse is released.
var mouseUp = function(e){
drag = false;
};
//when mouse is moving while mouse is pressed.
var mouseMove = function(e) {
if (!drag) return false;
if(!move){
//when m is not pressed.
dX = (e.pageX-old_x)*2*Math.PI/canvas.width,
dY = (e.pageY-old_y)*2*Math.PI/canvas.height;
THETA+= dX;
PHI+=dY;
old_x = e.pageX, old_y = e.pageY;
e.preventDefault();
}
else{
//when m is pressed.
mX = (e.pageX-old_x)/canvas.width*view_matrix[14];
mY = (-e.pageY+old_y)/canvas.height*view_matrix[14];
view_matrix[12]-=mX;
view_matrix[13]-=mY;
old_x = e.pageX, old_y = e.pageY;
e.preventDefault();
}
};
//when mouse wheels.
var Wheel = function(e){
if(e.deltaY<0){
if(view_matrix[14]<-5.1) view_matrix[14] = view_matrix[14]+0.2;
}
else {
if(view_matrix[14]>-20) view_matrix[14] = view_matrix[14]-0.2;
}
};
/*================= Keyboard events ======================*/
//when any keyboard key is pressed.
var onKeyPress = function(e){
//when c is pressed. c means change.
if(e.key=='c'){// when user pushes c, user can change the color of box
for(i in colors){
colors[i] = Math.random()+0.3;
}
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW);
}
//when m is pressed. m means move
if(e.key=='m'){
move=1;
return false;
}
};
// when all keys are released.
var onKeyUp = function(e){
move=0;
};
//EventListner has lots of action to trigger the event.
canvas.addEventListener("mousedown", mouseDown, false); //mouse clicked.
canvas.addEventListener("mouseup", mouseUp, false); //mouse released.
canvas.addEventListener("mouseout", mouseUp, false); //mouse cursor is going out of canvas
canvas.addEventListener("mousemove", mouseMove, false); //mouse is moving
canvas.addEventListener("wheel",Wheel, false); //mouse wheels.
window.addEventListener("keypress",onKeyPress, false); //key is pressed.
window.addEventListener("keyup",onKeyUp, false); //key is released.
/*=================== Drawing =================== */
var THETA = 0, //variable for rotate y-axis
PHI = 0; //variabe for rotate x-axis
var time_old = 0;
var animate = function(time) {
var dt = time-time_old;
if (!drag) {
dX *= AMORTIZATION, dY*=AMORTIZATION;
THETA+=dX, PHI+=dY;
}
glMatrix.mat4.identity(mo_matrix); //before drawing, model matrix is being identity matrix
glMatrix.mat4.rotateY(mo_matrix,mo_matrix,THETA); //
glMatrix.mat4.rotateX(mo_matrix,mo_matrix,PHI); //
time_old = time;
gl.enable(gl.DEPTH_TEST);//DEPTH_TEST is enabled.
gl.clearColor(0.7, 0.7, 0.7, 1.0);
gl.clearDepth(1.0);
gl.viewport(0.0, 0.0, canvas.width, canvas.height);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
//Uniform Matrices
gl.uniformMatrix4fv(_Pmatrix, false, proj_matrix);
gl.uniformMatrix4fv(_Vmatrix, false, view_matrix);
gl.uniformMatrix4fv(_Mmatrix, false, mo_matrix);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, index_buffer);
gl.drawElements(gl.TRIANGLES, indices.length, gl.UNSIGNED_SHORT, 0);
window.requestAnimationFrame(animate);
}
animate(0);
</script>
</body>
</html>
</script>
\ No newline at end of file
This diff is collapsed.
readme.md 0 → 100644
# WebGL Tutorial with Mouse and Keyboard Interaction
## Manifest
- WebGL.html
- gl-matrix.js
## Basic
- Canvas size is 500 x 500
- Vertex Shader code
```c
attribute vec3 position;
uniform mat4 Pmatrix;
uniform mat4 Vmatrix;
uniform mat4 Mmatrix;
attribute vec3 color;
varying vec3 vColor;
void main(void) {
gl_Position = Pmatrix*Vmatrix*Mmatrix*vec4(position, 1.);
vColor = color;
}
```
Model, View, Projective Matrices are Uniform.<br>
Position and color Matrices are attribute<br>
Return color vColor is varying to return to Fragment Shader.
- Fragment Shader code
```c
precision mediump float;
varying vec3 vColor;
void main(void) {
gl_FragColor = vec4(vColor, 1.);
}
```
vColor is returned from Vertex Shader.
- Perspective Matrix
```c
glMatrix.mat4.perspective(proj_matrix,40/180*Math.PI,canvas.width/canvas.height,1100);
```
Perspective matrix has 5 parameters.
1. out - Frustrum matrix will be written to.
2. fovy - Vertical field of view in radians. if has angle, convert to radians using angle/180*Math.PI
3. aspect - Aspect ratio of canvas typically viewport width/height
4. near - Near bound of the frustrum
5. far - Far bound of the frustrum. can be null or Infinity
## Events
HTML has addEventListner function that sets up a function that will be called whenever the specified event is delivered to the targer.<br>
I used this function to implement interation WebGL Program.
### Mouse Event
- mouseDown
this function is called when mouse is clicked.
```c
drag = true;
old_x = e.pageX, old_y = e.pageY;
e.preventDefault();
return false;
```
- mouseUp
this function is called when mouse is released.
```c
drag = false;
```
- mouseMove
this function has 2 ways. it collaborates with Keyboard Event.<br>
when mouse is not clicked, it ignores the function.<br>
when m(move) is pressed. mousemove is working as translator, else working as rotator.
```c
if (!drag) return false;
if(!move){
dX = (e.pageX-old_x)*2*Math.PI/canvas.width,
dY = (e.pageY-old_y)*2*Math.PI/canvas.height;
THETA+= dX;
PHI+=dY;
old_x = e.pageX, old_y = e.pageY;
e.preventDefault();
}
else{
mX = (e.pageX-old_x)/canvas.width*view_matrix[14];
mY = (-e.pageY+old_y)/canvas.height*view_matrix[14];
view_matrix[12]-=mX;
view_matrix[13]-=mY;
old_x = e.pageX, old_y = e.pageY;
e.preventDefault();
}
```
- Wheel
Wheel has 2 directions. When up, e.deltaY will be negative. when down, it will be positive.<br>
per 1 click, Zoom +-0.2 and view_matrix[14]is limited from -20 to -5.
```c
if(e.deltaY<0){
if(view_matrix[14]<-5.1) view_matrix[14] = view_matrix[14]+0.2;
}
else {
if(view_matrix[14]>-20) view_matrix[14] = view_matrix[14]-0.2;
}
```
### Keyboard Event
- onKeyPress
as I told above, mouseMove action collaborates with onKeyPress action.<br>
when m is pressed, variable move become 1. now mouseMove action will working as translator.<br>
when c is pressed, this action will change the color of cube. color will be randomly chosen.
```c
if(e.key=='c'){
for(i in colors){
colors[i] = Math.random()+0.3;
}
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW);
}
if(e.key=='m'){
move=1;
return false;
}
```
- onKeyUp
```c
move=0;
```
## References
- https://www.tutorialspoint.com/webgl/webgl_interactive_cube.htm
- http://glmatrix.net/
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment