Merge main branch (#258)

This commit is contained in:
GuoLei
2021-04-27 13:52:00 +08:00
committed by GitHub
parent 9e2a9d10ff
commit edaeee32ee
42 changed files with 263 additions and 207 deletions

View File

@@ -1,7 +1,38 @@
# [0.3.0](https://github.com/oasis-engine/engine/compare/e217213ec80f0aa9356d74ea12d2f1ef63776f85...0.3.0) (2021-04-05)
## [0.3.3](https://github.com/oasis-engine/engine/compare/v0.3.2...v0.3.3) (2021-04-16)
### Bug Fixes
* default active texture unit error ([#231](https://github.com/oasis-engine/engine/issues/231)) ([ed2f3ed](https://github.com/oasis-engine/engine/commit/ed2f3ede0e177caf319f7d862094cb15fcb2922c))
* memory crash caused by 'RenderElement' pool ([#211](https://github.com/oasis-engine/engine/issues/211)) ([0f8eb79](https://github.com/oasis-engine/engine/commit/0f8eb795d51229fcd3d6fba2d522335efdc23beb))
* model flicker bug ([ffa771d](https://github.com/oasis-engine/engine/commit/ffa771d3b60bcec55cbcce371cc9eba3bb3d8f94))
## [0.3.2](https://github.com/oasis-engine/engine/compare/v0.3.1...v0.3.2) (2021-04-14)
### Bug Fixes
* error caused by duplicate shader name ([839ec0f](https://github.com/oasis-engine/engine/commit/839ec0ff5103278b08546cb468b28a5048595dd9))
* material blend error ([#214](https://github.com/oasis-engine/engine/issues/214)) ([897fd21](https://github.com/oasis-engine/engine/commit/897fd21810b79293b65442321523c1d903c06cbe))
* shader wanning with unUpload texture ([#212](https://github.com/oasis-engine/engine/issues/212)) ([8f52847](https://github.com/oasis-engine/engine/commit/8f52847cdf02849953d7c4425183fc28828166b5))
* texture upload warnning ([#183](https://github.com/oasis-engine/engine/issues/183)) ([4a9c0c9](https://github.com/oasis-engine/engine/commit/4a9c0c9c49c8e63e7ee998569952a4d5d1cbd77a))
## [0.3.1](https://github.com/oasis-engine/engine/compare/0.3.0...v0.3.1) (2021-04-09)
### Bug Fixes
* GLTF DRACO decode bug ([#141](https://github.com/oasis-engine/engine/issues/141)) ([#164](https://github.com/oasis-engine/engine/issues/164)) ([19a1f32](https://github.com/oasis-engine/engine/commit/19a1f32e3e7b1699bc3a91fbca140a2996930363))
* SpriteRenderer bounds error ([#176](https://github.com/oasis-engine/engine/issues/176))
## [0.3.0](https://github.com/oasis-engine/engine/compare/e217213ec80f0aa9356d74ea12d2f1ef63776f85...0.3.0) (2021-04-05)
### Features
* add `materialCount`, `getInstanceMaterial()`, `getMaterial()/setMaterial()`, `getMaterials()/setMaterials()` properties and methods in `Renderer`. ([#75](https://github.com/oasis-engine/engine/issues/75))
* Delete `GeometryRenderer`, mesh renderer uniformly uses `MeshRenderer`.([#75](https://github.com/oasis-engine/engine/issues/75))
* Remove geometry classes such as `GeometryXX` and use `PrimitiveMesh` instead.([#85](https://github.com/oasis-engine/engine/issues/85))

View File

@@ -1,6 +1,6 @@
{
"npmClient": "npm",
"version": "0.3.0",
"version": "0.3.7",
"bootstrap": {
"hoist": true
},

View File

@@ -1,6 +1,6 @@
{
"name": "@oasis-engine/controls",
"version": "0.3.0",
"version": "0.3.7",
"license": "MIT",
"scripts": {
"b:types": "tsc",
@@ -15,6 +15,6 @@
"types/**/*"
],
"dependencies": {
"oasis-engine": "0.3.0"
"oasis-engine": "0.3.7"
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "@oasis-engine/core",
"version": "0.3.0",
"version": "0.3.7",
"license": "MIT",
"main": "dist/main.js",
"module": "dist/module.js",
@@ -13,9 +13,9 @@
"types/**/*"
],
"dependencies": {
"@oasis-engine/math": "0.3.0"
"@oasis-engine/math": "0.3.7"
},
"devDependencies": {
"@oasis-engine/design": "0.3.0"
"@oasis-engine/design": "0.3.7"
}
}

View File

@@ -26,14 +26,14 @@ const spriteFragmentShader = `
precision mediump float;
precision mediump int;
uniform sampler2D u_texture;
uniform sampler2D u_spriteTexture;
varying vec2 v_uv;
varying vec4 v_color;
void main()
{
// Only use the Alpha of the texture as a mask, so that the tint color can still be controlled to fade out.
vec4 baseColor = texture2D(u_texture, v_uv);
vec4 baseColor = texture2D(u_spriteTexture, v_uv);
gl_FragColor = baseColor * v_color;
}
`;

View File

@@ -4,7 +4,6 @@ import { assignmentClone, deepClone, ignoreClone } from "../../clone/CloneManage
import { Entity } from "../../Entity";
import { Material, RenderQueueType } from "../../material";
import { Renderer } from "../../Renderer";
import { SpriteElement } from "../../RenderPipeline/SpriteElement";
import { BlendFactor, BlendOperation, CullMode, Shader } from "../../shader";
import { ShaderProperty } from "../../shader/ShaderProperty";
import { UpdateFlag } from "../../UpdateFlag";
@@ -15,7 +14,7 @@ import "./SpriteMaterial";
* Renders a Sprite for 2D graphics.
*/
export class SpriteRenderer extends Renderer {
private static _textureProperty: ShaderProperty = Shader.getPropertyByName("u_texture");
private static _textureProperty: ShaderProperty = Shader.getPropertyByName("u_spriteTexture");
private static _tempVec3: Vector3 = new Vector3();
private static _defaultMaterial: Material = null;
@@ -166,7 +165,8 @@ export class SpriteRenderer extends Renderer {
this.shaderData.setTexture(SpriteRenderer._textureProperty, texture);
const material = this.getMaterial() || this._getDefaultMaterial();
const spriteElement = SpriteElement.getFromPool();
const spriteElementPool = this._engine._spriteElementPool;
const spriteElement = spriteElementPool.getFromPool();
spriteElement.setValue(this, _positions, sprite._uv, sprite._triangles, this.color, material, camera);
camera._renderPipeline.pushPrimitive(spriteElement);
}

View File

@@ -179,14 +179,14 @@ export class ComponentsManager {
element._updateShaderData(context);
element._render(camera);
// union camera global macro and renderer macro.
ShaderMacroCollection.unionCollection(
camera._globalShaderMacro,
element.shaderData._macroCollection,
element._globalShaderMacro
);
element._render(camera);
}
}

View File

@@ -16,6 +16,7 @@ import { Shader } from "./shader/Shader";
import { ShaderPool } from "./shader/ShaderPool";
import { ShaderProgramPool } from "./shader/ShaderProgramPool";
import { RenderState } from "./shader/state/RenderState";
import { Texture2D, TextureCubeFace, TextureCubeMap, TextureFormat } from "./texture";
/** TODO: delete */
const engineFeatureManager = new FeatureManager<EngineFeature>();
@@ -29,8 +30,13 @@ export class Engine extends EventDispatcher {
_hardwareRenderer: IHardwareRenderer;
_lastRenderState: RenderState = new RenderState();
_renderElementPool: ClassPool<RenderElement> = new ClassPool(RenderElement);
_spriteElementPool: ClassPool<SpriteElement> = new ClassPool(SpriteElement);
_renderContext: RenderContext = new RenderContext();
/* @internal */
_whiteTexture2D: Texture2D;
/* @internal */
_whiteTextureCube: TextureCubeMap;
/* @internal */
_renderCount: number = 0;
/* @internal */
@@ -137,6 +143,24 @@ export class Engine extends EventDispatcher {
// @todo delete
engineFeatureManager.addObject(this);
this._sceneManager.activeScene = new Scene(this, "DefaultScene");
const whitePixel = new Uint8Array([255, 255, 255, 255]);
const whiteTextrue2D = new Texture2D(this, 1, 1, TextureFormat.R8G8B8A8, false);
whiteTextrue2D.setPixelBuffer(whitePixel);
whiteTextrue2D.isGCIgnored = true;
const whiteTextrueCube = new TextureCubeMap(this, 1, TextureFormat.R8G8B8A8, false);
whiteTextrueCube.setPixelBuffer(TextureCubeFace.PositiveX, whitePixel);
whiteTextrueCube.setPixelBuffer(TextureCubeFace.NegativeX, whitePixel);
whiteTextrueCube.setPixelBuffer(TextureCubeFace.PositiveY, whitePixel);
whiteTextrueCube.setPixelBuffer(TextureCubeFace.NegativeY, whitePixel);
whiteTextrueCube.setPixelBuffer(TextureCubeFace.PositiveZ, whitePixel);
whiteTextrueCube.setPixelBuffer(TextureCubeFace.NegativeZ, whitePixel);
whiteTextrueCube.isGCIgnored = true;
this._whiteTexture2D = whiteTextrue2D;
this._whiteTextureCube = whiteTextrueCube;
}
/**
@@ -175,8 +199,8 @@ export class Engine extends EventDispatcher {
const deltaTime = time.deltaTime;
time.tick();
RenderElement._restPool();
SpriteElement._restPool();
this._renderElementPool.resetPool();
this._spriteElementPool.resetPool();
engineFeatureManager.callFeatureMethod(this, "preTick", [this, this._sceneManager._activeScene]);
@@ -211,7 +235,9 @@ export class Engine extends EventDispatcher {
*/
destroy(): void {
if (this._sceneManager) {
// -- event
this._whiteTexture2D.destroy(true);
this._whiteTextureCube.destroy(true);
this.trigger(new Event("shutdown", this));
engineFeatureManager.callFeatureMethod(this, "shutdown", [this]);

View File

@@ -25,7 +25,6 @@ export class BasicRenderPipeline {
private _camera: Camera;
private _defaultPass: RenderPass;
private _renderPassArray: Array<RenderPass>;
private _canvasDepthPass;
/**
* Create a basic render pipeline.
@@ -108,7 +107,14 @@ export class BasicRenderPipeline {
/**
* Destroy internal resources.
*/
destroy() {}
destroy(): void {
this._opaqueQueue.destroy();
this._alphaTestQueue.destroy();
this._transparentQueue.destroy();
this._renderPassArray = null;
this._defaultPass = null;
this._camera = null;
}
/**
* Perform scene rendering.
@@ -129,8 +135,6 @@ export class BasicRenderPipeline {
alphaTestQueue.sort(RenderQueue._compareFromNearToFar);
transparentQueue.sort(RenderQueue._compareFromFarToNear);
if (this._canvasDepthPass) this._canvasDepthPass.enabled = false;
for (let i = 0, len = this._renderPassArray.length; i < len; i++) {
this._drawRenderPass(this._renderPassArray[i], camera, cubeFace);
}

View File

@@ -28,7 +28,7 @@ export class ClassPool<T> {
/**
* Reset pool.
*/
restPool(): void {
resetPool(): void {
this._elementPoolIndex = 0;
}
}

View File

@@ -7,32 +7,6 @@ import { Renderer } from "../Renderer";
* Render element.
*/
export class RenderElement {
private static _elementPoolIndex: number = 0;
private static _elementPool: RenderElement[] = [];
/**
* Get render element from pool.
* @remark The return value is only valid for the current frame, and the next frame will be automatically recycled for reuse.
*/
static getFromPool(): RenderElement {
const { _elementPoolIndex: index, _elementPool: pool } = RenderElement;
RenderElement._elementPoolIndex++;
if (pool.length === index) {
const element = new RenderElement();
pool.push(element);
return element;
} else {
return pool[index];
}
}
/**
* @internal
*/
static _restPool() {
RenderElement._elementPoolIndex = 0;
}
/** Render component. */
component: Renderer;
/** Mesh. */

View File

@@ -106,6 +106,8 @@ export class RenderQueue {
program.uploadAll(program.cameraUniformBlock, cameraData);
program.uploadAll(program.rendererUniformBlock, rendererData);
program.uploadAll(program.materialUniformBlock, materialData);
// Ungroup textures should upload default value, texture uint maybe change by logic of texture bind.
program.uploadUngroupTextures();
program._uploadCamera = camera;
program._uploadRenderer = renderer;
program._uploadMaterial = material;
@@ -131,6 +133,11 @@ export class RenderQueue {
} else if (switchProgram) {
program.uploadTextures(program.materialUniformBlock, materialData);
}
// We only consider switchProgram case, because ungroup texure's value is always default.
if (switchProgram) {
program.uploadUngroupTextures();
}
}
material.renderState._apply(camera.engine);
rhi.drawPrimitive(element.mesh, element.subMesh, program);
@@ -151,6 +158,14 @@ export class RenderQueue {
this._spriteBatcher.clear();
}
/**
* Destroy internal resources.
*/
destroy(): void {
this._spriteBatcher.destroy();
this._spriteBatcher = null;
}
/**
* Sort the elements.
*/

View File

@@ -16,7 +16,7 @@ import { SpriteElement } from "./SpriteElement";
* @internal
*/
export class SpriteBatcher {
private static _textureProperty: ShaderProperty = Shader.getPropertyByName("u_texture");
private static _textureProperty: ShaderProperty = Shader.getPropertyByName("u_spriteTexture");
/** The maximum number of vertex. */
private static MAX_VERTEX_COUNT: number = 4096;
private static _canUploadSameBuffer: boolean = !SystemInfo._isIos();
@@ -263,4 +263,25 @@ export class SpriteBatcher {
this._spriteCount = 0;
this._batchedQueue.length = 0;
}
destroy(): void {
this._batchedQueue = null;
const { _meshes: meshes, _vertexBuffers: vertexBuffers, _indiceBuffers: indiceBuffers } = this;
for (let i = 0, n = meshes.length; i < n; ++i) {
meshes[i].destroy();
}
this._meshes = null;
for (let i = 0, n = vertexBuffers.length; i < n; ++i) {
vertexBuffers[i].destroy();
}
this._vertexBuffers = null;
for (let i = 0, n = indiceBuffers.length; i < n; ++i) {
indiceBuffers[i].destroy();
}
this._indiceBuffers = null;
}
}

View File

@@ -4,32 +4,6 @@ import { Material } from "../material";
import { Renderer } from "../Renderer";
export class SpriteElement {
private static _elementPoolIndex: number = 0;
private static _elementPool: SpriteElement[] = [];
/**
* Get sprite element from pool.
* @remark The return value is only valid for the current frame, and the next frame will be automatically recycled for reuse.
*/
static getFromPool(): SpriteElement {
const { _elementPoolIndex: index, _elementPool: pool } = SpriteElement;
SpriteElement._elementPoolIndex++;
if (pool.length === index) {
const element = new SpriteElement();
pool.push(element);
return element;
} else {
return pool[index];
}
}
/**
* @internal
*/
static _restPool() {
SpriteElement._elementPoolIndex = 0;
}
component: Renderer;
positions: Vector3[];
uv: Vector2[];

View File

@@ -1,3 +1,4 @@
import { Engine } from "../Engine";
import { BlendFactor, BlendOperation, CullMode, Shader } from "../shader";
import { ShaderMacro } from "../shader/ShaderMacro";
import { BlendMode } from "./enums/BlendMode";
@@ -9,10 +10,10 @@ export class BaseMaterial extends Material {
private static _alphaCutoffMacro: ShaderMacro = Shader.getMacroByName("ALPHA_CUTOFF");
private static _blendMacro: ShaderMacro = Shader.getMacroByName("ALPHA_BLEND");
private _isTransparent: boolean = false;
private _alphaCutoff: number = 0;
private _renderFace: RenderFace = RenderFace.Front;
private _blendMode: BlendMode = BlendMode.Normal;
private _isTransparent: boolean = false;
private _blendMode: BlendMode;
/**
* Is this material transparent.
@@ -35,7 +36,6 @@ export class BaseMaterial extends Material {
if (value) {
this.shaderData.enableMacro(BaseMaterial._blendMacro);
targetBlendState.enabled = true;
this.blendMode = this._blendMode;
depthState.writeEnabled = false;
this.renderQueueType = RenderQueueType.Transparent;
} else {
@@ -129,4 +129,14 @@ export class BaseMaterial extends Material {
break;
}
}
/**
* Create a BaseMaterial instance.
* @param engine - Engine to which the material belongs
* @param shader - Shader used by the material
*/
constructor(engine: Engine, shader: Shader) {
super(engine, shader);
this.blendMode = BlendMode.Normal;
}
}

View File

@@ -7,7 +7,6 @@ import { Entity } from "../Entity";
import { VertexElementFormat } from "../graphic/enums/VertexElementFormat";
import { Mesh } from "../graphic/Mesh";
import { Renderer } from "../Renderer";
import { RenderElement } from "../RenderPipeline/RenderElement";
import { Shader } from "../shader/Shader";
import { UpdateFlag } from "../UpdateFlag";
@@ -116,8 +115,9 @@ export class MeshRenderer extends Renderer implements ICustomClone {
*/
_onDestroy() {
super._onDestroy();
if (this._mesh) {
this._mesh._addRefCount(-1);
const mesh = this._mesh;
if (mesh && !mesh.destroyed) {
mesh._addRefCount(-1);
this._mesh = null;
}
}

View File

@@ -76,7 +76,7 @@ const _tempShpere = new BoundingSphere();
const localRay = _getLocalRay(this, ray);
// TODO
this.center.cloneTo(_tempShpere.center);
_tempShpere.radius = this.radio;
_tempShpere.radius = this.radius;
const intersect = localRay.intersectSphere(_tempShpere);
if (intersect !== -1) {
_updateHitResult(this, localRay, intersect, hit, ray.origin);

View File

@@ -77,7 +77,7 @@ export class Shader {
if (propertyNameMap[name] != null) {
return propertyNameMap[name];
} else {
const property = new ShaderProperty();
const property = new ShaderProperty(name);
propertyNameMap[name] = property;
return property;
}
@@ -131,14 +131,15 @@ export class Shader {
*
* @param engine - Engine to which the shader variant belongs
* @param macros - Macro name list
* @returns Is the compiled shader variant valid
*/
compileVariant(engine: Engine, macros: string[]): void {
compileVariant(engine: Engine, macros: string[]): boolean {
const compileMacros = Shader._compileMacros;
compileMacros.clear();
for (let i = 0, n = macros.length; i < n; i++) {
compileMacros.enable(Shader.getMacroByName(macros[i]));
}
this._getShaderProgram(engine, compileMacros);
return this._getShaderProgram(engine, compileMacros).isValid;
}
/**

View File

@@ -586,7 +586,7 @@ export class ShaderData implements IRefObject, IClone {
if (property._group === undefined) {
property._group = this._group;
} else {
throw `This property has been used as ${ShaderDataGroup[property._group]} property.`;
throw `Shader property ${property.name} has been used as ${ShaderDataGroup[property._group]} property.`;
}
}

View File

@@ -5,6 +5,7 @@ import { Engine } from "../Engine";
import { Material } from "../material/Material";
import { Renderer } from "../Renderer";
import { IHardwareRenderer } from "../renderingHardwareInterface/IHardwareRenderer";
import { Texture } from "../texture";
import { ShaderDataGroup } from "./enums/ShaderDataGroup";
import { Shader } from "./Shader";
import { ShaderData } from "./ShaderData";
@@ -123,7 +124,25 @@ export class ShaderProgram {
for (let i = 0, n = textureUniforms.length; i < n; i++) {
const uniform = textureUniforms[i];
const texture = properties[uniform.propertyId];
texture != null && uniform.applyFunc(uniform, texture);
if (texture) {
uniform.applyFunc(uniform, texture);
} else {
uniform.applyFunc(uniform, uniform.textureDefault);
}
}
}
}
/**
* Upload ungroup texture shader data in shader uniform block.
*/
uploadUngroupTextures(): void {
const textureUniforms = this.otherUniformBlock.textureUniforms;
// textureUniforms property maybe null if ShaderUniformBlock not contain any texture.
if (textureUniforms) {
for (let i = 0, n = textureUniforms.length; i < n; i++) {
const uniform = textureUniforms[i];
uniform.applyFunc(uniform, uniform.textureDefault);
}
}
}
@@ -162,7 +181,7 @@ export class ShaderProgram {
this._glProgram && gl.deleteProgram(this._glProgram);
}
private _groupingSubOtherUniforms(unifroms: ShaderUniform[], isTexture: boolean) {
private _groupingSubOtherUniforms(unifroms: ShaderUniform[], isTexture: boolean): void {
for (let i = unifroms.length - 1; i >= 0; i--) {
const uniform = unifroms[i];
const group = Shader._getShaderPropertyGroup(uniform.name);
@@ -382,24 +401,34 @@ export class ShaderProgram {
break;
case gl.SAMPLER_2D:
case gl.SAMPLER_CUBE:
const defaultTexture = type === gl.SAMPLER_2D ? this._engine._whiteTexture2D : this._engine._whiteTextureCube;
isTexture = true;
if (isArray) {
const defaultTextures = new Array<Texture>(size);
const textureIndices = new Int32Array(size);
const glTextureIndices = new Array<number>(size);
for (let i = 0; i < size; i++) {
defaultTextures[i] = defaultTexture;
textureIndices[i] = this._activeTextureUint;
glTextureIndices[i] = gl.TEXTURE0 + this._activeTextureUint++;
}
shaderUniform.textureDefault = defaultTextures;
shaderUniform.textureIndex = glTextureIndices;
shaderUniform.applyFunc = shaderUniform.uploadTextureArray;
this.bind();
gl.uniform1iv(location, textureIndices);
shaderUniform.uploadTextureArray(shaderUniform, defaultTextures);
} else {
const textureIndex = gl.TEXTURE0 + this._activeTextureUint;
shaderUniform.textureDefault = defaultTexture;
shaderUniform.textureIndex = textureIndex;
shaderUniform.applyFunc = shaderUniform.uploadTexture;
this.bind();
gl.uniform1i(location, this._activeTextureUint++);
shaderUniform.uploadTexture(shaderUniform, defaultTexture);
}
break;
}

View File

@@ -11,10 +11,14 @@ export class ShaderProperty {
/** @internal */
_group: ShaderDataGroup;
/** Shader property name. */
readonly name: string;
/**
* @internal
*/
constructor() {
constructor(name: string) {
this.name = name;
this._uniqueId = ShaderProperty._propertyNameCounter++;
}
}

View File

@@ -12,9 +12,10 @@ export class ShaderUniform {
name: string;
propertyId: number;
location: WebGLUniformLocation;
textureIndex: GLenum | GLenum[];
applyFunc: (shaderUniform: ShaderUniform, value: ShaderPropertyValueType) => void;
cacheValue: number | Vector2 | Vector3 | Vector4;
textureIndex: GLenum | GLenum[];
textureDefault: Texture | Texture[];
private _rhi: IHardwareRenderer;
private _gl: WebGLRenderingContext;

View File

@@ -1,4 +1,4 @@
import { WebGLEngine } from "../../rhi-webgl/src";
import { WebGLEngine } from "../../rhi-webgl/src/WebGLEngine";
import { Entity, Component, Engine, Scene } from "../src/index";
class TestComponent extends Component {}
@@ -29,7 +29,7 @@ describe("Component", () => {
const canvasDOM = document.createElement("canvas");
canvasDOM.getContext = getContext;
const engine: Engine = new Engine({ width: 1024, height: 1024 }, { init: jest.fn(), canIUse: jest.fn() });
const engine = new WebGLEngine(document.createElement("canvas"));
const scene = engine.sceneManager.activeScene;
const root = new Entity(engine, "root");
//@ts-ignore

View File

@@ -2,88 +2,50 @@ import { WebCanvas, WebGLEngine, WebGLRenderer } from "../../rhi-webgl/src";
import { Engine } from "../src";
describe("Engine test", () => {
const getContext = jest.fn().mockReturnValue({
canvas: { width: 1024, height: 1024 },
getParameter: jest.fn(),
enable: jest.fn(),
disable: jest.fn(),
colorMask: jest.fn(),
depthMask: jest.fn(),
blendFunc: jest.fn(),
blendFuncSeparate: jest.fn(),
blendEquationSeparate: jest.fn(),
blendColor: jest.fn(),
cullFace: jest.fn(),
frontFace: jest.fn(),
depthFunc: jest.fn(),
depthRange: jest.fn(),
polygonOffset: jest.fn(),
stencilFunc: jest.fn(),
stencilFuncSeparate: jest.fn(),
stencilMask: jest.fn(),
stencilOpSeparate: jest.fn(),
getExtension: jest.fn(),
bindFramebuffer: jest.fn(),
viewport: jest.fn(),
clearColor: jest.fn(),
clear: jest.fn()
});
const canvasDOM = document.createElement("canvas");
canvasDOM.getContext = getContext;
const offscreenCanvasDOM = <OffscreenCanvas | any>{
width: 1024,
height: 1024,
getContext
};
describe("test - create and destroy engine ", () => {
describe("Web platform engine", () => {
it("use Engine", () => {
const canvas = new WebCanvas(canvasDOM);
const rhi = new WebGLRenderer();
const engine = new Engine(canvas, rhi);
it("use Engine", () => {
const canvas = new WebCanvas(document.createElement("canvas"));
const rhi = new WebGLRenderer();
const engine = new Engine(canvas, rhi);
expect(engine.canvas).toBe(canvas);
expect(engine._hardwareRenderer).toBe(rhi);
});
expect(engine.canvas).toBe(canvas);
expect(engine._hardwareRenderer).toBe(rhi);
});
it("Use WebGLEngine", () => {
const engine = new WebGLEngine(canvasDOM);
it("Use WebGLEngine", () => {
const engine = new WebGLEngine(document.createElement("canvas"));
expect(engine._hardwareRenderer).toBeInstanceOf(WebGLRenderer);
});
expect(engine._hardwareRenderer).toBeInstanceOf(WebGLRenderer);
});
it("Use offscreen canvas", () => {
const canvas = new WebCanvas(offscreenCanvasDOM);
const rhi = new WebGLRenderer();
const engine = new Engine(canvas, rhi);
it("Use offscreen canvas", () => {
const canvas = new WebCanvas(new OffscreenCanvas(1024, 1024));
const rhi = new WebGLRenderer();
const engine = new Engine(canvas, rhi);
expect(engine.canvas).toBe(canvas);
expect(engine._hardwareRenderer).toBeInstanceOf(WebGLRenderer);
expect(canvas.width).toBe(1024);
expect(canvas.height).toBe(1024);
});
expect(engine.canvas).toBe(canvas);
expect(engine._hardwareRenderer).toBeInstanceOf(WebGLRenderer);
expect(canvas.width).toBe(1024);
expect(canvas.height).toBe(1024);
});
it("Destroy engine", () => {
const engine = new WebGLEngine(canvasDOM);
it("Destroy engine", () => {
const engine = new WebGLEngine(document.createElement("canvas"));
engine.destroy();
expect(engine.sceneManager).toBeNull();
expect(engine.isPaused).toBeTruthy();
});
engine.destroy();
expect(engine.sceneManager).toBeNull();
expect(engine.isPaused).toBeTruthy();
});
});
describe("test - sceneManager", () => {
it("Default scene", () => {
const engine = new WebGLEngine(canvasDOM);
const engine = new WebGLEngine(document.createElement("canvas"));
expect(engine.sceneManager.activeScene).not.toBeNull();
});
it("Destroy scene", () => {
const engine = new WebGLEngine(canvasDOM);
const engine = new WebGLEngine(document.createElement("canvas"));
const scene = engine.sceneManager.activeScene;
scene.destroy();
@@ -92,7 +54,7 @@ describe("Engine test", () => {
});
describe("test - tick/vSync", () => {
const engine = new WebGLEngine(canvasDOM);
const engine = new WebGLEngine(document.createElement("canvas"));
const mockTick = (engine.update = jest.fn());
it("Open vsync - pause/resume", () => {

View File

@@ -1,9 +1,9 @@
import { Engine } from "../src/Engine";
import { WebGLEngine } from "../../rhi-webgl/src/WebGLEngine";
import { Entity, Component } from "../src/index";
class TestComponent extends Component {}
describe("Entity", () => {
const engine = new Engine({ width: 1024, height: 1024 }, { init: jest.fn(), canIUse: jest.fn() });
const engine = new WebGLEngine(document.createElement("canvas"));
const scene = engine.sceneManager.activeScene;
engine.run();
beforeEach(() => {

View File

@@ -1,10 +1,11 @@
import { Loader } from "../src/asset/Loader";
import { LoadItem } from "../src/asset/LoadItem";
import { resourceLoader, ResourceManager } from "../src/asset/ResourceManager";
import { AssetType } from "../src/asset/AssetType";
import { WebGLEngine } from "../../rhi-webgl/src";
import { Engine } from "../src";
import { AssetPromise } from "../src/asset/AssetPromise";
import { AssetType } from "../src/asset/AssetType";
import { Loader } from "../src/asset/Loader";
import { LoadItem } from "../src/asset/LoadItem";
import { RefObject } from "../src/asset/RefObject";
import { resourceLoader, ResourceManager } from "../src/asset/ResourceManager";
@resourceLoader(AssetType.Text, ["txt"], false)
class TestLoader extends Loader<string> {
@@ -28,7 +29,6 @@ class TestRefObject extends RefObject {
class TestJsonLoader extends Loader<RefObject> {
load(item: LoadItem, resourceManager: ResourceManager): AssetPromise<RefObject> {
return new AssetPromise((resolve) => {
// console.log(resourceManager.engine.id)
setTimeout(() => {
resolve(new TestRefObject(resourceManager.engine));
}, 300);
@@ -37,7 +37,8 @@ class TestJsonLoader extends Loader<RefObject> {
}
describe("test resource manager", () => {
const engine = new Engine(null, { init: () => {}, canIUse: jest.fn() });
const engine = new WebGLEngine(document.createElement("canvas"));
engine._resourceManager = new ResourceManager(engine);
describe("Add Loader Test", function () {
it("load custom loader url", () => {
return expect(engine.resourceManager.load("xx.txt")).resolves.toEqual("test");
@@ -58,7 +59,8 @@ describe("test resource manager", () => {
});
});
const jsonEngine = new Engine(null, { init: () => {}, canIUse: jest.fn() });
const jsonEngine = new WebGLEngine(document.createElement("canvas"));
jsonEngine._resourceManager = new ResourceManager(engine);
it("test delete object", () => {
const path = "xaa.json";
const promiseAA = jsonEngine.resourceManager.load<RefObject>(path);

View File

@@ -1,8 +1,8 @@
import { Engine } from "../src/Engine";
import { WebGLEngine } from "../../rhi-webgl/src/WebGLEngine";
import { Entity } from "../src/index";
describe("Scene test", () => {
const engine = new Engine({ width: 1024, height: 1024 }, { init: jest.fn(), canIUse: jest.fn() });
const engine = new WebGLEngine(document.createElement("canvas"));
const scene = engine.sceneManager.activeScene;
engine.run();

View File

@@ -1,8 +1,8 @@
import { Engine } from "../src/Engine";
import { WebGLEngine } from "../../rhi-webgl/src/WebGLEngine";
import { Component, Entity, Script } from "../src/index";
describe("Script", () => {
const engine = new Engine({ width: 1024, height: 1024 }, { init: jest.fn(), canIUse: jest.fn() });
const engine = new WebGLEngine(document.createElement("canvas"));
const scene = engine.sceneManager.activeScene;
engine.run();

View File

@@ -1,6 +1,6 @@
{
"name": "@oasis-engine/design",
"version": "0.3.0",
"version": "0.3.7",
"license": "MIT",
"main": "dist/main.js",
"module": "dist/module.js",

View File

@@ -1,6 +1,6 @@
{
"name": "@oasis-engine/draco",
"version": "0.3.0",
"version": "0.3.7",
"license": "MIT",
"scripts": {
"b:types": "tsc"
@@ -13,6 +13,6 @@
"types/**/*"
],
"dependencies": {
"@oasis-engine/core": "0.3.0"
"@oasis-engine/core": "0.3.7"
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "@oasis-engine/framebuffer-picker",
"version": "0.3.0",
"version": "0.3.7",
"license": "MIT",
"main": "dist/main.js",
"module": "dist/module.js",
@@ -14,6 +14,6 @@
"types/**/*"
],
"dependencies": {
"oasis-engine": "0.3.0"
"oasis-engine": "0.3.7"
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "@oasis-engine/loader",
"version": "0.3.0",
"version": "0.3.7",
"license": "MIT",
"types": "types/index.d.ts",
"scripts": {
@@ -13,9 +13,9 @@
"types/**/*"
],
"dependencies": {
"@oasis-engine/core": "0.3.0",
"@oasis-engine/draco": "0.3.0",
"@oasis-engine/math": "0.3.0",
"@oasis-engine/rhi-webgl": "0.3.0"
"@oasis-engine/core": "0.3.7",
"@oasis-engine/draco": "0.3.7",
"@oasis-engine/math": "0.3.7",
"@oasis-engine/rhi-webgl": "0.3.7"
}
}

View File

@@ -839,7 +839,7 @@ export function buildSceneGraph(resources: GLTFParsed): GLTFResource {
materialIndex !== undefined
? getItemByIdx("materials", materialIndex, resources)
: getDefaultMaterial(node.engine);
renderer.setMaterial(j, material);
renderer.setMaterial(material);
}
}
}

View File

@@ -1,9 +1,9 @@
import "../src/JSONLoader";
import { Engine } from "@oasis-engine/core";
import { WebGLEngine } from "../../rhi-webgl/src/WebGLEngine";
describe("text loader test", () => {
it("text loader test", () => {
const engine = new Engine(null, { init: jest.fn(), canIUse: jest.fn() });
const engine = new WebGLEngine(document.createElement("canvas"));
const promise = engine.resourceManager.load(
"https://gw.alipayobjects.com/os/bmw-prod/73cba7a4-221b-4e32-8db6-c87968cf7ce0.json"
);

View File

@@ -1,9 +1,9 @@
import { Engine } from "@oasis-engine/core";
import { WebGLEngine } from "../../rhi-webgl/src/WebGLEngine";
import "../src/TextLoader";
describe("text loader test", () => {
it("text loader test", () => {
const engine = new Engine(null, { init: () => {}, canIUse: jest.fn() });
const engine = new WebGLEngine(document.createElement("canvas"));
const promise = engine.resourceManager.load(
"https://gw.alipayobjects.com/os/bmw-prod/d64cb568-bf86-41f0-8c9e-d1be9424bd98.txt"
);

View File

@@ -1,6 +1,6 @@
{
"name": "@oasis-engine/math",
"version": "0.3.0",
"version": "0.3.7",
"license": "MIT",
"main": "dist/main.js",
"module": "dist/module.js",
@@ -13,6 +13,6 @@
"types/**/*"
],
"devDependencies": {
"@oasis-engine/design": "0.3.0"
"@oasis-engine/design": "0.3.7"
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "oasis-engine",
"version": "0.3.0",
"version": "0.3.7",
"license": "MIT",
"scripts": {
"b:types": "tsc"
@@ -14,9 +14,9 @@
"types/**/*"
],
"dependencies": {
"@oasis-engine/core": "0.3.0",
"@oasis-engine/loader": "0.3.0",
"@oasis-engine/math": "0.3.0",
"@oasis-engine/rhi-webgl": "0.3.0"
"@oasis-engine/core": "0.3.7",
"@oasis-engine/loader": "0.3.7",
"@oasis-engine/math": "0.3.7",
"@oasis-engine/rhi-webgl": "0.3.7"
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "@oasis-engine/rhi-webgl",
"version": "0.3.0",
"version": "0.3.7",
"license": "MIT",
"main": "dist/main.js",
"module": "dist/module.js",
@@ -13,10 +13,10 @@
"types/**/*"
],
"dependencies": {
"@oasis-engine/core": "0.3.0",
"@oasis-engine/math": "0.3.0"
"@oasis-engine/core": "0.3.7",
"@oasis-engine/math": "0.3.7"
},
"devDependencies": {
"@oasis-engine/design": "0.3.0"
"@oasis-engine/design": "0.3.7"
}
}

View File

@@ -95,6 +95,7 @@ export class GLPrimitive implements IPlatformPrimitive {
this.vao.forEach((vao) => {
gl.deleteVertexArray(vao);
});
this.vao.clear();
}
}

View File

@@ -65,11 +65,10 @@ export class WebGLRenderer implements IHardwareRenderer {
private _gl: (WebGLRenderingContext & WebGLExtension) | WebGL2RenderingContext;
private _renderStates;
private _extensions;
private _spriteBatcher;
private _capability: GLCapability;
private _isWebGL2: boolean;
private _activedTextureID: number;
private _activedTextureID: number = WebGLRenderingContext.TEXTURE0;
private _activeTextures: GLTexture[] = new Array(32);
get isWebGL2() {
@@ -102,6 +101,8 @@ export class WebGLRenderer implements IHardwareRenderer {
init(canvas: Canvas) {
const option = this._options;
option.alpha === undefined && (option.alpha = false);
const webCanvas = (canvas as WebCanvas)._webCanvas;
const webGLMode = option.webGLMode || WebGLMode.Auto;
let gl: (WebGLRenderingContext & WebGLExtension) | WebGL2RenderingContext;
@@ -273,10 +274,10 @@ export class WebGLRenderer implements IHardwareRenderer {
}
bindTexture(texture: GLTexture): void {
const gl = this._gl;
if (this._activeTextures[this._activedTextureID - gl.TEXTURE0] !== texture) {
gl.bindTexture(texture._target, texture._glTexture);
this._activeTextures[this._activedTextureID - gl.TEXTURE0] = texture;
const index = this._activedTextureID - this._gl.TEXTURE0;
if (this._activeTextures[index] !== texture) {
this._gl.bindTexture(texture._target, texture._glTexture);
this._activeTextures[index] = texture;
}
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "@oasis-engine/stats",
"version": "0.3.0",
"version": "0.3.7",
"license": "MIT",
"scripts": {
"b:types": "tsc"
@@ -14,6 +14,6 @@
"types/**/*"
],
"dependencies": {
"oasis-engine": "0.3.0"
"oasis-engine": "0.3.7"
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "@oasis-engine/tween",
"version": "0.3.0",
"version": "0.3.7",
"license": "MIT",
"main": "dist/main.js",
"module": "dist/module.js",
@@ -14,6 +14,6 @@
},
"types": "types/index.d.ts",
"dependencies": {
"oasis-engine": "0.3.0"
"oasis-engine": "0.3.7"
}
}