diff options
Diffstat (limited to 'xp/cgxp')
-rw-r--r-- | xp/cgxp/1.html | 14 | ||||
-rw-r--r-- | xp/cgxp/2.html | 14 | ||||
-rw-r--r-- | xp/cgxp/main1.js | 320 | ||||
-rw-r--r-- | xp/cgxp/main2.js | 280 | ||||
-rw-r--r-- | xp/cgxp/wglmath.js | 102 |
5 files changed, 730 insertions, 0 deletions
diff --git a/xp/cgxp/1.html b/xp/cgxp/1.html new file mode 100644 index 0000000..b05e78f --- /dev/null +++ b/xp/cgxp/1.html @@ -0,0 +1,14 @@ +<!DOCTYPE html> +<html> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> +<title>CGxp1</title> +<link rel="icon" href="/favicon.png"> +<link rel="stylesheet" type="text/css" href="/common.css"> +<script type="text/javascript" src="main1.js"></script> +<script type="text/javascript" src="wglmath.js"></script> +</head> +<body onload="init();" style="margin:0;"> +<canvas id="glCvs" width="800" height="450" style=""></canvas> +</body> +</html> diff --git a/xp/cgxp/2.html b/xp/cgxp/2.html new file mode 100644 index 0000000..880c0cb --- /dev/null +++ b/xp/cgxp/2.html @@ -0,0 +1,14 @@ +<!DOCTYPE html> +<html> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> +<title>CGxp2</title> +<link rel="icon" href="/favicon.png"> +<link rel="stylesheet" type="text/css" href="/common.css"> +<script type="text/javascript" src="main2.js"></script> +<script type="text/javascript" src="wglmath.js"></script> +</head> +<body onload="init();" style="margin:0;"> +<canvas id="glCvs" width="800" height="450" style=""></canvas> +</body> +</html> diff --git a/xp/cgxp/main1.js b/xp/cgxp/main1.js new file mode 100644 index 0000000..bd52e13 --- /dev/null +++ b/xp/cgxp/main1.js @@ -0,0 +1,320 @@ +//Copyright Chris Xiong 2018 +//License: Expat (MIT) +var cvs,WGL,vpw,vph,hdiv; +var fsh=` +varying lowp vec4 vC; +void main(void) +{ + gl_FragColor=vC; +}`; +var vsh=` +attribute vec3 vp; +attribute vec4 vc; +uniform mat4 mmodelview; +uniform mat4 mprojection; +varying lowp vec4 vC; +void main(void) +{ + gl_Position=mprojection*mmodelview*vec4(vp,1.); + vC=vc; +}`; +var shp; +var vbufsize=4096; +var vbo,ibo; +var vb=new Float32Array(vbufsize*7); +var ib=new Uint16Array(vbufsize*6/4); +var Mprojection,Mmodelview; +var primc; +var kst=[]; +var dbc,mbtn,mup,mdn,mx,my,mox,moy; +var shapes=[]; +var curshape=null; +var dragging=false,drg; + +var Shape=function(t) +{ + this.type=t; + this.vert=[]; +} +function copyshape(s) +{ + var r=new Shape(s.type); + for(var i=0;i<s.vert.length;++i) + r.vert.push(new v3d(s.vert[i].x,s.vert[i].y,s.vert[i].z)); + return r; +} +Shape.prototype.draw=function(a,r,g,b) +{ + var drawseg=function(a,b,c,d,aa,rr,gg,bb) + { + var pa=new v3d(a,b,0); + var pb=new v3d(c,d,0); + var d=pb.subtract(pa); + var pd1=new v3d(-d.y,d.x,0),pd2=new v3d(d.y,-d.x,0); + pd1=pd1.n();pd2=pd2.n(); + var p1=pa.add(pd1),p2=pa.add(pd2); + var p3=pb.add(pd2),p4=pb.add(pd1); + var q=[]; + q.push(p1.x);q.push(vph-p1.y);q.push(p1.z); + q.push(rr);q.push(gg);q.push(bb);q.push(aa); + q.push(p2.x);q.push(vph-p2.y);q.push(p2.z); + q.push(rr);q.push(gg);q.push(bb);q.push(aa); + q.push(p3.x);q.push(vph-p3.y);q.push(p3.z); + q.push(rr);q.push(gg);q.push(bb);q.push(aa); + q.push(p4.x);q.push(vph-p4.y);q.push(p4.z); + q.push(rr);q.push(gg);q.push(bb);q.push(aa); + pushQuad(q); + } + if(this.type=='segment') + drawseg(this.vert[0].x,this.vert[0].y,this.vert[1].x,this.vert[1].y, + a,r,g,b); + if(this.type=='segstrip'||this.type=='segloop') + { + for(var i=0;i<this.vert.length-1;++i) + drawseg(this.vert[i].x,this.vert[i].y,this.vert[i+1].x,this.vert[i+1].y, + a,r,g,b); + if(this.type=='segloop') + { + var i=this.vert.length-1; + drawseg(this.vert[i].x,this.vert[i].y,this.vert[0].x,this.vert[0].y, + a,r,g,b); + } + } +} +Shape.prototype.coltest=function(x,y) +{ + var dp2s=function(x,y,_a,_b,_c,_d) + { + var a=new v3d(_a,_b,0); + var b=new v3d(_c,_d,0); + var p=new v3d(x,y,0); + var ab=b.subtract(a); + var ap=p.subtract(a); + var pl=ab.dot(ap)/ab.l(); + var pp=a.add(ab.n().ms(pl)); + if(pl<0||pl>ab.l())pp=new v3d(1e9,1e9,1e9); + return Math.min(p.subtract(pp).l(),p.subtract(a).l(),p.subtract(b).l()); + } + if(this.type=='segment') + { + var d=dp2s(x,y,this.vert[0].x,this.vert[0].y, + this.vert[1].x,this.vert[1].y); + if(d<5)return true; + } + if(this.type=='segstrip'||this.type=="segloop") + { + for(var i=0;i<this.vert.length-1;++i) + { + var d=dp2s(x,y,this.vert[i].x,this.vert[i].y, + this.vert[i+1].x,this.vert[i+1].y); + if(d<5)return true; + } + if(this.type=="segloop") + { + var i=this.vert.length-1; + var d=dp2s(x,y,this.vert[i].x,this.vert[i].y, + this.vert[0].x,this.vert[0].y); + if(d<5)return true; + } + } + return false; +} + +function createShader(sh,t) +{ + var shader=WGL.createShader(t); + WGL.shaderSource(shader,sh); + WGL.compileShader(shader); + if(!WGL.getShaderParameter(shader,WGL.COMPILE_STATUS)) + { + alert("shader error..."+WGL.getShaderInfoLog(shader)); + return null; + } + return shader; +} +function pushQuad(a) +{ + if(primc>=vbufsize/4)batchGL(); + for(var i=0;i<4;++i) + for(var j=0;j<7;++j)vb[primc*7*4+i*7+j]=a[i*7+j]; + ++primc; +} + +function init() +{ + cvs=document.getElementById("glCvs"); + if(!window.devicePixelRatio)window.devicePixelRatio=1; + cvs.width=window.innerWidth; + cvs.height=window.innerHeight; + cvs.style.width=cvs.width+"px"; + cvs.style.height=cvs.height+"px"; + cvs.width=cvs.width*window.devicePixelRatio; + cvs.height=cvs.height*window.devicePixelRatio; + vpw=cvs.width;vph=cvs.height; + try + {WGL=cvs.getContext("webgl")||cvs.getContext("experimental-webgl");} + catch(e){WGL=null;} + if(!WGL){alert("WebGL is not supported by your browser...");return;} + + WGL.clearColor(0.5,0.5,0.5,1.0); + WGL.clearDepth(1); + WGL.enable(WGL.DEPTH_TEST); + WGL.depthFunc(WGL.LESS); + WGL.enable(WGL.BLEND); + WGL.blendFunc(WGL.SRC_ALPHA,WGL.ONE_MINUS_SRC_ALPHA); + WGL.clear(WGL.COLOR_BUFFER_BIT|WGL.DEPTH_BUFFER_BIT); + WGL.viewport(0,0,cvs.width,cvs.height); + + shp=WGL.createProgram(); + var fshs=createShader(fsh,WGL.FRAGMENT_SHADER); + var vshs=createShader(vsh,WGL.VERTEX_SHADER); + WGL.attachShader(shp,vshs);WGL.attachShader(shp,fshs); + WGL.linkProgram(shp); + if(!WGL.getProgramParameter(shp,WGL.LINK_STATUS)) + { + alert("shader link error..."); + } + WGL.useProgram(shp); + + vbo=WGL.createBuffer(); + WGL.bindBuffer(WGL.ARRAY_BUFFER,vbo); + WGL.bufferData(WGL.ARRAY_BUFFER,vb,WGL.STATIC_DRAW); + var vpp=WGL.getAttribLocation(shp,"vp"); + var vcp=WGL.getAttribLocation(shp,"vc"); + WGL.enableVertexAttribArray(vpp); + WGL.enableVertexAttribArray(vcp); + WGL.bindBuffer(WGL.ARRAY_BUFFER,vbo); + WGL.vertexAttribPointer(vpp,3,WGL.FLOAT,false,7*4,0); + WGL.vertexAttribPointer(vcp,4,WGL.FLOAT,false,7*4,3*4); + + for(var i=0,n=0,p=0;i<vbufsize/4;++i) + { + ib[p++]=n;ib[p++]=n+1; + ib[p++]=n+2;ib[p++]=n+2; + ib[p++]=n+3;ib[p++]=n; + n+=4; + } + ibo=WGL.createBuffer(); + WGL.bindBuffer(WGL.ELEMENT_ARRAY_BUFFER,ibo); + WGL.bufferData(WGL.ELEMENT_ARRAY_BUFFER,ib,WGL.STATIC_DRAW); + + document.addEventListener('keydown',function(e){kst[e.code]=1;}); + document.addEventListener('keyup',function(e){kst[e.code]=0;}); + document.addEventListener('mousedown',function(e){mdn=true;mbtn=e.button;}); + document.addEventListener('contextmenu',function(e){e.preventDefault();}); + document.addEventListener('mouseup',function(e){mup=true;}); + document.addEventListener('dblclick',function(e){dbc=true;}); + document.addEventListener('mousemove',function(e) + {mx=e.clientX/window.innerWidth*vpw;my=e.clientY/window.innerHeight*vph;}); + + requestAnimationFrame(mainloop); +} +function getpick() +{ + for(var i=0;i<shapes.length;++i) + if(shapes[i].coltest(mx,my))return i; + return -1; +} + +function mainloop() +{ + WGL.clearColor(0.5,0.5,0.5,1.0); + WGL.clearDepth(1); + WGL.clear(WGL.COLOR_BUFFER_BIT|WGL.DEPTH_BUFFER_BIT); + primc=0; + Mmodelview=buildIdentityMatrix(); + var picked=getpick(); + + //interaction shit + if(dragging) + { + if(mup) + {dragging=false;curshape=null;mdn=mup=false;} + if(!mdn&&mbtn==0&&dragging) + for(var i=0;i<shapes[drg].vert.length;++i) + shapes[drg].vert[i]=curshape.vert[i].add(new v3d(mx,my,0).subtract(new v3d(mox,moy,0))); + if(!mdn&&mbtn==2&&dragging) + { + var newscale=new v3d(mox,moy,0).subtract(new v3d(mx,my,0)).l()/20; + if(mx<mox||my<moy)newscale=-newscale; + if(newscale<-95)newscale=-95; + var sc=(100+newscale)/100.; + var mmx=curshape.vert[0].x,mmy=curshape.vert[0].y; + for(var i=1;i<curshape.vert.length;++i) + mmx=Math.min(mmx,curshape.vert[i].x), + mmy=Math.min(mmy,curshape.vert[i].y); + var c=new v3d(mmx,mmy,0); + for(var i=0;i<shapes[drg].vert.length;++i) + shapes[drg].vert[i]=curshape.vert[i].subtract(c).n().ms + (curshape.vert[i].subtract(c).l()*sc).add(c); + } + + } + if(dbc) + { + if(dragging) + {dragging=false;curshape=null;} + else + if(curshape) + { + if(kst['ControlLeft']==1&&curshape.type=='segstrip') + curshape.type='segloop'; + shapes.push(curshape); + curshape=null; + } + } + else + { + if(mup&&kst['ControlLeft']==1&&!curshape) + { + if(picked!=-1) + { + dragging=true; + mox=mx,moy=my;drg=picked; + curshape=copyshape(shapes[picked]); + } + } + if(mup&&!dragging&&!kst['ControlLeft']) + { + if(!curshape) + { + curshape=new Shape('segment'); + curshape.vert.push(new v3d(mx,my,0)); + curshape.vert.push(new v3d(mx,my,0)); + } + else + { + if(curshape.type=='segment')curshape.type='segstrip'; + curshape.vert.push(new v3d(mx,my,0)); + } + } + } + + if(curshape&&!dragging) + curshape.vert[curshape.vert.length-1]=new v3d(mx,my,0); + + for(var i=0;i<shapes.length;++i) + if(!curshape&&!dragging&&i==picked)shapes[i].draw(1,0.8,0,0); + else shapes[i].draw(1,0.8,0.8,0.8); + + if(curshape&&!dragging)curshape.draw(1,0.8,0.8,0); + + batchGL(); + + mup=mdn=dbc=false; + requestAnimationFrame(mainloop); +} + +function batchGL() +{ + Mprojection=buildProjectionMatrix2D(vpw,vph); + var mpp=WGL.getUniformLocation(shp,"mprojection"); + WGL.uniformMatrix4fv(mpp,false,Mprojection); + var mvpp=WGL.getUniformLocation(shp,"mmodelview"); + WGL.uniformMatrix4fv(mvpp,false,Mmodelview); + WGL.bindBuffer(WGL.ARRAY_BUFFER,vbo); + WGL.bufferData(WGL.ARRAY_BUFFER,vb,WGL.STATIC_DRAW); + WGL.drawElements(WGL.TRIANGLES,6*primc,WGL.UNSIGNED_SHORT,0); + primc=0; +} + diff --git a/xp/cgxp/main2.js b/xp/cgxp/main2.js new file mode 100644 index 0000000..05b1fdb --- /dev/null +++ b/xp/cgxp/main2.js @@ -0,0 +1,280 @@ +//Copyright Chris Xiong 2018 +//License: Expat (MIT) +var cvs,WGL,vpw,vph,hdiv; +var fsh=` +varying lowp vec4 vC; +void main(void) +{ + gl_FragColor=vC; +}`; +var vsh=` +attribute vec3 vp; +attribute vec4 vc; +uniform mat4 mmodelview; +uniform mat4 mprojection; +varying lowp vec4 vC; +void main(void) +{ + gl_Position=mprojection*mmodelview*vec4(vp,1.); + vC=vc; +}`; +var shp; +var vbufsize=4096; +var vbo,ibo; +var vb=new Float32Array(vbufsize*7); +var ib=new Uint16Array(vbufsize*6/4); +var Mprojection,Mmodelview; +var primc; +var kst=[]; +var pos=[15,4,30]; +var ofs=[0.9,3.5,20]; +var mzw=50,mzh=35,ppx,ppy,ex,ey; +var maz=[]; + +var Sphere=function() +{ + this.x=10-Math.random()*20; + this.y=10-Math.random()*20; + this.timer=0;this.r=0.2; +} +Sphere.prototype.update=function() +{ + var d=Math.sqrt((this.x-pp.x)*(this.x-pp.x)+(this.y-pp.y)*(this.y-pp.y)); + if(d<0.5&&this.timer===0)this.timer=1; + if(this.timer>0&&state===0) + { + ++this.timer;health+=0.01; + this.r+=0.02;if(health>1)health=1; + } + if(this.timer>25)this.timer=-1; +} +Sphere.prototype.draw=function(x,y,a) +{ + if(this.timer!==-1)pushSphere(x,y,0,this.r,[0,1,0,a*(0.6-this.timer*0.6/25)]); +} + +function createShader(sh,t) +{ + var shader=WGL.createShader(t); + WGL.shaderSource(shader,sh); + WGL.compileShader(shader); + if(!WGL.getShaderParameter(shader,WGL.COMPILE_STATUS)) + { + alert("shader error..."+WGL.getShaderInfoLog(shader)); + return null; + } + return shader; +} +function pushQuad(a) +{ + if(primc>=vbufsize/4)batchGL(); + for(var i=0;i<4;++i) + for(var j=0;j<7;++j)vb[primc*7*4+i*7+j]=a[i*7+j]; + ++primc; +} +function cube(x,y,z,l,r,g,b,a) +{ + var L=x-l/2,R=x+l/2; + var B=y-l/2,T=y+l/2; + var N=z-l/2,F=z+l/2; + pushQuad([ + L,B,N,r,g,b,a, + L,T,N,r,g,b,a, + R,T,N,r,g,b,a, + R,B,N,r,g,b,a + ]); + pushQuad([ + L,B,F,r,g,b,a, + L,T,F,r,g,b,a, + R,T,F,r,g,b,a, + R,B,F,r,g,b,a + ]); + pushQuad([ + L,B,N,r,g,b,a, + L,T,N,r,g,b,a, + L,T,F,r,g,b,a, + L,B,F,r,g,b,a + ]); + pushQuad([ + R,B,N,r,g,b,a, + R,T,N,r,g,b,a, + R,T,F,r,g,b,a, + R,B,F,r,g,b,a + ]); + pushQuad([ + L,B,N,r,g,b,a, + R,B,N,r,g,b,a, + R,B,F,r,g,b,a, + L,B,F,r,g,b,a + ]); + pushQuad([ + L,T,N,r,g,b,a, + R,T,N,r,g,b,a, + R,T,F,r,g,b,a, + L,T,F,r,g,b,a + ]); +} +function pushSphere(x,y,z,r,col) +{ + for(var i=0;i<12;++i) + for(var j=0;j<12;++j) + { + var r1=r*Math.sin(i*Math.PI/12); + var a=new v3d(x+r1*Math.cos(j*Math.PI/12*2),y+r1*Math.sin(j*Math.PI/12*2),z+r*Math.cos(i*Math.PI/12)); + var b=new v3d(x+r1*Math.cos((j+1)*Math.PI/12*2),y+r1*Math.sin((j+1)*Math.PI/12*2),z+r*Math.cos(i*Math.PI/12)); + r1=r*Math.sin((i+1)*Math.PI/12); + var c=new v3d(x+r1*Math.cos(j*Math.PI/12*2),y+r1*Math.sin(j*Math.PI/12*2),z+r*Math.cos((i+1)*Math.PI/12)); + var d=new v3d(x+r1*Math.cos((j+1)*Math.PI/12*2),y+r1*Math.sin((j+1)*Math.PI/12*2),z+r*Math.cos((i+1)*Math.PI/12)); + pushQuad([ + a.x,a.y,a.z,col[0],col[1],col[2],col[3], + b.x,b.y,b.z,col[0],col[1],col[2],col[3], + d.x,d.y,d.z,col[0],col[1],col[2],col[3], + c.x,c.y,c.z,col[0],col[1],col[2],col[3] + ]); + } +} +function randint(c) +{return Math.floor(Math.random()*c);} +function genmaze() +{ + for(var i=0;i<mzw;++i) + { + maz[i]=[]; + for(var j=0;j<mzh;++j)maz[i][j]=false; + } + var dx=[0,0,-1,1], + dy=[1,-1,0,0]; + var lst=[]; + var cx=randint(mzw),cy=randint(mzh); + lst.push({x:cx,y:cy,z:cx,w:cy}); + while(lst.length) + { + var rm=lst.splice(randint(lst.length),1); + var x=rm[0].z,y=rm[0].w; + if(maz[x][y]==false) + { + maz[x][y]=maz[rm[0].x][rm[0].y]=true; + for(var i=0;i<4;++i) + { + cx=x+dx[i]*2;cy=y+dy[i]*2; + if(cx>=0&&cy>=0&&cx<mzw&&cy<mzh&& + maz[cx][cy]==false) + lst.push({x:x+dx[i],y:y+dy[i],z:cx,w:cy}); + } + } + } + for(var i=0;i<mzh;++i)maz[0][i]=maz[mzw-1][i]=false; + for(var i=0;i<mzw;++i)maz[i][0]=maz[i][mzh-1]=false; + for(var i=0;i<mzh;++i){if(maz[1][i])lst.push({x:1,y:i});if(maz[mzw-2][i])lst.push({x:mzw-2,y:i});} + for(var i=0;i<mzw;++i){if(maz[i][1])lst.push({x:i,y:1});if(maz[i][mzh-2])lst.push({x:i,y:mzh-2});} + if(lst.length<2)return genmaze(); + var rm=lst.splice(randint(lst.length),1); + ppx=rm[0].x,ppy=rm[0].y; + rm=lst.splice(randint(lst.length),1); + ex=rm[0].x,ey=rm[0].y; +} +function init() +{ + cvs=document.getElementById("glCvs"); + if(!window.devicePixelRatio)window.devicePixelRatio=1; + cvs.width=window.innerWidth; + cvs.height=window.innerHeight; + cvs.style.width=cvs.width+"px"; + cvs.style.height=cvs.height+"px"; + cvs.width=cvs.width*window.devicePixelRatio; + cvs.height=cvs.height*window.devicePixelRatio; + vpw=cvs.width;vph=cvs.height; + try + {WGL=cvs.getContext("webgl")||cvs.getContext("experimental-webgl");} + catch(e){WGL=null;} + if(!WGL){alert("WebGL is not supported by your browser...");return;} + + WGL.clearColor(0.5,0.5,0.5,1.0); + WGL.clearDepth(1); + WGL.enable(WGL.DEPTH_TEST); + WGL.depthFunc(WGL.LESS); + WGL.enable(WGL.BLEND); + WGL.blendFunc(WGL.SRC_ALPHA,WGL.ONE_MINUS_SRC_ALPHA); + WGL.clear(WGL.COLOR_BUFFER_BIT|WGL.DEPTH_BUFFER_BIT); + WGL.viewport(0,0,cvs.width,cvs.height); + + shp=WGL.createProgram(); + var fshs=createShader(fsh,WGL.FRAGMENT_SHADER); + var vshs=createShader(vsh,WGL.VERTEX_SHADER); + WGL.attachShader(shp,vshs);WGL.attachShader(shp,fshs); + WGL.linkProgram(shp); + if(!WGL.getProgramParameter(shp,WGL.LINK_STATUS)) + { + alert("shader link error..."); + } + WGL.useProgram(shp); + + vbo=WGL.createBuffer(); + WGL.bindBuffer(WGL.ARRAY_BUFFER,vbo); + WGL.bufferData(WGL.ARRAY_BUFFER,vb,WGL.STATIC_DRAW); + var vpp=WGL.getAttribLocation(shp,"vp"); + var vcp=WGL.getAttribLocation(shp,"vc"); + WGL.enableVertexAttribArray(vpp); + WGL.enableVertexAttribArray(vcp); + WGL.bindBuffer(WGL.ARRAY_BUFFER,vbo); + WGL.vertexAttribPointer(vpp,3,WGL.FLOAT,false,7*4,0); + WGL.vertexAttribPointer(vcp,4,WGL.FLOAT,false,7*4,3*4); + + for(var i=0,n=0,p=0;i<vbufsize/4;++i) + { + ib[p++]=n;ib[p++]=n+1; + ib[p++]=n+2;ib[p++]=n+2; + ib[p++]=n+3;ib[p++]=n; + n+=4; + } + ibo=WGL.createBuffer(); + WGL.bindBuffer(WGL.ELEMENT_ARRAY_BUFFER,ibo); + WGL.bufferData(WGL.ELEMENT_ARRAY_BUFFER,ib,WGL.STATIC_DRAW); + + document.addEventListener('keydown',function(e){kst[e.code]=1;}); + document.addEventListener('keyup',function(e) + { + kst[e.code]=0; + if(e.code=='KeyD'){if(ppx+1<mzw&&maz[ppx+1][ppy])++ppx;} + if(e.code=='KeyA'){if(ppx-1>=0&&maz[ppx-1][ppy])--ppx;} + if(e.code=='KeyW'){if(ppy+1<mzh&&maz[ppx][ppy+1])++ppy;} + if(e.code=='KeyS'){if(ppy-1>=0&&maz[ppx][ppy-1])--ppy;} + }); + genmaze(); + requestAnimationFrame(mainloop); +} + +function mainloop() +{ + const ofx=-9,ofy=-11; + WGL.clearColor(0.5,0.5,0.5,1.0); + WGL.clearDepth(1); + WGL.clear(WGL.COLOR_BUFFER_BIT|WGL.DEPTH_BUFFER_BIT); + primc=0; + Mmodelview=buildIdentityMatrix(); + + Mmodelview=buildLookAtMatrix(pos,[15,10,0],[0,0,1]); + for(var i=0;i<mzw;++i) + for(var j=0;j<mzh;++j) + if(!maz[i][j])cube(i+ofx,j+ofy,0,1,0.1,0.1,0.1,1); + + cube(ppx+ofx,ppy+ofy,0,0.6,0.1,0.8,0.1,1); + cube(ex+ofx,ey+ofy,0,0.8,0.4,0.9,0.9,1); + + batchGL(); + + requestAnimationFrame(mainloop); +} + +function batchGL() +{ + Mprojection=buildProjectionMatrix3D(vpw,vph,60,0.1,100); + var mpp=WGL.getUniformLocation(shp,"mprojection"); + WGL.uniformMatrix4fv(mpp,false,Mprojection); + var mvpp=WGL.getUniformLocation(shp,"mmodelview"); + WGL.uniformMatrix4fv(mvpp,false,Mmodelview); + WGL.bindBuffer(WGL.ARRAY_BUFFER,vbo); + WGL.bufferData(WGL.ARRAY_BUFFER,vb,WGL.STATIC_DRAW); + WGL.drawElements(WGL.TRIANGLES,6*primc,WGL.UNSIGNED_SHORT,0); + primc=0; +} diff --git a/xp/cgxp/wglmath.js b/xp/cgxp/wglmath.js new file mode 100644 index 0000000..1b9b9e3 --- /dev/null +++ b/xp/cgxp/wglmath.js @@ -0,0 +1,102 @@ +//Copyright Chris Xiong 2018 +//License: Expat (MIT) +var v3d=function(x,y,z) +{ + this.x=(x!==undefined)?x:0; + this.y=(y!==undefined)?y:0; + this.z=(z!==undefined)?z:0; +} +v3d.prototype.l=function(){return Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z);} +v3d.prototype.n=function(){var L=this.l();if(L==0)return new v3d();return new v3d(this.x/L,this.y/L,this.z/L);} +v3d.prototype.ms=function(s) +{ + return new v3d(this.x*s,this.y*s,this.z*s); +} +v3d.prototype.mm=function(m) +{ + return new v3d( + m[0]*this.x+m[4]*this.y+m[8]*this.z, + m[1]*this.x+m[5]*this.y+m[9]*this.z, + m[2]*this.x+m[6]*this.y+m[10]*this.z + ); +} +v3d.prototype.add=function(b) +{ + return new v3d(this.x+b.x,this.y+b.y,this.z+b.z); +} +v3d.prototype.subtract=function(b) +{ + return new v3d(this.x-b.x,this.y-b.y,this.z-b.z); +} +v3d.prototype.dot=function(b) +{ + return this.x*b.x+this.y*b.y+this.z*b.z; +} +v3d.prototype.cross=function(b) +{ + return new v3d( + this.y*b.z-this.z*b.y, + this.z*b.x-this.x*b.z, + this.x*b.y-this.y*b.x + ); +} +function buildIdentityMatrix() +{ + var m=new Float32Array(16); + for(var i=0;i<4;++i)m[i*4+i]=1.; + return m; +} +function buildProjectionMatrix2D(w,h) +{ + var m=buildIdentityMatrix(); + m[0]=2/w;m[5]=2/h;m[10]=-2; + m[12]=m[13]=m[14]=-1; + return m; +} +function buildProjectionMatrix3D(w,h,fov,near,far) +{ + var m=new Float32Array(16); + var f=1./Math.tan(Math.PI*fov/360.); + var ar=w/h; + m[0]=f/ar;m[5]=f;m[10]=(far+near)/(near-far); + m[11]=-1.;m[14]=(2*far*near)/(near-far); + return m; +} +function buildTranslationMatrix(x,y,z) +{ + var m=buildIdentityMatrix(); + m[12]=x;m[13]=y;m[14]=z; + return m; +} +function buildRotationMatrix(a,x,y,z) +{ + var m=buildIdentityMatrix(); + //check (x,y,z) here + var c=Math.cos(a),s=Math.sin(a); + m[0]=x*x*(1-c)+c;m[4]=x*y*(1-c)-z*s;m[8]=x*z*(1-c)+y*s; + m[1]=y*x*(1-c)+z*s;m[5]=y*y*(1-c)+c;m[9]=y*z*(1-c)-x*s; + m[2]=x*z*(1-c)-y*s;m[6]=y*z*(1-c)+x*s;m[10]=z*x*(1-c)+c; + m[15]=1.; + return m; +} +function buildLookAtMatrix(e,a,u) +{ + var f=new v3d(a[0]-e[0],a[1]-e[1],a[2]-e[2]).n(); + var up=new v3d(u[0],u[1],u[2]).n(); + var r=f.cross(up).n();var p=r.cross(f); + var m=buildIdentityMatrix(); + m[0]=r.x;m[4]=r.y;m[8]=r.z; + m[1]=p.x;m[5]=p.y;m[9]=p.z; + m[2]=-f.x;m[6]=-f.y;m[10]=-f.z; + m=multMatrix(m,buildTranslationMatrix(-e[0],-e[1],-e[2])); + return m; +} +function multMatrix(a,b) +{ + var r=new Float32Array(16); + for(var i=0;i<4;++i) + for(var j=0;j<4;++j) + for(var k=0;k<4;++k) + r[i*4+j]+=a[i*4+k]*b[k*4+j]; + return r; +} |