[转] MoleHill操作AGAL的Helper类之一


本帖最后由 sleep2death 于 2011-4-20 16:49 编辑


应7yue大大的要求,贴写小东西.
package shader {
        import flash.display3D.*;
        import flash.display3D.textures.*;
        import flash.geom.Matrix3D;

        import com.adobe.utils.*;

        public class AGALHelper {
                public  static var context : Context3D;
                public static var program : Program3D;

                public static var vaNames    : Vector.<String> = new Vector.<String>(8); // MAX 8
                public static var fsNames    : Vector.<String> = new Vector.<String>(8); // MAX 8

                public static var vcNames    : Vector.<String> = new Vector.<String>(128); // MAX 128
                public static var fcNames    : Vector.<String> = new Vector.<String>(28); // MAX 28

                public static var vtNames    : Vector.<String> = new Vector.<String>(8); // MAX 8
                public static var ftNames    : Vector.<String> = new Vector.<String>(8); // MAX 8

                public static var vNames    : Vector.<String> = new Vector.<String>(8); // MAX 8

                public static const FLOAT  : uint = 0;
                public static const FLOAT2 : uint = 1;
                public static const FLOAT3 : uint = 2;
                public static const FLOAT4 : uint = 3;

                public static const VERTEX  : uint = 0;
                public static const FRAMENT : uint = 1;

                public static function getAttributeIndex(name : String) : int {
                        var insertIndex : int = vaNames.indexOf(name);

                        if(insertIndex < 0) {
                                insertIndex = vaNames.indexOf(null);
                                vaNames[insertIndex] = name;

                                trace("assign " + name + " to va" + insertIndex);
                        }

                        return insertIndex;

                }

                public static function setAttribute(name : String, buffer : VertexBuffer3D, offset : uint = 0, format : String = "float4") : void {
                        context.setVertexBufferAt(getAttributeIndex(name), buffer, offset, format);
                }

                public static function getVertexConstantIndex(name : String) : int {
                        var insertIndex : int = vcNames.indexOf(name);

                        if(insertIndex < 0) {
                                insertIndex = vcNames.indexOf(null);
                                vcNames[insertIndex] = name;

                                trace("assign " + name + " to vc" + insertIndex);
                        }

                        return insertIndex;
                }

                public static function setVertexConstant(name : String, value : *) : void {
                        if(value is Vector.<Number>){
                                context.setProgramConstantsFromVector(Context3DProgramType.VERTEX, getVertexConstantIndex(name), value);
                        }else if(value is Matrix3D){
                                context.setProgramConstantsFromMatrix(Context3DProgramType.VERTEX, getVertexConstantIndex(name), value, true);
                        }
                }

                public static function getFragmentConstantIndex(name : String) : int {
                        var insertIndex : int = fcNames.indexOf(name);

                        if(insertIndex < 0) {
                                insertIndex = fcNames.indexOf(null);
                                fcNames[insertIndex] = name;

                                trace("assign " + name + " to fc" + insertIndex);
                        }

                        return insertIndex;

                }

                public static function setFragmentConstant(name : String, value : *) : void {
                        if(value is Vector.<Number>){
                                context.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, getVertexConstantIndex(name), value);
                        }else if(value is Matrix3D){
                                context.setProgramConstantsFromMatrix(Context3DProgramType.FRAGMENT, getVertexConstantIndex(name), value, true);
                        }
                }

                public static function getSampleIndex(name : String) : int {
                        var insertIndex : int = fsNames.indexOf(name);

                        if(insertIndex < 0) {
                                insertIndex = fsNames.indexOf(null);
                                fsNames[insertIndex] = name;

                                trace("assign " + name + " to fs" + insertIndex);
                        }

                        return insertIndex;
                }

                public static function setSample(name : String, value : Texture) : void {
                        context.setTextureAt(getSampleIndex(name), value);
                }

                public static function getIndexByName(vf : String, type : String, name : String) : uint {
                        
                        var first : String = type == "v" ? "v" : vf + type;        
                        var names : Vector.<String> = AGALHelper[first + "Names"];

                        var insertIndex : int = names.indexOf(type + "_" + name);

                        if(insertIndex < 0) {
                                insertIndex = names.indexOf(null);
                                names[insertIndex] = type + "_" + name;

                                trace("assign " + type + "_" + name + " to " + first  + insertIndex);
                        }

                        return insertIndex;
                }

                public static var v_code : String = new String();

                public static function addVertexCode(op_code : String, out : String, in1 : String ,in2 : String = null, extra : String = null) : void {
                        if(op_code == "len"){
                                ExtraCode_len(out, in1);
                        }else{
                                v_code += op_code + " " + parseParam(out, "v")  + ", " + parseParam(in1, "v");
                                if(in2 != null) v_code += " " + parseParam(in2, "v");
                                if(extra != null) v_code +=" " + extra;
                                
                                v_code += " \n";
                        }
                }

                public static var f_code : String = new String();

                public static function addFragmentCode(op_code : String, out : String, in1 : String ,in2 : String = null, extra : String = null) : void {
                        f_code += op_code + " " + parseParam(out, "f")  + ", " + parseParam(in1, "f");
                        if(in2 != null) f_code += " " + parseParam(in2, "f");
                        if(extra != null) f_code +=" " + extra;
                        
                        f_code += " \n";
                }

                private static var v_assembler : AGALMiniAssembler = new AGALMiniAssembler();
                private static var f_assembler : AGALMiniAssembler = new AGALMiniAssembler();

                public static function uploadCode() : void {
                        v_assembler.assemble(Context3DProgramType.VERTEX, v_code);
                        f_assembler.assemble( Context3DProgramType.FRAGMENT, f_code);

                        if(!program){
                                program = context.createProgram();
                                context.setProgram(program);
                        }

                        program.upload(v_assembler.agalcode, f_assembler.agalcode);
                }

                public static function printCode() : void {
                        trace("========  VERTEX     ========");
                        trace(v_code);
                        trace("========  FRAGMENT   ========");
                        trace(f_code);
                }

                private static function parseParam( code : String, vf : String ) : String {
                        var prop : Array = code.split(".");
                        var prop_str : String;

                        if(prop.length > 1) {
                                code = prop[0];
                                prop_str = "."+prop[1];
                        }else{
                                prop_str = "";
                        }

                        var codes : Array = code.split("_");

                        if(codes.length > 1)
                                return (codes[0] == "v" ?"" : vf) + codes[0] + getIndexByName(vf, codes[0], codes[1]) + prop_str;

                        return code + prop_str;
                }

                private static function ExtraCode_len(out : String, in1 : String) : void {
                        addVertexCode("dp3", out, in1, in1);
                        addVertexCode("sqr", out, out);
                }
        }
}


如何使用呢?

先用helper设置一些属性:
AGALHelper.setVertexConstant("c_a1", Vector.<Number>([1.025]));
AGALHelper.setAttribute("a_vb", vertexBuffer));
然后写汇编
                        AGALHelper.addVertexCode("mov", "t_vb", "a_vb");
                        AGALHelper.addVertexCode("mov", "t_uvb", "a_uvb");
                        AGALHelper.addVertexCode("mov", "t_nb", "a_nb");

                        AGALHelper.addVertexCode("sub", "t_v3Ray", "t_vb", "c_v3CameraPos.xyz");
                        AGALHelper.addVertexCode("len", "t_fFar.xyz", "t_v3Ray");

                       
                        AGALHelper.addVertexCode("m44", "op", "t_vb", "c_proj");

                        AGALHelper.addVertexCode("mov", "v_uvb", "t_uvb");
                        AGALHelper.addVertexCode("mov", "v_nb", "t_nb");

                        AGALHelper.addFragmentCode("mov", "t_uvb", "v_uvb");
                        AGALHelper.addFragmentCode("tex", "t_day", "t_uvb", "s_day", "<2d, clamp, linear>");
                        AGALHelper.addFragmentCode("mov", "oc", "t_day");

                        AGALHelper.printCode();
                        AGALHelper.uploadCode();

好处是你再也不要去记ft0, fc1到底是啥了...另外可以新增一些方法,比如length等等

你可能感兴趣的:(c,F#,Flash,vb,vc++)