Skip to content

Commit

Permalink
feat: add support for array uniforms (float, vec2, vec3, mat4)
Browse files Browse the repository at this point in the history
  • Loading branch information
bhouston committed Jul 9, 2020
1 parent e27f97d commit c27d7da
Show file tree
Hide file tree
Showing 2 changed files with 97 additions and 3 deletions.
44 changes: 44 additions & 0 deletions src/lib/math/arrays/Linearizers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { Matrix4 } from "../Matrix4";
import { Quaternion } from "../Quaternion";
import { Vector2 } from "../Vector2";
import { Vector3 } from "../Vector3";

export function linearizeNumberArray(array: number[]): Float32Array {
const result = new Float32Array(array.length);
for (let i = 0; i < array.length; i++) {
result[i] = array[i];
}
return result;
}

export function linearizeVector2Array(array: Vector2[]): Float32Array {
const result = new Float32Array(array.length * 2);
for (let i = 0; i < array.length; i++) {
array[i].toArray(result, i * 2);
}
return result;
}

export function linearizeVector3Array(array: Vector3[]): Float32Array {
const result = new Float32Array(array.length * 3);
for (let i = 0; i < array.length; i++) {
array[i].toArray(result, i * 3);
}
return result;
}

export function linearizeQuaternionArray(array: Quaternion[]): Float32Array {
const result = new Float32Array(array.length * 4);
for (let i = 0; i < array.length; i++) {
array[i].toArray(result, i * 4);
}
return result;
}

export function linearizeMatrix4Array(array: Matrix4[]): Float32Array {
const result = new Float32Array(array.length * 16);
for (let i = 0; i < array.length; i++) {
array[i].toArray(result, i * 16);
}
return result;
}
56 changes: 53 additions & 3 deletions src/lib/renderers/webgl/programs/ProgramUniform.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
import {
linearizeMatrix4Array,
linearizeNumberArray,
linearizeVector2Array,
linearizeVector3Array,
} from "../../../math/arrays/Linearizers";
import { Matrix4 } from "../../../math/Matrix4";
import { Vector2 } from "../../../math/Vector2";
import { Vector3 } from "../../../math/Vector3";
Expand All @@ -7,21 +13,33 @@ import { TexImage2D } from "../textures/TexImage2D";
import { Program } from "./Program";
import { UniformType } from "./UniformType";

export type UniformValue = number | Vector2 | Vector3 | Matrix4 | TexImage2D;
export type UniformValue =
| number
| Vector2
| Vector3
| Matrix4
| TexImage2D
| number[]
| Vector2[]
| Vector3[]
| Matrix4[];
export type UniformValueMap = { [key: string]: UniformValue };

const array1dRegexp = /^([a-zA-Z_0-9]+)\[[0-9]+\]$/;
// glsl v3+ only const array2dRegexp = /^[a-zA-Z_0-9]+\[[0-9]+,[0-9]+\]$/;

export class ProgramUniform {
context: RenderingContext;
name: string;
size: number;
dimensions: number;
uniformType: UniformType;
glLocation: WebGLUniformLocation;
valueHashCode = 0;
textureUnit = -1;

constructor(public program: Program, public index: number) {
this.context = program.context;
this.name = name;

const gl = program.context.gl;

Expand All @@ -32,7 +50,14 @@ export class ProgramUniform {
throw new Error(`Can not find uniform with index: ${index}`);
}

this.name = activeInfo.name;
const array1dMatch = activeInfo.name.match(array1dRegexp);
if (array1dMatch !== null) {
this.name = array1dMatch[1];
this.dimensions = 1;
} else {
this.name = activeInfo.name;
this.dimensions = 0;
}
this.size = activeInfo.size;
this.uniformType = activeInfo.type as UniformType;

Expand Down Expand Up @@ -72,6 +97,12 @@ export class ProgramUniform {
}
return this;
}
if (value instanceof Array && value.length > 0 && typeof value[0] === "number") {
const array = linearizeNumberArray(value as number[]);
gl.uniform1fv(this.glLocation, array);
this.valueHashCode = -1;
return this;
}
break;
case UniformType.FloatVec2:
if (value instanceof Vector2) {
Expand All @@ -82,6 +113,12 @@ export class ProgramUniform {
}
return this;
}
if (value instanceof Array && value.length > 0 && value[0] instanceof Vector2) {
const array = linearizeVector2Array(value as Vector2[]);
gl.uniform2fv(this.glLocation, array);
this.valueHashCode = -1;
return this;
}
break;
case UniformType.FloatVec3:
if (value instanceof Vector3) {
Expand All @@ -92,6 +129,13 @@ export class ProgramUniform {
}
return this;
}
if (value instanceof Array && value.length > 0 && value[0] instanceof Vector3) {
const array = linearizeVector3Array(value as Vector3[]);
console.log(this.name, "linearized array", array);
gl.uniform3fv(this.glLocation, array);
this.valueHashCode = -1;
return this;
}
break;
// case UniformType.FloatVec4:
// case UniformType.FloatMat2:
Expand All @@ -111,6 +155,12 @@ export class ProgramUniform {
}
return this;
}
if (value instanceof Array && value.length > 0 && value[0] instanceof Matrix4) {
const array = linearizeMatrix4Array(value as Matrix4[]);
gl.uniformMatrix4fv(this.glLocation, false, array);
this.valueHashCode = -1;
return this;
}
break;
case UniformType.Sampler2D:
// case UniformType.IntSampler2D:
Expand Down

0 comments on commit c27d7da

Please sign in to comment.