From efca42c57bae91b1a69e68eeeac28b2a6966a286 Mon Sep 17 00:00:00 2001 From: Leonid Gaev Date: Wed, 13 Jun 2012 14:24:38 +0600 Subject: [PATCH] materialKey -> int --- .../engine3d/materials/StandardMaterial.as | 100 +++++++++++++----- 1 file changed, 72 insertions(+), 28 deletions(-) diff --git a/src/alternativa/engine3d/materials/StandardMaterial.as b/src/alternativa/engine3d/materials/StandardMaterial.as index c1018cc..9cf3dcc 100644 --- a/src/alternativa/engine3d/materials/StandardMaterial.as +++ b/src/alternativa/engine3d/materials/StandardMaterial.as @@ -51,9 +51,21 @@ package alternativa.engine3d.materials { */ public class StandardMaterial extends TextureMaterial { + private static const LIGHT_MAP:int = 1; + private static const GLOSSINESS_MAP:int = 2; + private static const SPECULAR_MAP:int = 4; + private static const OPACITY_MAP:int = 8; + private static const NORMAL_MAP_SPACE_BIT:int = 4; + private static const ALPHA_TEST_BIT:int = 6; + private static const OMNI_LIGHT_BIT:int = 8; + private static const DIRECTIONAL_LIGHT_BIT:int = 11; + private static const SPOT_LIGHT_BIT:int = 14; + private static const OBJECT_TYPE_BIT:int = 17; + + private static var caches:Dictionary = new Dictionary(true); private var cachedContext3D:Context3D; - private var programsCache:Vector.; + private var programsCache:Array; private var groups:Vector.> = new Vector.>(); /** @@ -515,16 +527,17 @@ package alternativa.engine3d.materials { * @param directionalLight * @param lightsLength */ - private function getProgram(object:Object3D, programs:Vector., camera:Camera3D, materialKey:String, opacityMap:TextureResource, alphaTest:int, lightsGroup:Vector., lightsLength:int, isFirstGroup:Boolean, shadowedLight:Light3D):StandardMaterialProgram { - var key:String = materialKey + (opacityMap != null ? "O" : "o") + alphaTest.toString(); - var program:StandardMaterialProgram = null;//programs[key]; - - for (var i:int = 0; i, lightsLength:int, isFirstGroup:Boolean, shadowedLight:Light3D):StandardMaterialProgram { + var key:int = materialKey + (opacityMap != null ? OPACITY_MAP : 0) + alphaTest << ALPHA_TEST_BIT; + var program:StandardMaterialProgram = programs[key]; +// var programsCount:int = programs.length; +// for (var i:int = 0; i(); + programsCache = new Array(); caches[cachedContext3D] = programsCache; } } @@ -1034,15 +1047,18 @@ package alternativa.engine3d.materials { } // Iterate groups - var materialKey:String; + var materialKey:int; var program:StandardMaterialProgram; + var OmniLightCount:int = 0; + var DirectionalLightCount:int = 0; + var SpotLightCount:int = 0; if (groupsCount == 0 && shadowGroupLength == 0) { // There is only Ambient light on the scene // Form key - materialKey = (lightMap != null) ? "L" : "l"+ - ((glossinessMap != null) ? "G" : "g") + - ((specularMap != null) ? "S" : "s"); + materialKey = (lightMap != null) ? LIGHT_MAP : 0 + + (glossinessMap != null) ? GLOSSINESS_MAP : 0 + + (specularMap != null) ? SPECULAR_MAP : 0; if (opaquePass && alphaThreshold <= alpha) { if (alphaThreshold > 0) { @@ -1078,15 +1094,21 @@ package alternativa.engine3d.materials { // Group of lights without shadow // Form key - materialKey = (isFirstGroup)?((lightMap != null) ? "L" : "l"):""; + materialKey = (isFirstGroup)?((lightMap != null) ? LIGHT_MAP : 0) : 0; materialKey += - (_normalMapSpace.toString()) + - ((glossinessMap != null) ? "G" : "g") + - ((specularMap != null) ? "S" : "s"); + ((_normalMapSpace==NormalMapSpace.OBJECT) ? 1 : (_normalMapSpace==NormalMapSpace.TANGENT_LEFT_HANDED) ? 2 : 3) << NORMAL_MAP_SPACE_BIT + + (glossinessMap != null) ? GLOSSINESS_MAP : 0 + + (specularMap != null) ? SPECULAR_MAP : 0; for (j = 0; j < lightGroupLength; j++) { light = lightGroup[j]; - materialKey += light.lightID; + if (light is OmniLight) OmniLightCount++; + else if (light is DirectionalLight) DirectionalLightCount++; + else if (light is SpotLight) SpotLightCount++; } + materialKey += OmniLightCount << OMNI_LIGHT_BIT; + materialKey += DirectionalLightCount << DIRECTIONAL_LIGHT_BIT; + materialKey += SpotLightCount << SPOT_LIGHT_BIT; + // Create program and drawUnit for group // Opaque pass @@ -1126,13 +1148,35 @@ package alternativa.engine3d.materials { light = shadowGroup[j]; // Form key - materialKey = (isFirstGroup)?((lightMap != null) ? "L" : "l"):""; + materialKey = (isFirstGroup)?((lightMap != null) ? LIGHT_MAP : 0) : 0; materialKey += - (_normalMapSpace.toString()) + - ((glossinessMap != null) ? "G" : "g") + - ((specularMap != null) ? "S" : "s"); - materialKey += light.shadow.type; - materialKey += light.lightID; + ((_normalMapSpace==NormalMapSpace.OBJECT) ? 1 : (_normalMapSpace==NormalMapSpace.TANGENT_LEFT_HANDED) ? 2 : 3) << NORMAL_MAP_SPACE_BIT + + (glossinessMap != null) ? GLOSSINESS_MAP : 0 + + (specularMap != null) ? SPECULAR_MAP : 0; + + // TODO: rewrite + switch (light.shadow.type){ + case "OS": + materialKey += 7 << OMNI_LIGHT_BIT; + break; + case "os": + materialKey += 6 << OMNI_LIGHT_BIT; + break; + case "DS": + materialKey += 7 << DIRECTIONAL_LIGHT_BIT; + break; + case "ds": + materialKey += 6 << DIRECTIONAL_LIGHT_BIT; + break; + } + +// if (light is OmniLight) OmniLightCount++; +// else if (light is DirectionalLight) DirectionalLightCount++; +// else if (light is SpotLight) SpotLightCount++; +// +// materialKey += light.shadow.type; +// materialKey += light.lightID; + // Для группы создаем программу и дроуюнит // Opaque pass