Skip to content

Commit

Permalink
Merge pull request #1 from syntheticmagus/native
Browse files Browse the repository at this point in the history
Merging Native into Master
  • Loading branch information
syntheticmagus committed Aug 22, 2019
2 parents d006ce8 + e7b765a commit 2ffabef
Show file tree
Hide file tree
Showing 18 changed files with 1,538 additions and 97 deletions.
9 changes: 8 additions & 1 deletion loaders/src/glTF/2.0/glTFLoader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1546,6 +1546,13 @@ export class GLTFLoader implements IGLTFLoader {
return new VertexBuffer(this._babylonScene.getEngine(), data, kind, false);
});
}
// Load joint indices as a float array since the shaders expect float data but glTF uses unsigned byte/short.
// This prevents certain platforms (e.g. D3D) from having to convert the data to float on the fly.
else if (kind === VertexBuffer.MatricesIndicesKind) {
accessor._babylonVertexBuffer = this._loadFloatAccessorAsync(`/accessors/${accessor.index}`, accessor).then((data) => {
return new VertexBuffer(this._babylonScene.getEngine(), data, kind, false);
});
}
else {
const bufferView = ArrayItem.Get(`${context}/bufferView`, this._gltf.bufferViews, accessor.bufferView);
accessor._babylonVertexBuffer = this._loadVertexBufferViewAsync(bufferView, kind).then((babylonBuffer) => {
Expand Down Expand Up @@ -1866,7 +1873,7 @@ export class GLTFLoader implements IGLTFLoader {
promises.push(this.loadImageAsync(`/images/${image.index}`, image).then((data) => {
const name = image.uri || `${this._fileName}#image${image.index}`;
const dataUrl = `data:${this._uniqueRootUrl}${name}`;
babylonTexture.updateURL(dataUrl, new Blob([data], { type: image.mimeType }));
babylonTexture.updateURL(dataUrl, data);
}));
}

Expand Down
105 changes: 105 additions & 0 deletions src/Engines/Native/nativeShaderProcessor.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import { WebGL2ShaderProcessor } from "../WebGL/webGL2ShaderProcessors";
import { VertexBuffer } from "../../Meshes/buffer";

// These numbers must match the values for bgfx::Attrib::Enum
const attributeLocations: { [kind: string]: number } = {
[VertexBuffer.PositionKind]: 0,
[VertexBuffer.NormalKind]: 1,
[VertexBuffer.TangentKind]: 2,
[VertexBuffer.ColorKind]: 4,
[VertexBuffer.MatricesIndicesKind]: 8,
[VertexBuffer.MatricesWeightsKind]: 9,
};

// Must match bgfx::Attrib::TexCoord0
const firstGenericAttributeLocation = 10;

// Must match bgfx::Attrib::TexCoord7
const lastGenericAttributeLocation = 17;

/** @hidden */
export class NativeShaderProcessor extends WebGL2ShaderProcessor {
private _genericAttributeLocation: number;
private _varyingLocationCount: number;
private _varyingLocationMap: { [name: string]: number };
private _replacements: Array<{ searchValue: RegExp, replaceValue: string }>;
private _textureCount: number;
private _uniforms: Array<string>;

public lineProcessor(line: string): string {
for (const replacement of this._replacements) {
line = line.replace(replacement.searchValue, replacement.replaceValue);
}

return line;
}

public attributeProcessor(attribute: string): string {
const match = attribute.match(/attribute\s+[^\s]+\s+([^\s]+)\s*(?:\[.+\])?\s*;/)!;
const name = match[1];

let location = attributeLocations[name];
if (location === undefined) {
location = this._genericAttributeLocation++;
if (location > lastGenericAttributeLocation) {
throw new Error("Exceeded maximum custom attributes");
}
}

return `layout(location=${location}) ${super.attributeProcessor(attribute)}`;
}

public varyingProcessor(varying: string, isFragment: boolean): string {
let location: number;

if (isFragment) {
location = this._varyingLocationMap[varying];
}
else {
location = this._varyingLocationCount++;
this._varyingLocationMap[varying] = location;
}

return `layout(location=${location}) ${super.varyingProcessor(varying, isFragment)}`;
}

public uniformProcessor(uniform: string): string {
const match = uniform.match(/uniform\s+([^\s]+)\s+([^\s]+)\s*(?:\[.+\])?\s*;/)!;
const type = match[1];
const name = match[2];

switch (type) {
case "sampler2D":
case "samplerCube": {
const suffix = type.substr(7);
const binding = this._textureCount++;
this._replacements.push({ searchValue: new RegExp(`\\b${name}\\b`), replaceValue: `sampler${suffix}(${name}Texture, ${name})` });
return `layout(binding=${binding}) uniform texture${suffix} ${name}Texture;\nlayout(binding=${binding}) uniform sampler ${name};`;
}
}

this._uniforms.push(uniform);
return this._uniforms.length === 1 ? "<UNIFORM>" : "";
}

public preProcessor(code: string, defines: string[], isFragment: boolean): string {
this._genericAttributeLocation = firstGenericAttributeLocation;

if (!isFragment) {
this._varyingLocationCount = 0;
this._varyingLocationMap = {};
}

this._replacements = [];
this._textureCount = 0;
this._uniforms = [];
return code;
}

public postProcessor(code: string, defines: string[], isFragment: boolean): string {
code = super.postProcessor(code, defines, isFragment);
code = code.replace("<UNIFORM>", `uniform Frame {\n${this._uniforms.join("\n")}\n};`);
code = code.replace("out vec4 glFragColor", "layout(location=0) out vec4 glFragColor");
return code;
}
}
9 changes: 5 additions & 4 deletions src/Engines/Processors/shaderCodeNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ export class ShaderCodeNode {
let value: string = this.line;
let processor = options.processor;
if (processor) {
// This must be done before other replacements to avoid mistakenly changing something that was already changed.
if (processor.lineProcessor) {
value = processor.lineProcessor(value, options.isFragment);
}

if (processor.attributeProcessor && StringTools.StartsWith(this.line, "attribute")) {
value = processor.attributeProcessor(this.line);
} else if (processor.varyingProcessor && StringTools.StartsWith(this.line, "varying")) {
Expand All @@ -43,10 +48,6 @@ export class ShaderCodeNode {
value = processor.endOfUniformBufferProcessor(this.line, options.isFragment);
}
}

if (processor.lineProcessor) {
value = processor.lineProcessor(value, options.isFragment);
}
}

result += value + "\r\n";
Expand Down

0 comments on commit 2ffabef

Please sign in to comment.