Last active
December 21, 2022 09:15
-
-
Save orazdow/4392572231cbef14aa172cad84a595c5 to your computer and use it in GitHub Desktop.
webgl lib
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const canvas = document.querySelector('canvas'); | |
const gl = canvas.getContext('webgl2'); | |
var clearcolor = [.5,.5,.5,1]; | |
/* | |
reserved attributed names: position, indices | |
*/ // same as twgl | |
gl.clearColor(...clearcolor); | |
gl.clear(gl.COLOR_BUFFER_BIT); | |
const vs =/*glsl*/`#version 300 es | |
in vec2 position; | |
in vec3 color; | |
out vec3 vcolor; | |
void main() { | |
vcolor = color; | |
gl_Position = vec4(position, 0., 1.); | |
} | |
`; | |
const fs = /*glsl*/`#version 300 es | |
precision mediump float; | |
in vec3 vcolor; | |
out vec4 fragColor; | |
uniform float a; | |
#define g gl_FragCoord | |
void main() { | |
vec3 col = vcolor + .5*a*(cos((g.x+g.y)/20.)*.2+.2); | |
fragColor = vec4(col, 1.); | |
} | |
`; | |
const prog = { | |
arrays: { | |
position: { | |
components: 2, | |
stride:5, | |
offset: 0, | |
data: [ | |
-1,-1, 0,1,0, | |
1,-1, 0,0,1, | |
-1,1, 0,0,1, | |
1,1, 1,0,0, | |
] | |
}, | |
color: { | |
components: 3, | |
stride:5, | |
offset: 2, | |
data: 'position' | |
} | |
}, | |
uniforms: {a: 0}, | |
fs: fs, | |
vs: vs, | |
drawMode: 'TRIANGLE_STRIP', | |
shaderProgram: null, | |
subPrograms: null // [{fs, uniforms, cbs},] | |
} | |
const prog2 = { | |
arrays: { | |
position: { | |
components: 2, | |
data: [-.3,-.3, .3,-.3, 0,.2] | |
}, | |
color:{ | |
components: 3, | |
data: [.4,0,.8, .1,0,.8, .4,.5,.7] | |
} | |
}, | |
uniforms: {a: 1}, | |
fs: fs, | |
vs: vs | |
} | |
// need fragcoord res, mouse, time uniforms | |
createShaderProgram(gl, prog); | |
createBuffers(gl, prog); | |
createShaderProgram(gl, prog2); | |
createBuffers(gl, prog2); | |
enableAttributes(gl, prog); | |
setUniforms(gl, prog) | |
drawObj(gl, prog); | |
enableAttributes(gl, prog2); | |
setUniforms(gl, prog2) | |
drawObj(gl, prog2); | |
function createShaderProgram(gl, obj){ | |
let vs = gl.createShader(gl.VERTEX_SHADER); | |
let fs = gl.createShader(gl.FRAGMENT_SHADER); | |
gl.shaderSource(vs, obj.vs); | |
gl.shaderSource(fs, obj.fs); | |
gl.compileShader(fs); | |
gl.compileShader(vs); | |
[vs, fs].forEach((shader, i)=>{ | |
if(!gl.getShaderParameter(shader, gl.COMPILE_STATUS)){ | |
console.log('error compiling', i? 'fragment':'vertex', 'shader:'); | |
console.log(gl.getShaderInfoLog(shader)); | |
gl.deleteShader(shader); return null; | |
} | |
}); | |
let pgm = gl.createProgram(); | |
gl.attachShader(pgm, vs); | |
gl.attachShader(pgm, fs); | |
gl.linkProgram(pgm); | |
obj.shaderProgram = pgm; | |
for(let key in obj.arrays){ | |
obj.arrays[key].location = gl.getAttribLocation(pgm, key); | |
} | |
obj.uniformSetters = uniformSetters(gl, pgm); | |
} | |
function createBuffers(gl, obj){ | |
for(let key in obj.arrays){ | |
let attr = obj.arrays[key]; | |
let stride = attr.stride||0, offset = attr.offset||0; | |
if(typeof attr.data === 'string'){ | |
attr.buffer = obj.arrays[attr.data].buffer; | |
gl.bindBuffer(gl.ARRAY_BUFFER, attr.buffer); | |
gl.vertexAttribPointer(attr.location, attr.components, gl.FLOAT, 0, stride*4, offset*4); | |
gl.enableVertexAttribArray(attr.location); | |
}else{ | |
attr.buffer = gl.createBuffer(); | |
let count = attr.data.length/attr.components; | |
if(count-Math.floor(count)) console.log(key+': non-integer component count'); | |
if(key=='position'){ | |
obj.vao = gl.createVertexArray(); | |
gl.bindVertexArray(obj.vao); | |
}if(key=='indices'){ | |
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, attr.buffer); | |
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(attr.data), gl.STATIC_DRAW); | |
}else{ | |
gl.bindBuffer(gl.ARRAY_BUFFER, attr.buffer); | |
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(attr.data), gl.STATIC_DRAW); | |
gl.vertexAttribPointer(attr.location, attr.components, gl.FLOAT, 0, stride*4, offset*4); | |
gl.enableVertexAttribArray(attr.location); | |
} | |
} | |
} | |
gl.bindVertexArray(null); | |
if(typeof obj.drawMode === 'string') obj.drawMode = gl[obj.drawMode]; | |
else if (typeof obj.drawMode !== 'number') obj.drawMode = gl.TRIANGLES; | |
} | |
function enableAttributes(gl, obj){ | |
if(obj.vao) gl.bindVertexArray(obj.vao); | |
else for(let key in obj.arrays){ | |
let attr = obj.arrays[key]; | |
if(key === 'indices'){ | |
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, attr.buffer); | |
}else{ | |
gl.bindBuffer(gl.ARRAY_BUFFER, attr.buffer); | |
let stride = attr.stride||0, offset = attr.offset||0; | |
gl.vertexAttribPointer(attr.location, attr.components, gl.FLOAT, 0, stride*4, offset*4); | |
gl.enableVertexAttribArray(attr.location); | |
} | |
} | |
gl.useProgram(obj.shaderProgram); | |
} | |
function setUniforms(gl, obj){ | |
for(let u in obj.uniforms) | |
obj.uniformSetters[u](gl, obj.uniforms[u]); | |
} | |
function drawObj(gl, obj){ | |
let count = obj.arrays.indices ? obj.arrays.indices.data.length : | |
obj.arrays.position.data.length/(obj.arrays.position.stride||obj.arrays.position.components); | |
if(obj.arrays.indices) | |
gl.drawElements(obj.drawMode, count, gl.UNSIGNED_SHORT, 0); | |
else gl.drawArrays(obj.drawMode, 0, count); | |
} | |
function uniformSetters(gl, program){ | |
let setters = {}; | |
let count = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS); | |
for(let i = 0; i < count; i++){ | |
let info = gl.getActiveUniform(program, i); | |
let loc = gl.getUniformLocation(program, info.name); | |
setters[info.name] = utypes(gl, info.type, info.size, loc); | |
} | |
return setters; | |
} | |
function utypes(gl, type, size, loc){ | |
let v = (size > 1); | |
switch(type){ | |
case gl.FLOAT : return v ? (gl,v)=>{gl.uniform1fv(loc, v)} : (gl,v)=>{gl.uniform1f(loc, v)}; | |
case gl.FLOAT_VEC2 : return v ? (gl,v)=>{gl.uniform2fv(loc, v)} : (gl,v)=>{gl.uniform2f(loc, ...v)}; | |
case gl.FLOAT_VEC3 : return v ? (gl,v)=>{gl.uniform3fv(loc, v)} : (gl,v)=>{gl.uniform3f(loc, ...v)}; | |
case gl.FLOAT_VEC4 : return v ? (gl,v)=>{gl.uniform4fv(loc, v)} : (gl,v)=>{gl.uniform4f(loc, ...v)}; | |
case gl.FLOAT_MAT2 : return (gl,v)=>{gl.uniformMatrix2fv(loc, v)}; | |
case gl.FLOAT_MAT3 : return (gl,v)=>{gl.uniformMatrix3fv(loc, v)}; | |
case gl.FLOAT_MAT4 : return (gl,v)=>{gl.uniformMatrix4fv(loc, v)}; | |
case gl.SAMPLER_2D : (gl,v)=>{gl.uniform1i(loc, v)}; | |
case gl.SAMPLER_3D : (gl,v)=>{gl.uniform1i(loc, v)}; | |
case gl.SAMPLER_2D_ARRAY : (gl,v)=>{gl.uniform1iv(loc, v)}; | |
case gl.SAMPLER_CUBE : (gl,v)=>{gl.uniform1i(loc, v)}; | |
case gl.INT : return v ? (gl,v)=>{gl.uniform1iv(loc, v)} : (gl,v)=>{gl.uniform1i(loc, v)}; | |
case gl.INT_VEC2 : return v ? (gl,v)=>{gl.uniform2iv(loc, v)} : (gl,v)=>{gl.uniform2i(loc, ...v)}; | |
case gl.INT_VEC3 : return v ? (gl,v)=>{gl.uniform3iv(loc, v)} : (gl,v)=>{gl.uniform3i(loc, ...v)}; | |
case gl.INT_VEC4 : return v ? (gl,v)=>{gl.uniform4iv(loc, v)} : (gl,v)=>{gl.uniform4i(loc, ...v)}; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment