Skip to content

Commit

Permalink
feat(webgl): Enforce WebGPU style topology
Browse files Browse the repository at this point in the history
  • Loading branch information
ibgreen committed Aug 18, 2023
1 parent b1b1ba3 commit 39c13fa
Show file tree
Hide file tree
Showing 24 changed files with 199 additions and 485 deletions.
294 changes: 77 additions & 217 deletions docs/api-reference/core/resources/render-pipeline.md

Large diffs are not rendered by default.

12 changes: 1 addition & 11 deletions docs/sidebar.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,8 @@
"type": "category",
"label": "V8 API Reference",
"items": [
{
"type": "category",
"label": "@luma.gl/webgl-legacy",
"items": [
"api-reference-v8/webgl-legacy/README",
"api-reference-v8/constants/README",
"api-reference-v8/webgl-legacy/class-list",
"api-reference-v8/webgl-legacy/accessors",
"api-reference-v8/webgl-legacy/context/context-api",
Expand All @@ -85,13 +82,6 @@
"api-reference-v8/webgl-legacy/classes/vertex-array",
"api-reference-v8/webgl-legacy/classes/vertex-array-object"
]
},
{
"type": "category",
"label": "@luma.gl/constants",
"items": [
"api-reference-v8/constants/README"
]
}
]
},
Expand Down
1 change: 1 addition & 0 deletions examples/showcase/persistence/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ export default class AppAnimationLoopTemplate extends AnimationLoopTemplate {
const QUAD_POSITIONS = [-1, -1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1];

const quadGeometry = new Geometry({
topology: 'triangle-list',
attributes: {
aPosition: {
value: new Float32Array(QUAD_POSITIONS),
Expand Down
8 changes: 4 additions & 4 deletions modules-wip/experimental/src/gltf/gltf-instantiator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ export class GLTFInstantiator {
this.device,
{
id: gltfPrimitive.name || `${gltfMesh.name || gltfMesh.id}-primitive-${i}`,
topology: convertGLDrawModeToTopology(gltfPrimitive.mode || 4),
topology: convertGLPrimitiveTopologyToTopology(gltfPrimitive.mode || 4),
vertexCount,
attributes: this.createAttributes(gltfPrimitive.attributes, gltfPrimitive.indices),
...this.options
Expand Down Expand Up @@ -236,17 +236,17 @@ enum GL {
TRIANGLE_FAN = 0x6
}

export function convertGLDrawModeToTopology(
export function convertGLPrimitiveTopologyToTopology(
drawMode: GL.POINTS | GL.LINES | GL.LINE_STRIP | GL.LINE_LOOP | GL.TRIANGLES | GL.TRIANGLE_STRIP | GL.TRIANGLE_FAN,
): PrimitiveTopology {
switch (drawMode) {
case GL.POINTS: return 'point-list';
case GL.LINES: return 'line-list';
case GL.LINE_STRIP: return 'line-strip';
case GL.LINE_LOOP: return 'line-loop';
case GL.LINE_LOOP: return 'line-loop-webgl';
case GL.TRIANGLES: return 'triangle-list';
case GL.TRIANGLE_STRIP: return 'triangle-strip';
case GL.TRIANGLE_FAN: return 'triangle-fan';
case GL.TRIANGLE_FAN: return 'triangle-fan-webgl';
default: throw new Error(drawMode);
}
}
2 changes: 1 addition & 1 deletion modules/constants/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ export {GL} from './constants-enum';

// WebGL types
export type {
GLDrawMode,
GLPrimitiveTopology,
GLPrimitive,
GLDataType,
GLPixelType,
Expand Down
2 changes: 1 addition & 1 deletion modules/constants/src/webgl-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export type NumberArray = number[] | TypedArray;
type Framebuffer = unknown;

/** Rendering primitives. Constants passed to drawElements() or drawArrays() to specify what kind of primitive to render. */
export type GLDrawMode =
export type GLPrimitiveTopology =
| GL.POINTS
| GL.LINES
| GL.LINE_STRIP
Expand Down
4 changes: 2 additions & 2 deletions modules/core/src/adapter/types/parameters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ export type PrimitiveTopology =
'line-list' |
'line-strip' |
/** @deprecated */
'line-loop' |
'line-loop-webgl' |
'triangle-list' |
'triangle-strip' |
/** @deprecated */
'triangle-fan';
'triangle-fan-webgl';

export type IndexFormat = 'uint16' | 'uint32';

Expand Down
4 changes: 4 additions & 0 deletions modules/core/src/adapter/types/vertex-formats.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,13 @@ export type VertexFormat =
'uint8x4' |
'sint8x2' |
'sint8x4' |
'unorm8-webgl' |
'unorm8x2' |
'unorm8x3-webgl' |
'unorm8x4' |
'snorm8-webgl' |
'snorm8x2' |
'snorm8x3-webgl' |
'snorm8x4' |
'uint16x2' |
'uint16x4' |
Expand Down
35 changes: 28 additions & 7 deletions modules/core/src/adapter/utils/decode-vertex-format.ts
Original file line number Diff line number Diff line change
@@ -1,28 +1,49 @@
import {VertexFormat, VertexType} from '../types/vertex-formats';
import { decodeVertexType } from './decode-data-type';
import {decodeVertexType} from './decode-data-type';

/**
* Decodes a vertex format, returning type, components, byte length and flags (integer, signed, normalized)
*/
export function decodeVertexFormat(format: VertexFormat): {
export type VertexFormatInfo = {
/** Length in bytes */
byteLength: number;
/** Type of each component */
type: VertexType;
/** Number of components per vertex / row */
components: number;
/** Is this an integer format (normalized integer formats are not integer) */
integer: boolean;
/** Is this a signed format? */
signed: boolean;
/** Is this a normalized format? */
normalized: boolean;
} {
/** Is this a webgl only format? */
webglOnly?: boolean;
};

/**
* Decodes a vertex format, returning type, components, byte length and flags (integer, signed, normalized)
*/
export function decodeVertexFormat(format: VertexFormat): VertexFormatInfo {
// Strip the -webgl ending if present
let webglOnly: boolean | undefined;
if (format.endsWith('-webgl')) {
format.replace('-webgl', '');
webglOnly = true;
}
// split components from type
const [type_, count] = format.split('x');
const type = type_ as VertexType;
const components = count ? parseInt(count) : 1;
// decode the type
const decodedType = decodeVertexType(type);
return {
const result: VertexFormatInfo = {
type,
components,
byteLength: decodedType.byteLength * components,
integer: decodedType.integer,
signed: decodedType.signed,
normalized: decodedType.normalized
};
if (webglOnly) {
result.webglOnly = true;
}
return result;
}
2 changes: 2 additions & 0 deletions modules/engine/src/geometries/cube-geometry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,13 @@ export class CubeGeometry extends Geometry {
super(indices ? {
...props,
id,
topology: 'triangle-list',
indices: {size: 1, value: CUBE_INDICES},
attributes: {...ATTRIBUTES, ...props.attributes}
} : {
...props,
id,
topology: 'triangle-list',
indices: undefined,
attributes: {...NON_INDEXED_ATTRIBUTES, ...props.attributes}
});
Expand Down
1 change: 1 addition & 0 deletions modules/engine/src/geometries/ico-sphere-geometry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export class IcoSphereGeometry extends Geometry {
super({
...props,
id,
topology: 'triangle-list',
indices,
attributes: {...attributes, ...props.attributes}
});
Expand Down
1 change: 1 addition & 0 deletions modules/engine/src/geometries/plane-geometry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export class PlaneGeometry extends Geometry {
super({
...props,
id,
topology: 'triangle-list',
indices,
attributes: {...attributes, ...props.attributes}
});
Expand Down
1 change: 1 addition & 0 deletions modules/engine/src/geometries/sphere-geometry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export class SphereGeometry extends Geometry {
super({
...props,
id,
topology: 'triangle-list',
indices,
attributes: {...attributes, ...props.attributes}
});
Expand Down
1 change: 1 addition & 0 deletions modules/engine/src/geometries/truncated-cone-geometry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ export class TruncatedConeGeometry extends Geometry {
super({
...props,
id,
topology: 'triangle-list',
indices,
attributes: {
POSITION: {size: 3, value: attributes.POSITION},
Expand Down
120 changes: 35 additions & 85 deletions modules/engine/src/geometry/geometry.ts
Original file line number Diff line number Diff line change
@@ -1,89 +1,59 @@
// luma.gl, MIT license
import type {PrimitiveTopology, TypedArray} from '@luma.gl/core';
import {uid, assert} from '@luma.gl/core';
import {GL} from '@luma.gl/constants';

/**
* Rendering primitives - "topology" specifies how to extract primitives from vertices.
* @deprecated - use string constants instead
*/
export type GLTopology =
GL.POINTS | // draw single points.
GL.LINES | // draw lines. Each vertex connects to the one after it.
GL.LINE_LOOP | // draw lines. Each set of two vertices is treated as a separate line segment.
GL.LINE_STRIP | // draw a connected group of line segments from the first vertex to the last
GL.TRIANGLES | // draw triangles. Each set of three vertices creates a separate triangle.
GL.TRIANGLE_STRIP | // draw a connected group of triangles.
GL.TRIANGLE_FAN // draw a connected group of triangles.
;

export type GeometryAttribute = {
size?: number;
value: TypedArray;
[key: string]: any
}
[key: string]: any;
};

export type GeometryProps = {
id?: string;
attributes?: Record<string, GeometryAttribute | TypedArray>,
indices?: GeometryAttribute | TypedArray;
vertexCount?: number;
/** Determines how vertices are read from the 'vertex' attributes */
topology?: 'point-list' | 'line-list' | 'line-strip' | 'triangle-list' | 'triangle-strip';
/** @deprecated */
drawMode?: GLTopology;
topology:
| 'point-list'
| 'line-list'
| 'line-strip'
| 'line-loop-webgl'
| 'triangle-list'
| 'triangle-strip'
| 'triangle-fan-webgl';
/** Auto calculated from attributes if not provided */
vertexCount?: number;
attributes?: Record<string, GeometryAttribute | TypedArray>;
indices?: GeometryAttribute | TypedArray;
};

type GeometryAttributes = {
POSITION: GeometryAttribute,
NORMAL: GeometryAttribute,
TEXCOORD_0: GeometryAttribute,
COLOR_0?: GeometryAttribute,
indices?: {size?: number, value: Uint32Array | Uint16Array};
POSITION: GeometryAttribute;
NORMAL: GeometryAttribute;
TEXCOORD_0: GeometryAttribute;
COLOR_0?: GeometryAttribute;
indices?: {size?: number; value: Uint32Array | Uint16Array};
};

export class Geometry {
/** @deprecated */
static DRAW_MODE = {
POINTS: GL.POINTS, // draw single points.
LINES: GL.LINES, // draw lines. Each vertex connects to the one after it.
LINE_LOOP: GL.LINE_LOOP, // draw lines. Each set of two vertices is treated as a separate line segment.
LINE_STRIP: GL.LINE_STRIP, // draw a connected group of line segments from the first vertex to the last
TRIANGLES: GL.TRIANGLES, // draw triangles. Each set of three vertices creates a separate triangle.
TRIANGLE_STRIP: GL.TRIANGLE_STRIP, // draw a connected group of triangles.
TRIANGLE_FAN: GL.TRIANGLE_FAN // draw a connected group of triangles.
};

readonly id: string;
userData: Record<string, unknown> = {};

/** Determines how vertices are read from the 'vertex' attributes */
topology?: PrimitiveTopology;
/** @deprecated */
readonly drawMode: GLTopology = GL.TRIANGLES;

readonly topology?: PrimitiveTopology;
readonly vertexCount: number;
readonly indices?: Uint16Array | Uint32Array;
readonly attributes: {
POSITION: GeometryAttribute,
NORMAL: GeometryAttribute,
TEXCOORD_0: GeometryAttribute,
COLOR_0?: GeometryAttribute,
[key: string]: GeometryAttribute | undefined
POSITION: GeometryAttribute;
NORMAL: GeometryAttribute;
TEXCOORD_0: GeometryAttribute;
COLOR_0?: GeometryAttribute;
[key: string]: GeometryAttribute | undefined;
};
readonly indices?: Uint16Array | Uint32Array;

constructor(props: GeometryProps = {}) {
const {
id = uid('geometry'),
drawMode = GL.TRIANGLES,
attributes = {},
indices = null,
vertexCount = null
} = props;
userData: Record<string, unknown> = {};

constructor(props: GeometryProps) {
const {attributes = {}, indices = null, vertexCount = null} = props;

this.id = id;
this.drawMode = drawMode;
this.topology = props.topology || convertToTopology(drawMode);
this.id = props.id || uid('geometry');
this.topology = props.topology;

if (indices) {
// @ts-expect-error
Expand All @@ -94,9 +64,10 @@ export class Geometry {
this.attributes = {};

for (const [attributeName, attributeValue] of Object.entries(attributes)) {

// Wrap "unwrapped" arrays and try to autodetect their type
const attribute: GeometryAttribute = ArrayBuffer.isView(attributeValue) ? {value: attributeValue} : attributeValue;
const attribute: GeometryAttribute = ArrayBuffer.isView(attributeValue)
? {value: attributeValue}
: attributeValue;

assert(
ArrayBuffer.isView(attribute.value),
Expand Down Expand Up @@ -127,11 +98,6 @@ export class Geometry {
this.vertexCount = vertexCount || this._calculateVertexCount(this.attributes, this.indices);
}

/** @deprecated Use string topology constants instead */
get mode() {
return this.drawMode;
}

getVertexCount(): number {
return this.vertexCount;
}
Expand All @@ -154,7 +120,6 @@ export class Geometry {
// size: elements per vertex
// target: WebGL buffer type (string or constant)
_setAttributes(attributes: Record<string, GeometryAttribute>, indices: any): this {

return this;
}

Expand All @@ -175,18 +140,3 @@ export class Geometry {
return vertexCount;
}
}

function convertToTopology(drawMode: GLTopology): PrimitiveTopology {
switch (drawMode) {
case GL.POINTS: return 'point-list'; // draw single points.
case GL.LINES: return 'line-list'; // draw lines. Each vertex connects to the one after it.
case GL.LINE_STRIP: return 'line-strip'; // draw a connected group of line segments from the first vertex to the last
case GL.TRIANGLES: return 'triangle-list'; // draw triangles. Each set of three vertices creates a separate triangle.
case GL.TRIANGLE_STRIP: return 'triangle-strip'; // draw a connected group of triangles.

case GL.TRIANGLE_FAN: return 'triangle-fan'; // draw a connected group of triangles.
case GL.LINE_LOOP: return 'line-loop'; // draw lines. Each set of two vertices is treated as a separate line segment.
default:
throw new Error(String(drawMode));
}
}
1 change: 1 addition & 0 deletions modules/engine/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export {GroupNode} from './scenegraph/group-node';
export {ModelNode} from './scenegraph/model-node';

// Geometries
export type {GeometryProps} from './geometry/geometry';
export {Geometry} from './geometry/geometry';

// Primitives
Expand Down
Loading

0 comments on commit 39c13fa

Please sign in to comment.