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 runWebGLApp = function(){ loadJSONResource('/models/Susan.json', function(modelErr, modelObj){ if(modelErr){ alert('Fatal Error getting Model (see console)'); console.error(modelErr); }else{ WebGLRenderApp(modelObj, '/models/SusanTexture.png'); } }); }; var gl; var program; var canvas; function WebGLRenderApp(modelObj,imgSource) { 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 modelVertices = modelObj.meshes[0].vertices; var modelIndices = [].concat.apply([], modelObj.meshes[0].faces); //[[0,2,1],[0,2,3]] 이런식이라.. var modelTexCoords = modelObj.meshes[0].texturecoords[0]; //===================== // pos버퍼 var modelPosBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, modelPosBuffer); //gl에 버퍼를 바인딩 gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(modelVertices), gl.STATIC_DRAW); //버퍼에 버텍스 연결. // gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(triagleVertex), gl.STATIC_DRAW); //버퍼에 버텍스 연결. //texture 버퍼 var modelTextureBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, modelTextureBuffer); //gl에 버퍼를 바인딩 gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(modelTexCoords), gl.STATIC_DRAW); //버퍼에 버텍스 연결. //index버퍼 (나중에 그릴때 사용.) var modelIndexBuffer = gl.createBuffer(); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, modelIndexBuffer); //gl에 버퍼를 바인딩 gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(modelIndices), gl.STATIC_DRAW); //버퍼에 버텍스 연결. gl.bindBuffer(gl.ARRAY_BUFFER, modelPosBuffer); //gl에 버퍼를 바인딩 var positionLocation = gl.getAttribLocation(program,'vertPosition'); gl.vertexAttribPointer(positionLocation, 3, //Number of elements per attribute gl.FLOAT, //type of elements gl.FALSE, 3 * 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.enableVertexAttribArray(positionLocation); gl.bindBuffer(gl.ARRAY_BUFFER, modelTextureBuffer); //gl에 버퍼를 바인딩 var texCoordAttribLocation = gl.getAttribLocation(program,'vertTexCoord'); //$$택스쳐 gl.vertexAttribPointer(texCoordAttribLocation, 2, //Number of elements per attribute //$$택스쳐 gl.FLOAT, //type of elements gl.FALSE, 2 * 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.enableVertexAttribArray(texCoordAttribLocation); //==================================== //$$$ 텍스쳐 // https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/texParameter //create Texture // 1. vertexBuffers carousel1.png var modelTexture = gl.createTexture(); // 이미지 로드 var image = new Image(); image.onload = function(){ console.log("image onload"); gl.bindTexture(gl.TEXTURE_2D, modelTexture); gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL,true); //webgl은 택스쳐 멥핑의 y가 역방향입니다. 이거로보정. 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 = imgSource; //============================== //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, modelTexture); gl.activeTexture(gl.TEXTURE0); //0,1 순서대로 들어간다. gl.drawElements(gl.TRIANGLES, modelIndices.length, gl.UNSIGNED_SHORT, 0); //처음엔 없어서 에러.. // gl.drawArrays(gl.TRIANGLES, 0, 3); //처음엔 없어서 에러.. requestAnimationFrame(loop); } requestAnimationFrame(loop); }