-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsetup.js
88 lines (81 loc) · 3.06 KB
/
setup.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
/**
* Compile and link the WebGL shaders
* @param vs_source the source of the vertex shader
* @param fs_source the source of the fragment shader
*/
function compileAndLinkGLSL(vs_source, fs_source) {
let vs = gl.createShader(gl.VERTEX_SHADER)
gl.shaderSource(vs, vs_source)
gl.compileShader(vs)
if (!gl.getShaderParameter(vs, gl.COMPILE_STATUS)) {
console.error(gl.getShaderInfoLog(vs))
throw Error("Vertex shader compilation failed")
}
let fs = gl.createShader(gl.FRAGMENT_SHADER)
gl.shaderSource(fs, fs_source)
gl.compileShader(fs)
if (!gl.getShaderParameter(fs, gl.COMPILE_STATUS)) {
console.error(gl.getShaderInfoLog(fs))
throw Error("Fragment shader compilation failed")
}
window.program = gl.createProgram()
gl.attachShader(program, vs)
gl.attachShader(program, fs)
gl.linkProgram(program)
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
console.error(gl.getProgramInfoLog(program))
throw Error("Linking failed")
}
}
/**
* Load the data from the JSON object provided in to Float32Array buffers to be used by the vertex
* and fragment shaders for drawing the objects on the screen. Create a buffer for every
* list of values in the "attributes" and make a Float32Array array
*
* EX: attributes.position will make a buffer object data store and initializes it with the inital values from the
* JSON object we'rep parsing.
* @param geom
* @param drawType
* @returns {{mode: GLenum, vao: WebGLVertexArrayObject, count: number, type: GLenum}}
*/
function setupGeometry(geom, drawType = gl.STATIC_DRAW) {
var triangleArray = gl.createVertexArray()
gl.bindVertexArray(triangleArray)
Object.entries(geom.attributes).forEach(([name,data]) => {
let buf = gl.createBuffer()
gl.bindBuffer(gl.ARRAY_BUFFER, buf)
let f32 = new Float32Array(data.flat())
gl.bufferData(gl.ARRAY_BUFFER, f32, drawType)
let loc = gl.getAttribLocation(program, name)
gl.vertexAttribPointer(loc, data[0].length, gl.FLOAT, false, 0, 0)
gl.enableVertexAttribArray(loc)
})
var indices = new Uint16Array(geom.triangles.flat())
var indexBuffer = gl.createBuffer()
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer)
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, drawType)
return {
mode: gl.TRIANGLES,
count: indices.length,
type: gl.UNSIGNED_SHORT,
vao: triangleArray
}
}
/**
* Update the CSS style for width and height on the canvas to take up the entire screen. Also set up
* the perspective matrix and the viewport.
*/
function fillScreen() {
let canvas = document.querySelector('canvas')
document.body.style.margin = '0'
canvas.style.width = '100vw'
canvas.style.height = '100vh'
canvas.width = canvas.clientWidth
canvas.height = canvas.clientHeight
canvas.style.width = ''
canvas.style.height = ''
if (window.gl) {
gl.viewport(0, 0, canvas.width, canvas.height)
window.p = m4perspNegZ(0.1, 200, 1.5, canvas.width, canvas.height)
}
}