Vertax Shader
precision mediump float; attribute vec3 vertPosition; attribute vec2 vertTexCoord; //$$택스쳐 이미지 배열. uniform mat4 mWorld; uniform mat4 mView; //camera uniform mat4 mProj; varying vec2 fragTexCoord; void main() { fragTexCoord = vertTexCoord; gl_Position = mProj * mView * mWorld * vec4(vertPosition, 1.0); }
Fragment Shader
precision mediump float; varying vec2 fragTexCoord; uniform sampler2D sampler; //texture zero to texture size void main(){ gl_FragColor = texture2D(sampler, fragTexCoord); //$$택스쳐 }
Script
var gl; var program; var canvas; function runWebGLApp() { canvas = document.getElementById("canvas-element-id"); gl = canvas.getContext('webgl'); if(!gl){ console.log("WebGL not supported falling back on experimental-webgl"); gl = canvas.getContext('experimental-webgl'); } if(!gl){ alert("Your browser does not support WebGL"); } gl.clearColor(0.75, 0.85, 0.8, 1.0); gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); gl.enable(gl.DEPTH_TEST); gl.enable(gl.CULL_FACE); gl.frontFace(gl.CCW); gl.cullFace(gl.BACK); var fragmentShader = getShader(gl, "shader-fs"); var vertexShader = getShader(gl, "shader-vs"); //program program = gl.createProgram(); gl.attachShader(program, vertexShader); gl.attachShader(program, fragmentShader); gl.linkProgram(program); if (!gl.getProgramParameter(program, gl.LINK_STATUS)) { console.log('There was a problem with the PROGRAM :\n\n'+ gl.getProgramInfoLog(program)); gl.deleteProgram(program); } gl.validateProgram(program); if (!gl.getProgramParameter(program, gl.VALIDATE_STATUS)) { console.error('Error validating program!', gl.getProgramInfoLog(program)); } gl.useProgram(program); //buffer var triagleVertex = [ //X,Y,Z R,G,B 0.0, 0.5, 0.0, 1.0,1.0,0.0, -0.5, -0.5, 0.0, 0.7,0.0,1.0, 0.5, -0.5, 0.0, 0.1,1.0,0.6 ]; var boxVertices = //$$택스쳐 [ // X, Y, Z U,V // Top x와 z로 0과 1을 결정. 음수면 0 양수면 1 -1.0, 1.0, -1.0, 0,0, -1.0, 1.0, 1.0, 0,1, 1.0, 1.0, 1.0, 1,1, 1.0, 1.0, -1.0, 1,0, // Left y와 z로 양수면 0 음수면 1 -1.0, 1.0, 1.0, 0, 0, -1.0, -1.0, 1.0, 1, 0, -1.0, -1.0, -1.0, 1, 1, -1.0, 1.0, -1.0, 0, 1, // Right y와 z로 양수면1 음수면0 1.0, 1.0, 1.0, 1, 1, 1.0, -1.0, 1.0, 0, 1, 1.0, -1.0, -1.0, 0, 0, 1.0, 1.0, -1.0, 1, 0, // Front x와 y로 양수면1 음수면0 1.0, 1.0, 1.0, 1, 1, 1.0, -1.0, 1.0, 1, 0, -1.0, -1.0, 1.0, 0, 0, -1.0, 1.0, 1.0, 0, 1, // Back x와 y로 양수면0 음수면1 1.0, 1.0, -1.0, 0, 0, 1.0, -1.0, -1.0, 0, 1, -1.0, -1.0, -1.0, 1, 1, -1.0, 1.0, -1.0, 1, 0, // Bottom y와 z로 양수면0 음수면1 -1.0, -1.0, -1.0, 1, 1, -1.0, -1.0, 1.0, 1, 0, 1.0, -1.0, 1.0, 0, 0, 1.0, -1.0, -1.0, 0, 1, ]; var boxIndices = [ // Top 0, 1, 2, 0, 2, 3, // Left 5, 4, 6, 6, 4, 7, // Right 8, 9, 10, 8, 10, 11, // Front 13, 12, 14, 15, 14, 12, // Back 16, 17, 18, 16, 18, 19, // Bottom 21, 20, 22, 22, 20, 23 ]; var triBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, triBuffer); //gl에 버퍼를 바인딩 gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(boxVertices), gl.STATIC_DRAW); //버퍼에 버텍스 연결. // gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(triagleVertex), gl.STATIC_DRAW); //버퍼에 버텍스 연결. //index버퍼 var boxIndexBuffer = gl.createBuffer(); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, boxIndexBuffer); //gl에 버퍼를 바인딩 gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(boxIndices), gl.STATIC_DRAW); //버퍼에 버텍스 연결. var positionLocation = gl.getAttribLocation(program,'vertPosition'); var texCoordAttribLocation = gl.getAttribLocation(program,'vertTexCoord'); //$$택스쳐 // gl.vertexAttribPointer(positionLocation, // 2, //Number of elements per attribute // gl.FLOAT, //type of elements // gl.FALSE, // 2 * Float32Array.BYTES_PER_ELEMENT, //size of an individual vertex 2*4 // 0 //offset from the beginning of a single vertext to this attribute // ); gl.vertexAttribPointer(positionLocation, 3, //Number of elements per attribute gl.FLOAT, //type of elements gl.FALSE, 5 * Float32Array.BYTES_PER_ELEMENT, //size of an individual vertex 5*4 //$$택스쳐 간격이 5 0 //offset from the beginning of a single vertext to this attribute ); gl.vertexAttribPointer(texCoordAttribLocation, 2, //Number of elements per attribute //$$택스쳐 gl.FLOAT, //type of elements gl.FALSE, 5 * Float32Array.BYTES_PER_ELEMENT, //size of an individual vertex 5*4 //$$택스쳐 5 3 * Float32Array.BYTES_PER_ELEMENT //offset from the beginning of a single vertext to this attribute ); gl.enableVertexAttribArray(positionLocation); gl.enableVertexAttribArray(texCoordAttribLocation); //==================================== //$$$ 텍스쳐 // https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/texParameter //create Texture // 1. vertexBuffers carousel1.png var boxTexture = gl.createTexture(); // 이미지 로드 var image = new Image(); image.onload = function(){ console.log("image onload"); gl.bindTexture(gl.TEXTURE_2D, boxTexture); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); // gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); // gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image); gl.bindTexture(gl.TEXTURE_2D, null); } image.src = '/img/ui/우열.jpg'; //============================== //uniform - useProgram이 선언되야 한다. var mWorldLocation = gl.getUniformLocation(program, 'mWorld'); var mViewLocation = gl.getUniformLocation(program, 'mView'); var mProjLocation = gl.getUniformLocation(program, 'mProj'); var worldMatrix = new Float32Array(16); var viewMatrix = new Float32Array(16); var projMatrix = new Float32Array(16); glMatrix.mat4.identity(worldMatrix); glMatrix.mat4.lookAt(viewMatrix,[0,0,-5],[0,0,0],[0,1,0]); //카메라. eye, center, up glMatrix.mat4.perspective(projMatrix, 45 * Math.PI / 180 ,canvas.width/canvas.height, 0.1, 1000.0); //projection fovy 45도 라디안, aspect:뷰포트 w/h 임 0.333, near:플러스트럼 영역 ,far 플러스트럼 영역 gl.uniformMatrix4fv(mWorldLocation, gl.FALSE, worldMatrix); //must be FALSE, gl.uniformMatrix4fv(mViewLocation, gl.FALSE, viewMatrix); //must be FALSE, gl.uniformMatrix4fv(mProjLocation, gl.FALSE, projMatrix); //must be FALSE, var xRotateMat4= new Float32Array(16); var yRotateMat4= new Float32Array(16); //rotation 메트릭스. var identityMatrix = new Float32Array(16); glMatrix.mat4.identity(identityMatrix); var loop = function(){ //회전을 월드 메트릭스에 적용. var angle = performance.now() / 1000/ 6 * 2 * Math.PI; //12초동안 한바퀴 회전 glMatrix.mat4.rotate(yRotateMat4,identityMatrix, angle, [0,1,0]); //y축 glMatrix.mat4.rotate(xRotateMat4,identityMatrix, angle/4, [1,0,0]); //x축 glMatrix.mat4.mul(worldMatrix,xRotateMat4,yRotateMat4); gl.uniformMatrix4fv(mWorldLocation, gl.FALSE, worldMatrix); gl.clearColor(0.75, 0.85, 0.8, 1.0); gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); //$$$ 텍스쳐 gl.bindTexture(gl.TEXTURE_2D, boxTexture); gl.activeTexture(gl.TEXTURE0); //0,1 순서대로 들어간다. gl.drawElements(gl.TRIANGLES, boxIndices.length, gl.UNSIGNED_SHORT, 0); //처음엔 없어서 에러.. // gl.drawArrays(gl.TRIANGLES, 0, 3); //처음엔 없어서 에러.. requestAnimationFrame(loop); } requestAnimationFrame(loop); }