diff --git a/src/alternativa/engine3d/materials/StandardMaterial.as b/src/alternativa/engine3d/materials/StandardMaterial.as index 87ab20a..59fd23e 100644 --- a/src/alternativa/engine3d/materials/StandardMaterial.as +++ b/src/alternativa/engine3d/materials/StandardMaterial.as @@ -515,9 +515,9 @@ package alternativa.engine3d.materials { * @param directionalLight * @param lightsLength */ - private function getProgram(object:Object3D, programs:Dictionary, camera:Camera3D, materialKey:String, opacityMap:TextureResource, alphaTest:int, lightsGroup:Vector., lightsLength:int, isFirstGroup:Boolean, shadowedLight:Light3D):ShaderProgram { + private function getProgram(object:Object3D, programs:Dictionary, 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:ShaderProgram = programs[key]; + var program:StandardMaterialProgram = programs[key]; if (program == null) { var vertexLinker:Linker = new Linker(Context3DProgramType.VERTEX); var fragmentLinker:Linker = new Linker(Context3DProgramType.FRAGMENT); @@ -737,7 +737,7 @@ package alternativa.engine3d.materials { // } fragmentLinker.varyings = vertexLinker.varyings; - program = new ShaderProgram(vertexLinker, fragmentLinker); + program = new StandardMaterialProgram(vertexLinker, fragmentLinker); program.upload(camera.context3D); programs[key] = program; @@ -746,7 +746,7 @@ package alternativa.engine3d.materials { } // TODO: return not neccessary more - private function getDrawUnit(program:ShaderProgram, camera:Camera3D, surface:Surface, geometry:Geometry, opacityMap:TextureResource, lights:Vector., lightsLength:int, isFirstGroup:Boolean, shadowedLight:Light3D, opaqueOption:Boolean, transparentOption:Boolean, objectRenderPriority:int):DrawUnit { + private function getDrawUnit(program:StandardMaterialProgram, camera:Camera3D, surface:Surface, geometry:Geometry, opacityMap:TextureResource, lights:Vector., lightsLength:int, isFirstGroup:Boolean, shadowedLight:Light3D, opaqueOption:Boolean, transparentOption:Boolean, objectRenderPriority:int):DrawUnit { // Buffers var positionBuffer:VertexBuffer3D = geometry.getVertexBuffer(VertexAttributes.POSITION); var uvBuffer:VertexBuffer3D = geometry.getVertexBuffer(VertexAttributes.TEXCOORDS[0]); @@ -759,15 +759,15 @@ package alternativa.engine3d.materials { var drawUnit:DrawUnit = camera.renderer.createDrawUnit(object, program.program, geometry._indexBuffer, surface.indexBegin, surface.numTriangles, program); // Streams - drawUnit.setVertexBufferAt(program.vertexShader.getVariableIndex("aPosition"), positionBuffer, geometry._attributesOffsets[VertexAttributes.POSITION], VertexAttributes.FORMATS[VertexAttributes.POSITION]); - drawUnit.setVertexBufferAt(program.vertexShader.getVariableIndex("aUV"), uvBuffer, geometry._attributesOffsets[VertexAttributes.TEXCOORDS[0]], VertexAttributes.FORMATS[VertexAttributes.TEXCOORDS[0]]); + drawUnit.setVertexBufferAt(program.aPosition, positionBuffer, geometry._attributesOffsets[VertexAttributes.POSITION], VertexAttributes.FORMATS[VertexAttributes.POSITION]); + drawUnit.setVertexBufferAt(program.aUV, uvBuffer, geometry._attributesOffsets[VertexAttributes.TEXCOORDS[0]], VertexAttributes.FORMATS[VertexAttributes.TEXCOORDS[0]]); // Constants object.setTransformConstants(drawUnit, surface, program.vertexShader, camera); - drawUnit.setProjectionConstants(camera, program.vertexShader.getVariableIndex("cProjMatrix"), object.localToCameraTransform); + drawUnit.setProjectionConstants(camera, program.cProjMatrix, object.localToCameraTransform); // Set options for a surface. X should be 0. - drawUnit.setFragmentConstantsFromNumbers(program.fragmentShader.getVariableIndex("cSurface"), 0, glossiness, specularPower, 1); - drawUnit.setFragmentConstantsFromNumbers(program.fragmentShader.getVariableIndex("cThresholdAlpha"), alphaThreshold, 0, 0, alpha); + drawUnit.setFragmentConstantsFromNumbers(program.cSurface, 0, glossiness, specularPower, 1); + drawUnit.setFragmentConstantsFromNumbers(program.cThresholdAlpha, alphaThreshold, 0, 0, alpha); var light:Light3D; var len:Number; @@ -781,13 +781,13 @@ package alternativa.engine3d.materials { if (lightsLength > 0 || shadowedLight) { if (_normalMapSpace == NormalMapSpace.TANGENT_RIGHT_HANDED || _normalMapSpace == NormalMapSpace.TANGENT_LEFT_HANDED) { - drawUnit.setVertexBufferAt(program.vertexShader.getVariableIndex("aNormal"), normalsBuffer, geometry._attributesOffsets[VertexAttributes.NORMAL], VertexAttributes.FORMATS[VertexAttributes.NORMAL]); - drawUnit.setVertexBufferAt(program.vertexShader.getVariableIndex("aTangent"), tangentsBuffer, geometry._attributesOffsets[VertexAttributes.TANGENT4], VertexAttributes.FORMATS[VertexAttributes.TANGENT4]); + drawUnit.setVertexBufferAt(program.aNormal, normalsBuffer, geometry._attributesOffsets[VertexAttributes.NORMAL], VertexAttributes.FORMATS[VertexAttributes.NORMAL]); + drawUnit.setVertexBufferAt(program.aTangent, tangentsBuffer, geometry._attributesOffsets[VertexAttributes.TANGENT4], VertexAttributes.FORMATS[VertexAttributes.TANGENT4]); } - drawUnit.setTextureAt(program.fragmentShader.getVariableIndex("sBump"), normalMap._texture); + drawUnit.setTextureAt(program.sBump, normalMap._texture); var camTransform:Transform3D = object.cameraToLocalTransform; - drawUnit.setVertexConstantsFromNumbers(program.vertexShader.getVariableIndex("cCameraPosition"), camTransform.d, camTransform.h, camTransform.l); + drawUnit.setVertexConstantsFromNumbers(program.cCameraPosition, camTransform.d, camTransform.h, camTransform.l); for (var i:int = 0; i < lightsLength; i++) { light = lights[i]; @@ -861,32 +861,32 @@ package alternativa.engine3d.materials { } // Textures - drawUnit.setTextureAt(program.fragmentShader.getVariableIndex("sDiffuse"), diffuseMap._texture); + drawUnit.setTextureAt(program.sDiffuse, diffuseMap._texture); if (opacityMap != null) { - drawUnit.setTextureAt(program.fragmentShader.getVariableIndex("sOpacity"), opacityMap._texture); + drawUnit.setTextureAt(program.sOpacity, opacityMap._texture); } if (glossinessMap != null) { - drawUnit.setTextureAt(program.fragmentShader.getVariableIndex("sGlossiness"), glossinessMap._texture); + drawUnit.setTextureAt(program.sGlossiness, glossinessMap._texture); } if (specularMap != null) { - drawUnit.setTextureAt(program.fragmentShader.getVariableIndex("sSpecular"), specularMap._texture); + drawUnit.setTextureAt(program.sSpecular, specularMap._texture); } if (isFirstGroup){ if (lightMap != null) { - drawUnit.setVertexBufferAt(program.vertexShader.getVariableIndex("aUV1"), + drawUnit.setVertexBufferAt(program.aUV1, geometry.getVertexBuffer(VertexAttributes.TEXCOORDS[lightMapChannel]), geometry._attributesOffsets[VertexAttributes.TEXCOORDS[lightMapChannel]], Context3DVertexBufferFormat.FLOAT_2); - drawUnit.setFragmentConstantsFromNumbers(program.fragmentShader.getVariableIndex("cAmbientColor"), 0,0,0, 1); - drawUnit.setTextureAt(program.fragmentShader.getVariableIndex("sLightMap"), lightMap._texture); + drawUnit.setFragmentConstantsFromNumbers(program.cAmbientColor, 0,0,0, 1); + drawUnit.setTextureAt(program.sLightMap, lightMap._texture); } else { - drawUnit.setFragmentConstantsFromVector(program.fragmentShader.getVariableIndex("cAmbientColor"), camera.ambient, 1); + drawUnit.setFragmentConstantsFromVector(program.cAmbientColor, camera.ambient, 1); } } else{ - drawUnit.setFragmentConstantsFromNumbers(program.fragmentShader.getVariableIndex("cAmbientColor"), 0,0,0, 1); + drawUnit.setFragmentConstantsFromNumbers(program.cAmbientColor, 0,0,0, 1); } setPassUVProcedureConstants(drawUnit, program.vertexShader); @@ -1034,7 +1034,7 @@ package alternativa.engine3d.materials { // Iterate groups var materialKey:String; - var program:ShaderProgram; + var program:StandardMaterialProgram; var drawUnit:DrawUnit; if (groupsCount==0 && shadowGroupLength==0){ @@ -1197,3 +1197,55 @@ package alternativa.engine3d.materials { } } + +import alternativa.engine3d.materials.ShaderProgram; +import alternativa.engine3d.materials.compiler.Linker; + +import flash.display3D.Context3D; + +class StandardMaterialProgram extends ShaderProgram { + + public var aPosition:int = -1; + public var aUV:int = -1; + public var aUV1:int = -1; + public var aNormal:int = -1; + public var aTangent:int = -1; + public var cProjMatrix:int = -1; + public var cCameraPosition:int = -1; + public var cAmbientColor:int = -1; + public var cSurface:int = -1; + public var cThresholdAlpha:int = -1; + public var sDiffuse:int = -1; + public var sOpacity:int = -1; + public var sBump:int = -1; + public var sGlossiness:int = -1; + public var sSpecular:int = -1; + public var sLightMap:int = -1; + + public function StandardMaterialProgram(vertex:Linker, fragment:Linker) { + super(vertex, fragment); + } + + override public function upload(context3D:Context3D):void { + super.upload(context3D); + + aPosition = vertexShader.findVariable("aPosition"); + aUV = vertexShader.findVariable("aUV"); + aUV1 = vertexShader.findVariable("aUV1"); + aNormal = vertexShader.findVariable("aNormal"); + aTangent = vertexShader.findVariable("aTangent"); + cProjMatrix = vertexShader.findVariable("cProjMatrix"); + cCameraPosition = vertexShader.findVariable("cCameraPosition"); + + cAmbientColor = fragmentShader.findVariable("cAmbientColor"); + cSurface = fragmentShader.findVariable("cSurface"); + cThresholdAlpha = fragmentShader.findVariable("cThresholdAlpha"); + sDiffuse = fragmentShader.findVariable("sDiffuse"); + sOpacity = fragmentShader.findVariable("sOpacity"); + sBump = fragmentShader.findVariable("sBump"); + sGlossiness = fragmentShader.findVariable("sGlossiness"); + sSpecular = fragmentShader.findVariable("sSpecular"); + sLightMap = fragmentShader.findVariable("sLightMap"); + } + +}