import { appGlobals } from './globals.js' import { wasmPntrToJsString, wasmPntrAndLengthToJsString, jsStringToWasmPntr } from './wasm_functions.js' export var glObjects = { buffers: [ null ], textures: [ null ], vaos: [ null ], shaders: [ null ], programs: [ null ], uniformLocations: [ null ], }; // +--------------------------------------------------------------+ // | Helpers | // +--------------------------------------------------------------+ function verifyGlBufferId(bufferId, allowZero) { if (typeof(bufferId) != "number") { return "BufferId is not a number!"; } if (bufferId == 0) { return allowZero ? null : "BufferId is 0!"; } if (glObjects == null || glObjects.buffers == null) { return "Buffers array has not been initialized yet!"; } if (bufferId >= glObjects.buffers.length) { return "BufferId is too high!"; } if (glObjects.buffers[bufferId] == null) { return "BufferId is for a destroyed vertBuffer!"; } return null; } function verifyGlTextureId(textureId, allowZero) { if (typeof(textureId) != "number") { return "TextureId is not a number!"; } if (textureId == 0) { return allowZero ? null : "TextureId is 0!"; } if (glObjects == null || glObjects.textures == null) { return "Textures array has not been initialized yet!"; } if (textureId >= glObjects.textures.length) { return "TextureId is too high!"; } if (glObjects.textures[textureId] == null) { return "TextureId is for a destroyed texture!"; } return null; } function verifyGlVaoId(vaoId, allowZero) { if (typeof(vaoId) != "number") { return "VaoId is not a number!"; } if (vaoId == 0) { return allowZero ? null : "VaoId is 0!"; } if (glObjects == null || glObjects.vaos == null) { return "Vaos array has not been initialized yet!"; } if (vaoId >= glObjects.vaos.length) { return "VaoId is too high!"; } if (glObjects.vaos[vaoId] == null) { return "VaoId is for a destroyed array!"; } return null; } function verifyGlShaderId(shaderId, allowZero) { if (typeof(shaderId) != "number") { return "ShaderId is not a number!"; } if (shaderId == 0) { return allowZero ? null : "ShaderId is 0!"; } if (glObjects == null || glObjects.shaders == null) { return "Shaders array has not been initialized yet!"; } if (shaderId >= glObjects.shaders.length) { return "ShaderId is too high!"; } if (glObjects.shaders[shaderId] == null) { return "ShaderId is for a destroyed shader!"; } return null; } function verifyGlProgramId(programId, allowZero) { if (typeof(programId) != "number") { return "ProgramId is not a number!"; } if (programId == 0) { return allowZero ? null : "ProgramId is 0!"; } if (glObjects == null || glObjects.programs == null) { return "Programs array has not been initialized yet!"; } if (programId >= glObjects.programs.length) { return "ProgramId is too high!"; } if (glObjects.programs[programId] == null) { return "ProgramId is for a destroyed program!"; } return null; } function verifyGlUniformLocationId(locationId, allowZero) { if (typeof(locationId) != "number") { return "LocationId is not a number!"; } if (locationId == 0) { return allowZero ? null : "LocationId is 0!"; } if (glObjects == null || glObjects.uniformLocations == null) { return "Locations array has not been initialized yet!"; } if (locationId >= glObjects.uniformLocations.length) { return "LocationId is too high!"; } if (glObjects.uniformLocations[locationId] == null) { return "LocationId is for a destroyed program!"; } return null; } function verifyParameter(verifyResult, functionName, parameterName, parameterValue) { if (verifyResult == null) { return true; } console.error("Invalid argument \"" + parameterName + "\" passed to " + functionName + ": " + verifyResult); console.error("Argument value: " + parameterValue); return false; } // +--------------------------------------------------------------+ // | WebGL API | // +--------------------------------------------------------------+ export function jsGlGetError(capability) { return appGlobals.glContext.getError(); } export function jsGlGetParameterBool(parameter) { let paramValue = appGlobals.glContext.getParameter(parameter); if (typeof(paramValue) != "boolean") { console.error("Tried to get GL parameter " + parameter + " as bool when it's actually: " + typeof(paramValue)); return false; } return paramValue; } export function jsGlGetParameterEnum(parameter) { let paramValue = appGlobals.glContext.getParameter(parameter); if (typeof(paramValue) != "number") { console.error("Tried to get GL parameter " + parameter + " as enum when it's actually: " + typeof(paramValue)); return false; } return paramValue; } export function jsGlGetParameterInt(parameter) { let paramValue = appGlobals.glContext.getParameter(parameter); if (typeof(paramValue) != "number") { console.error("Tried to get GL parameter " + parameter + " as int when it's actually: " + typeof(paramValue)); return false; } return paramValue; } export function jsGlGetParameterFloat(parameter) { let paramValue = appGlobals.glContext.getParameter(parameter); if (typeof(paramValue) != "number") { console.error("Tried to get GL parameter " + parameter + " as float when it's actually: " + typeof(paramValue)); return false; } return paramValue; } export function jsGlGetParameterString(arenaPntr, parameter) { let paramValue = appGlobals.glContext.getParameter(parameter); if (typeof(paramValue) != "string") { console.error("Tried to get GL parameter " + parameter + " as string when it's actually: " + typeof(paramValue)); return false; } let paramValuePntr = jsStringToWasmPntr(arenaPntr, paramValue, true); return paramValuePntr; } export function jsGlEnable(capability) { appGlobals.glContext.enable(capability); } export function jsGlDisable(capability) { appGlobals.glContext.disable(capability); } export function jsGlBlendFunc(srcFactor, dstFactor) { appGlobals.glContext.blendFunc(srcFactor, dstFactor); } export function jsGlBlendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha) { appGlobals.glContext.blendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha); } export function jsGlBlendEquation(equation) { appGlobals.glContext.blendEquation(equation); } export function jsGlDepthFunc(depthFunc) { appGlobals.glContext.depthFunc(depthFunc); } export function jsGlFrontFace(cullMode) { appGlobals.glContext.frontFace(cullMode); } // +==============================+ // | Buffer Functions | // +==============================+ export function jsGlDeleteBuffer(bufferId) { if (!verifyParameter(verifyGlBufferId(bufferId, false), "gl.deleteBuffer", "bufferId", bufferId)) { return; } appGlobals.glContext.deleteBuffer(glObjects.buffers[bufferId]); glObjects.buffers[bufferId] = null; } export function jsGlCreateBuffer() { let newBuffer = appGlobals.glContext.createBuffer(); let newBufferId = glObjects.buffers.length; glObjects.buffers.push(newBuffer); return newBufferId; } export function jsGlBindBuffer(bufferType, bufferId) { if (!verifyParameter(verifyGlBufferId(bufferId, true), "gl.bindBuffer", "bufferId", bufferId)) { return; } let buffer = glObjects.buffers[bufferId]; appGlobals.glContext.bindBuffer(bufferType, buffer); } export function jsGlBufferData(bufferType, dataLength, dataPntr, usageHint) { let dataArray = appGlobals.memDataView.buffer.slice(dataPntr, dataPntr + dataLength); appGlobals.glContext.bufferData(bufferType, dataArray, usageHint); } // +==============================+ // | Texture Functions | // +==============================+ export function jsGlDeleteTexture(textureId) { if (!verifyParameter(verifyGlTextureId(textureId, false), "gl.deleteTexture", "textureId", textureId)) { return; } appGlobals.glContext.deleteTexture(glObjects.textures[textureId]); glObjects.textures[textureId] = null; } export function jsGlCreateTexture() { let newTexture = appGlobals.glContext.createTexture(); let newTextureId = glObjects.textures.length; glObjects.textures.push(newTexture); return newTextureId; } export function jsGlActiveTexture(textureIndex) { appGlobals.glContext.activeTexture(textureIndex); } export function jsGlBindTexture(target, textureId) { if (!verifyParameter(verifyGlTextureId(textureId, true), "gl.bindTexture", "textureId", textureId)) { return; } let texture = glObjects.textures[textureId]; appGlobals.glContext.bindTexture(target, texture); } export function jsGlPixelStorei(parameter, value) { appGlobals.glContext.pixelStorei(parameter, value); } export function jsGlTexImage2D(target, level, internalFormat, width, height, border, format, type, dataLength, dataPntr) { let dataBuffer = new Uint8Array(appGlobals.memDataView.buffer, dataPntr, dataLength); appGlobals.glContext.texImage2D(target, level, internalFormat, width, height, border, format, type, dataBuffer); } export function jsGlTexParameteri(target, parameter, value) { appGlobals.glContext.texParameteri(target, parameter, value) } export function jsGlGenerateMipmap(target) { appGlobals.glContext.generateMipmap(target); } // +==============================+ // | Vertex Array Functions | // +==============================+ export function jsGlDeleteVertexArray(vaoId) { if (!verifyParameter(verifyGlVaoId(vaoId, true), "gl.deleteVertexArray", "vaoId", vaoId)) { return; } appGlobals.glContext.deleteVertexArray(glObjects.vaos[vaoId]); glObjects.vaos[vaoId] = null; } export function jsGlCreateVertexArray() { let newVao = appGlobals.glContext.createVertexArray(); let newVaoId = glObjects.vaos.length; glObjects.vaos.push(newVao); return newVaoId; } export function jsGlBindVertexArray(vaoId) { if (!verifyParameter(verifyGlVaoId(vaoId, true), "gl.bindVertexArray", "vaoId", vaoId)) { return; } let vao = glObjects.vaos[vaoId]; appGlobals.glContext.bindVertexArray(vao); } export function jsGlEnableVertexAttribArray(location) { appGlobals.glContext.enableVertexAttribArray(location); } export function jsGlVertexAttribPointer(attribLocation, componentCount, componentType, normalized, stride, offset) { appGlobals.glContext.vertexAttribPointer(attribLocation, componentCount, componentType, normalized, stride, offset); } // +==============================+ // | Shader Functions | // +==============================+ export function jsGlDeleteShader(shaderId) { if (!verifyParameter(verifyGlShaderId(shaderId, false), "gl.deleteShader", "shaderId", shaderId)) { return; } appGlobals.glContext.deleteShader(glObjects.shaders[shaderId]); glObjects.shaders[shaderId] = null; } export function jsGlCreateShader(shaderType) { let newShader = appGlobals.glContext.createShader(shaderType); let newShaderId = glObjects.shaders.length; glObjects.shaders.push(newShader); return newShaderId; } export function jsGlShaderSource(shaderId, sourceLength, sourcePntr) { if (!verifyParameter(verifyGlShaderId(shaderId, false), "gl.shaderSource", "shaderId", shaderId)) { return; } let shader = glObjects.shaders[shaderId]; let sourceStr = wasmPntrAndLengthToJsString(sourcePntr, sourceLength); appGlobals.glContext.shaderSource(shader, sourceStr); } export function jsGlCompileShader(shaderId) { if (!verifyParameter(verifyGlShaderId(shaderId, false), "gl.compileShader", "shaderId", shaderId)) { return; } let shader = glObjects.shaders[shaderId]; appGlobals.glContext.compileShader(shader); } export function jsGlGetShaderParameterBool(shaderId, parameter) { if (!verifyParameter(verifyGlShaderId(shaderId, false), "gl.getShaderParameter", "shaderId", shaderId)) { return false; } let shader = glObjects.shaders[shaderId]; let paramValue = appGlobals.glContext.getShaderParameter(shader, parameter); if (typeof(paramValue) != "boolean") { console.error("Tried to get GL parameter " + parameter + " as bool when it's actually: " + typeof(paramValue)); return false; } return paramValue; } export function jsGlGetShaderParameterInt(shaderId, parameter) { if (!verifyParameter(verifyGlShaderId(shaderId, false), "gl.getShaderParameter", "shaderId", shaderId)) { return false; } let shader = glObjects.shaders[shaderId]; let paramValue = appGlobals.glContext.getShaderParameter(shader, parameter); if (typeof(paramValue) != "number") { console.error("Tried to get GL parameter " + parameter + " as number when it's actually: " + typeof(paramValue)); return false; } return paramValue; } export function jsGlGetShaderInfoLog(arenaPntr, shaderId) { if (!verifyParameter(verifyGlShaderId(shaderId, false), "gl.getShaderInfoLog", "shaderId", shaderId)) { return false; } let shader = glObjects.shaders[shaderId]; let logString = appGlobals.glContext.getShaderInfoLog(shader); if (logString.length == 0) { return null; } let logStringPntr = jsStringToWasmPntr(arenaPntr, logString, true); return logStringPntr; } export function jsGlDeleteProgram(programId) { if (!verifyParameter(verifyGlProgramId(programId, false), "gl.deleteProgram", "programId", programId)) { return; } appGlobals.glContext.deleteProgram(glObjects.programs[programId]); glObjects.programs[programId] = null; } export function jsGlCreateProgram() { let newProgram = appGlobals.glContext.createProgram(); let newProgramId = glObjects.programs.length; glObjects.programs.push(newProgram); return newProgramId; } export function jsGlAttachShader(programId, shaderId) { if (!verifyParameter(verifyGlProgramId(programId, false), "gl.attachShader", "programId", programId)) { return; } if (!verifyParameter(verifyGlShaderId(shaderId, false), "gl.attachShader", "shaderId", shaderId)) { return; } let program = glObjects.programs[programId]; let shader = glObjects.shaders[shaderId]; appGlobals.glContext.attachShader(program, shader); } export function jsGlLinkProgram(programId) { if (!verifyParameter(verifyGlProgramId(programId, false), "gl.linkProgram", "programId", programId)) { return; } let program = glObjects.programs[programId]; appGlobals.glContext.linkProgram(program); } export function jsGlGetProgramInfoLog(arenaPntr, programId) { if (!verifyParameter(verifyGlProgramId(programId, false), "gl.getProgramInfoLog", "programId", programId)) { return false; } let program = glObjects.programs[programId]; let logString = appGlobals.glContext.getProgramInfoLog(program); if (logString.length == 0) { return null; } let logStringPntr = jsStringToWasmPntr(arenaPntr, logString, true); return logStringPntr; } export function jsGlUseProgram(programId) { if (!verifyParameter(verifyGlProgramId(programId, true), "gl.useProgram", "programId", programId)) { return; } let program = glObjects.programs[programId]; appGlobals.glContext.useProgram(program); } export function jsGlGetProgramParameterBool(programId, parameter) { if (!verifyParameter(verifyGlProgramId(programId, false), "gl.getProgramParameter", "programId", programId)) { return false; } let program = glObjects.programs[programId]; let paramValue = appGlobals.glContext.getProgramParameter(program, parameter); if (typeof(paramValue) != "boolean") { console.error("Tried to get GL parameter " + parameter + " as bool when it's actually: " + typeof(paramValue)); return false; } return paramValue; } export function jsGlGetProgramParameterInt(programId, parameter) { if (!verifyParameter(verifyGlProgramId(programId, false), "gl.getProgramParameter", "programId", programId)) { return false; } let program = glObjects.programs[programId]; let paramValue = appGlobals.glContext.getProgramParameter(program, parameter); if (typeof(paramValue) != "number") { console.error("Tried to get GL parameter " + parameter + " as number when it's actually: " + typeof(paramValue)); return false; } return paramValue; } // +==============================+ // | Clearing Functions | // +==============================+ export function jsGlClearColor(rValue, gValue, bValue, aValue) { appGlobals.glContext.clearColor(rValue, gValue, bValue, aValue); } export function jsGlClearDepth(depth) { appGlobals.glContext.clearDepth(depth); } export function jsGlClearStencil(stencilValue) { appGlobals.glContext.clearStencil(stencilValue); } export function jsGlClear(bufferBits) { appGlobals.glContext.clear(bufferBits); } // +==============================+ // | Drawing Functions | // +==============================+ export function jsGlDrawArrays(geometryType, startIndex, count) { appGlobals.glContext.drawArrays(geometryType, startIndex, count); } // +==============================+ // | Uniform Functions | // +==============================+ export function jsGlGetUniformLocation(programId, nameLength, namePntr) { if (!verifyParameter(verifyGlProgramId(programId, false), "gl.getUniformLocation", "programId", programId)) { return false; } let program = glObjects.programs[programId]; let nameStr = wasmPntrAndLengthToJsString(namePntr, nameLength); let newLocation = appGlobals.glContext.getUniformLocation(program, nameStr); let newLocationId = glObjects.uniformLocations.length; glObjects.uniformLocations.push(newLocation); return newLocationId; } export function jsGlUniform1f(locationId, value) { if (!verifyParameter(verifyGlUniformLocationId(locationId, false), "gl.uniform1f", "locationId", locationId)) { return false; } let location = glObjects.uniformLocations[locationId]; appGlobals.glContext.uniform1f(location, value); } export function jsGlUniform2f(locationId, value0, value1) { if (!verifyParameter(verifyGlUniformLocationId(locationId, false), "gl.uniform2f", "locationId", locationId)) { return false; } let location = glObjects.uniformLocations[locationId]; appGlobals.glContext.uniform2f(location, value0, value1); } export function jsGlUniform3f(locationId, value0, value1, value2) { if (!verifyParameter(verifyGlUniformLocationId(locationId, false), "gl.uniform3f", "locationId", locationId)) { return false; } let location = glObjects.uniformLocations[locationId]; appGlobals.glContext.uniform3f(location, value0, value1, value2); } export function jsGlUniform4f(locationId, value0, value1, value2, value3) { if (!verifyParameter(verifyGlUniformLocationId(locationId, false), "gl.uniform4f", "locationId", locationId)) { return false; } let location = glObjects.uniformLocations[locationId]; appGlobals.glContext.uniform4f(location, value0, value1, value2, value3); } export function jsGlUniform1fv(locationId, valuesCount, valuesPntr) { if (!verifyParameter(verifyGlUniformLocationId(locationId, false), "gl.uniform1fv", "locationId", locationId)) { return false; } let location = glObjects.uniformLocations[locationId]; let valuesArray = new Float32Array(appGlobals.memDataView.buffer, valuesPntr, valuesCount); appGlobals.glContext.uniform1fv(location, valuesArray); } export function jsGlUniform2fv(locationId, valuesCount, valuesPntr) { if (!verifyParameter(verifyGlUniformLocationId(locationId, false), "gl.uniform2fv", "locationId", locationId)) { return false; } let location = glObjects.uniformLocations[locationId]; let valuesArray = new Float32Array(appGlobals.memDataView.buffer, valuesPntr, valuesCount*2); appGlobals.glContext.uniform2fv(location, valuesArray); } export function jsGlUniform3fv(locationId, valuesCount, valuesPntr) { if (!verifyParameter(verifyGlUniformLocationId(locationId, false), "gl.uniform3fv", "locationId", locationId)) { return false; } let location = glObjects.uniformLocations[locationId]; let valuesArray = new Float32Array(appGlobals.memDataView.buffer, valuesPntr, valuesCount*3); appGlobals.glContext.uniform3fv(location, valuesArray); } export function jsGlUniform4fv(locationId, valuesCount, valuesPntr) { if (!verifyParameter(verifyGlUniformLocationId(locationId, false), "gl.uniform4fv", "locationId", locationId)) { return false; } let location = glObjects.uniformLocations[locationId]; let valuesArray = new Float32Array(appGlobals.memDataView.buffer, valuesPntr, valuesCount*4); appGlobals.glContext.uniform4fv(location, valuesArray); } export function jsGlUniform1i(locationId, value) { if (!verifyParameter(verifyGlUniformLocationId(locationId, false), "gl.uniform1i", "locationId", locationId)) { return false; } let location = glObjects.uniformLocations[locationId]; appGlobals.glContext.uniform1i(location, value); } export function jsGlUniform2i(locationId, value0, value1) { if (!verifyParameter(verifyGlUniformLocationId(locationId, false), "gl.uniform2i", "locationId", locationId)) { return false; } let location = glObjects.uniformLocations[locationId]; appGlobals.glContext.uniform2i(location, value0, value1); } export function jsGlUniform3i(locationId, value0, value1, value2) { if (!verifyParameter(verifyGlUniformLocationId(locationId, false), "gl.uniform3i", "locationId", locationId)) { return false; } let location = glObjects.uniformLocations[locationId]; appGlobals.glContext.uniform3i(location, value0, value1, value2); } export function jsGlUniform4i(locationId, value0, value1, value2, value3) { if (!verifyParameter(verifyGlUniformLocationId(locationId, false), "gl.uniform4i", "locationId", locationId)) { return false; } let location = glObjects.uniformLocations[locationId]; appGlobals.glContext.uniform4i(location, value0, value1, value2, value3); } export function jsGlUniform1iv(locationId, valuesCount, valuesPntr) { if (!verifyParameter(verifyGlUniformLocationId(locationId, false), "gl.uniform1iv", "locationId", locationId)) { return false; } let location = glObjects.uniformLocations[locationId]; let valuesArray = new Int32Array(appGlobals.memDataView.buffer, valuesPntr, valuesCount); appGlobals.glContext.uniform1iv(location, valuesArray); } export function jsGlUniform2iv(locationId, valuesCount, valuesPntr) { if (!verifyParameter(verifyGlUniformLocationId(locationId, false), "gl.uniform2iv", "locationId", locationId)) { return false; } let location = glObjects.uniformLocations[locationId]; let valuesArray = new Int32Array(appGlobals.memDataView.buffer, valuesPntr, valuesCount*2); appGlobals.glContext.uniform2iv(location, valuesArray); } export function jsGlUniform3iv(locationId, valuesCount, valuesPntr) { if (!verifyParameter(verifyGlUniformLocationId(locationId, false), "gl.uniform3iv", "locationId", locationId)) { return false; } let location = glObjects.uniformLocations[locationId]; let valuesArray = new Int32Array(appGlobals.memDataView.buffer, valuesPntr, valuesCount*3); appGlobals.glContext.uniform3iv(location, valuesArray); } export function jsGlUniform4iv(locationId, valuesCount, valuesPntr) { if (!verifyParameter(verifyGlUniformLocationId(locationId, false), "gl.uniform4iv", "locationId", locationId)) { return false; } let location = glObjects.uniformLocations[locationId]; let valuesArray = new Int32Array(appGlobals.memDataView.buffer, valuesPntr, valuesCount*4); appGlobals.glContext.uniform4iv(location, valuesArray); } export function jsGlUniformMatrix2fv(locationId, valuesPntr) { if (!verifyParameter(verifyGlUniformLocationId(locationId, false), "gl.uniformMatrix2fv", "locationId", locationId)) { return false; } let location = glObjects.uniformLocations[locationId]; let valuesArray = new Float32Array(appGlobals.memDataView.buffer, valuesPntr, 2*2); appGlobals.glContext.uniformMatrix2fv(location, false, valuesArray); } export function jsGlUniformMatrix3fv(locationId, valuesPntr) { if (!verifyParameter(verifyGlUniformLocationId(locationId, false), "gl.uniformMatrix3fv", "locationId", locationId)) { return false; } let location = glObjects.uniformLocations[locationId]; let valuesArray = new Float32Array(appGlobals.memDataView.buffer, valuesPntr, 3*3); appGlobals.glContext.uniformMatrix3fv(location, false, valuesArray); } export function jsGlUniformMatrix4fv(locationId, valuesPntr) { if (!verifyParameter(verifyGlUniformLocationId(locationId, false), "gl.uniformMatrix4fv", "locationId", locationId)) { return false; } let location = glObjects.uniformLocations[locationId]; let valuesArray = new Float32Array(appGlobals.memDataView.buffer, valuesPntr, 4*4); appGlobals.glContext.uniformMatrix4fv(location, false, valuesArray); } // +==============================+ // | Functions List | // +==============================+ export let jsGlFunctions = { jsGlGetError: jsGlGetError, jsGlGetParameterBool: jsGlGetParameterBool, jsGlGetParameterEnum: jsGlGetParameterEnum, jsGlGetParameterInt: jsGlGetParameterInt, jsGlGetParameterFloat: jsGlGetParameterFloat, jsGlGetParameterString: jsGlGetParameterString, jsGlEnable: jsGlEnable, jsGlDisable: jsGlDisable, jsGlBlendFunc: jsGlBlendFunc, jsGlBlendFuncSeparate: jsGlBlendFuncSeparate, jsGlBlendEquation: jsGlBlendEquation, jsGlDepthFunc: jsGlDepthFunc, jsGlFrontFace: jsGlFrontFace, jsGlDeleteBuffer: jsGlDeleteBuffer, jsGlCreateBuffer: jsGlCreateBuffer, jsGlBindBuffer: jsGlBindBuffer, jsGlBufferData: jsGlBufferData, jsGlDeleteTexture: jsGlDeleteTexture, jsGlCreateTexture: jsGlCreateTexture, jsGlActiveTexture: jsGlActiveTexture, jsGlBindTexture: jsGlBindTexture, jsGlPixelStorei: jsGlPixelStorei, jsGlTexImage2D: jsGlTexImage2D, jsGlTexParameteri: jsGlTexParameteri, jsGlGenerateMipmap: jsGlGenerateMipmap, jsGlDeleteVertexArray: jsGlDeleteVertexArray, jsGlCreateVertexArray: jsGlCreateVertexArray, jsGlBindVertexArray: jsGlBindVertexArray, jsGlEnableVertexAttribArray: jsGlEnableVertexAttribArray, jsGlVertexAttribPointer: jsGlVertexAttribPointer, jsGlDeleteShader: jsGlDeleteShader, jsGlCreateShader: jsGlCreateShader, jsGlShaderSource: jsGlShaderSource, jsGlCompileShader: jsGlCompileShader, jsGlGetShaderParameterBool: jsGlGetShaderParameterBool, jsGlGetShaderParameterInt: jsGlGetShaderParameterInt, jsGlGetShaderInfoLog: jsGlGetShaderInfoLog, jsGlDeleteProgram: jsGlDeleteProgram, jsGlCreateProgram: jsGlCreateProgram, jsGlAttachShader: jsGlAttachShader, jsGlLinkProgram: jsGlLinkProgram, jsGlGetProgramInfoLog: jsGlGetProgramInfoLog, jsGlUseProgram: jsGlUseProgram, jsGlGetProgramParameterBool: jsGlGetProgramParameterBool, jsGlGetProgramParameterInt: jsGlGetProgramParameterInt, jsGlClearColor: jsGlClearColor, jsGlClearDepth: jsGlClearDepth, jsGlClearStencil: jsGlClearStencil, jsGlClear: jsGlClear, jsGlDrawArrays: jsGlDrawArrays, jsGlGetUniformLocation: jsGlGetUniformLocation, jsGlUniform1f: jsGlUniform1f, jsGlUniform2f: jsGlUniform2f, jsGlUniform3f: jsGlUniform3f, jsGlUniform4f: jsGlUniform4f, jsGlUniform1fv: jsGlUniform1fv, jsGlUniform2fv: jsGlUniform2fv, jsGlUniform3fv: jsGlUniform3fv, jsGlUniform4fv: jsGlUniform4fv, jsGlUniform1i: jsGlUniform1i, jsGlUniform2i: jsGlUniform2i, jsGlUniform3i: jsGlUniform3i, jsGlUniform4i: jsGlUniform4i, jsGlUniform1iv: jsGlUniform1iv, jsGlUniform2iv: jsGlUniform2iv, jsGlUniform3iv: jsGlUniform3iv, jsGlUniform4iv: jsGlUniform4iv, jsGlUniformMatrix2fv: jsGlUniformMatrix2fv, jsGlUniformMatrix3fv: jsGlUniformMatrix3fv, jsGlUniformMatrix4fv: jsGlUniformMatrix4fv, }; //TODO: string getShaderInfoLog(shaderId) //TODO: string getProgramInfoLog(programId)