Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .vs/ProjectSettings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"CurrentProjectSetting": null
}
12 changes: 12 additions & 0 deletions .vs/VSWorkspaceState.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"ExpandedNodes": [
"",
"\\src",
"\\src\\geometry",
"\\src\\rendering",
"\\src\\rendering\\gl",
"\\src\\shaders"
],
"SelectedNode": "\\src\\shaders\\lambert-vert.glsl",
"PreviewInSolutionExplorer": false
}
Binary file added .vs/hw00-webgl-intro/v16/.suo
Binary file not shown.
Binary file added .vs/slnx.sqlite
Binary file not shown.
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
# HW 0: Noisy Planet Part 1 (Intro to Javascript and WebGL)

Description:
I implemented the dat.gui.
I used fractal brownian motion as the noise function to paint procedural color on geometries. Also, the fbm moves over time.
The geometries are changing size as well as changing position over time.

Screenshot:
![](./mySS.png)

Live Demo Link:
https://hli605.github.io/hw00-webgl-intro/

<p align="center">
<img width="360" height="360" src="https://user-images.githubusercontent.com/1758825/132532354-e3a45402-e484-499e-bfa7-2d73b9f2c946.png">
</p>
Expand Down
Binary file added mySS.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
134 changes: 134 additions & 0 deletions src/geometry/Cube.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
import { vec3, vec4 } from 'gl-matrix';
import Drawable from '../rendering/gl/Drawable';
import { gl } from '../globals';

class Cube extends Drawable {
indices: Uint32Array;
positions: Float32Array;
normals: Float32Array;
center: vec4;

constructor(center: vec3) {
super();
this.center = vec4.fromValues(center[0], center[1], center[2], 1);
}

create() {
// array of vertex indices
this.indices = new Uint32Array([
0, 1, 2,
0, 2, 3,

4, 5, 6,
4, 6, 7,

8, 9, 10,
8, 10, 11,

12, 13, 14,
12, 14, 15,

16, 17, 18,
16, 18, 19,

20, 21, 22,
20, 22, 23
]);

// array of vertex normals
this.normals = new Float32Array([
0, 0, 1, 0,
0, 0, 1, 0,
0, 0, 1, 0,
0, 0, 1, 0,

0, 0, -1, 0,
0, 0, -1, 0,
0, 0, -1, 0,
0, 0, -1, 0,

1, 0, 0, 0,
1, 0, 0, 0,
1, 0, 0, 0,
1, 0, 0, 0,

-1, 0, 0, 0,
-1, 0, 0, 0,
-1, 0, 0, 0,
-1, 0, 0, 0,

0, 1, 0, 0,
0, 1, 0, 0,
0, 1, 0, 0,
0, 1, 0, 0,

0, -1, 0, 0,
0, -1, 0, 0,
0, -1, 0, 0,
0, -1, 0, 0
]);

// array of vertex positions
this.positions = new Float32Array([
0.5, 0.5, 0.5, 1.0,
0.5, -0.5, 0.5, 1.0,
-0.5, -0.5, 0.5, 1.0,
-0.5, 0.5, 0.5, 1.0,

-0.5, 0.5, -0.5, 1.0,
-0.5, -0.5, -0.5, 1.0,
0.5, -0.5, -0.5, 1.0,
0.5, 0.5, -0.5, 1.0,

0.5, 0.5, -0.5, 1.0,
0.5, -0.5, -0.5, 1.0,
0.5, -0.5, 0.5, 1.0,
0.5, 0.5, 0.5, 1.0,

-0.5, 0.5, 0.5, 1.0,
-0.5, -0.5, 0.5, 1.0,
-0.5, -0.5, -0.5, 1.0,
-0.5, 0.5, -0.5, 1.0,

0.5, 0.5, -0.5, 1.0,
0.5, 0.5, 0.5, 1.0,
-0.5, 0.5, 0.5, 1.0,
-0.5, 0.5, -0.5, 1.0,

0.5, -0.5, 0.5, 1.0,
0.5, -0.5, -0.5, 1.0,
-0.5, -0.5, -0.5, 1.0,
-0.5, -0.5, 0.5, 1.0
]);

for (let i = 0; i < this.positions.length; i++) {
if (i % 4 == 0) {
this.positions[i] += this.center[0];
}
else if (i % 4 == 1) {
this.positions[i] += this.center[1];
}
else if (i % 4 == 2) {
this.positions[i] += this.center[2];
}
}

this.generateIdx();
this.generatePos();
this.generateNor();

this.count = this.indices.length;
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.bufIdx);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.indices, gl.STATIC_DRAW);

gl.bindBuffer(gl.ARRAY_BUFFER, this.bufNor);
gl.bufferData(gl.ARRAY_BUFFER, this.normals, gl.STATIC_DRAW);

gl.bindBuffer(gl.ARRAY_BUFFER, this.bufPos);
gl.bufferData(gl.ARRAY_BUFFER, this.positions, gl.STATIC_DRAW);

console.log(`Created cube`);
}
};

export default Cube;
171 changes: 100 additions & 71 deletions src/main.ts
Original file line number Diff line number Diff line change
@@ -1,103 +1,132 @@
import {vec3} from 'gl-matrix';
import { vec3, vec4 } from 'gl-matrix';
const Stats = require('stats-js');
import * as DAT from 'dat.gui';
import Icosphere from './geometry/Icosphere';
import Square from './geometry/Square';
import Cube from './geometry/Cube';
import OpenGLRenderer from './rendering/gl/OpenGLRenderer';
import Camera from './Camera';
import {setGL} from './globals';
import ShaderProgram, {Shader} from './rendering/gl/ShaderProgram';
import { setGL } from './globals';
import ShaderProgram, { Shader } from './rendering/gl/ShaderProgram';

// Define an object with application parameters and button callbacks
// This will be referred to by dat.GUI's functions that add GUI elements.
const controls = {
tesselations: 5,
'Load Scene': loadScene, // A function pointer, essentially
tesselations: 5,
'Load Scene': loadScene, // A function pointer, essentially
Color: [0, 255, 0],
};

let icosphere: Icosphere;
let square: Square;
let cube: Cube;
let prevTesselations: number = 5;

function loadScene() {
icosphere = new Icosphere(vec3.fromValues(0, 0, 0), 1, controls.tesselations);
icosphere.create();
square = new Square(vec3.fromValues(0, 0, 0));
square.create();
icosphere = new Icosphere(vec3.fromValues(0, 3, 0), 1, controls.tesselations);
icosphere.create();
square = new Square(vec3.fromValues(0, 0, 0));
square.create();
cube = new Cube(vec3.fromValues(3, 0, 0));
cube.create();
}

function main() {
// Initial display for framerate
const stats = Stats();
stats.setMode(0);
stats.domElement.style.position = 'absolute';
stats.domElement.style.left = '0px';
stats.domElement.style.top = '0px';
document.body.appendChild(stats.domElement);

// Add controls to the gui
const gui = new DAT.GUI();
gui.add(controls, 'tesselations', 0, 8).step(1);
gui.add(controls, 'Load Scene');

// get canvas and webgl context
const canvas = <HTMLCanvasElement> document.getElementById('canvas');
const gl = <WebGL2RenderingContext> canvas.getContext('webgl2');
if (!gl) {
alert('WebGL 2 not supported!');
}
// `setGL` is a function imported above which sets the value of `gl` in the `globals.ts` module.
// Later, we can import `gl` from `globals.ts` to access it
setGL(gl);

// Initial call to load scene
loadScene();

const camera = new Camera(vec3.fromValues(0, 0, 5), vec3.fromValues(0, 0, 0));

const renderer = new OpenGLRenderer(canvas);
renderer.setClearColor(0.2, 0.2, 0.2, 1);
gl.enable(gl.DEPTH_TEST);

const lambert = new ShaderProgram([
new Shader(gl.VERTEX_SHADER, require('./shaders/lambert-vert.glsl')),
new Shader(gl.FRAGMENT_SHADER, require('./shaders/lambert-frag.glsl')),
]);

// This function will be called every frame
function tick() {
camera.update();
stats.begin();
gl.viewport(0, 0, window.innerWidth, window.innerHeight);
renderer.clear();
if(controls.tesselations != prevTesselations)
{
prevTesselations = controls.tesselations;
icosphere = new Icosphere(vec3.fromValues(0, 0, 0), 1, prevTesselations);
icosphere.create();
// Initial display for framerate
const stats = Stats();
stats.setMode(0);
stats.domElement.style.position = 'absolute';
stats.domElement.style.left = '0px';
stats.domElement.style.top = '0px';
document.body.appendChild(stats.domElement);

// Add controls to the gui
const gui = new DAT.GUI();
gui.add(controls, 'tesselations', 0, 8).step(1);
gui.add(controls, 'Load Scene');
gui.addColor(controls, 'Color').onChange(setAllGeometryColor);

// get canvas and webgl context
const canvas = <HTMLCanvasElement>document.getElementById('canvas');
const gl = <WebGL2RenderingContext>canvas.getContext('webgl2');
if (!gl) {
alert('WebGL 2 not supported!');
}
renderer.render(camera, lambert, [
icosphere,
// square,
// `setGL` is a function imported above which sets the value of `gl` in the `globals.ts` module.
// Later, we can import `gl` from `globals.ts` to access it
setGL(gl);

// Initial call to load scene
loadScene();

const camera = new Camera(vec3.fromValues(0, 0, 5), vec3.fromValues(0, 0, 0));

const renderer = new OpenGLRenderer(canvas);
renderer.setClearColor(0.2, 0.2, 0.2, 1);
gl.enable(gl.DEPTH_TEST);

const lambert = new ShaderProgram([
new Shader(gl.VERTEX_SHADER, require('./shaders/lambert-vert.glsl')),
new Shader(gl.FRAGMENT_SHADER, require('./shaders/lambert-frag.glsl')),
]);
stats.end();
lambert.setGeometryColor(vec4.fromValues(0, 1, 0, 1));

// Tell the browser to call `tick` again whenever it renders a new frame
requestAnimationFrame(tick);
}
const custom = new ShaderProgram([
new Shader(gl.VERTEX_SHADER, require('./shaders/custom-vert.glsl')),
new Shader(gl.FRAGMENT_SHADER, require('./shaders/custom-frag.glsl')),
]);
custom.setGeometryColor(vec4.fromValues(0, 1, 0, 1));

// This function will be called every frame
function tick() {
camera.update();
stats.begin();
gl.viewport(0, 0, window.innerWidth, window.innerHeight);
renderer.clear();
if (controls.tesselations != prevTesselations) {
prevTesselations = controls.tesselations;
icosphere = new Icosphere(vec3.fromValues(0, 0, 0), 1, prevTesselations);
icosphere.create();
}

// Render with custom shader
renderer.render(camera, custom, [
icosphere,
square,
cube,
]);

// Render with Lambert shader
//renderer.render(camera, lambert, [
// icosphere,
// square,
// cube,
//]);

stats.end();

// Tell the browser to call `tick` again whenever it renders a new frame
requestAnimationFrame(tick);
}

window.addEventListener('resize', function () {
renderer.setSize(window.innerWidth, window.innerHeight);
camera.setAspectRatio(window.innerWidth / window.innerHeight);
camera.updateProjectionMatrix();
}, false);

window.addEventListener('resize', function() {
renderer.setSize(window.innerWidth, window.innerHeight);
camera.setAspectRatio(window.innerWidth / window.innerHeight);
camera.updateProjectionMatrix();
}, false);

renderer.setSize(window.innerWidth, window.innerHeight);
camera.setAspectRatio(window.innerWidth / window.innerHeight);
camera.updateProjectionMatrix();
// Start the render loop
tick();

// Start the render loop
tick();
// Help function
function setAllGeometryColor() {
lambert.setGeometryColor(vec4.fromValues(controls.Color[0] / 255.0, controls.Color[1] / 255.0, controls.Color[2] / 255.0, 1));
custom.setGeometryColor(vec4.fromValues(controls.Color[0] / 255.0, controls.Color[1] / 255.0, controls.Color[2] / 255.0, 1));
}
}

main();
Loading