From d08989b9b1362555f6333e2ed691e7920711513a Mon Sep 17 00:00:00 2001 From: Yaski Date: Tue, 31 Jul 2012 21:53:03 +0600 Subject: [PATCH] Get context properties in Camera3D --- src/alternativa/engine3d/core/Camera3D.as | 30 +++++++++++++++-- src/alternativa/engine3d/core/Renderer.as | 32 ++++++------------- .../core/RendererContext3DProperties.as | 2 ++ .../engine3d/materials/EnvironmentMaterial.as | 2 +- .../engine3d/materials/StandardMaterial.as | 2 +- .../materials/VertexLightTextureMaterial.as | 2 +- src/alternativa/engine3d/objects/LOD.as | 1 + 7 files changed, 42 insertions(+), 29 deletions(-) diff --git a/src/alternativa/engine3d/core/Camera3D.as b/src/alternativa/engine3d/core/Camera3D.as index 9f0a18e..50de4ca 100644 --- a/src/alternativa/engine3d/core/Camera3D.as +++ b/src/alternativa/engine3d/core/Camera3D.as @@ -46,6 +46,12 @@ package alternativa.engine3d.core { */ public class Camera3D extends Object3D { + /** + * @private + * Key - context, value - properties. + */ + alternativa3d static var context3DPropertiesPool:Dictionary = new Dictionary(true); + /** * The viewport defines part of screen to which renders image seen by the camera. * If viewport is not defined, the camera would not draws anything. @@ -156,6 +162,11 @@ public class Camera3D extends Object3D { */ alternativa3d var context3D:Context3D; + /** + * @private + */ + alternativa3d var context3DProperties:RendererContext3DProperties; + /** * @private * Camera's renderer. If is not defined, the camera will no draw anything. @@ -195,7 +206,6 @@ public class Camera3D extends Object3D { * @param stage3D Stage3D to which image will be rendered. */ public function render(stage3D:Stage3D):void { - // TODO: don't check mouse events if no listeners var i:int; var j:int; var light:Light3D; @@ -214,11 +224,26 @@ public class Camera3D extends Object3D { ambient[2] = 0; ambient[3] = 1; // Receiving the context - context3D = stage3D.context3D; + var currentContext3D:Context3D = stage3D.context3D; + if (currentContext3D != context3D) { + if (currentContext3D != null) { + context3DProperties = context3DPropertiesPool[currentContext3D]; + if (context3DProperties == null) { + context3DProperties = new RendererContext3DProperties(); + context3DProperties.isConstrained = currentContext3D.driverInfo.lastIndexOf("(Baseline Constrained)") >= 0; + context3DPropertiesPool[currentContext3D] = context3DProperties; + } + context3D = currentContext3D; + } else { + context3D = null; + context3DProperties = null; + } + } if (context3D != null && view != null && renderer != null && (view.stage != null || view._canvas != null)) { renderer.camera = this; // Projection argument calculating calculateProjection(view._width, view._height); + // TODO: clear after shadows rendering // Preparing to rendering view.prepareToRender(stage3D, context3D); // Transformations calculating @@ -403,7 +428,6 @@ public class Camera3D extends Object3D { lights.length = 0; childLights.length = 0; occluders.length = 0; - context3D = null; } /** diff --git a/src/alternativa/engine3d/core/Renderer.as b/src/alternativa/engine3d/core/Renderer.as index 211bad2..77fae35 100644 --- a/src/alternativa/engine3d/core/Renderer.as +++ b/src/alternativa/engine3d/core/Renderer.as @@ -16,7 +16,6 @@ package alternativa.engine3d.core { import flash.display3D.Context3DProgramType; import flash.display3D.IndexBuffer3D; import flash.display3D.Program3D; - import flash.utils.Dictionary; use namespace alternativa3d; @@ -37,9 +36,6 @@ package alternativa.engine3d.core { public static const NEXT_LAYER:int = 50; - // Key - context, value - properties. - protected static var properties:Dictionary = new Dictionary(true); - // Collector protected var collector:DrawUnit; @@ -47,9 +43,6 @@ package alternativa.engine3d.core { alternativa3d var drawUnits:Vector. = new Vector.(); - alternativa3d var isConstrainedMode:Boolean = false; - - protected var _context3D:Context3D; protected var _contextProperties:RendererContext3DProperties; alternativa3d function render(context3D:Context3D):void { @@ -61,29 +54,29 @@ package alternativa.engine3d.core { if (list != null) { switch (i) { case SKY: - _context3D.setDepthTest(false, Context3DCompareMode.ALWAYS); + context3D.setDepthTest(false, Context3DCompareMode.ALWAYS); break; case OPAQUE: - _context3D.setDepthTest(true, Context3DCompareMode.LESS); + context3D.setDepthTest(true, Context3DCompareMode.LESS); break; case OPAQUE_OVERHEAD: - _context3D.setDepthTest(false, Context3DCompareMode.EQUAL); + context3D.setDepthTest(false, Context3DCompareMode.EQUAL); break; case DECALS: - _context3D.setDepthTest(false, Context3DCompareMode.LESS_EQUAL); + context3D.setDepthTest(false, Context3DCompareMode.LESS_EQUAL); break; case TRANSPARENT_SORT: if (list.next != null) list = sortByAverageZ(list); - _context3D.setDepthTest(false, Context3DCompareMode.LESS); + context3D.setDepthTest(false, Context3DCompareMode.LESS); break; case NEXT_LAYER: - _context3D.setDepthTest(false, Context3DCompareMode.ALWAYS); + context3D.setDepthTest(false, Context3DCompareMode.ALWAYS); break; } // Rendering while (list != null) { var next:DrawUnit = list.next; - renderDrawUnit(list, _context3D, camera); + renderDrawUnit(list, context3D, camera); // Send to collector list.clear(); list.next = collector; @@ -92,6 +85,7 @@ package alternativa.engine3d.core { } } } + // TODO: not free buffers and textures in each renderer, only when full camera cycle finishes. freeContext3DProperties(context3D); // Clear drawUnits.length = 0; @@ -182,15 +176,7 @@ package alternativa.engine3d.core { } protected function updateContext3D(value:Context3D):void { - if (_context3D != value) { - _contextProperties = properties[value]; - if (_contextProperties == null) { - _contextProperties = new RendererContext3DProperties(); - properties[value] = _contextProperties; - } - _context3D = value; - isConstrainedMode = _context3D.driverInfo.lastIndexOf("(Baseline Constrained)") >= 0; - } + _contextProperties = camera.context3DProperties; } /** diff --git a/src/alternativa/engine3d/core/RendererContext3DProperties.as b/src/alternativa/engine3d/core/RendererContext3DProperties.as index a92aad0..4c2fabe 100644 --- a/src/alternativa/engine3d/core/RendererContext3DProperties.as +++ b/src/alternativa/engine3d/core/RendererContext3DProperties.as @@ -16,6 +16,8 @@ package alternativa.engine3d.core { */ public class RendererContext3DProperties { + public var isConstrained:Boolean = false; + public var usedBuffers:uint = 0; public var usedTextures:uint = 0; diff --git a/src/alternativa/engine3d/materials/EnvironmentMaterial.as b/src/alternativa/engine3d/materials/EnvironmentMaterial.as index 276044d..24dcb83 100644 --- a/src/alternativa/engine3d/materials/EnvironmentMaterial.as +++ b/src/alternativa/engine3d/materials/EnvironmentMaterial.as @@ -825,7 +825,7 @@ package alternativa.engine3d.materials { if (_reflectionMap != null && _reflectionMap._texture == null) return; if (_lightMap != null && _lightMap._texture == null) return; - if (camera.renderer.isConstrainedMode) { + if (camera.context3DProperties.isConstrained) { // fallback to simpler material if (lightMap == null) { fallbackTextureMaterial.diffuseMap = diffuseMap; diff --git a/src/alternativa/engine3d/materials/StandardMaterial.as b/src/alternativa/engine3d/materials/StandardMaterial.as index 3cb1022..f451c23 100644 --- a/src/alternativa/engine3d/materials/StandardMaterial.as +++ b/src/alternativa/engine3d/materials/StandardMaterial.as @@ -995,7 +995,7 @@ package alternativa.engine3d.materials { // Check if textures uploaded in to the context. if (opacityMap != null && opacityMap._texture == null || glossinessMap != null && glossinessMap._texture == null || specularMap != null && specularMap._texture == null || lightMap != null && lightMap._texture == null) return; - if (camera.renderer.isConstrainedMode) { + if (camera.context3DProperties.isConstrained) { // fallback to simpler material if (lightMap == null) { fallbackTextureMaterial.diffuseMap = diffuseMap; diff --git a/src/alternativa/engine3d/materials/VertexLightTextureMaterial.as b/src/alternativa/engine3d/materials/VertexLightTextureMaterial.as index 57efd3f..ceb0664 100644 --- a/src/alternativa/engine3d/materials/VertexLightTextureMaterial.as +++ b/src/alternativa/engine3d/materials/VertexLightTextureMaterial.as @@ -287,7 +287,7 @@ package alternativa.engine3d.materials { override alternativa3d function collectDraws(camera:Camera3D, surface:Surface, geometry:Geometry, lights:Vector., lightsLength:int, useShadow:Boolean, objectRenderPriority:int = -1):void { if (diffuseMap == null || diffuseMap._texture == null || opacityMap != null && opacityMap._texture == null) return; - if (camera.renderer.isConstrainedMode) { + if (camera.context3DProperties.isConstrained) { // fallback to texture material fallbackMaterial.diffuseMap = diffuseMap; fallbackMaterial.opacityMap = opacityMap; diff --git a/src/alternativa/engine3d/objects/LOD.as b/src/alternativa/engine3d/objects/LOD.as index 487da9c..04d38a0 100644 --- a/src/alternativa/engine3d/objects/LOD.as +++ b/src/alternativa/engine3d/objects/LOD.as @@ -176,6 +176,7 @@ package alternativa.engine3d.objects { * @private */ override alternativa3d function calculateVisibility(camera:Camera3D):void { + // TODO: optimize - use square of distance var distance:Number = Math.sqrt(localToCameraTransform.d*localToCameraTransform.d + localToCameraTransform.h*localToCameraTransform.h + localToCameraTransform.l*localToCameraTransform.l); for (level = levelList; level != null; level = level.next) { if (distance <= level.distance) {