It finally works

This commit is contained in:
John 2022-07-01 01:48:56 -05:00
parent aeff7e396c
commit 1c6e30b882
2 changed files with 111 additions and 25 deletions

View File

@ -18,9 +18,11 @@ const vertex_shader = `
const fragment_shader = ` const fragment_shader = `
precision mediump float;
uniform vec4 u_Color;
void main() void main()
{ {
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); gl_FragColor = u_Color;
} `; } `;
// Point size of the anchor // Point size of the anchor
@ -53,7 +55,7 @@ function main() {
// create a pendulum object // create a pendulum object
var pendulum = new Pendulum({ angle: 0, length: PEN_LENGTH, radius: BOB_RADIUS }); var pendulum = new Pendulum({ angle: 0, length: PEN_LENGTH, radius: BOB_RADIUS });
init(gl, pendulum); pendulum.init(gl);
// Specify the color for clearing <canvas> // Specify the color for clearing <canvas>
gl.clearColor(0, 0, 0, 1); gl.clearColor(0, 0, 0, 1);
@ -82,10 +84,6 @@ function main() {
tick(); tick();
} }
function init(gl, pendulum) {
pendulum.init(gl);
}
function draw(gl, pendulum, modelMatrix, u_ModelMatrix) { function draw(gl, pendulum, modelMatrix, u_ModelMatrix) {
// Clear <canvas> // Clear <canvas>
gl.clear(gl.COLOR_BUFFER_BIT); gl.clear(gl.COLOR_BUFFER_BIT);

View File

@ -16,7 +16,7 @@ function acquire_buffer(gl) {
return vertexBuffer; return vertexBuffer;
} }
function acquire_VAO(gl, name, size, type) { function acquire_attribute(gl, name, size, type) {
// Acquire a reference to named attr // Acquire a reference to named attr
var ret = gl.getAttribLocation(gl.program, name); var ret = gl.getAttribLocation(gl.program, name);
if (ret < 0) { if (ret < 0) {
@ -26,10 +26,19 @@ function acquire_VAO(gl, name, size, type) {
gl.vertexAttribPointer(ret, size, type, false, 0, 0); gl.vertexAttribPointer(ret, size, type, false, 0, 0);
return ret; return ret;
} }
function acquire_uniform(gl, name) {
// Acquire a reference to named attr
var ret = gl.getUniformLocation(gl.program, name);
if (!ret) {
console.log(`Failed to get the storage location of ${name}`);
return -1;
}
return ret;
}
// Classes // Classes
// homo2: Stores a 2d vector or point in homog. coords // homo2: Stores a 2d vector or point in homog. coords
class homog2 { class Homogeneous2D {
constructor(x = 0, y = 0, w = 0) { constructor(x = 0, y = 0, w = 0) {
this.x = x; this.x = x;
this.y = y; this.y = y;
@ -57,7 +66,7 @@ class homog2 {
} }
// copy // copy
copy() { copy() {
return new homog2(this.x, this.y, this.w); return new Homogeneous2D(this.x, this.y, this.w);
} }
// create vector/point from 2d polar coordinates // create vector/point from 2d polar coordinates
from_polar(r = 0, theta = 0, w = 0) { from_polar(r = 0, theta = 0, w = 0) {
@ -68,12 +77,78 @@ class homog2 {
} }
} }
class Rod {
constructor({ anchor = { x: 0, y: 0 }, bob = { x: 0, y: 0 }, color = { r: 1.0, g: 0.0, b: 0.0, a: 1.0 } } = {}) {
// Set the object's vertices
this.vertices = [ new Homogeneous2D(anchor.x, anchor.y, 1),
new Homogeneous2D(bob.x, bob.y, 1)]
// Set object's color
this.color = [color.r, color.g, color.b, color.a];
}
// Convert to Float32Array [x, y]
vertex_array() {
// allocate space for center.xy + vertices.xy
var ret = new Float32Array((this.vertices.length) * 2);
// save the vertices
for (var i = 0; i < this.vertices.length; i++) {
var j = 2 * i;
ret[j] = this.vertices[i].x;
ret[j + 1] = this.vertices[i].y;
}
return ret;
}
// Generate the index_array for the shape
index_array() {
var ret = new Uint8Array(this.vertices.length + 1);
for (var i = 0; i < this.vertices.length; i++) {
ret[i] = i
}
ret[this.vertices.length] = 0;
return ret;
}
// Initialize the object's drawing parameters
init(gl) {
// Make the buffers
this.vertexBuffer = acquire_buffer(gl);
this.indexBuffer = acquire_buffer(gl);
// Bind the buffers
gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer);
// Write date into the buffers
gl.bufferData(gl.ARRAY_BUFFER, this.vertex_array(), gl.STATIC_DRAW);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.index_array(), gl.STATIC_DRAW);
}
// Draw the object
draw(gl, modelMatrix, u_ModelMatrix) {
// Bind the buffers
gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer);
// Set the object's color
var u_Color = acquire_uniform(gl, 'u_Color');
gl.uniform4fv(u_Color, this.color);
// get a_Position
var a_Position = acquire_attribute(gl, 'a_Position', 2, gl.FLOAT);
// Enable the assignment to a_Position variable
gl.enableVertexAttribArray(a_Position);
// Pass the rotation matrix to the vertex shader
gl.uniformMatrix4fv(u_ModelMatrix, false, modelMatrix.elements);
// Draw the Anchor
gl.drawElements(gl.LINES, 2, gl.UNSIGNED_BYTE, 0);
}
}
class Anchor { class Anchor {
constructor({ center = { x: 0, y: 0 } } = {}) { constructor({ center = { x: 0, y: 0 }, color = { r: 0.0, g: 1.0, b: 0.0, a: 1.0 } } = {}) {
this.position = new homog2(center.x, center.y, 1); this.position = new Homogeneous2D(center.x, center.y, 1);
// Set object color
this.color = [color.r, color.g, color.b, color.a];
} }
// Convert to Float32Array [center, v0, v1, ...] // Convert to Float32Array [x, y]
vertex_array() { vertex_array() {
// allocate space for center.xy + vertices.xy // allocate space for center.xy + vertices.xy
var ret = new Float32Array(2); var ret = new Float32Array(2);
@ -89,7 +164,7 @@ class Anchor {
console.log(ret); console.log(ret);
return ret; return ret;
} }
// Initialize the object's drawing parameters
init(gl) { init(gl) {
// Make the buffers // Make the buffers
this.vertexBuffer = acquire_buffer(gl); this.vertexBuffer = acquire_buffer(gl);
@ -103,14 +178,18 @@ class Anchor {
gl.bufferData(gl.ARRAY_BUFFER, this.vertex_array(), gl.STATIC_DRAW); gl.bufferData(gl.ARRAY_BUFFER, this.vertex_array(), gl.STATIC_DRAW);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.index_array(), gl.STATIC_DRAW); gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.index_array(), gl.STATIC_DRAW);
} }
// Draw the object
draw(gl, modelMatrix, u_ModelMatrix) { draw(gl, modelMatrix, u_ModelMatrix) {
// Bind the buffers // Bind the buffers
gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer);
// Set the object's color
var u_Color = acquire_uniform(gl, 'u_Color');
gl.uniform4fv(u_Color, this.color);
// get a_Position // get a_Position
var a_Position = acquire_VAO(gl, 'a_Position', 2, gl.FLOAT); var a_Position = acquire_attribute(gl, 'a_Position', 2, gl.FLOAT);
// Enable the assignment to a_Position variable // Enable the assignment to a_Position variable
gl.enableVertexAttribArray(a_Position); gl.enableVertexAttribArray(a_Position);
@ -121,18 +200,21 @@ class Anchor {
} }
} }
// hexagon2 class: Holds vertices and a center point. Only constructs regular polygons // Polygon class: Holds vertices and a center point. Only constructs regular polygons
class Polygon { class Polygon {
// constructor: Make a new regular polygon // constructor: Make a new regular polygon
constructor({ sides = 6, radius = 1, rotation = 0, center = { x: 0, y: 0 }, color = { r: 0, g: 0, b: 1 } } = {}) { constructor({ sides = 6, radius = 1, rotation = 0, center = { x: 0, y: 0 }, color = { r: 0, g: 0, b: 1, a: 1 } } = {}) {
this.length = 0; this.length = 0;
// vertices // Mark center point
this.center = new Homogeneous2D(center.x, center.y, 1);
// Create vertices
this.vertices = []; this.vertices = [];
this.center = new homog2(center.x, center.y, 1);
for (var i = 0; i <= sides; i++) { for (var i = 0; i <= sides; i++) {
this.vertices[i] = new homog2().from_polar(radius, rotation + (i * 2 * Math.PI / sides)).add_m(this.center); this.vertices[i] = new Homogeneous2D().from_polar(radius, rotation + (i * 2 * Math.PI / sides)).add_m(this.center);
this.length++; this.length++;
} }
// Set object color
this.color = [color.r, color.g, color.b, color.a];
} }
// Convert to Float32Array [center, v0, v1, ...] // Convert to Float32Array [center, v0, v1, ...]
vertex_array() { vertex_array() {
@ -155,7 +237,7 @@ class Polygon {
ret[this.vertices.length] = 0; ret[this.vertices.length] = 0;
return ret; return ret;
} }
// Initialize the object's drawing parameters
init(gl) { init(gl) {
// Make the buffers // Make the buffers
this.vertexBuffer = acquire_buffer(gl); this.vertexBuffer = acquire_buffer(gl);
@ -169,14 +251,18 @@ class Polygon {
gl.bufferData(gl.ARRAY_BUFFER, this.vertex_array(), gl.STATIC_DRAW); gl.bufferData(gl.ARRAY_BUFFER, this.vertex_array(), gl.STATIC_DRAW);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.index_array(), gl.STATIC_DRAW); gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.index_array(), gl.STATIC_DRAW);
} }
// Draw the object
draw(gl, modelMatrix, u_ModelMatrix) { draw(gl, modelMatrix, u_ModelMatrix) {
// Bind the buffers // Bind the buffers
gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer);
// Set the object's color
var u_Color = acquire_uniform(gl, 'u_Color');
gl.uniform4fv(u_Color, this.color);
// get a_Position // get a_Position
var a_Position = acquire_VAO(gl, 'a_Position', 2, gl.FLOAT); var a_Position = acquire_attribute(gl, 'a_Position', 2, gl.FLOAT);
// Enable the assignment to a_Position variable // Enable the assignment to a_Position variable
gl.enableVertexAttribArray(a_Position); gl.enableVertexAttribArray(a_Position);
@ -190,7 +276,9 @@ class Polygon {
class Pendulum { class Pendulum {
constructor({ angle = 0, length = PEN_LENGTH, radius = BOB_RADIUS, anchor = { x: 0, y: 0 } } = {}) { constructor({ angle = 0, length = PEN_LENGTH, radius = BOB_RADIUS, anchor = { x: 0, y: 0 } } = {}) {
this.angle = angle; this.angle = angle;
var bob = {x: 0, y: -length};
this.components = [ this.components = [
new Rod({ anchor: anchor, bob: bob}),
new Anchor({ center: anchor }), new Anchor({ center: anchor }),
new Polygon({ radius: radius, center: { x: 0, y: -length } }) new Polygon({ radius: radius, center: { x: 0, y: -length } })
]; ];
@ -206,7 +294,7 @@ class Pendulum {
// Initialize the pendulum // Initialize the pendulum
init(gl) { init(gl) {
// initialize the components // initialize the components
for(var component of this.components) { for (var component of this.components) {
component?.init(gl); component?.init(gl);
} }
// start the clock // start the clock