cables_dev/cables_ui/src/ui/components/overlay/overlaymeshes.js
import userSettings from "../usersettings.js";
import overlayShaderVert from "./overlaymeshes.vert";
import overlayShaderFrag from "./overlaymeshes.frag";
const helperMeshes = {};
helperMeshes.count = 0;
export default helperMeshes;
helperMeshes.startFramebuffer = function (cgl)
{
if (!helperMeshes.FB || !helperMeshes.FB.fb)
{
helperMeshes.FB = {};
if (cgl.glVersion == 1)
{
helperMeshes.FB.fb = new CGL.Framebuffer(cgl, 8, 8, {
"isFloatingPointTexture": false,
"depth": true,
"clear": false,
});
}
else
{
helperMeshes.FB.fb = new CGL.Framebuffer2(cgl, 8, 8, {
"isFloatingPointTexture": false,
"depth": true,
"clear": false,
"multisampling": true,
"multisamplingSamples": 4,
});
}
}
if (helperMeshes.FB.oldWidth != cgl.getViewPort()[2] || helperMeshes.FB.oldHeight != cgl.getViewPort()[3])
{
helperMeshes.FB.fb.setSize(cgl.getViewPort()[2], cgl.getViewPort()[3]);
helperMeshes.FB.oldWidth = cgl.getViewPort()[2];
helperMeshes.FB.oldHeight = cgl.getViewPort()[3];
}
helperMeshes.FB.fb.renderStart(cgl);
if (cgl.frameCycler != helperMeshes.FB.oldFrameCycle)
{
cgl.gl.clearColor(0, 0, 0, 0);
cgl.gl.clear(cgl.gl.COLOR_BUFFER_BIT | cgl.gl.DEPTH_BUFFER_BIT);
helperMeshes.FB.oldFrameCycle = cgl.frameCycler;
}
};
helperMeshes.endFramebuffer = function (cgl)
{
helperMeshes.FB.fb.renderEnd();
};
helperMeshes.getDefaultShader = function (cgl, options = {})
{
let name = "defaultShader";
if (options.billboarded)name = "defaultShaderBillboard";
if (!helperMeshes[name])
{
helperMeshes[name] = new CGL.Shader(cgl, "marker shader");
helperMeshes[name].setSource(overlayShaderVert, CGL.Shader.getDefaultFragmentShader(0.6, 0.6, 0.6));
if (options.billboarded)helperMeshes[name].toggleDefine("BILLBOARD", true);
}
return helperMeshes[name];
};
helperMeshes.getSelectedShader = function (cgl, options = {})
{
let name = "selectedShader";
if (options.billboarded)name = "selectedShaderBillboard";
if (!helperMeshes[name])
{
helperMeshes[name] = new CGL.Shader(cgl, "marker shader");
helperMeshes[name].setSource(overlayShaderVert, CGL.Shader.getDefaultFragmentShader(0, 1, 1));
if (options.billboarded)helperMeshes[name].toggleDefine("BILLBOARD", true);
}
return helperMeshes[name];
};
helperMeshes.drawCircle = function (op, size)
{
const cgl = op.patch.cgl;
if (!helperMeshes.CIRCLE)
{
helperMeshes.CIRCLE = {};
helperMeshes.CIRCLE.vScale = vec3.create();
function bufferData()
{
let verts = [];
let tc = [];
const segments = 80;
let degInRad = 0;
const radius = 1;
for (let i = 0; i <= Math.round(segments); i++)
{
degInRad = (360.0 / Math.round(segments)) * i * CGL.DEG2RAD;
verts.push(
Math.cos(degInRad) * radius,
Math.sin(degInRad) * radius,
0
);
tc.push(0, 0);
}
let geom = new CGL.Geometry("sphere marker");
geom.setPointVertices(verts);
geom.setTexCoords(tc);
geom.vertexNormals = verts.slice();
helperMeshes.CIRCLE.mesh = new CGL.Mesh(cgl, geom);
}
bufferData();
}
if (cgl.lastMesh) cgl.lastMesh.unBind();
cgl.pushModelMatrix();
helperMeshes.startFramebuffer(cgl);
vec3.set(helperMeshes.CIRCLE.vScale, size, size, size);
mat4.scale(cgl.mvMatrix, cgl.mvMatrix, helperMeshes.CIRCLE.vScale);
let shader = helperMeshes.getDefaultShader(cgl, { "billboarded": true });
if (gui.patchView.isCurrentOp(op)) shader = helperMeshes.getSelectedShader(cgl, { "billboarded": true });
shader.glPrimitive = cgl.gl.LINE_STRIP;
helperMeshes.CIRCLE.mesh.render(shader);
helperMeshes.count++;
cgl.popModelMatrix();
helperMeshes.endFramebuffer(cgl);
};
helperMeshes.drawSphere = function (op, size)
{
const cgl = op.patch.cgl;
if (!helperMeshes.SPHERE)
{
helperMeshes.SPHERE = {};
helperMeshes.SPHERE.vScale = vec3.create();
function bufferData()
{
let verts = [];
let tc = [];
const segments = 80;
let i = 0, degInRad = 0;
const radius = 1;
for (i = 0; i <= Math.round(segments); i++)
{
degInRad = (360.0 / Math.round(segments)) * i * CGL.DEG2RAD;
verts.push(Math.cos(degInRad) * radius);
verts.push(0);
verts.push(Math.sin(degInRad) * radius);
tc.push(0, 0);
}
const geom = new CGL.Geometry("sphere marker");
geom.setPointVertices(verts);
geom.setTexCoords(tc);
geom.vertexNormals = verts.slice();
//---
verts = [];
tc = [];
for (i = 0; i <= Math.round(segments); i++)
{
degInRad = (360.0 / Math.round(segments)) * i * CGL.DEG2RAD;
verts.push(Math.cos(degInRad) * radius);
verts.push(Math.sin(degInRad) * radius);
verts.push(0);
tc.push(0, 0);
}
const geom2 = new CGL.Geometry("sphere marker");
geom2.setPointVertices(verts);
geom2.setTexCoords(tc);
geom2.vertexNormals = verts.slice();
//---
verts = [];
tc = [];
for (i = 0; i <= Math.round(segments); i++)
{
degInRad = (360.0 / Math.round(segments)) * i * CGL.DEG2RAD;
verts.push(0);
verts.push(Math.cos(degInRad) * radius);
verts.push(Math.sin(degInRad) * radius);
tc.push(0, 0);
}
const geom3 = new CGL.Geometry("sphere marker");
geom3.setPointVertices(verts);
geom3.setTexCoords(tc);
geom3.vertexNormals = verts.slice();
geom.merge(geom2);
geom.merge(geom3);
helperMeshes.SPHERE.mesh = new CGL.Mesh(cgl, geom);
}
bufferData();
}
if (cgl.lastMesh) cgl.lastMesh.unBind();
cgl.pushModelMatrix();
helperMeshes.startFramebuffer(cgl);
vec3.set(helperMeshes.SPHERE.vScale, size, size, size);
mat4.scale(cgl.mvMatrix, cgl.mvMatrix, helperMeshes.SPHERE.vScale);
let shader = helperMeshes.getDefaultShader(cgl);
if (gui.patchView.isCurrentOp(op)) shader = helperMeshes.getSelectedShader(cgl);
shader.glPrimitive = cgl.gl.LINE_STRIP;
helperMeshes.SPHERE.mesh.render(shader);
helperMeshes.count++;
cgl.popModelMatrix();
helperMeshes.endFramebuffer(cgl);
};
helperMeshes.drawAxisMarker = function (op, size)
{
const cgl = op.patch.cgl;
if (!helperMeshes.MARKER)
{
helperMeshes.MARKER = {};
const geom = new CGL.Geometry("marker");
geom.setPointVertices([
0.00001, 0, 0, 1, 0, 0,
0, 0.00001, 0, 0, 1, 0,
0, 0, 0.00001, 0, 0, 1
]);
// geom.resetTextureCoords();
helperMeshes.MARKER.mesh = new CGL.Mesh(cgl, geom, { "glPrimitive": cgl.gl.LINES });
helperMeshes.MARKER.mesh.setGeom(geom);
const frag = "".endl() + "IN vec3 axisColor;".endl() + "void main()".endl() + "{".endl() + " vec4 col=vec4(axisColor,1.0);".endl() + " outColor = col;".endl() + "}";
const vert = "".endl()
+ "IN vec3 vPosition;".endl()
+ "UNI mat4 projMatrix;".endl()
+ "UNI mat4 mvMatrix;".endl()
+ "OUT vec3 axisColor;".endl()
+ "void main()".endl()
+ "{".endl()
+ " vec4 pos=vec4(vPosition, 1.0);".endl()
+ " if(pos.x!=0.0)axisColor=vec3(1.0,0.3,0.0);".endl()
+ " if(pos.y!=0.0)axisColor=vec3(0.0,1.0,0.2);".endl()
+ " if(pos.z!=0.0)axisColor=vec3(0.0,0.5,1.0);".endl()
+ " gl_Position = projMatrix * mvMatrix * pos;".endl()
+ "}";
helperMeshes.MARKER.shader = new CGL.Shader(cgl, "markermaterial");
helperMeshes.MARKER.shader.setSource(vert, frag);
helperMeshes.MARKER.vScale = vec3.create();
}
helperMeshes.startFramebuffer(cgl);
if (size === undefined) size = 2;
cgl.pushModelMatrix();
cgl.pushShader(helperMeshes.MARKER.shader);
vec3.set(helperMeshes.MARKER.vScale, size, size, size);
mat4.scale(cgl.mvMatrix, cgl.mvMatrix, helperMeshes.MARKER.vScale);
cgl.pushDepthTest(false);
helperMeshes.MARKER.mesh.render(cgl.getShader());
helperMeshes.count++;
cgl.popDepthTest();
cgl.popShader();
cgl.popModelMatrix();
helperMeshes.endFramebuffer(cgl);
};
helperMeshes.drawLineSourceDest = function (op, sourceX, sourceY, sourceZ, destX, destY, destZ)
{
const cgl = op.patch.cgl;
if (!helperMeshes.ARROW_SRC_DST)
{
helperMeshes.ARROW_SRC_DST = {};
const verts = [];
verts.push(sourceX, sourceY, sourceZ);
verts.push(destX, destY, destZ);
const tc = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
const geom = new CGL.Geometry("helpermesh");
geom.vertices = verts;
geom.setTexCoords(tc);
geom.vertexNormals = verts.slice();
helperMeshes.ARROW_SRC_DST.geom = geom;
helperMeshes.ARROW_SRC_DST.cube = new CGL.Mesh(cgl, geom, { "glPrimitive": cgl.gl.LINES });
}
else
{
helperMeshes.ARROW_SRC_DST.geom.setVertices([sourceX, sourceY, sourceZ, destX, destY, destZ]);
helperMeshes.ARROW_SRC_DST.cube.updateVertices(helperMeshes.ARROW_SRC_DST.geom);
}
if (cgl.lastMesh) cgl.lastMesh.unBind();
cgl.pushModelMatrix();
helperMeshes.startFramebuffer(cgl);
let shader = helperMeshes.getDefaultShader(cgl);
if (gui.patchView.isCurrentOp(op)) shader = helperMeshes.getSelectedShader(cgl);
helperMeshes.ARROW_SRC_DST.cube.render(shader);
helperMeshes.count++;
cgl.popModelMatrix();
helperMeshes.endFramebuffer(cgl);
};
helperMeshes.drawArrow = function (op, sizeX, rotX, rotY, rotZ)
{
const cgl = op.patch.cgl;
if (!helperMeshes.ARROW)
{
helperMeshes.ARROW = {};
helperMeshes.ARROW.vScale = vec3.create();
function bufferData()
{
const verts = [];
verts.push(0, -1, 0);
verts.push(0.25, -0.75, 0);
verts.push(0, -1, 0);
verts.push(-0.25, -0.75, 0);
verts.push(0, -1, 0);
verts.push(0, 0, 0);
const tc = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
const geom = new CGL.Geometry("helpermesh");
geom.vertices = verts;
geom.setTexCoords(tc);
geom.vertexNormals = verts.slice();
helperMeshes.ARROW.cube = new CGL.Mesh(cgl, geom, { "glPrimitive": cgl.gl.LINES });
}
bufferData();
}
if (cgl.lastMesh) cgl.lastMesh.unBind();
cgl.pushModelMatrix();
helperMeshes.startFramebuffer(cgl);
vec3.set(helperMeshes.ARROW.vScale, sizeX, sizeX, sizeX);
mat4.scale(cgl.mvMatrix, cgl.mvMatrix, helperMeshes.ARROW.vScale);
if (rotX) mat4.rotateX(cgl.mvMatrix, cgl.mvMatrix, rotX * CGL.DEG2RAD);
if (rotY) mat4.rotateY(cgl.mvMatrix, cgl.mvMatrix, rotY * CGL.DEG2RAD);
if (rotZ) mat4.rotateZ(cgl.mvMatrix, cgl.mvMatrix, rotZ * CGL.DEG2RAD);
let shader = helperMeshes.getDefaultShader(cgl);
if (gui.patchView.isCurrentOp(op)) shader = helperMeshes.getSelectedShader(cgl);
helperMeshes.ARROW.cube.render(shader);
helperMeshes.count++;
cgl.popModelMatrix();
helperMeshes.endFramebuffer(cgl);
};
helperMeshes.drawXPlane = function (op, sizeX, rotX, rotY, rotZ)
{
const cgl = op.patch.cgl;
if (!helperMeshes.XPLANE)
{
helperMeshes.XPLANE = {};
helperMeshes.XPLANE.vScale = vec3.create();
function bufferData()
{
const verts = [
-1, -1, 0,
1, 1, 0,
-1, 1, 0,
1, -1, 0,
1, 1, 0,
-1, 1, 0,
-1, -1, 0,
1, -1, 0
];
const tc = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
const geom = new CGL.Geometry("helpermesh");
geom.vertices = verts;
geom.setTexCoords(tc);
geom.vertexNormals = verts.slice();
helperMeshes.XPLANE.mesh = new CGL.Mesh(cgl, geom, cgl.gl.LINE_STRIP);
}
bufferData();
}
if (cgl.lastMesh) cgl.lastMesh.unBind();
cgl.pushModelMatrix();
helperMeshes.startFramebuffer(cgl);
vec3.set(helperMeshes.XPLANE.vScale, sizeX, sizeX, sizeX);
mat4.scale(cgl.mvMatrix, cgl.mvMatrix, helperMeshes.XPLANE.vScale);
if (rotX) mat4.rotateX(cgl.mvMatrix, cgl.mvMatrix, rotX * CGL.DEG2RAD);
if (rotY) mat4.rotateY(cgl.mvMatrix, cgl.mvMatrix, rotY * CGL.DEG2RAD);
if (rotZ) mat4.rotateZ(cgl.mvMatrix, cgl.mvMatrix, rotZ * CGL.DEG2RAD);
let shader = helperMeshes.getDefaultShader(cgl);
if (gui.patchView.isCurrentOp(op)) shader = helperMeshes.getSelectedShader(cgl);
helperMeshes.XPLANE.mesh.render(shader);
helperMeshes.count++;
cgl.popModelMatrix();
helperMeshes.endFramebuffer(cgl);
};
helperMeshes.drawCube = function (op, sizeX, sizeY, sizeZ)
{
const cgl = op.patch.cgl;
if (!helperMeshes.CUBE)
{
helperMeshes.CUBE = {};
helperMeshes.CUBE.vScale = vec3.create();
function bufferData()
{
const verts = new Float32Array([
-1, -1, 1,
1, -1, 1,
1, 1, 1,
-1, 1, 1,
-1, -1, 1,
-1, -1, -1,
1, -1, -1,
1, 1, -1,
-1, 1, -1,
-1, -1, -1,
-1, -1, -1,
-1, 1, -1,
-1, 1, 1,
-1, -1, 1,
-1, -1, -1,
1, -1, -1,
1, 1, -1,
1, 1, 1,
1, -1, 1,
1, -1, -1
]);
const tc = new Float32Array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
const geom = new CGL.Geometry("helpermesh");
geom.vertices = verts;
geom.setTexCoords(tc);
geom.vertexNormals = verts.slice();
helperMeshes.CUBE.mesh = new CGL.Mesh(cgl, geom, cgl.gl.LINE_STRIP);
}
bufferData();
}
if (cgl.lastMesh) cgl.lastMesh.unBind();
cgl.pushModelMatrix();
helperMeshes.startFramebuffer(cgl);
if (sizeY == undefined) sizeY = sizeX;
if (sizeZ == undefined) sizeZ = sizeX;
vec3.set(helperMeshes.CUBE.vScale, sizeX, sizeY, sizeZ);
mat4.scale(cgl.mvMatrix, cgl.mvMatrix, helperMeshes.CUBE.vScale);
let shader = helperMeshes.getDefaultShader(cgl);
if (gui.patchView.isCurrentOp(op)) shader = helperMeshes.getSelectedShader(cgl);
helperMeshes.CUBE.mesh.render(shader);
helperMeshes.count++;
cgl.popModelMatrix();
helperMeshes.endFramebuffer(cgl);
};
helperMeshes.drawMarkerLayer = function (cgl, size)
{
// CABLES.UI.renderHelper = userSettings.get("overlaysShow");
if (!gui.shouldDrawOverlay) return;
if (helperMeshes.count == 0) return;
helperMeshes.count = 0;
if (!helperMeshes.FB || !helperMeshes.FB.fb)
{
return;
}
const currentViewPort = cgl.getViewPort();
const w = currentViewPort[2];
const h = currentViewPort[3];
if (!helperMeshes.fullscreenRectMesh || helperMeshes.FSWIDTH != w || helperMeshes.FSHEIGHT != h)
{
const fsGeom = new CGL.Geometry("fullscreen rectangle");
helperMeshes.FSWIDTH = w;
helperMeshes.FSHEIGHT = h;
// prettier-ignore
fsGeom.vertices = new Float32Array([
w, h, 0,
0, h, 0,
w, 0, 0,
0, 0, 0
]);
fsGeom.texCoords = new Float32Array([
1.0, 1.0,
0.0, 1.0,
1.0, 0.0,
0.0, 0.0,
]);
fsGeom.vertexNormals = new Float32Array([
0, 0, 1,
0, 0, 1,
0, 0, 1,
0, 0, 1
]);
fsGeom.verticesIndices = new Uint16Array([
0, 1, 2,
3, 1, 2,
]);
// helperMeshes.fsGeom=fsGeom;
if (!helperMeshes.fullscreenRectMesh) helperMeshes.fullscreenRectMesh = new CGL.Mesh(cgl, fsGeom);
else helperMeshes.fullscreenRectMesh.setGeom(fsGeom);
// ------------
if (!helperMeshes.fullscreenRectShader)
{
const shader = new CGL.Shader(cgl, "marker overlay");
const shader_frag = "".endl()
+ "UNI sampler2D tex;".endl()
+ "IN vec2 texCoord;".endl()
+ "void main()".endl()
+ "{"
// .endl()+' vec3 gray = vec3(dot( vec3(0.2126,0.7152,0.0722), texture2D(tex,vec2(texCoord.x,(1.0-texCoord.y))).rgb ));'
// .endl()+' gl_FragColor = vec4(gray,1.0);'
.endl()
+ " gl_FragColor = texture2D(tex,texCoord);"
// .endl()+' if(gl_FragColor.a<0.5)gl_FragColor.a=0.7;'
.endl()
+ "}";
const shader_vert = "".endl()
+ "IN vec3 vPosition;".endl()
+ "UNI mat4 projMatrix;".endl()
+ "UNI mat4 mvMatrix;".endl()
+ "OUT vec2 texCoord;".endl()
+ "IN vec2 attrTexCoord;".endl()
+ "void main()".endl()
+ "{".endl()
+ " vec4 pos=vec4(vPosition, 1.0);".endl()
+ " texCoord=vec2(attrTexCoord.x,1.0-attrTexCoord.y);".endl()
+ " gl_Position = projMatrix * mvMatrix * pos;".endl()
+ "}";
shader.setSource(shader_vert, shader_frag);
shader.texUniform = new CGL.Uniform(shader, "t", "tex", 0);
helperMeshes.fullscreenRectShader = shader;
// shader.bindTextures = function ()
// {
// cgl.gl.activeTexture(cgl.gl.TEXTURE0);
// cgl.gl.bindTexture(cgl.gl.TEXTURE_2D, helperMeshes.FB.fb.getTextureColor().tex);
// };
}
}
cgl.gl.clear(cgl.gl.DEPTH_BUFFER_BIT);
cgl.pushPMatrix();
mat4.identity(cgl.pMatrix);
mat4.ortho(cgl.pMatrix, 0, w, h, 0, -10.0, 1000);
cgl.pushModelMatrix();
mat4.identity(cgl.mvMatrix);
cgl.pushViewMatrix();
mat4.identity(cgl.vMatrix);
helperMeshes.fullscreenRectShader.popTextures();
helperMeshes.fullscreenRectShader.pushTexture(helperMeshes.fullscreenRectShader.texUniform, helperMeshes.FB.fb.getTextureColor().tex);
cgl.pushShader(helperMeshes.fullscreenRectShader);
// helperMeshes.fullscreenRectShader.bind();
// cgl.getShader().bind
// for (var i =0;i< cgl.gl.getProgramParameter(cgl.getShader().getProgram(), cgl.gl.ACTIVE_ATTRIBUTES) ; i++)
// {
// console.log(i, cgl.gl.getActiveAttrib(cgl.getShader().getProgram(), i) );
// }
cgl.pushBlend(true);
cgl.gl.blendEquation(cgl.gl.FUNC_ADD);
cgl.gl.blendFunc(cgl.gl.ONE, cgl.gl.ONE_MINUS_SRC_ALPHA);
helperMeshes.fullscreenRectMesh.render(cgl.getShader());
cgl.gl.blendFunc(cgl.gl.SRC_ALPHA, cgl.gl.ONE_MINUS_SRC_ALPHA);
cgl.gl.clear(cgl.gl.DEPTH_BUFFER_BIT);
cgl.popBlend();
cgl.popShader();
cgl.popPMatrix();
cgl.popModelMatrix();
cgl.popViewMatrix();
cgl.frameCycler = !cgl.frameCycler;
};