This commit is contained in:
Theo 2024-10-24 11:41:22 +02:00
parent 1da24b1250
commit b8ed3dd52e
2 changed files with 333 additions and 490 deletions

View File

@ -3,362 +3,6 @@
<body> <body>
<canvas width = "300" height = "300" id = "my_Canvas"></canvas> <canvas width = "300" height = "300" id = "my_Canvas"></canvas>
<script> <script src="main.js"></script>
// Mapping function
function map(smin, smax, val, omin, omax) {
const percent = (val - smin) / (smax - smin);
return (omax - omin) * percent + omin;
}
/*======= Creating a canvas =========*/
var canvas = document.getElementById('my_Canvas');
var gl = canvas.getContext('webgl');
/*======= Filling values =========*/
var nc = 3; // Number of curves
var courbe = [
[5, 0.1, 0.4, 0.7, 0.9, 1.0], // Example data
[5, 0.2, 0.3, 0.6, 0.8, 0.95],
[5, 0.05, 0.15, 0.5, 0.75, 0.85],
];
var valmin = [0.1, 0.2, 0.05];
var valmax = [1.0, 0.95, 0.85];
// Drawing modes
const HORIZONTAL = 0;
const VERTICAL = 1;
const SUPERPOSER = 2;
// Drawing types
const LIGNE = 0;
const LIGNE_AXES = 1;
const HISTOGRAMME = 2;
let mode_affichage = HORIZONTAL;
let type_dessin = LIGNE_AXES;
function toVertices(index)
{
const size = courbe[index][0];
var vertices = new Array(size*3).fill(0);
let j = 0;
for (let i = 1; i <= size; i++) {
vertices[j] = map(1, size, i, -1, 1);
if(mode_affichage == SUPERPOSER)
{
vertices[j+1] = map(valmin[index], valmax[index], courbe[index][i], -1, 1);
}else
{
var start = map(0, nc, index, -1, 1);
var end = map(0, nc, index+1, -1, 1);
vertices[j+1] = map(valmin[index], valmax[index], courbe[index][i], start, end);
if(mode_affichage == VERTICAL)
{
[vertices[j], vertices[j+1]] = [vertices[j+1], vertices[j]];
}
}
vertices[j+2] = 0;
j += 3;
}
return vertices;
}
function getCurveVertices(index)
{
const size = courbe[index][0];
var vertices = toVertices(index);
// Create an empty buffer object
var vertex_buffer = gl.createBuffer();
// Bind appropriate array buffer to it
gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);
// Pass the vertex data to the buffer
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
// Unbind the buffer
gl.bindBuffer(gl.ARRAY_BUFFER, null);
//console.log(vertices);
return vertex_buffer;
}
/*=================== Shaders ====================*/
function setShader(red)
{
// Vertex shader source code
var vertCode =
'attribute vec3 coordinates;' +
'void main(void) {' +
' gl_Position = vec4(coordinates, 1.0);' +
'}';
// Create a vertex shader object
var vertShader = gl.createShader(gl.VERTEX_SHADER);
// Attach vertex shader source code
gl.shaderSource(vertShader, vertCode);
// Compile the vertex shader
gl.compileShader(vertShader);
// Fragment shader source code
var fragCode = "";
if(red == false)
{
var fragCode =
'void main(void) {' +
'gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);' +
'}';
}else{
var fragCode =
'void main(void) {' +
'gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);' +
'}';
}
// Create fragment shader object
var fragShader = gl.createShader(gl.FRAGMENT_SHADER);
// Attach fragment shader source code
gl.shaderSource(fragShader, fragCode);
// Compile the fragmentt shader
gl.compileShader(fragShader);
// Create a shader program object to store
// the combined shader program
var shaderProgram = gl.createProgram();
// Attach a vertex shader
gl.attachShader(shaderProgram, vertShader);
// Attach a fragment shader
gl.attachShader(shaderProgram, fragShader);
// Link both the programs
gl.linkProgram(shaderProgram);
// Use the combined shader program object
gl.useProgram(shaderProgram);
return shaderProgram;
}
var shaderProgramRed = setShader(true);
var shaderProgram = setShader(false);
function draw(index)
{
var vertex_buffer = getCurveVertices(index);
// Bind vertex buffer object
gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);
// Get the attribute location
var coord = gl.getAttribLocation(shaderProgram, "coordinates");
// Point an attribute to the currently bound VBO
gl.vertexAttribPointer(coord, 3, gl.FLOAT, false, 0, 0);
// Enable the attribute
gl.enableVertexAttribArray(coord);
// Set the view port
gl.viewport(0,0,canvas.width,canvas.height);
// Draw the triangle
gl.drawArrays(gl.LINE_STRIP, 0, courbe[index][0]);
}
function axe(index, ax)
{
const size = courbe[index][0];
x_start = -1.0;
x_end = map(1, size, ax+1, -1, 1);
y_start = -1;
y_end = map(valmin[index], valmax[index], courbe[index][ax+1], -1, 1);
if(mode_affichage != SUPERPOSER)
{
y_start = map(0, nc, index, -1, 1);
var end = map(0, nc, index+1, -1, 1);
y_end = map(valmin[index], valmax[index], courbe[index][ax+1], y_start, end);
}
if(mode_affichage == VERTICAL)
{
[x_start, y_start] = [y_start, x_start];
[x_end, y_end] = [y_end, x_end];
}
var vertices = [
x_start, y_end, 0.0,
x_end, y_end, 0.0,
x_end, y_end, 0.0,
x_end, y_start, 0.0,
]
return vertices;
}
function drawAxes(index)
{
const size = courbe[index][0];
var vertices = [];
for(let i = 1; i < size; i++)
{
let v = axe(index, i);
vertices.push(...v);
}
console.log(vertices);
// Create an empty buffer object
var vertex_buffer = gl.createBuffer();
// Bind appropriate array buffer to it
gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);
// Pass the vertex data to the buffer
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
// Get the attribute location
var coord = gl.getAttribLocation(shaderProgram, "coordinates");
// Point an attribute to the currently bound VBO
gl.vertexAttribPointer(coord, 3, gl.FLOAT, false, 0, 0);
// Enable the attribute
gl.enableVertexAttribArray(coord);
// Set the view port
gl.viewport(0,0,canvas.width,canvas.height);
gl.useProgram(shaderProgramRed);
// Draw the triangle
gl.drawArrays(gl.LINES, 0, (courbe[index][0]-1) * 4);
gl.useProgram(shaderProgram);
}
function square(index, squ)
{
const size = courbe[index][0];
x_start = map(1, size, squ, -1, 1);
x_end = map(1, size, squ+1, -1, 1);
y_start = -1;
y_end = map(valmin[index], valmax[index], courbe[index][squ], -1, 1);
if(mode_affichage != SUPERPOSER)
{
y_start = map(0, nc, index, -1, 1);
var end = map(0, nc, index+1, -1, 1);
y_end = map(valmin[index], valmax[index], courbe[index][squ], y_start, end);
}
if(mode_affichage == VERTICAL)
{
[x_start, y_start] = [y_start, x_start];
[x_end, y_end] = [y_end, x_end];
}
var vertices = [
x_start, y_start, 0,
x_end, y_start, 0,
x_end, y_end, 0,
x_start, y_end, 0
]
return vertices;
}
function drawHisto(index)
{
const size = courbe[index][0];
for(let i = 1; i < size; i++)
{
var vertices = square(index, i);
//console.log(i);
//console.log(vertices);
indices = [0, 2, 1, 0, 3, 2];
// Create an empty buffer object to store vertex buffer
var vertex_buffer = gl.createBuffer();
// Bind appropriate array buffer to it
gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);
// Pass the vertex data to the buffer
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
// Unbind the buffer
gl.bindBuffer(gl.ARRAY_BUFFER, null);
// Create an empty buffer object to store Index buffer
var Index_Buffer = gl.createBuffer();
// Bind appropriate array buffer to it
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, Index_Buffer);
// Pass the vertex data to the buffer
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW);
// Unbind the buffer
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
// Bind vertex buffer object
gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);
// Bind index buffer object
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, Index_Buffer);
// Get the attribute location
var coord = gl.getAttribLocation(shaderProgram, "coordinates");
// Point an attribute to the currently bound VBO
gl.vertexAttribPointer(coord, 3, gl.FLOAT, false, 0, 0);
// Enable the attribute
gl.enableVertexAttribArray(coord);
// Set the view port
gl.viewport(0,0,canvas.width,canvas.height);
// Draw the triangle
gl.drawElements(gl.TRIANGLES, indices.length, gl.UNSIGNED_SHORT,0);
}
}
gl.clearColor(0, 0, 0, 0.5);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
for(var i = 0; i < nc; i++)
{
if(type_dessin == HISTOGRAMME)
{
drawHisto(i);
}else{
draw(i);
if(type_dessin == LIGNE_AXES)
{
drawAxes(i);
}
}
}
</script>
</body> </body>
</html> </html>

433
main.js
View File

@ -1,11 +1,24 @@
// Global variables
const MAXC = 20;
const MAXV = 100;
let courbe = new Array(MAXC).fill().map(() => new Array(MAXV).fill(0)); // Mapping function
let valmin = new Array(MAXC).fill(0); function map(smin, smax, val, omin, omax) {
let valmax = new Array(MAXC).fill(0); const percent = (val - smin) / (smax - smin);
let nc = 0; return (omax - omin) * percent + omin;
}
/*======= Creating a canvas =========*/
var canvas = document.getElementById('my_Canvas');
var gl = canvas.getContext('webgl');
/*======= Filling values =========*/
var nc = 3; // Number of curves
var courbe = [
[5, 0.1, 0.4, 0.7, 0.9, 1.0], // Example data
[5, 0.2, 0.3, 0.6, 0.8, 0.95],
[5, 0.05, 0.15, 0.5, 0.75, 0.85],
];
var valmin = [0.1, 0.2, 0.05];
var valmax = [1.0, 0.95, 0.85];
// Drawing modes // Drawing modes
const HORIZONTAL = 0; const HORIZONTAL = 0;
@ -18,138 +31,324 @@ const LIGNE_AXES = 1;
const HISTOGRAMME = 2; const HISTOGRAMME = 2;
let mode_affichage = HORIZONTAL; let mode_affichage = HORIZONTAL;
let type_dessin = LIGNE; let type_dessin = LIGNE_AXES;
// WebGL setup function toVertices(index)
function initWebGL() { {
const canvas = document.getElementById("glCanvas"); const size = courbe[index][0];
const gl = canvas.getContext("webgl"); var vertices = new Array(size*3).fill(0);
if (!gl) { let j = 0;
console.error("Unable to initialize WebGL."); for (let i = 1; i <= size; i++) {
return null; vertices[j] = map(1, size, i, -1, 1);
if(mode_affichage == SUPERPOSER)
{
vertices[j+1] = map(valmin[index], valmax[index], courbe[index][i], -1, 1);
}else
{
var start = map(0, nc, index, -1, 1);
var end = map(0, nc, index+1, -1, 1);
vertices[j+1] = map(valmin[index], valmax[index], courbe[index][i], start, end);
if(mode_affichage == VERTICAL)
{
[vertices[j], vertices[j+1]] = [vertices[j+1], vertices[j]];
}
} }
return gl; vertices[j+2] = 0;
} j += 3;
// Mapping function
function map(smin, smax, val, omin, omax) {
const percent = (val - smin) / (smax - smin);
return (omax - omin) * percent + omin;
}
// Draw axes
function drawAxes(gl, x1, x2, y1, y2) {
gl.lineWidth(1);
gl.strokeStyle = "#FF8080";
gl.beginPath();
gl.moveTo(x1, y2);
gl.lineTo(x2, y2);
gl.lineTo(x2, y1);
gl.stroke();
}
// Draw curve
function drawCurve(gl, index, hgx, hgy, bdx, bdy) {
if (index >= nc) {
console.error("Invalid curve index");
return;
} }
return vertices;
}
gl.strokeStyle = "#FFFFFF"; // Set line color to white function getCurveVertices(index)
{
const size = courbe[index][0];
var vertices = toVertices(index);
// Create an empty buffer object
var vertex_buffer = gl.createBuffer();
// Bind appropriate array buffer to it
gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);
// Pass the vertex data to the buffer
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
// Unbind the buffer
gl.bindBuffer(gl.ARRAY_BUFFER, null);
//console.log(vertices);
return vertex_buffer;
}
/*=================== Shaders ====================*/
function setShader(red)
{
// Vertex shader source code
var vertCode =
'attribute vec3 coordinates;' +
'void main(void) {' +
' gl_Position = vec4(coordinates, 1.0);' +
'}';
// Create a vertex shader object
var vertShader = gl.createShader(gl.VERTEX_SHADER);
// Attach vertex shader source code
gl.shaderSource(vertShader, vertCode);
// Compile the vertex shader
gl.compileShader(vertShader);
// Fragment shader source code
var fragCode = "";
if(red == false)
{
var fragCode =
'void main(void) {' +
'gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);' +
'}';
}else{
var fragCode =
'void main(void) {' +
'gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);' +
'}';
}
// Create fragment shader object
var fragShader = gl.createShader(gl.FRAGMENT_SHADER);
// Attach fragment shader source code
gl.shaderSource(fragShader, fragCode);
// Compile the fragmentt shader
gl.compileShader(fragShader);
// Create a shader program object to store
// the combined shader program
var shaderProgram = gl.createProgram();
// Attach a vertex shader
gl.attachShader(shaderProgram, vertShader);
// Attach a fragment shader
gl.attachShader(shaderProgram, fragShader);
// Link both the programs
gl.linkProgram(shaderProgram);
// Use the combined shader program object
gl.useProgram(shaderProgram);
return shaderProgram;
}
var shaderProgramRed = setShader(true);
var shaderProgram = setShader(false);
function draw(index)
{
var vertex_buffer = getCurveVertices(index);
// Bind vertex buffer object
gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);
// Get the attribute location
var coord = gl.getAttribLocation(shaderProgram, "coordinates");
// Point an attribute to the currently bound VBO
gl.vertexAttribPointer(coord, 3, gl.FLOAT, false, 0, 0);
// Enable the attribute
gl.enableVertexAttribArray(coord);
// Set the view port
gl.viewport(0,0,canvas.width,canvas.height);
// Draw the triangle
gl.drawArrays(gl.LINE_STRIP, 0, courbe[index][0]);
}
function axe(index, ax)
{
const size = courbe[index][0]; const size = courbe[index][0];
gl.beginPath(); x_start = -1.0;
for (let i = 1; i <= size; i++) { x_end = map(1, size, ax+1, -1, 1);
let posX = map(0, size - 1, i - 1, hgx, bdx);
let posY = map(valmin[index], valmax[index], courbe[index][i], bdy, hgy);
if (mode_affichage === VERTICAL) { y_start = -1;
// Swap x and y for vertical mode y_end = map(valmin[index], valmax[index], courbe[index][ax+1], -1, 1);
[posX, posY] = [posY, posX]; if(mode_affichage != SUPERPOSER)
{
y_start = map(0, nc, index, -1, 1);
var end = map(0, nc, index+1, -1, 1);
y_end = map(valmin[index], valmax[index], courbe[index][ax+1], y_start, end);
} }
if (i === 1) { if(mode_affichage == VERTICAL)
gl.moveTo(posX, posY); {
} else { [x_start, y_start] = [y_start, x_start];
gl.lineTo(posX, posY); [x_end, y_end] = [y_end, x_end];
} }
}
gl.stroke(); var vertices = [
x_start, y_end, 0.0,
x_end, y_end, 0.0,
x_end, y_end, 0.0,
x_end, y_start, 0.0,
]
return vertices;
} }
// Draw histogram function drawAxes(index)
function drawHistogram(gl, index, hgx, hgy, bdx, bdy) { {
if (index >= nc) {
console.error("Invalid curve index");
return;
}
gl.fillStyle = "#FFFFFF"; // Set fill color to white
const size = courbe[index][0]; const size = courbe[index][0];
for (let i = 1; i <= size; i++) { var vertices = [];
let gauche = map(0, size, i - 1, hgx, bdx); for(let i = 1; i < size; i++)
let droite = map(0, size, i, hgx, bdx); {
let haut = map(valmin[index], valmax[index], courbe[index][i], bdy, hgy); let v = axe(index, i);
let bas = bdy; vertices.push(...v);
if (mode_affichage === VERTICAL) {
[gauche, haut] = [haut, droite];
[droite, bas] = [bas, gauche];
} }
gl.fillRect(gauche, haut, droite - gauche, bas - haut); //console.log(vertices);
}
// Create an empty buffer object
var vertex_buffer = gl.createBuffer();
// Bind appropriate array buffer to it
gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);
// Pass the vertex data to the buffer
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
// Get the attribute location
var coord = gl.getAttribLocation(shaderProgram, "coordinates");
// Point an attribute to the currently bound VBO
gl.vertexAttribPointer(coord, 3, gl.FLOAT, false, 0, 0);
// Enable the attribute
gl.enableVertexAttribArray(coord);
// Set the view port
gl.viewport(0,0,canvas.width,canvas.height);
gl.useProgram(shaderProgramRed);
// Draw the triangle
gl.drawArrays(gl.LINES, 0, (courbe[index][0]-1) * 4);
gl.useProgram(shaderProgram);
} }
// Display function (main rendering function) function square(index, squ)
function display(gl) { {
gl.clearColor(0.0, 0.0, 0.0, 1.0); const size = courbe[index][0];
gl.clear(gl.COLOR_BUFFER_BIT);
if (mode_affichage === HORIZONTAL) { x_start = map(1, size, squ, -1, 1);
for (let i = 0; i < nc; i++) { x_end = map(1, size, squ+1, -1, 1);
console.log(i);
let haut = map(0, nc, i, 1.0, -1.0); y_start = -1;
let bas = map(0, nc, i + 1, 1.0, -1.0); y_end = map(valmin[index], valmax[index], courbe[index][squ], -1, 1);
if (type_dessin === LIGNE || type_dessin === LIGNE_AXES) { if(mode_affichage != SUPERPOSER)
console.log("drawCurve"); {
drawCurve(gl, i, -1.0, haut, 1.0, bas); y_start = map(0, nc, index, -1, 1);
console.log("drawCurve"); var end = map(0, nc, index+1, -1, 1);
} else if (type_dessin === HISTOGRAMME) { y_end = map(valmin[index], valmax[index], courbe[index][squ], y_start, end);
drawHistogram(gl, i, -1.0, haut, 1.0, bas);
} }
if(mode_affichage == VERTICAL)
{
[x_start, y_start] = [y_start, x_start];
[x_end, y_end] = [y_end, x_end];
}
var vertices = [
x_start, y_start, 0,
x_end, y_start, 0,
x_end, y_end, 0,
x_start, y_end, 0
]
return vertices;
}
function drawHisto(index)
{
const size = courbe[index][0];
for(let i = 1; i < size; i++)
{
var vertices = square(index, i);
//console.log(i);
//console.log(vertices);
indices = [0, 2, 1, 0, 3, 2];
// Create an empty buffer object to store vertex buffer
var vertex_buffer = gl.createBuffer();
// Bind appropriate array buffer to it
gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);
// Pass the vertex data to the buffer
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
// Unbind the buffer
gl.bindBuffer(gl.ARRAY_BUFFER, null);
// Create an empty buffer object to store Index buffer
var Index_Buffer = gl.createBuffer();
// Bind appropriate array buffer to it
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, Index_Buffer);
// Pass the vertex data to the buffer
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW);
// Unbind the buffer
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
// Bind vertex buffer object
gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);
// Bind index buffer object
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, Index_Buffer);
// Get the attribute location
var coord = gl.getAttribLocation(shaderProgram, "coordinates");
// Point an attribute to the currently bound VBO
gl.vertexAttribPointer(coord, 3, gl.FLOAT, false, 0, 0);
// Enable the attribute
gl.enableVertexAttribArray(coord);
// Set the view port
gl.viewport(0,0,canvas.width,canvas.height);
// Draw the triangle
gl.drawElements(gl.TRIANGLES, indices.length, gl.UNSIGNED_SHORT,0);
}
}
gl.clearColor(0, 0, 0, 0.5);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
for(var i = 0; i < nc; i++)
{
if(type_dessin == HISTOGRAMME)
{
drawHisto(i);
}else{
draw(i);
if(type_dessin == LIGNE_AXES)
{
drawAxes(i);
} }
} }
} }
// Load the data from file (simulated in JavaScript)
function loadFile() {
nc = 3; // Number of curves
courbe = [
[5, 0.1, 0.4, 0.7, 0.9, 1.0], // Example data
[5, 0.2, 0.3, 0.6, 0.8, 0.95],
[5, 0.05, 0.15, 0.5, 0.75, 0.85],
];
valmin = [0.1, 0.2, 0.05];
valmax = [1.0, 0.95, 0.85];
}
// Initialize everything and run
function main() {
const gl = initWebGL();
if (!gl) return;
loadFile(); // Load example data
console.log(courbe);
console.log(nc);
display(gl); // Render the curves
}
// Run the WebGL program
window.onload = main;