diff --git a/Final_Project/final_project.css b/Final_Project/final_project.css index 712169b20c9154bfe5d6a88b475a3d25c51dc65a..0cf3d361fd844e388b5fb1a6c14829b0f9c59e04 100644 --- a/Final_Project/final_project.css +++ b/Final_Project/final_project.css @@ -1,7 +1,12 @@ -table { - margin: 10px; +/* (CC-NC-BY) JungYeun Won 2019 + WebGL 1.0 Tutorial - After-images of roatating Cube */ + +body { + padding: 30px; + background: #ebf9ff } + .layout-td { padding: 20px; /* background: pink; */ @@ -17,6 +22,7 @@ table { margin: 5px; } + .tab { overflow: hidden; border: 1px solid #8795d3; @@ -56,3 +62,40 @@ table { to {opacity: 1;} } + .slider { + -webkit-appearance: none; /* Override default CSS styles */ + appearance: none; + width: 100%; /* Full-width */ + height: 10px; /* Specified height */ + background: #d0d9ff; /* Grey background */ + outline: none; /* Remove outline */ + opacity: 0.7; /* Set transparency (for mouse-over effects on hover) */ + -webkit-transition: .2s; /* 0.2 seconds transition on hover */ + transition: opacity .2s; + } + + .slider:hover { + opacity: 1; /* Fully shown on mouse-over */ + } + + +.cont_btn2 { + border: 1px solid #4f98c2; + background-color: #bfe4fc; + outline: none; + cursor: pointer; + padding: 10px 12px; + margin: 5px; +} + +.cont_btn2:hover { + background-color: #9cd5fc; +} + +.code-box { + width: 300px; + background: #daf1ff; + border: 1px solid #4f98c2; + margin: 5px; + padding: 10px; +} \ No newline at end of file diff --git a/Final_Project/final_project.html b/Final_Project/final_project.html index 0e2826f3011fa0011e170800bf8b70bfaa5c2d03..8904e3b868ffc1dc123434fe1141bb24af80a5b6 100644 --- a/Final_Project/final_project.html +++ b/Final_Project/final_project.html @@ -1,27 +1,30 @@ <!-- (CC-NC-BY) JungYeun Won 2019 --> +<!-- WebGL 1.0 Tutorial - After-images of roatating Cube --> <html> <head> <title>201620955 wonjungyeun</title> <meta http-equiv="content-type" content="text/html; charset=ISO-8859-1"> - <script type="text/javascript" src="final_project.js"> - </script> + <script type="text/javascript" src="final_project.js"></script> <link rel="stylesheet" href="final_project.css"> </head> <body onload="main()"> - <H2> WebGL - After-image of Cube </H2> - Example - After-image of rotating Cube - <br><br> - + <H2> WebGL - After-images of rotating Cube </H2> + <p style="width:700px"> + This demo shows the after-images when the 3D cube rotates. + Each after-image has a location coordinate where the cube was at previous frames. + The older after-image, the fainter it is, and you can control the number of after-images. + The after-image is saved every frame. If you change the frequency of after-images, you can set to display the after-image every n frames. + </p> <table> <tr> <tr> <td class="layout-td"> - <canvas id="helloapicanvas" style="border: none;" width="500" height="500"></canvas> + <canvas id="helloapicanvas" style="border: none;" width="500" height="500"></canvas><br><br> <table border=2> <tr > <td id="matrix0"> <td id="matrix4"> <td id="matrix8"> <td id="matrix12"> @@ -36,7 +39,7 @@ </td> <td class="layout-td"> <div class="tab"> - <button class="tablinks" onclick="openControls(event, 'Translation')">Translation</button> + <button class="tablinks" id="clickedBtn" onclick="openControls(event, 'Translation')">Translation</button> <button class="tablinks" onclick="openControls(event, 'Rotation')">Rotation</button> <button class="tablinks" onclick="openControls(event, 'After-image')">After-image</button> </div> @@ -74,12 +77,12 @@ <h3>After-image</h3> <p id="val_traceNum">The Number of After-image: 5</p> <div class="slidecontainer"> - <input type="range" min="1" max="10" value="5" class="slider" id="traceNum" onchange="changeTraceNum(this.value)"> + <input type="range" class="slider" min="1" max="10" value="5" class="slider" id="traceNum" onchange="changeTraceNum(this.value)"> </div> <br> - <p id="val_traceFreq">Frequency of After-image: 3</p> + <p id="val_traceFreq">Frequency of After-image: 5</p> <div class="slidecontainer"> - <input type="range" min="1" max="7" value="3" class="slider" id="traceFreq" onchange="changeTraceFreq(this.value)"> + <input type="range" class="slider" min="1" max="7" value="5" class="slider" id="traceFreq" onchange="changeTraceFreq(this.value)"> </div> <h4>Color of After-image</h4> <button class="cont_btn" onclick="changeTraceColor('color')">Original</button> @@ -90,7 +93,21 @@ </td> <td class="layout-td"> - <h3>area4</h3> + <h3>major code</h3> + <button class="cont_btn2" onclick="changeTraceColor('color')">Original</button> + <button class="cont_btn2" onclick="changeTraceColor('white')">White</button> + <button class="cont_btn2" onclick="changeTraceColor('gray')">Gray</button> + <div class="code-box"> + <p id="code-content"> + This is space for major code. + </p> + </div> + <div class="code-box"> + <h4>About After-image</h4> + <p> + In OpenGL, it 'draw' every frame. So in order to display the after-images, the location coordinate of the cube at that time should be stored every frame. In this demo, the set number of after-image(saved as the cube moves) is set number * frequency and the rest is deleted for saving memory. And after drawing the cube, it 'draw' after-image more and more transparent from the most recent saved. + </p> + </div> </td> </tr> </tr> diff --git a/Final_Project/final_project.js b/Final_Project/final_project.js index f927da164a66ba232f6892ef281310cf5364c2b9..6a11f9fa33ec78182a605b363fb987fd75f739a5 100644 --- a/Final_Project/final_project.js +++ b/Final_Project/final_project.js @@ -1,5 +1,5 @@ // (CC-NC-BY) JungYeun Won 2019 -// WebGL 1.0 Tutorial - Trace of Cube +// WebGL 1.0 Tutorial - After-images of roatating Cube var gl; @@ -16,6 +16,8 @@ function testGLError(functionLastCalled) { } function initialiseGL(canvas) { + document.getElementById("clickedBtn").click(); + try { // Try to grab the standard context. If it fails, fallback to experimental gl = canvas.getContext("webgl") || canvas.getContext("experimental-webgl"); @@ -38,13 +40,13 @@ function vertexData(color_a, mode){ var vertex = []; if(mode == "color"){ vertex = [ - -0.5, 0.5, 0.5, 1.0, 1.0, 0.7, color_a, 0.0, 1.0,//3 - 0.5, 0.5, 0.5, 1.0, 1.0, 0.7, color_a, 1.0, 1.0,//1 - 0.5, 0.5, -0.5, 1.0, 1.0, 0.7, color_a, 1.0, 1.0,//2 + -0.5, 0.5, 0.5, 1.0, 0.0, 0.5, color_a, 0.0, 1.0,//3 + 0.5, 0.5, 0.5, 1.0, 0.0, 0.5, color_a, 1.0, 1.0,//1 + 0.5, 0.5, -0.5, 1.0, 0.0, 0.5, color_a, 1.0, 1.0,//2 - -0.5, 0.5, 0.5, 1.0, 1.0, 0.7, color_a, 0.0, 1.0,//3 - 0.5, 0.5, -0.5, 1.0, 1.0, 0.7, color_a, 1.0, 1.0,//2 - -0.5, 0.5, -0.5, 1.0, 1.0, 0.7, color_a, 0.0, 1.0,//4 + -0.5, 0.5, 0.5, 1.0, 0.0, 0.5, color_a, 0.0, 1.0,//3 + 0.5, 0.5, -0.5, 1.0, 0.0, 0.5, color_a, 1.0, 1.0,//2 + -0.5, 0.5, -0.5, 1.0, 0.0, 0.5, color_a, 0.0, 1.0,//4 0.5, 0.5, -0.5, 0.0, 0.5, 0.0, color_a, 1.0, 1.0,//2 0.5, -0.5, -0.5, 0.0, 0.5, 0.0, color_a, 1.0, 0.0,//6 @@ -91,7 +93,7 @@ function vertexData(color_a, mode){ if(mode == "white") color = 1.0; else if(mode == "gray") - color = 0.4; + color = 0.0; vertex = [ -0.5, 0.5, 0.5, color, color, color, color_a, 0.0, 1.0,//3 0.5, 0.5, 0.5, color, color, color, color_a, 1.0, 1.0,//1 @@ -162,7 +164,7 @@ function initialiseShaders() { varying mediump vec4 color; \ void main(void) \ { \ - gl_FragColor = 0.8 * color;\ + gl_FragColor = 1.0 * color;\ }'; gl.fragShader = gl.createShader(gl.FRAGMENT_SHADER); @@ -176,21 +178,14 @@ function initialiseShaders() { var vertexShaderSource = '\ attribute highp vec3 myVertex; \ attribute highp vec4 myColor; \ - attribute highp vec2 myUV; \ uniform mediump mat4 Pmatrix; \ uniform mediump mat4 Vmatrix; \ uniform mediump mat4 Mmatrix; \ varying mediump vec4 color; \ - varying mediump vec2 texCoord;\ void main(void) \ { \ gl_Position = Pmatrix*Vmatrix*Mmatrix*vec4(myVertex, 1.0); \ - /*if(gl_Position.w !=0.0) \ - gl_Position.x = (gl_Position.x/gl_Position.w + 1.0)*gl_Position.w; \ - else \ - gl_Position.x+=1.0;*/ \ color = myColor;\ - texCoord = myUV; \ }'; gl.vertexShader = gl.createShader(gl.VERTEX_SHADER); @@ -210,7 +205,6 @@ function initialiseShaders() { // Bind the custom vertex attribute gl.bindAttribLocation(gl.programObject, 0, "myVertex"); gl.bindAttribLocation(gl.programObject, 1, "myColor"); - gl.bindAttribLocation(gl.programObject, 2, "myUV"); // Link the program gl.linkProgram(gl.programObject); @@ -336,11 +330,11 @@ function trZinc(sign) // translate Z increase or decrease var trace = []; var traceNum = 5; -var traceFreq = 3; +var traceFreq = 5; var traceTotalNum = traceNum * traceFreq; var trace_alpha = 0.5/traceNum; var slider_traceNum = document.getElementById("traceNum"); -var traceColor = "gray"; +var traceColor = "color"; function addTrace(mat){ if(trace.length>=traceTotalNum){ @@ -384,7 +378,7 @@ function renderScene() { } // gl.enable(gl.DEPTH_TEST); // gl.depthFunc(gl.LEQUAL); - // gl.enable(gl.CULL_FACE); // 이거(Culling) 켜면 뒷면 안그림 + gl.enable(gl.CULL_FACE); // 이거(Culling) 켜면 뒷면 안그림 gl.enable(gl.BLEND); gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA); gl.blendEquation(gl.FUNC_ADD); @@ -413,8 +407,14 @@ function renderScene() { var mov_matrix_child = mov_matrix.slice(); addTrace(mov_matrix_child); + // original cube + gl.bindBuffer(gl.ARRAY_BUFFER, gl.vertexBuffer); + gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertexData(1.0, "color")), gl.STATIC_DRAW); + gl.uniformMatrix4fv(locMmatrix, false, trace[trace.length -1].slice()); + gl.drawArrays(gl.TRIANGLES, 0, 36); + // draw trace of cube - color_a = 1.0; + color_a = 0.5; for (var i = trace.length -1; i>=0;i-=traceFreq){ color_a -= trace_alpha; gl.bindBuffer(gl.ARRAY_BUFFER, gl.vertexBuffer); @@ -423,13 +423,6 @@ function renderScene() { if (color_a > 0.0) gl.drawArrays(gl.TRIANGLES, 0, 36); } - - // original cube - gl.bindBuffer(gl.ARRAY_BUFFER, gl.vertexBuffer); - gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertexData(1.0, "color")), gl.STATIC_DRAW); - gl.uniformMatrix4fv(locMmatrix, false, trace[trace.length -1].slice()); - gl.drawArrays(gl.TRIANGLES, 0, 36); - // 회전 수치 표 document.getElementById("matrix0").innerHTML = mov_matrix[0].toFixed(4); @@ -489,6 +482,11 @@ function main() { })(); } +function showCode(){ + var codeContent = document.getElementById("code-content"); + +} + function openControls(evt, contName) { // Declare all variables var i, tabcontent, tablinks;