class deviceData { constructor(lx, ly, lz, gsx, gsy, gsz, oh, op, or){ this.lx = lx; this.ly = ly; this.lz = lz; this.gsx = gsx; // (gyro_speed_x) <- angular velocity this.gsy = gsy; this.gsz = gsz; this.oh = oh; this.op = op; this.or = or; this.px = 0.0; this.py = 0.0; this.pz = 0.0; this.ox = 0.0; this.oy = 0.0; this.oz = 0.0; } setBaseData(lx, ly, lz, gsx, gsy, gsz, oh, op, or){ this.lx = lx; this.ly = ly; this.lz = lz; this.gsx = gsx; this.gsy = gsy; this.gsz = gsz; this.oh = oh; this.op = op; this.or = or; } setOH(oh){ this.oh = oh; } setOP(op){ this.op = op; } setOR(or){ this.or = or; } setPosX(px){ this.px = px; } setPosY(py){ this.py = py; } setPosZ(pz){ this.pz = pz; } setOriX(ox){ this.ox = ox; } setOriY(oy){ this.oy = oy; } setOriZ(oz){ this.oz = oz; } reset(){ this.px = 0; this.py = 0; this.pz = 0; this.ox = 0; this.oy = 0; this.oz = 0; } getLX() { return this.lx; } getLY() { return this.ly; } getLZ() { return this.lz; } getGSX() { return this.gsx; } getGSY() { return this.gsy; } getGSZ() { return this.gsz; } getOH() { return this.oh; } getOP() { return this.op; } getOR() { return this.or; } getOH() { return this.oh; } getPX() { return this.px; } getPY() { return this.py; } getPZ() { return this.pz; } getOX() { return this.ox; } getOY() { return this.oy; } getOZ() { return this.oz; } max() { var m = -1; if (Math.abs(this.gsx) > Math.abs(this.gsy)) m = 0; else m = 1; if (Math.abs(this.gsz) > Math.abs(this.gsx) && Math.abs(this.gsz) > Math.abs(this.gsy)) m = 2; return m; } moveCheck() { if (this.gsx > 25 || this.gsx < -20 || this.gsy > 25 || this.gsy < -20 || this.gsz > 25 || this.gsz < -20){ return true; } return false; } } var mode = -1; function modeLock() { if (mode < 0){ mode = 100; return true; } return false } function modeRelese(){ mode = -1; } var time = [Date.now(), Date.now()]; var time_diff = 0; var stopTime = Date.now(); var lTime = 0; var rTime = 0; var dL = new deviceData(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0); var dR = new deviceData(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0); var dD = new deviceData(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0); var speedL = 0.0; var positionL = 0.0; var speedR = 0.0; var positionR = 0.0; var orienL = 0.0; var orienR = 0.0; function initLROri() { orienL = 0; orienR = 0; } var angleX = 0; var angleY = 0; var angleZ = 0; var preOXL = 0; var preOYL = 0; var preOZL = 0; var preOXR = 0; var preOYR = 0; var preOZR = 0; var transV = [0.0, 0.0, 0.0]; function reset() { dL.reset(); dR.reset(); dD.reset(); orienL = 0; orienR = 0; angleX = 0; angleY = 0; angleZ = 0; preOXL = 0; preOYL = 0; preOZL = 0; preOXR = 0; preOYR = 0; preOZR = 0; } /*------------------------------input data----------------------------*/ var firstDevice; var secondDevice; // var serviceS; // var myCharacteristic; var started = false; function leftScanning(){ console.log("starting left scan") navigator.bluetooth.requestDevice({ filters: [{ services: ['0000c001-0000-1000-8000-00805f9b34fb'] }] }) .then(device => { firstDevice = device; console.log(device) return device.gatt.connect() }) .then(server=>{ console.log("passing service uuid") return server.getPrimaryService("0000c001-0000-1000-8000-00805f9b34fb"); }) .then(service=>{ console.log("passing service characteristics uuid") return service.getCharacteristic("d7b83c07-eae9-469c-ba5c-12db92c7cfa2"); }) .then(characteristic=>{ console.log("subscribing"); characteristic.startNotifications().then(_ => { console.log('> Notifications started'); characteristic.addEventListener('characteristicvaluechanged', handleLeftNotifications); started = true; }); }) .catch(error => { console.error(error.message); }); }; function rightScanning(){ console.log("starting right scan") navigator.bluetooth.requestDevice({ filters: [{ services: ['0000c001-0000-1000-8000-00805f9b34fb'] }] }) .then(device => { secondDevice = device; console.log(device) return device.gatt.connect() }) .then(server=>{ console.log("passing service uuid") return server.getPrimaryService("0000c001-0000-1000-8000-00805f9b34fb"); }) .then(service=>{ console.log("passing service characteristics uuid") return service.getCharacteristic("d7b83c07-eae9-469c-ba5c-12db92c7cfa2"); }) .then(characteristic=>{ console.log("subscribing"); characteristic.startNotifications().then(_ => { console.log('> Notifications started'); characteristic.addEventListener('characteristicvaluechanged', handleRightNotifications); started = true; }); }) .catch(error => { console.error(error.message); }); }; function fromTwosComplement(twosComplement, numberBytes) { var numberBits = (numberBytes || 1) * 8; if (twosComplement < 0 || twosComplement > (1 << numberBits) - 1) throw "Two's complement out of range given " + numberBytes + " byte(s) to represent."; // If less than the maximum positive: 2^(n-1)-1, the number stays positive if (twosComplement <= Math.pow(2, numberBits - 1) - 1) return twosComplement; // Else convert to it's negative representation return -(((~twosComplement) & ((1 << numberBits) - 1)) + 1); } function handleLeftNotifications(e) { //handle data here let dataView = new Uint8Array(e.target.value.buffer) var pHeading = (dataView[12]<<8) + dataView[13] var pPitch = (dataView[14]<<8) + dataView[15] var pRoll = (dataView[16]<<8) + dataView[17] //pPitch = 65200; if(pPitch != null && pRoll != null){ pPitch = fromTwosComplement(pPitch,2); pRoll = fromTwosComplement(pRoll,2); // heading = pPitch > 16383 ? pHeading * 0.011 : 360-(pHeading * 0.011) } else { pHeading = 0; pPitch = 0; pRoll = 0; } dL.setBaseData( fromTwosComplement((dataView[2]<<8) + dataView[3],2)*0.000244, fromTwosComplement((dataView[0]<<8) + dataView[1],2)*0.000244, fromTwosComplement((dataView[4]<<8) + dataView[5],2)*0.000244, fromTwosComplement((dataView[10]<<8) + dataView[11],2)*0.061037, fromTwosComplement((dataView[6]<<8) + dataView[7],2)*0.061037, fromTwosComplement((dataView[8]<<8) + dataView[9],2)*0.061037, pHeading * 0.011, pPitch * 0.011, pRoll * 0.011); } function handleRightNotifications(e) { //handle data here let dataView = new Uint8Array(e.target.value.buffer) var pHeading = (dataView[12]<<8) + dataView[13] var pPitch = (dataView[14]<<8) + dataView[15] var pRoll = (dataView[16]<<8) + dataView[17] //pPitch = 65200; if(pPitch != null && pRoll != null){ pPitch = fromTwosComplement(pPitch,2); pRoll = fromTwosComplement(pRoll,2); // heading = pPitch > 16383 ? pHeading * 0.011 : 360-(pHeading * 0.011) } else { pHeading = 0; pPitch = 0; pRoll = 0; } dR.setBaseData( fromTwosComplement((dataView[2]<<8) + dataView[3],2)*0.000244148075808, fromTwosComplement((dataView[0]<<8) + dataView[1],2)*0.000244148075808, fromTwosComplement((dataView[4]<<8) + dataView[5],2)*0.000244148075808, fromTwosComplement((dataView[10]<<8) + dataView[11],2)*0.061037018951994, fromTwosComplement((dataView[6]<<8) + dataView[7],2)*0.061037018951994, fromTwosComplement((dataView[8]<<8) + dataView[9],2)*0.061037018951994, pHeading * 0.011, pPitch * 0.011, pRoll * 0.011); } /*------------------------------data control function--------------------*/ function sleep(ms) { const wakeUpTime = Date.now() + ms; while (Date.now() < wakeUpTime) { if (Date.now() > wakeUpTime) break; } } function modeOneHandCheck(){ if (dL.moveCheck() && !dR.moveCheck()){ if (lTime == 0){ lTime = Date.now(); } else { var timeNow = Date.now(); var ldiff = timeNow - stopTime; if (ldiff > 200) { var LM = dL.max(); if (LM == 0) mode = modeLock() ? 3 : -1; else if (LM == 1) mode = modeLock() ? 4 : -1; else mode = modeLock() ? 5 : -1; lTime = 0; } } } else if (!dL.moveCheck() && dR.moveCheck()){ if (rTime == 0){ rTime = Date.now(); } else { var timeNow = Date.now(); var rdiff = timeNow - rTime; if (rdiff > 200) { var RM = dR.max(); if (RM == 0) mode = modeLock() ? 3 : -1; else if (RM == 1) mode = modeLock() ? 4 : -1; else mode = modeLock() ? 5 : -1; rTime = 0; } } } } function modeReleseCheck(){ if(!dL.moveCheck() && !dR.moveCheck()) { if (stopTime == 0){ stopTime = Date.now(); } else { var timeNow = Date.now(); var diff = timeNow - stopTime; if (diff > 2000) { modeRelese(); console.log(mode); stopTime = 0; } } } } function modeCheck() { if (mode == -1) { if (dL.moveCheck() && dR.moveCheck()) { var LM = dL.max(); var RM = dR.max(); if (LM == RM){ if (LM == 0){ if ((dL.getGSX() > 20 && dR.getGSX() > 20) || (dL.getGSX() < -10 && dR.getGSX() < -10)) mode = modeLock() ? 0 : -1; else if ((dL.getGSX() > 20 && dR.getGSX() < -10) || (dL.getGSX() < -10 && dR.getGSX() > 20)) mode = modeLock() ? 6 : -1; } else if (LM == 1){ if ((dL.getGSY() > 20 && dR.getGSY() > 20) || (dL.getGSY() < -10 && dR.getGSY() < -10)) mode = modeLock() ? 1 : -1; else if ((dL.getGSY() > 20 && dR.getGSY() < -10) || (dL.getGSY() < -10 && dR.getGSY() > 20)) mode = modeLock() ? 7 : -1; } else{ if ((dL.getGSZ() > 20 && dR.getGSZ() > 20) || (dL.getGSZ() < -10 && dR.getGSZ() < -10)) mode = modeLock() ? 8 : -1; else if ((dL.getGSZ() > 20 && dR.getGSZ() < -10) || (dL.getGSZ() < -10 && dR.getGSZ() > 20)) mode = modeLock() ? 2 : -1; } } } else { modeOneHandCheck(); } if (mode > -1) console.log(mode); } else { modeReleseCheck(); } } function recodeSpX() { if ((dL.getGSX() > 15 || dL.getGSX() < -10) && (dR.getGSX() > 15 || dR.getGSX() < -10)) { orienL = dL.getGSX()*time_diff*0.1; orienR = dR.getGSX()*time_diff*0.1; if (mode == 0) { // x trans dD.setPosX( dD.getPX() + (orienL + orienR) / 2 ); dD.setPosX( dD.getPX() > 5 ? 5 : dD.getPX() ); dD.setPosX( dD.getPX() < -5 ? -5 : dD.getPX() ); } else { // x scale if (orienL > 0 && orienR < 0) { dL.setPosX( dL.getPX() + orienL ); dR.setPosX( dR.getPX() + orienR ); } else if (dL.getPX() - dR.getPX() > 0) { dL.setPosX( dL.getPX() + orienL ); dR.setPosX( dR.getPX() + orienR ); } dL.setPosX( dL.getPX() > 5 ? 5 : dL.getPX() ); dL.setPosX( dL.getPX() < -5 ? -5 : dL.getPX() ); dR.setPosX( dR.getPX() > 5 ? 5 : dR.getPX() ); dR.setPosX( dR.getPX() < -5 ? -5 : dR.getPX() ); } } } function recodeSpY() { if ((dL.getGSY() > 15 || dL.getGSY() < -10) && (dR.getGSY() > 15 || dR.getGSY() < -10)) { orienL = dL.getGSY()*time_diff*0.1; orienR = dR.getGSY()*time_diff*0.1; if (mode == 1) { // y trans dD.setPosY( dD.getPY() + (orienL + orienR) / 2 ); dD.setPosY( dD.getPY() > 2 ? 2 : dD.getPY() ); dD.setPosY( dD.getPY() < -2 ? -2 : dD.getPY() ); } else { // y scale if (orienL < 0 && orienR > 0) { dL.setPosY( dL.getPY() + orienL ); dR.setPosY( dR.getPY() + orienR ); } else if (-dL.getPY() + dR.getPY() > 0) { dL.setPosY( dL.getPY() + orienL ); dR.setPosY( dR.getPY() + orienR ); } dL.setPosY( dL.getPY() > 2 ? 2 : dL.getPY() ); dL.setPosY( dL.getPY() < -2 ? -2 : dL.getPY() ); dR.setPosY( dR.getPY() > 2 ? 2 : dR.getPY() ); dR.setPosY( dR.getPY() < -2 ? -2 : dR.getPY() ); } } } function recodeSpZ() { if ((dL.getGSZ() > 15 || dL.getGSZ() < -10) && (dR.getGSZ() > 15 || dR.getGSZ() < -10)) { orienL = dL.getGSZ()*time_diff*0.1; orienR = dR.getGSZ()*time_diff*0.1; if (mode == 2) { // Z trans dD.setPosZ( dD.getPZ() + (-orienL + orienR) / 2 ); dD.setPosZ( dD.getPZ() > 7 ? 7 : dD.getPZ() ); dD.setPosZ( dD.getPZ() < -2 ? -2 : dD.getPZ() ); } else { // Z scale if (orienL < 0 && orienR < 0) { dL.setPosZ( dL.getPZ() + orienL ); dR.setPosZ( dR.getPZ() + orienR ); } else if (-dL.getPZ() - dR.getPZ() > 0) { dL.setPosZ( dL.getPZ() + orienL ); dR.setPosZ( dR.getPZ() + orienR ); } dL.setPosZ( dL.getPZ() > 5 ? 5 : dL.getPZ() ); dL.setPosZ( dL.getPZ() < -5 ? -5 : dL.getPZ() ); dR.setPosZ( dR.getPZ() > 5 ? 5 : dR.getPZ() ); dR.setPosZ( dR.getPZ() < -5 ? -5 : dR.getPZ() ); } } } function recodeOX() { if ((dL.getGSX() > 15 || dL.getGSX() < -10) && (dR.getGSX() > 15 || dR.getGSX() < -10)) { var ori_diff_l = dL.getOX() - preOXL; var ori_diff_r = dR.getOX() - preOXR; ori_diff_l = ori_diff_l > 100 ? 0 : ori_diff_l; ori_diff_l = ori_diff_l < -100 ? 0 : ori_diff_l; ori_diff_r = ori_diff_r > 100 ? 0 : ori_diff_r; ori_diff_r = ori_diff_r < -100 ? 0 : ori_diff_r; orienL = (dL.getGSX()*time_diff - ori_diff_l) / 2; orienR = (dR.getGSX()*time_diff - ori_diff_r) / 2; angleX = angleX + (orienL + orienR) / 2; dD.setOriX(angleX%360); } } function recodeOY() { if ((dL.getGSY() > 15 || dL.getGSY() < -10) && (dR.getGSY() > 15 || dR.getGSY() < -10)) { var ori_diff_l = dL.getOY() - preOYL; var ori_diff_r = dR.getOY() - preOYR; ori_diff_l = ori_diff_l > 100 ? 0 : ori_diff_l; ori_diff_l = ori_diff_l < -100 ? 0 : ori_diff_l; ori_diff_r = ori_diff_r > 100 ? 0 : ori_diff_r; ori_diff_r = ori_diff_r < -100 ? 0 : ori_diff_r; orienL = (dL.getGSY()*time_diff - ori_diff_l) / 2; orienR = (dR.getGSY()*time_diff - ori_diff_r) / 2; angleY = angleY + (-orienL+orienR)/2; dD.setOriY(angleY%360); } } function recodeOZ() { if ((dL.getGSZ() > 15 || dL.getGSZ() < -10) && (dR.getGSZ() > 15 || dR.getGSZ() < -10)) { var ori_diff_l = dL.getOZ() - preOZL; var ori_diff_r = dR.getOZ() - preOZR; ori_diff_l = ori_diff_l > 100 ? 0 : ori_diff_l; ori_diff_l = ori_diff_l < -100 ? 0 : ori_diff_l; ori_diff_r = ori_diff_r > 100 ? 0 : ori_diff_r; ori_diff_r = ori_diff_r < -100 ? 0 : ori_diff_r; orienL = (dL.getGSZ()*time_diff - ori_diff_l) / 2; orienR = (dR.getGSZ()*time_diff - ori_diff_r) / 2; angleZ = angleZ + (-orienL+orienR)/2; dD.setOriZ(angleZ%360); } } function preOrien() { preOXL = dL.getOX(); preOYL = dL.getOY(); preOZL = dL.getOZ(); preOXR = dR.getOX(); preOYR = dR.getOY(); preOZR = dR.getOZ(); } function controlLOH() { if (dL.getOP() < 130 && dL.getOP() > -130) dL.setOriX(dL.getOH()); } function controlLOP() { dL.setOriY(dL.getOP()); } function controlLOR() { if (dL.getOP() < 135 && dL.getOP() > -135){ dL.setOriZ(dL.getOR()); } } function controlROH() { if (dR.getOP() < 130 && dR.getOP() > -130) dR.setOriX(dR.getOH()); } function controlROP() { dR.setOriY(dR.getOP()); } function controlROR() { if (dR.getOP() < 135 && dR.getOP() > -135){ dR.setOriZ(dR.getOR()); } } /*--------------------------------translation Matrix-----------------------*/ function scaleLinear(M){ scaleV=[1+Math.abs(dL.getPX() - dR.getPX()), 1+Math.abs(-dL.getPY() + dR.getPY()), 1+Math.abs(dL.getPZ() + dR.getPZ())]; glMatrix.mat4.scale(M, M, scaleV); return M; } function rotateOri(M) { var xaxis = [1.0, 0.0, 0.0]; // var yaxis = [0.0, 1.0, 0.0]; var zaxis = [0.0, 0.0, 1.0]; glMatrix.mat4.rotateY(M, M, dD.getOX()*0.0174444); //heading //3.14/180 glMatrix.vec3.transformMat4(xaxis, xaxis, M); glMatrix.mat4.rotate(M, M, dD.getOZ()*0.0174444, xaxis);//pitch glMatrix.vec3.transformMat4(zaxis, zaxis, M); glMatrix.mat4.rotate(M, M, dD.getOY()*0.0174444, zaxis);//roll return M; } function moveLinear(M){ transV = [dD.getPX(), dD.getPY(), dD.getPZ()] glMatrix.mat4.translate(M, M, transV); return M; } function matrixByMode(){ var M = [1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0]; M = moveLinear(M); M = rotateOri(M); M = scaleLinear(M); return M; } /*-----------------------------------Web gl code---------------------------*/ //code for cube var gl; //var texture; //var videoE; var image; var viewMatrixData = new Array(1400); var minutes = 1000 * 60; var hours = minutes * 60; var days = hours * 24; var years = days * 365; var d = new Date(); var t = d.getTime(); //밀리초 var yt = Math.round(t / years); function testGLError(functionLastCalled) { 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"); 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 vertexData = [ // Backface (RED/WHITE) -> z = 0.5 -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 (YELLOE/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 ]; var screenData = [ //screen data, texture plane -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0 ]; const textureCoordinates = [ // Front 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 0.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); gl.screenBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, gl.screenBuffer); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(screenData), gl.STATIC_DRAW); gl.textureBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, gl.textureBuffer); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(textureCoordinates), gl.STATIC_DRAW); return testGLError("initialiseBuffers"); } function initTexture() { const texture = gl.createTexture(); gl.bindTexture(gl.TEXTURE_2D, texture); var pixel = new Uint8Array([0, 0, 120, 255]); // opaque blue //gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, pixel); 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); return texture; } function updateTexture(texture) { const level = 0; gl.bindTexture(gl.TEXTURE_2D, texture); gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true); gl.texImage2D(gl.TEXTURE_2D, level, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE); } copyVideo = false; function initialiseShaders() { var fragmentShaderSource1 = '\ varying highp vec4 color; \ void main(void) \ { \ gl_FragColor = color;\ }'; gl.fragShader1 = gl.createShader(gl.FRAGMENT_SHADER); gl.shaderSource(gl.fragShader1, fragmentShaderSource1); gl.compileShader(gl.fragShader1); // Check if compilation succeeded if (!gl.getShaderParameter(gl.fragShader1, gl.COMPILE_STATUS)) { alert("Failed to compile the fragment shader1.\n" + gl.getShaderInfoLog(gl.fragShader1)); return false; } // Vertex shader code1 var vertexShaderSource1 = '\ attribute highp vec4 myVertex; \ attribute highp vec4 myColor; \ uniform mediump mat4 mMat; \ uniform mediump mat4 vMat; \ uniform mediump mat4 pMat; \ varying highp vec4 color;\ void main(void) \ { \ gl_Position = pMat * vMat * mMat * myVertex; \ gl_PointSize = 8.0; \ color = myColor; \ }'; gl.vertexShader1 = gl.createShader(gl.VERTEX_SHADER); gl.shaderSource(gl.vertexShader1, vertexShaderSource1); gl.compileShader(gl.vertexShader1); // Check if compilation succeeded if (!gl.getShaderParameter(gl.vertexShader1, gl.COMPILE_STATUS)) { alert("Failed to compile the vertex shader1.\n" + gl.getShaderInfoLog(gl.vertexShader1)); return false; } var fragmentShaderSource2 = '\ precision mediump float; \ varying vec2 vTexture; \ uniform sampler2D uSampler; \ void main(void) \ { \ gl_FragColor = texture2D(uSampler, vTexture); \ }'; gl.fragShader2 = gl.createShader(gl.FRAGMENT_SHADER); gl.shaderSource(gl.fragShader2, fragmentShaderSource2); gl.compileShader(gl.fragShader2); // Check if compilation succeeded if (!gl.getShaderParameter(gl.fragShader2, gl.COMPILE_STATUS)) { alert("Failed to compile the fragment shader2.\n" + gl.getShaderInfoLog(gl.fragShader2)); return false; } // Vertex shader code2 var vertexShaderSource2 = '\ attribute vec3 myVertex; \ attribute vec2 myTexture; \ uniform mediump mat4 mMat; \ uniform mediump mat4 vMat; \ uniform mediump mat4 pMat; \ varying vec2 vTexture; \ void main(void) \ { \ gl_Position = pMat * vMat * mMat * vec4(myVertex, 1.0); \ vTexture = myTexture; \ }'; gl.vertexShader2 = gl.createShader(gl.VERTEX_SHADER); gl.shaderSource(gl.vertexShader2, vertexShaderSource2); gl.compileShader(gl.vertexShader2); // Check if compilation succeeded if (!gl.getShaderParameter(gl.vertexShader2, gl.COMPILE_STATUS)) { alert("Failed to compile the vertex shader2.\n" + gl.getShaderInfoLog(gl.vertexShader2)); return false; } // Create the shader program gl.programObject1 = gl.createProgram(); // Attach the fragment and vertex shaders to it gl.attachShader(gl.programObject1, gl.fragShader1); gl.attachShader(gl.programObject1, gl.vertexShader1); // Bind the custom vertex attribute "myVertex" to location 0 gl.bindAttribLocation(gl.programObject1, 0, "myVertex"); gl.bindAttribLocation(gl.programObject1, 1, "myColor"); gl.programObject2 = gl.createProgram(); // Attach the fragment and vertex shaders to it gl.attachShader(gl.programObject2, gl.fragShader2); gl.attachShader(gl.programObject2, gl.vertexShader2); gl.bindAttribLocation(gl.programObject2, 2, "myVertex"); gl.bindAttribLocation(gl.programObject2, 3, "myTexture"); //gl.bindAttribLocation(gl.programObject, 2, "aTexture") // Link the program gl.linkProgram(gl.programObject1); // Check if linking succeeded in a similar way we checked for compilation errors if (!gl.getProgramParameter(gl.programObject1, gl.LINK_STATUS)) { alert("Failed to link the program1.\n" + gl.getProgramInfoLog(gl.programObject1)); return false; } gl.linkProgram(gl.programObject2); // Check if linking succeeded in a similar way we checked for compilation errors if (!gl.getProgramParameter(gl.programObject2, gl.LINK_STATUS)) { alert("Failed to link the program2.\n" + gl.getProgramInfoLog(gl.programObject2)); return false; } gl.useProgram(gl.programObject1); gl.useProgram(gl.programObject2); return testGLError("initialiseShaders"); } var tMs = [1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ]; function drawTexture(texture){ //texture screen 그리기 gl.useProgram(gl.programObject2); var worldMatrix = new Float32Array(16); var viewMatrix = new Float32Array(16); var projMatrix = new Float32Array(16); glMatrix.mat4.identity(worldMatrix); glMatrix.mat4.identity(viewMatrix); var matWorldUniformLocation2 = gl.getUniformLocation(gl.programObject2, 'mMat'); var matViewUniformLocation2 = gl.getUniformLocation(gl.programObject2, 'vMat'); var matProjUniformLocation2 = gl.getUniformLocation(gl.programObject2, 'pMat'); //glMatrix.mat4.lookAt(viewMatrix, [0.0, 0.0, 5.0], [0.0, 0.0, 0.0], [0.0, 1.0, 0.0]); //viewMatrix가 카메라 glMatrix.mat4.ortho(projMatrix, -1, 1, -1, 1, 0, 1); gl.uniformMatrix4fv(matWorldUniformLocation2, gl.FALSE, worldMatrix); gl.uniformMatrix4fv(matViewUniformLocation2, gl.FALSE, viewMatrix); gl.uniformMatrix4fv(matProjUniformLocation2, gl.FALSE, projMatrix); if (!testGLError("gl.uniformMatrix4fv")) { return false; } gl.bindBuffer(gl.ARRAY_BUFFER, gl.screenBuffer); gl.enableVertexAttribArray(2); gl.vertexAttribPointer(2, 3, gl.FLOAT, gl.FALSE, 0, 0); gl.bindBuffer(gl.ARRAY_BUFFER, gl.textureBuffer); gl.enableVertexAttribArray(3); gl.vertexAttribPointer(3, 2, gl.FLOAT, gl.FALSE, 0, 0); //텍스쳐 적용 gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, texture); gl.uniform1i(gl.getUniformLocation(gl.programObject2, "uSampler"), 0); if (!testGLError("gl.vertexAttribPointer")) { return false; } //텍스쳐 스크린 그리는 드로 근데 바인드가 안됨 왜??? gl.drawArrays(gl.TRIANGLES, 0, 6); if (!testGLError("gl.drawArrays")) { return false; } } var lookDistance = 5.0; function incDistance(){ lookDistance += 0.1; } function decDistance(){ lookDistance -= 0.1; } var frames = 0; function drawCube(){ gl.useProgram(gl.programObject1); var matWorldUniformLocation1 = gl.getUniformLocation(gl.programObject1, 'mMat'); var matViewUniformLocation1 = gl.getUniformLocation(gl.programObject1, 'vMat'); var matProjUniformLocation1 = gl.getUniformLocation(gl.programObject1, 'pMat'); var tMatrix = new Float32Array(16); glMatrix.mat4.identity(tMatrix); if (started) tMatrix = matrixByMode(); var worldMatrix = new Float32Array(16); var viewMatrix = new Float32Array(16); var projMatrix = new Float32Array(16); glMatrix.mat4.identity(worldMatrix); glMatrix.mat4.identity(projMatrix); glMatrix.mat4.lookAt(viewMatrix, [0.0, 0.0, -lookDistance], [0.0, 0.0, 0.0], [0.0, 1.0, 0.0]); //viewMatrix가 카메라 glMatrix.mat4.perspective(projMatrix, glMatrix.glMatrix.toRadian(55.2), 1600.0 / 900.0, 0.1, 15.0); // 0.1 가장 가까운것 1000.0가장 먼것 , projMatrix //시간 t = new Date().getTime(); t = (t - start)/10; t = Math.floor(t); //console.log(t); if(started){ //console.clear() //console.log(roll*57.32) } glMatrix.mat4.mul(worldMatrix, tMatrix, worldMatrix); //glMatrix.mat4.mul(viewMatrix, iMs, viewMatrix); //vM lookAT이후 gl.uniformMatrix4fv(matWorldUniformLocation1, gl.FALSE, worldMatrix); gl.uniformMatrix4fv(matViewUniformLocation1, gl.FALSE, viewMatrix); gl.uniformMatrix4fv(matProjUniformLocation1, gl.FALSE, projMatrix); if (!testGLError("gl.uniformMatrix4fv")) { return false; } // */ gl.bindBuffer(gl.ARRAY_BUFFER, gl.vertexBuffer); gl.enableVertexAttribArray(0); gl.vertexAttribPointer( 0, // Attribute location 3, // Number of elements per attribute gl.FLOAT, // Type of elements gl.FALSE, 28, 0 // Offset from the beginning of a single vertex to this attribute ); 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); if (!testGLError("gl.drawArrays")) { return false; } } function renderScene(texture) { gl.clearColor(0.0, 0.0, 0.0, 1.0); gl.clearDepth(1.0); gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); gl.disable(gl.DEPTH_TEST); drawTexture(texture); gl.enable(gl.DEPTH_TEST); time[0] = time[1]; time[1] = Date.now(); time_diff = (time[1]-time[0])*0.001; //second modeCheck(); if (mode == -1){ initLROri(); i = 0; } else if (mode == 0) recodeSpX(); else if (mode == 1) recodeSpY(); else if (mode == 2) recodeSpZ(); else if (mode == 3) { controlLOH(); controlROH(); recodeOX(); } else if (mode == 4){ controlLOP(); controlROP(); recodeOY(); } else if (mode == 5) { controlLOR(); controlROR(); recodeOZ(); } else if (mode == 6) recodeSpX(); else if (mode == 7) recodeSpY(); else if (mode == 8) recodeSpZ(); drawCube(); preOrien(); return true; } pA = [0, 1, 0]; tA = [1, 0, 0]; rA = [0, 0, 1]; function degreeToRadian(deg){ var crad = glMatrix.glMatrix.toRadian(deg * 360 / 32767); return crad; } /* ----------------------mouse event function-------------------*/ var dragging = false; var rightclick_count = 0; var dblclick_count = 0; function doDoubleClick(evt){ if (modeLock()){ modeRelese(); reset(); } } /*------------------------------main function------------------------*/ var start; function main() { const canvas = document.querySelector('#helloapicanvas'); this.addEventListener("dblclick", doDoubleClick, false); if (!initialiseGL(canvas)) { return; } if (!initialiseBuffer()) { return; } //attriblocation if (!initialiseShaders()) { return; } const texture = initTexture(); // Render loop requestAnimFrame = (function () { return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || function (callback) { window.setTimeout(callback, 100); }; })(); t = 0; var p = 0; (function renderLoop() { if(!p){ t = new Date().getTime(); start = t; p = 1; } if (renderScene(texture)) { // Everything was successful, request that we redraw our scene again in the future requestAnimFrame(renderLoop); } })(); }