blob: 384df4844647e44acde039f9bfc929bba8c8d91c [file] [edit]
// Copyright (C) 2026 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
export function getUniformLocation(
gl: WebGL2RenderingContext,
program: WebGLProgram,
name: string,
): WebGLUniformLocation {
const loc = gl.getUniformLocation(program, name);
if (loc === null) {
throw new Error(`Uniform "${name}" not found (optimized out or typo?)`);
}
return loc;
}
export function getAttribLocation(
gl: WebGL2RenderingContext,
program: WebGLProgram,
name: string,
): number {
const loc = gl.getAttribLocation(program, name);
if (loc === -1) {
throw new Error(`Attribute "${name}" not found (optimized out or typo?)`);
}
return loc;
}
export function compileShader(
gl: WebGL2RenderingContext,
type: number,
source: string,
): WebGLShader {
const shader = gl.createShader(type);
if (!shader) throw new Error('Failed to create shader');
gl.shaderSource(shader, source);
gl.compileShader(shader);
const status = gl.getShaderParameter(shader, gl.COMPILE_STATUS) as GLboolean;
if (!status) {
const info = gl.getShaderInfoLog(shader);
gl.deleteShader(shader);
throw new Error(`Shader compile error: ${info}`);
}
return shader;
}
export function linkProgram(
gl: WebGL2RenderingContext,
vertexShader: WebGLShader,
fragmentShader: WebGLShader,
): WebGLProgram {
const program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
const status = gl.getProgramParameter(program, gl.LINK_STATUS) as GLboolean;
if (!status) {
const info = gl.getProgramInfoLog(program);
gl.deleteProgram(program);
throw new Error(`Program link error: ${info}`);
}
return program;
}
// Convenience - compile both and link in one go
export function createProgram(
gl: WebGL2RenderingContext,
vertSource: string,
fragSource: string,
): WebGLProgram {
const vert = compileShader(gl, gl.VERTEX_SHADER, vertSource);
const frag = compileShader(gl, gl.FRAGMENT_SHADER, fragSource);
return linkProgram(gl, vert, frag);
}