Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
929 changes: 929 additions & 0 deletions custom-webgl/CustomWebGL.wlp

Large diffs are not rendered by default.

80 changes: 80 additions & 0 deletions custom-webgl/app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/**
* /!\ This file is auto-generated.
*
* This is the entry point of your standalone application.
*
* There are multiple tags used by the editor to inject code automatically:
* - `wle:auto-constants:start` and `wle:auto-constants:end`: The project's constants,
* such as the project's name, whether it should use the physx runtime, etc...
* - `wle:auto-benchmark:start` and `wle:auto-benchmark:end`: Append the benchmarking code
*/

import {loadRuntime} from '@wonderlandengine/api';

/* wle:auto-constants:start */
const Constants = {
ProjectName: 'CustomWebGL.wlp',
RuntimeBaseName: 'WonderlandRuntime',
WebXRRequiredFeatures: ['local',],
WebXROptionalFeatures: ['local','hand-tracking','hit-test',],
};
const RuntimeOptions = {
webgl2: true,
webgpu: false,
physx: false,
loader: false,
xrFramebufferScaleFactor: 1,
loadUncompressedImagesAsBitmap: false,
xrOfferSession: {
mode: 'auto',
features: Constants.WebXRRequiredFeatures,
optionalFeatures: Constants.WebXROptionalFeatures,
},
canvas: 'canvas',
};
/* wle:auto-constants:end */

const engine = await loadRuntime(Constants.RuntimeBaseName, RuntimeOptions);
engine.onLoadingScreenEnd.once(() => {
const el = document.getElementById('version');
if (el) setTimeout(() => el.remove(), 2000);
});

/* WebXR setup. */

function requestSession(mode) {
engine
.requestXRSession(mode, Constants.WebXRRequiredFeatures, Constants.WebXROptionalFeatures)
.catch((e) => console.error(e));
}

function setupButtonsXR() {
/* Setup AR / VR buttons */
const arButton = document.getElementById('ar-button');
if (arButton) {
arButton.setAttribute('data-supported', engine.arSupported.toString());
arButton.addEventListener('click', () => requestSession('immersive-ar'));
}
const vrButton = document.getElementById('vr-button');
if (vrButton) {
vrButton.setAttribute('data-supported', engine.vrSupported.toString());
vrButton.addEventListener('click', () => requestSession('immersive-vr'));
}
}

if (document.readyState === 'loading') {
window.addEventListener('load', setupButtonsXR);
} else {
setupButtonsXR();
}

/* Load main scene */
try {
await engine.loadMainScene(`${Constants.ProjectName}.bin`);
} catch (e) {
console.error(e);
window.alert(`Failed to load ${Constants.ProjectName}.bin:`, e);
}

/* wle:auto-benchmark:start */
/* wle:auto-benchmark:end */
63 changes: 63 additions & 0 deletions custom-webgl/js/custom-webgl.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { Component, Pipeline, TextureManager } from "@wonderlandengine/api";

const TextureUnit = 6;

export class CustomWebGL extends Component {
static TypeName = 'custom-webgl';

url = 'noise.png';

_gl: WebGL2RenderingContext | null = null;
_texture: WebGLTexture | null = null;

_pipeline: Pipeline;
_ready = false;

_draw = () => {
const gl = this._gl;

const prevActive = gl.getParameter(gl.ACTIVE_TEXTURE);
gl.activeTexture(WebGL2RenderingContext.TEXTURE0 + TextureUnit);
gl.bindTexture(WebGL2RenderingContext.TEXTURE_2D, this._texture);

if(!this._ready) {
const shader = this._pipeline.webglProgram;
gl.useProgram(shader);
const loc = gl.getUniformLocation(shader, 'customTexture');
gl.uniform1i(loc, TextureUnit);
this._ready = true;
}

/* This is required to avoid breaking the current active state in the engine */
gl.activeTexture(prevActive);
};

async init() {
this._gl = this.engine.canvas.getContext('webgl2')!;
this._texture = this._gl.createTexture();

const img = await TextureManager.fetchImage(this.url, 'anonymous');

const gl = this._gl!;
gl.bindTexture(gl.TEXTURE_2D, this._texture);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, img);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
}

onActivate(): void {
this._pipeline = this.engine.pipelines.findByName('CustomShader');
this._pipeline.onPreRender.add(this._draw);
}

onDeactivate(): void {
if (!this._pipeline) return;
this._pipeline.onPreRender.remove(this._draw);
}

onDestroy(): void {
this._gl.deleteTexture(this._texture);
}
}
23 changes: 23 additions & 0 deletions custom-webgl/js/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/**
* /!\ This file is auto-generated.
*
* This is the entry point of your standalone application.
*
* There are multiple tags used by the editor to inject code automatically:
* - `wle:auto-imports:start` and `wle:auto-imports:end`: The list of import statements
* - `wle:auto-register:start` and `wle:auto-register:end`: The list of component to register
*/

/* wle:auto-imports:start */
import {MouseLookComponent} from '@wonderlandengine/components';
import {WasdControlsComponent} from '@wonderlandengine/components';
import {CustomWebGL} from './custom-webgl.js';
/* wle:auto-imports:end */

export default function(engine) {
/* wle:auto-register:start */
engine.registerComponent(MouseLookComponent);
engine.registerComponent(WasdControlsComponent);
engine.registerComponent(CustomWebGL);
/* wle:auto-register:end */
}
22 changes: 22 additions & 0 deletions custom-webgl/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"name": "default-scene",
"version": "1.0.0",
"description": "Wonderland Engine default template",
"main": "js/index.js",
"type": "module",
"module": "js/index.js",
"scripts": {
"build": "echo \"The 'build' script is run by the editor and should produce your application bundle\""
},
"keywords": [
"wonderland-engine"
],
"dependencies": {
"@wonderlandengine/api": "file:../../../wonderland-engine/js/api/packages/api",
"@wonderlandengine/components": "^1.2.1",
"gl-matrix": "^3.4.3"
},
"overrides": {
"@wonderlandengine/api": "$@wonderlandengine/api"
}
}
34 changes: 34 additions & 0 deletions custom-webgl/shaders/CustomShader.frag
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#include "lib/Compatibility.glsl"

#define USE_TEXTURE_COORDS /* provides fragTextureCoords */
#define USE_MATERIAL_ID /* provides fragMaterialId */

#include "lib/Inputs.glsl"
#include "lib/Packing.glsl"
#include "lib/Materials.glsl"

uniform sampler2D customTexture; /* Binding 6 */

/* This structure is essential. Wonderland Editor will look
* for it and parse the material properties to generate UI
* from it.
* If a uint property ends with "*Texture", it will be regarded
* as a texture, only 2D textures are currently supported. */
struct Material {
lowp vec4 color;
};

/* Wonderland Engine does some material packing magic and
* automatically generates the matching unpacking code
* if it finds this snippet in a shader. */
Material decodeMaterial(uint matIndex) {
{{decoder}}
return mat;
}

void main() {
Material mat = decodeMaterial(fragMaterialId);
vec4 tex = textureLod(customTexture, fragTextureCoords, 0.0);
outColor = tex * mat.color;
outColor.a = length(tex.rgb);
}
3 changes: 3 additions & 0 deletions custom-webgl/static/noise.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 10 additions & 0 deletions custom-webgl/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"compilerOptions": {
"target": "es2022",
"module": "nodenext",
"moduleResolution": "nodenext",
"experimentalDecorators": true,
},
"include": [ "./**/*.ts" ],
"exclude": ["node_modules", "deploy"]
}
Loading