diff --git a/.gitignore b/.gitignore index 070094f9..03c3e8dc 100644 --- a/.gitignore +++ b/.gitignore @@ -18,4 +18,5 @@ npm-debug.log # Misc deploy_key -deploy_key.pub \ No newline at end of file +deploy_key.pub +.vscode/settings.json diff --git a/lib/SecurityDomain.ts b/lib/SecurityDomain.ts index 682aed1a..03d8454a 100644 --- a/lib/SecurityDomain.ts +++ b/lib/SecurityDomain.ts @@ -17,6 +17,7 @@ import { EventDispatcher } from './events/EventDispatcher'; import { DisplayObject } from './display/DisplayObject'; import { DisplayObjectContainer } from './display/DisplayObjectContainer'; import { Stage } from './display/Stage'; +import { Stage3D } from './display/Stage3D'; import { Loader } from './display/Loader'; import { LoaderInfo } from './display/LoaderInfo'; import { MovieClip } from './display/MovieClip'; @@ -77,6 +78,14 @@ import { FocusEvent } from './events/FocusEvent'; import { UncaughtErrorEvents } from './events/UncaughtErrorEvents'; import { NetConnection } from './net/NetConnection'; import { Responder } from './net/Responder'; +import { Context3D } from './display3D/Context3D'; +import { IndexBuffer3D } from './display3D/IndexBuffer3D'; +import { Program3D } from './display3D/Program3D'; +import { VertexBuffer3D } from './display3D/VertexBuffer3D'; +import { TextureBase } from './display3D/textures/TextureBase'; +import { Texture } from './display3D/textures/Texture'; +import { CubeTexture } from './display3D/textures/CubeTexture'; +import { RectangleTexture } from './display3D/textures/RectangleTexture'; export class Mouse {} @@ -87,6 +96,7 @@ export class SecurityDomain extends AXSecurityDomain { DisplayObject: DisplayObject, DisplayObjectContainer: DisplayObjectContainer, Stage: Stage, + Stage3D: Stage3D, Loader: Loader, LoaderInfo: LoaderInfo, MovieClip: MovieClip, @@ -98,6 +108,18 @@ export class SecurityDomain extends AXSecurityDomain { Shape: Shape, FrameLabel: FrameLabel }, + display3D: { + Context3D: Context3D, + IndexBuffer3D: IndexBuffer3D, + Program3D: Program3D, + VertexBuffer3D: VertexBuffer3D, + textures: { + TextureBase: TextureBase, + Texture: Texture, + RectangleTexture: RectangleTexture, + CubeTexture: CubeTexture, + } + }, events: { EventDispatcher: EventDispatcher, Event: Event, diff --git a/lib/display/Stage.ts b/lib/display/Stage.ts index 5c8717fd..9389a9e7 100644 --- a/lib/display/Stage.ts +++ b/lib/display/Stage.ts @@ -16,6 +16,9 @@ import { Loader as PlayerGlobalLoader } from './Loader'; import { LoaderInfo, LoaderInfoCompleteQueue } from './LoaderInfo'; import { Debug } from '@awayjs/core'; import { InteractiveObject } from './InteractiveObject'; +import { StageManager } from '@awayjs/stage'; +import { GenericVector } from '@awayfl/avm2'; +import { Stage3D } from './Stage3D'; /** * Dispatched by the Stage object when the state of the stageVideos property changes. @@ -153,7 +156,7 @@ import { InteractiveObject } from './InteractiveObject'; export class Stage extends DisplayObjectContainer { - private _stage3Ds: AwayStage[]; + private _stage3Ds: GenericVector; private _sendEventRender: boolean; @@ -162,7 +165,10 @@ export class Stage extends DisplayObjectContainer { this._isStage = true; - this._stage3Ds = []; + this._stage3Ds = new ( this.sec).ObjectVector(); + for (let i: number = 0; i < AVMStage.instance().stage3Ds.length; i++) { + this._stage3Ds.axSetNumericProperty(i, new ( this.sec).flash.display.Stage3D(i)); + } // resize event listens on window this._resizeCallbackDelegate = (event: any) => this.resizeCallback(event); @@ -476,7 +482,7 @@ export class Stage extends DisplayObjectContainer { public get contentsScaleFactor (): number { // @todo Debug.throwPIR('playerglobals/display/Stage', 'get contentsScaleFactor', ''); - return 0; + return 1; } public get displayContextInfo (): string { @@ -805,9 +811,7 @@ export class Stage extends DisplayObjectContainer { } - public get stage3Ds (): AwayStage[] { - // @todo - Debug.throwPIR('playerglobals/display/Stage', 'get stage3Ds', ''); + public get stage3Ds (): GenericVector { return this._stage3Ds; } @@ -1140,4 +1144,4 @@ export class Stage extends DisplayObjectContainer { return false; } -} \ No newline at end of file +} diff --git a/lib/display/Stage3D.ts b/lib/display/Stage3D.ts new file mode 100644 index 00000000..a6272cdb --- /dev/null +++ b/lib/display/Stage3D.ts @@ -0,0 +1,102 @@ +import { AVMStage } from '@awayfl/swf-loader'; +import { ContextGLProfile, Stage as AwayStage } from '@awayjs/stage'; +import { Context3D } from '../display3D/Context3D'; +import { Event } from '../events/Event'; +import { EventDispatcher } from '../events/EventDispatcher'; +import { SecurityDomain } from '../SecurityDomain'; +import { AXSecurityDomain } from '@awayfl/avm2'; +import { ErrorEvent } from '../events/ErrorEvent'; + +export class Stage3D extends EventDispatcher { + // Called whenever the class is initialized. + public static classInitializer: any = null; + + // List of static symbols to link. + public static classSymbols: string[] = null; // []; + + // List of instance symbols to link. + public static instanceSymbols: string[] = null; // []; + private _context3D: Context3D + private _adaptee: AwayStage + + constructor(i) { + super(); + console.log('Stage3D Constructor'); + this._adaptee = AVMStage.instance().stage3Ds[i]; + } + + public get adaptee(): AwayStage { + return this._adaptee; + } + + public get x(): number { + return this._adaptee.x; + } + + public set x(value: number) { + this._adaptee.y = value; + } + + public get y(): number { + return this._adaptee.y; + } + + public set y(value: number) { + this._adaptee.y = value; + } + + public get visible(): boolean { + return this._adaptee.visible ; + } + + public set visible(value: boolean) { + this._adaptee.visible = value; + } + + public get context3D(): Context3D { + return this._context3D; + } + + public requestContext3D(context3DRenderMode: string = 'auto', profile: string = 'baseline'): void { + this._context3D = new (this.sec as SecurityDomain).flash.display3D.Context3D(this, context3DRenderMode, profile); + + const dispatchContextCreated = (e: Event) => { + this._context3D.removeEventListener(Event.CONTEXT3D_CREATE, dispatchContextCreated); + this.dispatchEvent(new (this.sec).flash.events.Event(Event.CONTEXT3D_CREATE)); + } + + this._context3D.addEventListener(Event.CONTEXT3D_CREATE, dispatchContextCreated); + setTimeout(() => { + console.log('Request Context'); + const forceSoftware: boolean = (context3DRenderMode == 'software'); + let awayContextProfile: ContextGLProfile = ContextGLProfile.BASELINE; + switch (profile) { + case 'baseline': + awayContextProfile = ContextGLProfile.BASELINE; + break; + case 'baseline_constrained': + awayContextProfile = ContextGLProfile.BASELINE_CONSTRAINED; + break; + case 'baseline_extended': + awayContextProfile = ContextGLProfile.BASELINE_EXTENDED; + break; + case 'standard': + awayContextProfile = ContextGLProfile.STANDARD; + break; + case 'standard_constrained': + awayContextProfile = ContextGLProfile.STANDARD_CONSTRAINED; + break; + case 'standard_extended': + awayContextProfile = ContextGLProfile.STANDARD_EXTENDED; + break; + case 'enhanced': + awayContextProfile = ContextGLProfile.BASELINE_EXTENDED; + break; + default: + break; + } + console.log('Context3D Config: ', 'forceSoftware: ', forceSoftware, ' profile: ', profile); + this._adaptee.requestContext(forceSoftware, awayContextProfile); + } , 0); + } +} diff --git a/lib/display3D/Context3D.ts b/lib/display3D/Context3D.ts index 882b07c6..03779bf5 100644 --- a/lib/display3D/Context3D.ts +++ b/lib/display3D/Context3D.ts @@ -1 +1,591 @@ -export { ContextWebGL as Context3D } from '@awayjs/stage'; +import { + BitmapImage2D, + ContextGLDrawMode, + ContextGLProgramType, + ContextGLVertexBufferFormat, + ContextWebGL, + Stage as AwayStage, + StageEvent, + ContextGLClearMask, + ContextGLCompareMode, + ContextGLStencilAction, + ContextGLTriangleFace, + ContextGLBlendFactor, + ContextGLBlendEquation, +} from '@awayjs/stage'; +import { axCoerceString, Float64Vector } from '@awayfl/avm2'; +import { AVMStage, Debug } from '@awayfl/swf-loader'; +import { BitmapData } from '../display/BitmapData'; +import { Stage3D } from '../display/Stage3D'; +import { Context3DProgramType } from '../display3D/Context3DProgramType'; +import { Context3DVertexBufferFormat } from '../display3D/Context3DVertexBufferFormat'; +import { IndexBuffer3D } from '../display3D/IndexBuffer3D'; +import { Program3D } from '../display3D/Program3D'; +import { VertexBuffer3D } from '../display3D/VertexBuffer3D'; +import { EventDispatcher } from '../events/EventDispatcher'; +import { Matrix3D } from '../geom/Matrix3D'; +import { Rectangle } from '../geom/Rectangle'; +import { ByteArray } from '../utils/ByteArray'; +import { SecurityDomain } from '../SecurityDomain'; +import { Event } from '../events/Event'; +import { Texture } from './textures/Texture'; +import { RectangleTexture } from './textures/RectangleTexture'; +import { CubeTexture } from './textures/CubeTexture'; +import { TextureBase } from './textures/TextureBase'; +import { Context3DClearMask } from './Context3DClearMask'; +import { CoordinateSystem } from '@awayjs/core'; +import { Context3DTriangleFace } from './Context3DTriangleFace'; +import { Context3DCompareMode } from './Context3DCompareMode'; +import { Context3DStencilAction } from './Context3DStencilAction'; +import { Context3DBlendFactor } from './Context3DBlendFactor'; + +export class Context3D extends EventDispatcher { + // Called whenever the class is initialized. + public static classInitializer: any = null; + + // List of static symbols to link. + public static classSymbols: string[] = null; // []; + + // List of instance symbols to link. + public static instanceSymbols: string[] = null; // []; + + private _adaptee: AwayStage; + private _profile: string; + private _gl: WebGL2RenderingContext | WebGLRenderingContext; + private _fragmentProgramConstants = []; + private _vertexProgramConstants = []; + private _resizeStage: boolean = false; + + // @todo: Constructor isn't meant to be public + constructor(stage3D: Stage3D, renderMode: string = 'auto', profile: string = 'baseline') { + super(); + + console.log(`Context3D Create: ${renderMode} ${profile}`); + this._profile = profile; + this._adaptee = stage3D.adaptee; + const dispatchContextCreated = (e: StageEvent) => { + stage3D.dispatchEvent(new (this.sec as SecurityDomain).flash.events.Event(Event.CONTEXT3D_CREATE)); + this._gl = (this.adaptee.context as unknown as ContextWebGL)._gl; + } + this._adaptee.addEventListener(StageEvent.CONTEXT_RECREATED, dispatchContextCreated); + } + + public get adaptee(): AwayStage { + return this._adaptee; + } + + public get backBufferHeight(): number { + return this._adaptee.height; + } + + public get backBufferWidth(): number { + return this._adaptee.width; + } + + public get driverInfo(): string { + Debug.notImplemented('public flash.display3D.Context3D::get driverInfo'); + return axCoerceString('OpenGL (' + this.profile.replace(/([a-z])([A-Z])/g, '$1 $2').replace(/^./, str => str.toUpperCase()) + ')'); + } + + public get enableErrorChecking(): boolean { + Debug.notImplemented('public flash.display3D.Context3D::get enableErrorChecking'); + return false; + } + + public set enableErrorChecking(toggle: boolean) { + toggle = !!toggle; + Debug.notImplemented('public flash.display3D.Context3D::set enableErrorChecking'); return; + // this._enableErrorChecking = toggle; + } + + public get maxBackBufferWidth(): number { + return this._gl.getParameter(this._gl.MAX_VIEWPORT_DIMS); + } + + public set maxBackBufferWidth(value: number) { + Debug.notImplemented('public flash.display3D.Context3D::set maxBackBufferWidth'); + } + + public get maxBackBufferHeight(): number { + return this._gl.getParameter(this._gl.MAX_VIEWPORT_DIMS); + } + + public set maxBackBufferHeight(value: number) { + Debug.notImplemented('public flash.display3D.Context3D::set maxBackBufferHeight'); + } + + public get profile(): string { + return axCoerceString(this._profile); + } + + public static get supportsVideoTexture(): boolean { + return false; + } + + public get totalGPUMemory(): number { + Debug.notImplemented('public flash.display3D.Context3D::get totalGPUMemory'); + return 1024; + } + + public dispose(recreate: boolean = true): void { + this._adaptee.context.dispose(); + this._profile = "Disposed"; + } + + public configureBackBuffer(width: number, height: number, antiAlias: number, enableDepthAndStencil: boolean = true, wantsBestResolution: boolean = false, wantsBestResolutionOnBrowserZoom: boolean = false): void { + // Hack so that if we don't use noScale, the Stage3Ds get Scaled + // This isn't done directly here because some games seem to blow up if we do + // @todo: Should probably make this a Setting + let stageManager = AVMStage.instance(); + this._resizeStage = width == stageManager.stageWidth && height == stageManager.stageHeight && stageManager.scaleMode != 'noScale'; + + this._adaptee.configureBackBuffer(width, height, antiAlias, enableDepthAndStencil); + } + + public clear(red: number = 0.0, green: number = 0.0, blue: number = 0.0, alpha: number = 1.0, depth: number = 1.0, stencil: number = 0, mask: number = 0xffffffff): void { + + let awayMask: number = 0; + if (mask & Context3DClearMask.COLOR) + awayMask |= ContextGLClearMask.COLOR; + if (mask & Context3DClearMask.DEPTH) + awayMask |= ContextGLClearMask.DEPTH; + if (mask & Context3DClearMask.STENCIL) + awayMask |= ContextGLClearMask.STENCIL; + + this._adaptee.clear(red, green, blue, alpha, depth, stencil, awayMask); + } + + public drawTriangles(indexBuffer: IndexBuffer3D, firstIndex: number = 0, numTriangles: number = -1): void { + this._adaptee.context.drawIndices(ContextGLDrawMode.TRIANGLES, indexBuffer._adaptee, firstIndex, (numTriangles == -1) ? -1 : (numTriangles * 3)); + this._vertexProgramConstants.length = 0; + this._fragmentProgramConstants.length = 0; + } + + public present(): void { + if (this._resizeStage) { + AVMStage.instance().stageWidth = AVMStage.instance().stageWidth; + this._resizeStage = false; + } + + this._adaptee.present(); + } + + public setProgram(program: Program3D): void { + this._adaptee.context.setProgram(program._adaptee); + this._vertexProgramConstants.length = 0; + this._fragmentProgramConstants.length = 0; + //this._currentProgram = program + } + + public setProgramConstantsFromVector(programType: string, firstRegister: number /*int*/, data: Float64Vector, numRegisters: number /*int*/ = -1): void { + let awayProgramType: ContextGLProgramType; + switch (programType) { + case Context3DProgramType.FRAGMENT: + awayProgramType = ContextGLProgramType.FRAGMENT; + break; + case Context3DProgramType.VERTEX: + awayProgramType = ContextGLProgramType.VERTEX; + break; + default: + break; + } + + let programConstants = (programType == Context3DProgramType.FRAGMENT) ? this._fragmentProgramConstants : this._vertexProgramConstants; + if (numRegisters == -1) + { + numRegisters = (data.length >> 2); + } + let sourceIndex = 0; + let destIndex = firstRegister * 4; + for (let i = 0; i < numRegisters; i++) + { + programConstants[destIndex++] = data.axGetNumericProperty(sourceIndex++); + programConstants[destIndex++] = data.axGetNumericProperty(sourceIndex++); + programConstants[destIndex++] = data.axGetNumericProperty(sourceIndex++); + programConstants[destIndex++] = data.axGetNumericProperty(sourceIndex++); + } + + this._adaptee.context.setProgramConstantsFromArray(awayProgramType, new Float32Array(programConstants)); + } + + public setProgramConstantsFromMatrix(programType: string, firstRegister: number, matrix: Matrix3D, transposedMatrix: boolean = false): void { + let awayProgramType: ContextGLProgramType; + switch (programType) { + case Context3DProgramType.FRAGMENT: + awayProgramType = ContextGLProgramType.FRAGMENT; + break; + case Context3DProgramType.VERTEX: + awayProgramType = ContextGLProgramType.VERTEX; + break; + default: + break; + } + let programConstants = (programType == Context3DProgramType.FRAGMENT) ? this._fragmentProgramConstants : this._vertexProgramConstants; + + let i = firstRegister * 4; + let matrixData = new Float32Array(16); + matrix.adaptee.copyRawDataTo(matrixData, 0, transposedMatrix); + for(let j = 0; j < 16; j+=4) + { + programConstants[i++] = matrixData[j+0]; + programConstants[i++] = matrixData[j+1]; + programConstants[i++] = matrixData[j+2]; + programConstants[i++] = matrixData[j+3]; + } + + + this._adaptee.context.setProgramConstantsFromArray(awayProgramType, new Float32Array(programConstants)); + } + + public setProgramConstantsFromByteArray(programType: string, firstRegister: number /*int*/, numRegisters: number /*int*/, data: ByteArray, byteArrayOffset: number /*uint*/): void { + Debug.notImplemented('public flash.display3D.Context3D::setProgramConstantsFromByteArray'); return; + } + + public setVertexBufferAt(index: number, buffer: VertexBuffer3D, bufferOffset: number = 0, format: string = 'float4'): void { + let awayFormat: number; + switch (format) { + case Context3DVertexBufferFormat.BYTES_4: + awayFormat = ContextGLVertexBufferFormat.BYTE_4; + break; + case Context3DVertexBufferFormat.FLOAT_1: + awayFormat = ContextGLVertexBufferFormat.FLOAT_1; + break; + case Context3DVertexBufferFormat.FLOAT_2: + awayFormat = ContextGLVertexBufferFormat.FLOAT_2; + break; + case Context3DVertexBufferFormat.FLOAT_3: + awayFormat = ContextGLVertexBufferFormat.FLOAT_3; + break; + case Context3DVertexBufferFormat.FLOAT_4: + awayFormat = ContextGLVertexBufferFormat.FLOAT_4; + break; + default: + break; + } + this._adaptee.context.setVertexBufferAt(buffer ? index : -1, buffer?._adaptee, bufferOffset * 4, awayFormat); + + } + + public setBlendFactors(sourceFactor: string, destinationFactor: string): void { + let awaySourceFactor: ContextGLBlendFactor; + switch (sourceFactor) { + case Context3DBlendFactor.ONE: + awaySourceFactor = ContextGLBlendFactor.ONE; + break; + case Context3DBlendFactor.ZERO: + awaySourceFactor = ContextGLBlendFactor.ZERO; + break; + case Context3DBlendFactor.SOURCE_ALPHA: + awaySourceFactor = ContextGLBlendFactor.SOURCE_ALPHA; + break; + case Context3DBlendFactor.SOURCE_COLOR: + awaySourceFactor = ContextGLBlendFactor.SOURCE_COLOR; + break; + case Context3DBlendFactor.ONE_MINUS_SOURCE_ALPHA: + awaySourceFactor = ContextGLBlendFactor.ONE_MINUS_SOURCE_ALPHA; + break; + case Context3DBlendFactor.ONE_MINUS_SOURCE_COLOR: + awaySourceFactor = ContextGLBlendFactor.ONE_MINUS_SOURCE_COLOR; + break; + case Context3DBlendFactor.DESTINATION_ALPHA: + awaySourceFactor = ContextGLBlendFactor.DESTINATION_ALPHA; + break; + case Context3DBlendFactor.DESTINATION_COLOR: + awaySourceFactor = ContextGLBlendFactor.DESTINATION_COLOR; + break; + case Context3DBlendFactor.ONE_MINUS_DESTINATION_ALPHA: + awaySourceFactor = ContextGLBlendFactor.ONE_MINUS_DESTINATION_ALPHA; + break; + case Context3DBlendFactor.ONE_MINUS_DESTINATION_COLOR: + awaySourceFactor = ContextGLBlendFactor.ONE_MINUS_DESTINATION_COLOR; + break; + default: + break; + } + + let awayDestinationFactor: ContextGLBlendFactor; + switch (destinationFactor) { + case Context3DBlendFactor.ONE: + awayDestinationFactor = ContextGLBlendFactor.ONE; + break; + case Context3DBlendFactor.ZERO: + awayDestinationFactor = ContextGLBlendFactor.ZERO; + break; + case Context3DBlendFactor.SOURCE_ALPHA: + awayDestinationFactor = ContextGLBlendFactor.SOURCE_ALPHA; + break; + case Context3DBlendFactor.SOURCE_COLOR: + awayDestinationFactor = ContextGLBlendFactor.SOURCE_COLOR; + break; + case Context3DBlendFactor.ONE_MINUS_SOURCE_ALPHA: + awayDestinationFactor = ContextGLBlendFactor.ONE_MINUS_SOURCE_ALPHA; + break; + case Context3DBlendFactor.ONE_MINUS_SOURCE_COLOR: + awayDestinationFactor = ContextGLBlendFactor.ONE_MINUS_SOURCE_COLOR; + break; + case Context3DBlendFactor.DESTINATION_ALPHA: + awayDestinationFactor = ContextGLBlendFactor.DESTINATION_ALPHA; + break; + case Context3DBlendFactor.DESTINATION_COLOR: + awayDestinationFactor = ContextGLBlendFactor.DESTINATION_COLOR; + break; + case Context3DBlendFactor.ONE_MINUS_DESTINATION_ALPHA: + awayDestinationFactor = ContextGLBlendFactor.ONE_MINUS_DESTINATION_ALPHA; + break; + case Context3DBlendFactor.ONE_MINUS_DESTINATION_COLOR: + awayDestinationFactor = ContextGLBlendFactor.ONE_MINUS_DESTINATION_COLOR; + break; + default: + break; + } + + this._adaptee.context.setBlendFactors(awaySourceFactor, awayDestinationFactor); + this._adaptee.context.setBlendEquation(ContextGLBlendEquation.ADD, ContextGLBlendEquation.ADD); + } + + public setColorMask(red: boolean, green: boolean, blue: boolean, alpha: boolean): void { + this._adaptee.context.setColorMask(red, green, blue, alpha); + } + + public setDepthTest(depthMask: boolean, passCompareMode: string): void { + let awayPassCompareMode: ContextGLCompareMode = ContextGLCompareMode.ALWAYS; + switch (passCompareMode) { + case Context3DCompareMode.ALWAYS: + awayPassCompareMode = ContextGLCompareMode.ALWAYS; + break; + case Context3DCompareMode.NEVER: + awayPassCompareMode = ContextGLCompareMode.NEVER; + break; + case Context3DCompareMode.LESS: + awayPassCompareMode = ContextGLCompareMode.LESS; + break; + case Context3DCompareMode.LESS_EQUAL: + awayPassCompareMode = ContextGLCompareMode.LESS_EQUAL; + break; + case Context3DCompareMode.EQUAL: + awayPassCompareMode = ContextGLCompareMode.EQUAL; + break; + case Context3DCompareMode.GREATER_EQUAL: + awayPassCompareMode = ContextGLCompareMode.GREATER_EQUAL; + break; + case Context3DCompareMode.GREATER: + awayPassCompareMode = ContextGLCompareMode.GREATER; + break; + case Context3DCompareMode.NOT_EQUAL: + awayPassCompareMode = ContextGLCompareMode.NOT_EQUAL; + break; + default: + break; + } + this._adaptee.context.setDepthTest(depthMask, awayPassCompareMode); + } + + public setCulling(triangleFaceToCull: string): void { + let awayTriangleFaceToCull: ContextGLTriangleFace; + switch (triangleFaceToCull) { + case Context3DTriangleFace.NONE: + awayTriangleFaceToCull = ContextGLTriangleFace.NONE; + break; + case Context3DTriangleFace.BACK: + awayTriangleFaceToCull = ContextGLTriangleFace.BACK; + break; + case Context3DTriangleFace.FRONT: + awayTriangleFaceToCull = ContextGLTriangleFace.FRONT; + break; + case Context3DTriangleFace.FRONT_AND_BACK: + awayTriangleFaceToCull = ContextGLTriangleFace.FRONT_AND_BACK; + break; + } + this._adaptee.context.setCulling(awayTriangleFaceToCull); + } + + public setStencilActions(triangleFace: string = 'frontAndBack', compareMode: string = 'always', actionOnBothPass: string = 'keep', actionOnDepthFail: string = 'keep', actionOnDepthPassStencilFail: string = 'keep'): void { + let awayTriangleFace: ContextGLTriangleFace = ContextGLTriangleFace.FRONT_AND_BACK; + switch (triangleFace) { + case Context3DTriangleFace.BACK: + awayTriangleFace = ContextGLTriangleFace.BACK; + break; + case Context3DTriangleFace.FRONT: + awayTriangleFace = ContextGLTriangleFace.FRONT; + break; + case Context3DTriangleFace.FRONT_AND_BACK: + awayTriangleFace = ContextGLTriangleFace.FRONT_AND_BACK; + break; + case Context3DTriangleFace.NONE: + awayTriangleFace = ContextGLTriangleFace.NONE; + break; + default: + break; + } + + let awayCompareMode: ContextGLCompareMode = ContextGLCompareMode.ALWAYS; + switch (compareMode) { + case Context3DCompareMode.ALWAYS: + awayCompareMode = ContextGLCompareMode.ALWAYS; + break; + case Context3DCompareMode.NEVER: + awayCompareMode = ContextGLCompareMode.NEVER; + break; + case Context3DCompareMode.LESS: + awayCompareMode = ContextGLCompareMode.LESS; + break; + case Context3DCompareMode.LESS_EQUAL: + awayCompareMode = ContextGLCompareMode.LESS_EQUAL; + break; + case Context3DCompareMode.EQUAL: + awayCompareMode = ContextGLCompareMode.EQUAL; + break; + case Context3DCompareMode.GREATER_EQUAL: + awayCompareMode = ContextGLCompareMode.GREATER_EQUAL; + break; + case Context3DCompareMode.GREATER: + awayCompareMode = ContextGLCompareMode.GREATER; + break; + case Context3DCompareMode.NOT_EQUAL: + awayCompareMode = ContextGLCompareMode.NOT_EQUAL; + break; + default: + break; + } + + let awayActionOnBothPass: ContextGLStencilAction = ContextGLStencilAction.KEEP; + switch (actionOnBothPass) { + case Context3DStencilAction.DECREMENT_SATURATE: + awayActionOnBothPass = ContextGLStencilAction.DECREMENT_SATURATE; + break; + case Context3DStencilAction.DECREMENT_WRAP: + awayActionOnBothPass = ContextGLStencilAction.DECREMENT_WRAP; + break; + case Context3DStencilAction.INCREMENT_SATURATE: + awayActionOnBothPass = ContextGLStencilAction.INCREMENT_SATURATE; + break; + case Context3DStencilAction.INCREMENT_WRAP: + awayActionOnBothPass = ContextGLStencilAction.INCREMENT_WRAP; + break; + case Context3DStencilAction.INVERT: + awayActionOnBothPass = ContextGLStencilAction.INVERT; + break; + case Context3DStencilAction.KEEP: + awayActionOnBothPass = ContextGLStencilAction.KEEP; + break; + case Context3DStencilAction.SET: + awayActionOnBothPass = ContextGLStencilAction.SET; + break; + case Context3DStencilAction.ZERO: + awayActionOnBothPass = ContextGLStencilAction.ZERO; + break; + default: + break; + } + + let awayActionOnDepthFail: ContextGLStencilAction = ContextGLStencilAction.KEEP; + switch (actionOnDepthFail) { + case Context3DStencilAction.DECREMENT_SATURATE: + awayActionOnDepthFail = ContextGLStencilAction.DECREMENT_SATURATE; + break; + case Context3DStencilAction.DECREMENT_WRAP: + awayActionOnDepthFail = ContextGLStencilAction.DECREMENT_WRAP; + break; + case Context3DStencilAction.INCREMENT_SATURATE: + awayActionOnDepthFail = ContextGLStencilAction.INCREMENT_SATURATE; + break; + case Context3DStencilAction.INCREMENT_WRAP: + awayActionOnDepthFail = ContextGLStencilAction.INCREMENT_WRAP; + break; + case Context3DStencilAction.INVERT: + awayActionOnDepthFail = ContextGLStencilAction.INVERT; + break; + case Context3DStencilAction.KEEP: + awayActionOnDepthFail = ContextGLStencilAction.KEEP; + break; + case Context3DStencilAction.SET: + awayActionOnDepthFail = ContextGLStencilAction.SET; + break; + case Context3DStencilAction.ZERO: + awayActionOnDepthFail = ContextGLStencilAction.ZERO; + break; + default: + break; + } + + let awayActionOnDepthPassStencilFail: ContextGLStencilAction = ContextGLStencilAction.KEEP; + switch (actionOnDepthPassStencilFail) { + case Context3DStencilAction.DECREMENT_SATURATE: + awayActionOnDepthPassStencilFail = ContextGLStencilAction.DECREMENT_SATURATE; + break; + case Context3DStencilAction.DECREMENT_WRAP: + awayActionOnDepthPassStencilFail = ContextGLStencilAction.DECREMENT_WRAP; + break; + case Context3DStencilAction.INCREMENT_SATURATE: + awayActionOnDepthPassStencilFail = ContextGLStencilAction.INCREMENT_SATURATE; + break; + case Context3DStencilAction.INCREMENT_WRAP: + awayActionOnDepthPassStencilFail = ContextGLStencilAction.INCREMENT_WRAP; + break; + case Context3DStencilAction.INVERT: + awayActionOnDepthPassStencilFail = ContextGLStencilAction.INVERT; + break; + case Context3DStencilAction.KEEP: + awayActionOnDepthPassStencilFail = ContextGLStencilAction.KEEP; + break; + case Context3DStencilAction.SET: + awayActionOnDepthPassStencilFail = ContextGLStencilAction.SET; + break; + case Context3DStencilAction.ZERO: + awayActionOnDepthPassStencilFail = ContextGLStencilAction.ZERO; + break; + default: + break; + } + + this._adaptee.context.setStencilActions(awayTriangleFace, awayCompareMode, awayActionOnBothPass, awayActionOnDepthFail, awayActionOnDepthPassStencilFail, CoordinateSystem.LEFT_HANDED); + } + + public setStencilReferenceValue(referenceValue: number /*uint*/, readMask: number /*uint*/ = 255, writeMask: number /*uint*/ = 255): void { + this._adaptee.context.setStencilReferenceValue(referenceValue, readMask, writeMask); + } + + public setScissorRectangle(rectangle: Rectangle): void { + this._adaptee.context.setScissorRectangle(rectangle?.adaptee); + } + + public createVertexBuffer(numVertices: number, data32PerVertex: number, bufferUsage: string = 'staticDraw'): VertexBuffer3D { + return new (this.sec as SecurityDomain).flash.display3D.VertexBuffer3D(this, numVertices, data32PerVertex); + } + + public createIndexBuffer(numIndices: number, bufferUsage: string = 'staticDraw'): IndexBuffer3D { + return new (this.sec as SecurityDomain).flash.display3D.IndexBuffer3D(this, numIndices); + } + + public createTexture(width: number /*int*/, height: number /*int*/, format: string, optimizeForRenderToTexture: boolean, streamingLevels: number /*int*/ = 0): Texture { + return new (this.sec as SecurityDomain).flash.display3D.textures.Texture(this, width, height, format, optimizeForRenderToTexture, streamingLevels); + } + + public createRectangleTexture(width: number /*int*/, height: number /*int*/, format: string, optimizeForRenderToTexture: boolean): RectangleTexture { + return new (this.sec as SecurityDomain).flash.display3D.textures.RectangleTexture(this, width, height, format, optimizeForRenderToTexture); + } + + public createCubeTexture(size: number /*int*/, format: string, optimizeForRenderToTexture: boolean, streamingLevels: number /*int*/ = 0): CubeTexture /*CubeTexture*/ { + return new (this.sec as SecurityDomain).flash.display3D.textures.CubeTexture(this, size, format, optimizeForRenderToTexture, streamingLevels); + } + + public createProgram(): Program3D { + return new (this.sec as SecurityDomain).flash.display3D.Program3D(this); + } + + public drawToBitmapData(destination: BitmapData): void { + this.adaptee.context.drawToBitmapImage2D(destination.adaptee as unknown as BitmapImage2D); + } + + public setRenderToBackBuffer(): void { + this._adaptee.context.setRenderToBackBuffer(); + } + + public setRenderToTexture(texture:TextureBase, enableDepthAndStencil:boolean = false, antiAlias:number/*int*/ = 0, surfaceSelector:number/*int*/ = 0, colorOutputIndex:number/*int*/ = 0): void { + this._adaptee.context.setRenderToTexture(texture?._adaptee, enableDepthAndStencil, antiAlias, surfaceSelector); + } + + public setTextureAt(sampler: number /*int*/, texture: TextureBase): void { + this._adaptee.context.setTextureAt(sampler, texture?._adaptee); + } +} diff --git a/lib/display3D/Context3DBlendFactor.ts b/lib/display3D/Context3DBlendFactor.ts new file mode 100644 index 00000000..27e78a97 --- /dev/null +++ b/lib/display3D/Context3DBlendFactor.ts @@ -0,0 +1,43 @@ +/** + * Copyright 2014 Mozilla Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { ASObject } from '@awayfl/avm2'; + +// Class: Context3DBlendFactor +export class Context3DBlendFactor extends ASObject { + + // Called whenever the class is initialized. + public static classInitializer: any = null; + + constructor () { + super(); + } + + // JS -> AS Bindings + public static ONE: string = 'one'; + public static ZERO: string = 'zero'; + public static SOURCE_ALPHA: string = 'sourceAlpha'; + public static SOURCE_COLOR: string = 'sourceColor'; + public static ONE_MINUS_SOURCE_ALPHA: string = 'oneMinusSourceAlpha'; + public static ONE_MINUS_SOURCE_COLOR: string = 'oneMinusSourceColor'; + public static DESTINATION_ALPHA: string = 'destinationAlpha'; + public static DESTINATION_COLOR: string = 'destinationColor'; + public static ONE_MINUS_DESTINATION_ALPHA: string = 'oneMinusDestinationAlpha'; + public static ONE_MINUS_DESTINATION_COLOR: string = 'oneMinusDestinationColor'; + + // AS -> JS Bindings + +} diff --git a/lib/display3D/Context3DClearMask.ts b/lib/display3D/Context3DClearMask.ts index 73d8f6f3..a6c0aa92 100644 --- a/lib/display3D/Context3DClearMask.ts +++ b/lib/display3D/Context3DClearMask.ts @@ -1 +1,20 @@ -export { ContextGLClearMask as Context3DClearMask } from '@awayjs/stage'; +import { ASObject } from '@awayfl/avm2'; + +// Based on https://github.com/ruffle-rs/ruffle/blob/master/core/src/avm2/globals/flash/display3D/Context3DClearMask.as +export class Context3DClearMask extends ASObject { + + // Called whenever the class is initialized. + public static classInitializer: any = null; + + // Clear only the color buffer. + public static COLOR: number = 1 << 0; + + // Clear only the depth buffer. + public static DEPTH: number = 1 << 1; + + // Clear only the stencil buffer. + public static STENCIL: number = 1 << 2; + + // Clear all buffers. + public static ALL: number = Context3DClearMask.COLOR | Context3DClearMask.DEPTH | Context3DClearMask.STENCIL; +} \ No newline at end of file diff --git a/lib/display3D/Context3DCompareMode.ts b/lib/display3D/Context3DCompareMode.ts new file mode 100644 index 00000000..bac90ebb --- /dev/null +++ b/lib/display3D/Context3DCompareMode.ts @@ -0,0 +1,40 @@ +/** + * Copyright 2014 Mozilla Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { ASObject } from '@awayfl/avm2'; + +export class Context3DCompareMode extends ASObject { + + // Called whenever the class is initialized. + static classInitializer: any = null; + + constructor () { + super(); + } + + // JS -> AS Bindings + static ALWAYS: string = 'always'; + static NEVER: string = 'never'; + static LESS: string = 'less'; + static LESS_EQUAL: string = 'lessEqual'; + static EQUAL: string = 'equal'; + static GREATER_EQUAL: string = 'greaterEqual'; + static GREATER: string = 'greater'; + static NOT_EQUAL: string = 'notEqual'; + + // AS -> JS Bindings + +} diff --git a/lib/display3D/Context3DProfile.ts b/lib/display3D/Context3DProfile.ts new file mode 100644 index 00000000..6c1f62bc --- /dev/null +++ b/lib/display3D/Context3DProfile.ts @@ -0,0 +1,13 @@ +import { ASObject } from '@awayfl/avm2'; + +export class Context3DProfile extends ASObject { + // Called whenever the class is initialized. + public static classInitializer: any = null; + + public static BASELINE: string = 'baseline'; + public static BASELINE_CONSTRAINED: string = 'baselineConstrained'; + public static BASELINE_EXTENDED: string = 'baselineExtended'; + public static STANDARD: string = 'standard'; + public static STANDARD_CONSTRAINED: string = 'standardConstrained'; + public static STANDARD_EXTENDED: string = 'standardExtended'; +} \ No newline at end of file diff --git a/lib/display3D/Context3DProgramType.ts b/lib/display3D/Context3DProgramType.ts index 325b76b5..d59de964 100644 --- a/lib/display3D/Context3DProgramType.ts +++ b/lib/display3D/Context3DProgramType.ts @@ -1 +1,9 @@ -export { ContextGLProgramType as Context3DProgramType } from '@awayjs/stage'; +import { ASObject } from '@awayfl/avm2'; + +export class Context3DProgramType extends ASObject { + // Called whenever the class is initialized. + public static classInitializer: any = null; + + public static FRAGMENT: string = 'fragment'; + public static VERTEX = 'vertex'; +} \ No newline at end of file diff --git a/lib/display3D/Context3DRenderMode.ts b/lib/display3D/Context3DRenderMode.ts new file mode 100644 index 00000000..c0e45372 --- /dev/null +++ b/lib/display3D/Context3DRenderMode.ts @@ -0,0 +1,9 @@ +import { ASObject } from '@awayfl/avm2'; + +export class Context3DRenderMode extends ASObject { + // Called whenever the class is initialized. + public static classInitializer: any = null; + + public static AUTO: string = 'auto'; + public static SOFTWARE: string = 'software'; +} \ No newline at end of file diff --git a/lib/display3D/Context3DStencilAction.ts b/lib/display3D/Context3DStencilAction.ts new file mode 100644 index 00000000..93d744af --- /dev/null +++ b/lib/display3D/Context3DStencilAction.ts @@ -0,0 +1,41 @@ +/** + * Copyright 2014 Mozilla Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { ASObject } from '@awayfl/avm2'; + +// Class: Context3DStencilAction +export class Context3DStencilAction extends ASObject { + + // Called whenever the class is initialized. + static classInitializer: any = null; + + constructor () { + super(); + } + + // JS -> AS Bindings + static KEEP: string = 'keep'; + static ZERO: string = 'zero'; + static INCREMENT_SATURATE: string = 'incrementSaturate'; + static DECREMENT_SATURATE: string = 'decrementSaturate'; + static INVERT: string = 'invert'; + static INCREMENT_WRAP: string = 'incrementWrap'; + static DECREMENT_WRAP: string = 'decrementWrap'; + static SET: string = 'set'; + + // AS -> JS Bindings + +} diff --git a/lib/display3D/Context3DTextureFormat.ts b/lib/display3D/Context3DTextureFormat.ts new file mode 100644 index 00000000..f38f3dd6 --- /dev/null +++ b/lib/display3D/Context3DTextureFormat.ts @@ -0,0 +1,34 @@ +import { ASObject } from '@awayfl/avm2'; + +/** + * Copyright 2014 Mozilla Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +export class Context3DTextureFormat extends ASObject { + + // Called whenever the class is initialized. + static classInitializer: any = null; + + constructor () { + super(); + } + + // JS -> AS Bindings + static BGRA: string = 'bgra'; + static COMPRESSED: string = 'compressed'; + static COMPRESSED_ALPHA: string = 'compressedAlpha'; + + // AS -> JS Bindings + +} diff --git a/lib/display3D/Context3DTriangleFace.ts b/lib/display3D/Context3DTriangleFace.ts new file mode 100644 index 00000000..f9558329 --- /dev/null +++ b/lib/display3D/Context3DTriangleFace.ts @@ -0,0 +1,37 @@ +/** + * Copyright 2014 Mozilla Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// Class: Context3DTriangleFace + +import { ASObject } from '@awayfl/avm2'; + +export class Context3DTriangleFace extends ASObject { + + // Called whenever the class is initialized. + static classInitializer: any = null; + + constructor () { + super(); + } + + // JS -> AS Bindings + static NONE: string = 'none'; + static BACK: string = 'back'; + static FRONT: string = 'front'; + static FRONT_AND_BACK: string = 'frontAndBack'; + + // AS -> JS Bindings + +} diff --git a/lib/display3D/Context3DVertexBufferFormat.ts b/lib/display3D/Context3DVertexBufferFormat.ts new file mode 100644 index 00000000..f5d1e82f --- /dev/null +++ b/lib/display3D/Context3DVertexBufferFormat.ts @@ -0,0 +1,12 @@ +import { ASObject } from '@awayfl/avm2'; + +export class Context3DVertexBufferFormat extends ASObject { + // Called whenever the class is initialized. + public static classInitializer: any = null; + + public static BYTES_4: string = 'bytes4'; + public static FLOAT_1: string = 'float1'; + public static FLOAT_2: string = 'float2'; + public static FLOAT_3: string = 'float3'; + public static FLOAT_4: string = 'float4'; +} \ No newline at end of file diff --git a/lib/display3D/IndexBuffer3D.ts b/lib/display3D/IndexBuffer3D.ts new file mode 100644 index 00000000..f69b2168 --- /dev/null +++ b/lib/display3D/IndexBuffer3D.ts @@ -0,0 +1,36 @@ +import { ASObject, AXClass, Uint32Vector } from '@awayfl/avm2'; +import { Debug } from '@awayfl/swf-loader'; +import { IIndexBuffer } from '@awayjs/stage'; +import { ByteArray } from '../utils/ByteArray'; +import { Context3D } from './Context3D'; + +export class IndexBuffer3D extends ASObject { + static axClass: typeof IndexBuffer3D & AXClass; + static classInitializer: any = null; + static classSymbols: string [] = null; // []; + static instanceSymbols: string [] = null; + + public _adaptee: IIndexBuffer + + constructor(context3D: Context3D, numIndices: number) { + super(); + this._adaptee = context3D.adaptee.context.createIndexBuffer(numIndices); + } + + public uploadFromVector(data: Uint32Vector, startOffset: number, count: number): void { + const uint16ArrayData = new Uint16Array(data.length); + for (let i: number = 0; i < data.length; i++) { + uint16ArrayData[i] = data.axGetNumericProperty(i); + } + this._adaptee.uploadFromArray(uint16ArrayData, startOffset, count); + } + + public uploadFromByteArray(data: ByteArray, byteArrayOffset: number /*int*/, startOffset: number /*int*/, count: number /*int*/): void { + Debug.notImplemented('public flash.display3D.IndexBuffer3D::uploadFromByteArray'); return; + } + + public dispose(): void { + this._adaptee.dispose(); + } + +} \ No newline at end of file diff --git a/lib/display3D/Program3D.ts b/lib/display3D/Program3D.ts new file mode 100644 index 00000000..6a342f40 --- /dev/null +++ b/lib/display3D/Program3D.ts @@ -0,0 +1,28 @@ +import { ASObject, AXClass } from '@awayfl/avm2'; +import { IContextGL, IProgram } from '@awayjs/stage'; +import { ByteArray } from '../utils/ByteArray'; +import { Context3D } from './Context3D'; + +export class Program3D extends ASObject { + static axClass: typeof Program3D & AXClass; + static classInitializer: any = null; + static classSymbols: string [] = null; // []; + static instanceSymbols: string [] = null; + + public _adaptee: IProgram + private _context: IContextGL + + constructor(context3D: Context3D) { + super(); + this._context = context3D.adaptee.context; + this._adaptee = context3D.adaptee.context.createProgram(); + } + + public dispose() { + this._adaptee.dispose(); + } + + public upload(vertexProgram: ByteArray, fragmentProgram: ByteArray): void { + this._adaptee.upload(vertexProgram, fragmentProgram); + } +} \ No newline at end of file diff --git a/lib/display3D/Texture.ts b/lib/display3D/Texture.ts deleted file mode 100644 index be3d1019..00000000 --- a/lib/display3D/Texture.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { BitmapData } from './../display/BitmapData'; -import { ByteArray } from './../utils/ByteArray'; -export class Texture { - - // todo. can probably route directly to awayjs class - - public static fromBitmapData(bitmapData: BitmapData): Texture { - console.warn('[playerglobal/display3D/Texture] - fromBitmapData not implemented'); - return null; - } - - constructor () { - } - - public uploadCompressedTextureFromByteArray (data: ByteArray, byteArrayOffset: number, async: boolean = false) { - console.warn('[playerglobal/display3D/Texture] - uploadCompressedTextureFromByteArray not implemented'); - - } - - public uploadFromBitmapData (source: BitmapData, miplevel: number = 0) { - console.warn('[playerglobal/display3D/Texture] - uploadFromBitmapData not implemented'); - - } - - public uploadFromByteArray (data: ByteArray, byteArrayOffset: number, miplevel: number = 0) { - console.warn('[playerglobal/display3D/Texture] - uploadFromByteArray not implemented'); - - } -} diff --git a/lib/display3D/VertexBuffer3D.ts b/lib/display3D/VertexBuffer3D.ts new file mode 100644 index 00000000..f4b51199 --- /dev/null +++ b/lib/display3D/VertexBuffer3D.ts @@ -0,0 +1,34 @@ +import { ASObject, AXClass, Float64Vector } from '@awayfl/avm2'; +import { Debug } from '@awayfl/swf-loader'; +import { IVertexBuffer } from '@awayjs/stage'; +import { ByteArray } from '../utils/ByteArray'; +import { Context3D } from './Context3D'; + +export class VertexBuffer3D extends ASObject { + static axClass: typeof VertexBuffer3D & AXClass; + static classInitializer: any = null; + static classSymbols: string [] = null; // []; + static instanceSymbols: string [] = null; + public _adaptee: IVertexBuffer + + constructor(context3D: Context3D, numVertices: number, data32PerVertex: number) { + super(); + this._adaptee = context3D.adaptee.context.createVertexBuffer(numVertices, data32PerVertex * 4); + } + + public uploadFromVector(data: Float64Vector, startVertex: number, numVertices) { + const dataFloat32Array: Float32Array = new Float32Array(data.length); + for (let i: number = 0; i < data.length; i++) { + dataFloat32Array[i] = data.axGetNumericProperty(i); + } + this._adaptee.uploadFromArray(dataFloat32Array, startVertex, numVertices); + } + + public uploadFromByteArray(data: ByteArray, byteArrayOffset: number /*int*/, startVertex: number /*int*/, numVertices: number /*int*/): void { + Debug.notImplemented('public flash.display3D.VertexBuffer3D::uploadFromByteArray'); return; + } + + public dispose(): void { + this._adaptee.dispose(); + } +} \ No newline at end of file diff --git a/lib/display3D/textures/CubeTexture.ts b/lib/display3D/textures/CubeTexture.ts new file mode 100644 index 00000000..ac472f20 --- /dev/null +++ b/lib/display3D/textures/CubeTexture.ts @@ -0,0 +1,75 @@ +/** + * Copyright 2014 Mozilla Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// Class: CubeTexture +import { Debug } from '@awayfl/swf-loader'; +import { ContextGLTextureFormat, CubeTextureWebGL, TextureWebGL } from '@awayjs/stage'; +import { Context3D } from '../Context3D'; +import { BitmapData } from './../../display/BitmapData'; +import { ByteArray } from './../../utils/ByteArray'; +import { TextureBase } from './TextureBase'; + +export class CubeTexture extends TextureBase { + // Called whenever the class is initialized. + static classInitializer: any = null; + + constructor( + context: Context3D, + size: number, + format: String, + optimizeForRenderToTexture: boolean, + streamingLevels: number = 0 + ) { + super(); + let awayTextureFormat: ContextGLTextureFormat; + switch (format) { + case 'bgra': + awayTextureFormat = ContextGLTextureFormat.BGRA; + break; + case 'compressed': + awayTextureFormat = ContextGLTextureFormat.COMPRESSED; + break; + case 'compressedAlpha': + awayTextureFormat = ContextGLTextureFormat.COMPRESSED_ALPHA; + break; + } + this._adaptee = context.adaptee.context.createCubeTexture( + size, + awayTextureFormat, + optimizeForRenderToTexture, + streamingLevels + ) as CubeTextureWebGL; + } + + public uploadFromBitmapData(source: BitmapData, side: number /*uint*/, miplevel: number /*uint*/ = 0): void { + if (miplevel == 0) // @todo: Additional Mips cause errors + ( this._adaptee).uploadFromArray(new Uint8Array(source.adaptee.getDataInternal()), side, miplevel); + } + + public uploadFromByteArray(data: ByteArray,byteArrayOffset: number /*uint*/,side: number /*uint*/,miplevel: number /*uint*/ = 0 + ): void { + if (miplevel == 0) // @todo: Additional Mips cause errors + ( this._adaptee).uploadFromArray(new Uint8Array(data.arraybytes), side, miplevel); + } + + public uploadCompressedTextureFromByteArray(data: ByteArray,byteArrayOffset: number /*uint*/,async: boolean = false + ): void { + data = data; + byteArrayOffset = byteArrayOffset >>> 0; + async = !!async; + Debug.notImplemented('public flash.display3D.textures.CubeTexture::uploadCompressedTextureFromByteArray'); + return; + } +} diff --git a/lib/display3D/textures/RectangleTexture.ts b/lib/display3D/textures/RectangleTexture.ts new file mode 100644 index 00000000..8e5f6ae5 --- /dev/null +++ b/lib/display3D/textures/RectangleTexture.ts @@ -0,0 +1,51 @@ +import { Debug } from '@awayfl/swf-loader'; +import { ContextGLTextureFormat, TextureWebGL } from '@awayjs/stage'; +import { Context3D } from '../Context3D'; +import { BitmapData } from './../../display/BitmapData'; +import { ByteArray } from './../../utils/ByteArray'; +import { TextureBase } from './TextureBase'; + +export class RectangleTexture extends TextureBase { + constructor( + context: Context3D, + width: number, + height: number, + format: string, + optimizeForRenderToTexture: boolean, + streamingLevels: number = 0 + ) { + super(); + let awayTextureFormat: ContextGLTextureFormat; + switch (format) { + case 'bgra': + awayTextureFormat = ContextGLTextureFormat.BGRA; + break; + case 'compressed': + awayTextureFormat = ContextGLTextureFormat.COMPRESSED; + break; + case 'compressedAlpha': + awayTextureFormat = ContextGLTextureFormat.COMPRESSED_ALPHA; + break; + } + this._adaptee = context.adaptee.context.createTexture( + width, + height, + awayTextureFormat, + optimizeForRenderToTexture + ) as TextureWebGL; + } + + public uploadCompressedTextureFromByteArray(data: ByteArray, byteArrayOffset: number, async: boolean = false) { + Debug.notImplemented('public flash.display3D.textures.RectangleTexture::uploadCompressedTextureFromByteArray'); + } + + public uploadFromBitmapData(source: BitmapData, miplevel: number = 0) { + if (miplevel == 0) // @todo: Additional Mips cause errors + ( this._adaptee).uploadFromArray(new Uint8Array(source.adaptee.getDataInternal()), miplevel); + } + + public uploadFromByteArray(data: ByteArray, byteArrayOffset: number, miplevel: number = 0) { + if (miplevel == 0) // @todo: Additional Mips cause errors + ( this._adaptee).uploadFromArray(new Uint8Array(data.arraybytes), miplevel); + } +} diff --git a/lib/display3D/textures/Texture.ts b/lib/display3D/textures/Texture.ts new file mode 100644 index 00000000..3731a725 --- /dev/null +++ b/lib/display3D/textures/Texture.ts @@ -0,0 +1,50 @@ +import { Debug } from '@awayfl/swf-loader'; +import { ContextGLTextureFormat, TextureWebGL } from '@awayjs/stage'; +import { Context3D } from '../Context3D'; +import { BitmapData } from './../../display/BitmapData'; +import { ByteArray } from './../../utils/ByteArray'; +import { TextureBase } from './TextureBase'; +export class Texture extends TextureBase { + constructor( + context: Context3D, + width: number, + height: number, + format: string, + optimizeForRenderToTexture: boolean, + streamingLevels: number = 0 + ) { + super(); + let awayTextureFormat: ContextGLTextureFormat; + switch (format) { + case 'bgra': + awayTextureFormat = ContextGLTextureFormat.BGRA; + break; + case 'compressed': + awayTextureFormat = ContextGLTextureFormat.COMPRESSED; + break; + case 'compressedAlpha': + awayTextureFormat = ContextGLTextureFormat.COMPRESSED_ALPHA; + break; + } + this._adaptee = context.adaptee.context.createTexture( + width, + height, + awayTextureFormat, + optimizeForRenderToTexture + ) as TextureWebGL; + } + + public uploadCompressedTextureFromByteArray(data: ByteArray, byteArrayOffset: number, async: boolean = false) { + Debug.notImplemented('public flash.display3D.textures.Texture::uploadCompressedTextureFromByteArray'); + } + + public uploadFromBitmapData(source: BitmapData, miplevel: number = 0) { + if (miplevel == 0) // @todo: Additional Mips cause errors + ( this._adaptee).uploadFromArray(new Uint8Array(source.adaptee.getDataInternal()), miplevel); + } + + public uploadFromByteArray(data: ByteArray, byteArrayOffset: number, miplevel: number = 0) { + if (miplevel == 0) // @todo: Additional Mips cause errors + ( this._adaptee).uploadFromArray(new Uint8Array(data.arraybytes), miplevel); + } +} diff --git a/lib/display3D/textures/TextureBase.ts b/lib/display3D/textures/TextureBase.ts new file mode 100644 index 00000000..574d58f1 --- /dev/null +++ b/lib/display3D/textures/TextureBase.ts @@ -0,0 +1,35 @@ +/** + * Copyright 2014 Mozilla Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Debug } from '@awayfl/swf-loader'; +import { CubeTextureWebGL, TextureBaseWebGL, TextureWebGL } from '@awayjs/stage'; +import { EventDispatcher } from '../../events/EventDispatcher'; +import { CubeTexture } from './CubeTexture'; +import { Texture } from './Texture'; + +export class TextureBase extends EventDispatcher { + + // Called whenever the class is initialized. + static classInitializer: any = null; + public _adaptee: TextureBaseWebGL; + constructor () { + super(); + } + + public dispose(): void { + this._adaptee.dispose(); + } +} diff --git a/lib/geom/Matrix3D.ts b/lib/geom/Matrix3D.ts index 9f975a2c..ad0c0141 100644 --- a/lib/geom/Matrix3D.ts +++ b/lib/geom/Matrix3D.ts @@ -1,8 +1,8 @@ import { Vector3D } from './Vector3D'; -import { ASObject } from '@awayfl/avm2'; +import { ASObject, Errors } from '@awayfl/avm2'; import { notImplemented, release, somewhatImplemented } from '@awayfl/swf-loader'; import { axCoerceString } from '@awayjs/graphics'; -import { Matrix3D as AwayMatrix3D } from '@awayjs/core'; +import { Matrix3D as AwayMatrix3D, Vector3D as AwayVector3D, Orientation3D } from '@awayjs/core'; import { Float64Vector, GenericVector } from '@awayfl/avm2'; import { SecurityDomain } from '../SecurityDomain'; @@ -107,10 +107,107 @@ export class Matrix3D extends ASObject { return v; } - public recompose(components: Float64Vector, orientationStyle: string = 'eulerAngles'): boolean { - //this._adaptee.recompose() - orientationStyle = axCoerceString(orientationStyle); - release || notImplemented('public flash.geom.Matrix3D::recompose'); return; + public recompose(components: GenericVector, orientationStyle: string = 'eulerAngles'): boolean { + // RUFFLE - unlike in OpenFL, we continue on even if some of the 'scale' components are 0 + if (components.length < 3) { + return false; + } + + if (!(orientationStyle == Orientation3D.AXIS_ANGLE || orientationStyle == Orientation3D.EULER_ANGLES || orientationStyle == Orientation3D.QUATERNION)) { + this.sec.throwError("flash.geom.Matrix3D", Errors.Matrix3DDecomposeTypeInvalid, orientationStyle); + } + + let awayComponets: Array = new Array(3); + + for (let i = 0; i < 3; i++) + awayComponets[i] = components.axGetNumericProperty(i).adaptee; + + if (orientationStyle == Orientation3D.QUATERNION) { + // Flash throws exceptions from 'recompose' certain values of 'components', + // which we need to reproduce. See the 'matrix3d_compose' test + somewhatImplemented("public flash.geom.Matrix3D::recompose with Orientation3D.QUATERNION"); + } + + this.adaptee.identity(); + + let _rawData = this.adaptee._rawData; + + var scale = []; + scale[0] = scale[1] = scale[2] = awayComponets[2].x; + scale[4] = scale[5] = scale[6] = awayComponets[2].y; + scale[8] = scale[9] = scale[10] = awayComponets[2].z; + + switch (orientationStyle) { + case Orientation3D.EULER_ANGLES: + var cx = Math.cos(awayComponets[1].x); + var cy = Math.cos(awayComponets[1].y); + var cz = Math.cos(awayComponets[1].z); + var sx = Math.sin(awayComponets[1].x); + var sy = Math.sin(awayComponets[1].y); + var sz = Math.sin(awayComponets[1].z); + + _rawData[0] = cy * cz * scale[0]; + _rawData[1] = cy * sz * scale[1]; + _rawData[2] = -sy * scale[2]; + _rawData[3] = 0; + _rawData[4] = (sx * sy * cz - cx * sz) * scale[4]; + _rawData[5] = (sx * sy * sz + cx * cz) * scale[5]; + _rawData[6] = sx * cy * scale[6]; + _rawData[7] = 0; + _rawData[8] = (cx * sy * cz + sx * sz) * scale[8]; + _rawData[9] = (cx * sy * sz - sx * cz) * scale[9]; + _rawData[10] = cx * cy * scale[10]; + _rawData[11] = 0; + _rawData[12] = awayComponets[0].x; + _rawData[13] = awayComponets[0].y; + _rawData[14] = awayComponets[0].z; + _rawData[15] = 1; + break; + + default: + var x = awayComponets[1].x; + var y = awayComponets[1].y; + var z = awayComponets[1].z; + var w = awayComponets[1].w; + + if (orientationStyle == Orientation3D.AXIS_ANGLE) { + x *= Math.sin(w / 2); + y *= Math.sin(w / 2); + z *= Math.sin(w / 2); + w = Math.cos(w / 2); + } + + _rawData[0] = (1 - 2 * y * y - 2 * z * z) * scale[0]; + _rawData[1] = (2 * x * y + 2 * w * z) * scale[1]; + _rawData[2] = (2 * x * z - 2 * w * y) * scale[2]; + _rawData[3] = 0; + _rawData[4] = (2 * x * y - 2 * w * z) * scale[4]; + _rawData[5] = (1 - 2 * x * x - 2 * z * z) * scale[5]; + _rawData[6] = (2 * y * z + 2 * w * x) * scale[6]; + _rawData[7] = 0; + _rawData[8] = (2 * x * z + 2 * w * y) * scale[8]; + _rawData[9] = (2 * y * z - 2 * w * x) * scale[9]; + _rawData[10] = (1 - 2 * x * x - 2 * y * y) * scale[10]; + _rawData[11] = 0; + _rawData[12] = awayComponets[0].x; + _rawData[13] = awayComponets[0].y; + _rawData[14] = awayComponets[0].z; + _rawData[15] = 1; + } + + if (awayComponets[2].x == 0) { + _rawData[0] = 1e-15; + } + + if (awayComponets[2].y == 0) { + _rawData[5] = 1e-15; + } + + if (awayComponets[2].z == 0) { + _rawData[10] = 1e-15; + } + + return !(awayComponets[2].x == 0 || awayComponets[2].y == 0 || awayComponets[2].y == 0); } public appendTranslation(x: number, y: number, z: number): void { @@ -142,7 +239,7 @@ export class Matrix3D extends ASObject { } public transformVector(v: Vector3D): Vector3D { - return new ( this.sec).flash.geom.Vector3D(this._adaptee.transformVector(v.adaptee, null, true)); + return new ( this.sec).flash.geom.Vector3D(this._adaptee.transformVector(v.adaptee)); } public deltaTransformVector(v: Vector3D): Vector3D { @@ -225,4 +322,4 @@ export class Matrix3D extends ASObject { public copyColumnFrom(column: number /*uint*/, vector3D: Vector3D): void { this._adaptee.copyColumnFrom(column >>> 0, vector3D.adaptee); } -} \ No newline at end of file +} diff --git a/lib/geom/Utils3D.ts b/lib/geom/Utils3D.ts index 198a48ec..6fa566ed 100644 --- a/lib/geom/Utils3D.ts +++ b/lib/geom/Utils3D.ts @@ -21,16 +21,16 @@ export class Utils3D extends ASObject { // AS -> JS Bindings static projectVector(m: Matrix3D, v: Vector3D): Vector3D { Matrix3D; - release || notImplemented('public flash.geom.Utils3D::static projectVector'); return; + notImplemented('public flash.geom.Utils3D::static projectVector'); return; } static projectVectors(m: Matrix3D, verts: Float64Vector, projectedVerts: Float64Vector, uvts: Float64Vector): void { - release || notImplemented('public flash.geom.Utils3D::static projectVectors'); return; + notImplemented('public flash.geom.Utils3D::static projectVectors'); return; } static pointTowards(percent: number, mat: Matrix3D, pos: Vector3D, at: Vector3D = null, up: Vector3D = null): Matrix3D { percent = +percent; - release || notImplemented('public flash.geom.Utils3D::static pointTowards'); return; + notImplemented('public flash.geom.Utils3D::static pointTowards'); return; } } \ No newline at end of file diff --git a/lib/link.ts b/lib/link.ts index d4ffa7fc..e7bc8d7d 100644 --- a/lib/link.ts +++ b/lib/link.ts @@ -26,6 +26,26 @@ import { SimpleButton } from './display/SimpleButton'; import { Sprite } from './display/Sprite'; import { Stage } from './display/Stage'; +import { Stage3D } from './display/Stage3D'; +import { Context3D } from './display3D/Context3D'; +import { Context3DBlendFactor } from './display3D/Context3DBlendFactor'; +import { Context3DClearMask } from './display3D/Context3DClearMask'; +import { Context3DCompareMode } from './display3D/Context3DCompareMode'; +import { Context3DProfile } from './display3D/Context3DProfile'; +import { Context3DProgramType } from './display3D/Context3DProgramType'; +import { Context3DRenderMode } from './display3D/Context3DRenderMode'; +import { Context3DStencilAction } from './display3D/Context3DStencilAction'; +import { Context3DTextureFormat } from './display3D/Context3DTextureFormat'; +import { Context3DTriangleFace } from './display3D/Context3DTriangleFace'; +import { Context3DVertexBufferFormat } from './display3D/Context3DVertexBufferFormat'; +import { IndexBuffer3D } from './display3D/IndexBuffer3D'; +import { Program3D } from './display3D/Program3D'; +import { VertexBuffer3D } from './display3D/VertexBuffer3D'; +import { CubeTexture } from './display3D/textures/CubeTexture'; +import { RectangleTexture } from './display3D/textures/RectangleTexture'; +import { Texture } from './display3D/textures/Texture'; +import { TextureBase } from './display3D/textures/TextureBase'; + import { EOFError } from './errors/EOFError'; import { IllegalOperationError } from './errors/IllegalOperationError'; import { InvalidSWFError } from './errors/InvalidSWFError'; @@ -286,7 +306,8 @@ export function initLink() { //M('flash.display.SpreadMethod', SpreadMethod); M('flash.display.Sprite', Sprite); M('flash.display.Stage', Stage); - //M('flash.display.Stage3D', Stage3D); + M('flash.display.Stage3D', Stage3D); + //M('flash.display.StageAlign', StageAlign); //M('flash.display.StageAspectRatio', StageAspectRatio);//AIR //M('flash.display.StageDisplayState', StageDisplayState); @@ -294,8 +315,25 @@ export function initLink() { //M('flash.display.StageScaleMode', StageScaleMode); //M('flash.display.TriangleCulling', TriangleCulling); - // flash.display3D - // flash.display3D.textures + M('flash.display3D.Context3D', Context3D); + M('flash.display3D.Context3DBlendFactor', Context3DBlendFactor); + M('flash.display3D.Context3DClearMask', Context3DClearMask); + M('flash.display3D.Context3DCompareMode', Context3DCompareMode); + M('flash.display3D.Context3DProfile', Context3DProfile); + M('flash.display3D.Context3DProgramType', Context3DProgramType); + M('flash.display3D.Context3DRenderMode', Context3DRenderMode); + M('flash.display3D.Context3DStencilAction', Context3DStencilAction); + M('flash.display3D.Context3DTextureFormat', Context3DTextureFormat); + M('flash.display3D.Context3DTriangleFace', Context3DTriangleFace); + M('flash.display3D.Context3DVertexBufferFormat', Context3DVertexBufferFormat); + M('flash.display3D.IndexBuffer3D', IndexBuffer3D); + M('flash.display3D.Program3D', Program3D); + M('flash.display3D.VertexBuffer3D', VertexBuffer3D); + + M('flash.display3D.textures.TextureBase', TextureBase); + M('flash.display3D.textures.Texture', Texture); + M('flash.display3D.textures.RectangleTexture', RectangleTexture); + M('flash.display3D.textures.CubeTexture', CubeTexture); //M('flash.errors.DRMManagerError', DRMManagerError);//AIR M('flash.errors.EOFError', EOFError); diff --git a/lib/media/SoundChannel.ts b/lib/media/SoundChannel.ts index 8060849c..5cc5d17e 100644 --- a/lib/media/SoundChannel.ts +++ b/lib/media/SoundChannel.ts @@ -5,7 +5,7 @@ import { SecurityDomain } from '../SecurityDomain'; import { Event } from '../events/Event'; import { EventBase, IAudioChannel } from '@awayjs/core'; import { ISoundSource, SoundMixer } from './SoundMixer'; -import { BaseAudioChannel } from '@awayjs/core/dist/lib/managers/BaseAudioChannel'; +import { BaseAudioChannel } from '@awayjs/core'; /** * Dispatched when a sound has finished playing. diff --git a/lib/system/Capabilities.ts b/lib/system/Capabilities.ts index 7b251fd1..098a21c1 100644 --- a/lib/system/Capabilities.ts +++ b/lib/system/Capabilities.ts @@ -54,7 +54,7 @@ export class Capabilities extends ASObject { private static _os: string = null; // static _cpuArchitecture: string; private static _playerType: string = null;// DEFAULT_CAPABILITIES.PLAYER_TYPE; - private static _version: string = 'SHUMWAY 10,0,0,0'; + private static _version: string = 'WIN 32,0,0,465'; // static _screenColor: string; // static _pixelAspectRatio: number; private static _screenDPI: number = 0;// = DEFAULT_CAPABILITIES.SCREEN_DPI;