Ejemplo n.º 1
0
        public static unsafe void PMD2MDL0(MDL0Node model)
        {
            model._version = 9;
            model._isImport = true;
            Collada._importOptions = BrawlLib.Properties.Settings.Default.ColladaImportOptions;
            Collada._importOptions._forceCCW = true;
            Collada._importOptions._fltVerts = true;
            Collada._importOptions._fltNrms = true;
            Collada._importOptions._fltUVs = true;

            model.InitGroups();

            List<MDL0BoneNode> BoneCache = new List<MDL0BoneNode>();

            int index = 0;
            if (!String.IsNullOrWhiteSpace(_header._modelNameEnglish))
                model.Name = _header._modelNameEnglish;
            else
                model.Name = _header._modelName;

            if (!String.IsNullOrWhiteSpace(_header._commentEnglish))
                MessageBox.Show(_header._commentEnglish);
            else
                MessageBox.Show(_header._comment);

            ModelBone parent = null;
            foreach (ModelBone b in _bones)
            {
                MDL0BoneNode bone = new MDL0BoneNode();

                if (!String.IsNullOrWhiteSpace(b._boneNameEnglish))
                    bone._name = b._boneNameEnglish;
                else
                    bone._name = b._boneName;

                bone._entryIndex = index++;

                if (b._parentBoneIndex != ushort.MaxValue)
                {
                    parent = _bones[b._parentBoneIndex];
                    foreach (MDL0BoneNode v in model._boneGroup._children)
                        AssignParent(v, b, bone, parent);
                }
                else
                {
                    bone.Parent = model._boneGroup;
                    bone._bindState._scale = new Vector3(1.0f);
                    bone._bindState._translate = new Vector3(b._wPos[0], b._wPos[1], b._wPos[2]);
                    bone._bindState.CalcTransforms();
                    bone.RecalcBindState();
                }

                BoneCache.Add(bone);
            }

            MDL0ShaderNode texSpa = null, tex = null, colorSpa = null, color = null;

            index = 0;
            foreach (ModelMaterial m in _materials)
            {
                MDL0MaterialNode mn = new MDL0MaterialNode();
                mn.Name = "Material" + index++;

                MDL0MaterialRefNode texRef = null;
                MDL0MaterialRefNode spaRef = null;

                if (!String.IsNullOrEmpty(m._textureFileName))
                    if (m._textureFileName.Contains('*'))
                    {
                        string[] names = m._textureFileName.Split('*');
                        if (!String.IsNullOrEmpty(names[0]))
                        {
                            texRef = new MDL0MaterialRefNode();
                            texRef.Name = names[0].Substring(0, names[0].IndexOf('.'));
                        }
                        if (!String.IsNullOrEmpty(names[1]))
                        {
                            spaRef = new MDL0MaterialRefNode();
                            spaRef.Name = names[1].Substring(0, names[1].IndexOf('.'));
                            spaRef.MapMode = MDL0MaterialRefNode.MappingMethod.EnvCamera;
                            spaRef.UWrapMode = MDL0MaterialRefNode.WrapMode.Clamp;
                            spaRef.VWrapMode = MDL0MaterialRefNode.WrapMode.Clamp;
                            spaRef.Projection = Wii.Graphics.TexProjection.STQ;
                            spaRef.InputForm = Wii.Graphics.TexInputForm.ABC1;
                            spaRef.Coordinates = Wii.Graphics.TexSourceRow.Normals;
                            spaRef.Normalize = true;
                        }
                    }
                    else
                    {
                        texRef = new MDL0MaterialRefNode();
                        texRef.Name = m._textureFileName.Substring(0, m._textureFileName.IndexOf('.'));
                        texRef.Coordinates = Wii.Graphics.TexSourceRow.TexCoord0;
                    }

                if (texRef != null)
                {
                    (texRef._texture = model.FindOrCreateTexture(texRef.Name))._references.Add(texRef);
                    texRef._parent = mn;
                    mn._children.Add(texRef);
                }
                if (spaRef != null)
                {
                    (spaRef._texture = model.FindOrCreateTexture(spaRef.Name))._references.Add(spaRef);
                    spaRef._parent = mn;
                    mn._children.Add(spaRef);
                }

                mn._chan1._matColor = new RGBAPixel((byte)(m._diffuseColor[0] * 255), (byte)(m._diffuseColor[1] * 255), (byte)(m._diffuseColor[2] * 255), 255);
                mn._chan1.ColorMaterialSource = GXColorSrc.Register;

                if (texRef != null && spaRef != null)
                {
                    if (texSpa == null)
                    {
                        MDL0ShaderNode n = TexSpaShader;
                        n._parent = model._shadGroup;
                        model._shadList.Add(n);
                        texSpa = n;
                    }
                    mn.ShaderNode = texSpa;
                }
                else if (texRef != null)
                {
                    if (tex == null)
                    {
                        MDL0ShaderNode n = TexShader;
                        n._parent = model._shadGroup;
                        model._shadList.Add(n);
                        tex = n;
                    }
                    mn.ShaderNode = tex;
                }
                else if (spaRef != null)
                {
                    if (colorSpa == null)
                    {
                        MDL0ShaderNode n = ColorSpaShader;
                        n._parent = model._shadGroup;
                        model._shadList.Add(n);
                        colorSpa = n;
                    }
                    mn.ShaderNode = colorSpa;
                }
                else
                {
                    if (color == null)
                    {
                        MDL0ShaderNode n = ColorShader;
                        n._parent = model._shadGroup;
                        model._shadList.Add(n);
                        color = n;
                    }
                    mn.ShaderNode = color;
                }

                mn._parent = model._matGroup;
                model._matList.Add(mn);
            }

            model._numFaces = 0;
            model._numFacepoints = 0;

            int x = 0;
            int offset = 0;
            foreach (ModelMaterial m in _materials)
            {
                PrimitiveManager manager = new PrimitiveManager() { _pointCount = (int)m._faceVertCount };
                MDL0ObjectNode p = new MDL0ObjectNode() { _manager = manager, _opaMaterial = (MDL0MaterialNode)model._matList[x] };
                p._opaMaterial._objects.Add(p);
                p._manager._vertices = new List<Vertex3>();
                p.Name = "polygon" + x++;
                p._parent = model._objGroup;

                model._numFaces += p._numFaces = manager._faceCount = manager._pointCount / 3;
                model._numFacepoints += p._numFacepoints = manager._pointCount;

                p._manager._indices = new UnsafeBuffer((int)m._faceVertCount * 2);
                p._manager._faceData[0] = new UnsafeBuffer((int)m._faceVertCount * 12);
                p._manager._faceData[1] = new UnsafeBuffer((int)m._faceVertCount * 12);
                p._manager._faceData[4] = new UnsafeBuffer((int)m._faceVertCount * 8);

                p._manager._dirty[0] = true;
                p._manager._dirty[1] = true;
                p._manager._dirty[4] = true;

                ushort* Indices = (ushort*)p._manager._indices.Address;
                Vector3* Vertices = (Vector3*)p._manager._faceData[0].Address;
                Vector3* Normals = (Vector3*)p._manager._faceData[1].Address;
                Vector2* UVs = (Vector2*)p._manager._faceData[4].Address;

                manager._triangles = new NewPrimitive((int)m._faceVertCount, BeginMode.Triangles);
                uint[] pTriarr = manager._triangles._indices;
                uint pTri = 0;

                index = 0;
                List<int> usedVertices = new List<int>();
                List<int> vertexIndices = new List<int>();
                for (int s = offset, l = 0; l < (int)m._faceVertCount; l++, s++)
                {
                    ushort i = _faceIndices[s];
                    ModelVertex mv = _vertices[i];
                    ushort j = 0;
                    if (!usedVertices.Contains(i))
                    {
                        Influence inf;
                        BoneWeight weight1 = null, weight2 = null;

                        float weight = ((float)mv._boneWeight / 100.0f).Clamp(0.0f, 1.0f);

                        if (weight > 0.0f && weight < 1.0f)
                        {
                            weight1 = new BoneWeight(BoneCache[mv._boneIndex[0]], weight);
                            weight2 = new BoneWeight(BoneCache[mv._boneIndex[1]], 1.0f - weight);
                        }
                        else if (weight == 0.0f)
                            weight1 = new BoneWeight(BoneCache[mv._boneIndex[1]]);
                        else
                            weight1 = new BoneWeight(BoneCache[mv._boneIndex[0]]);

                        if (weight2 != null)
                            inf = new Influence(new List<BoneWeight> { weight1, weight2 });
                        else
                            inf = new Influence(new List<BoneWeight> { weight1 });

                        Vector3 t = new Vector3();
                        Vertex3 v;
                        t._x = mv._position[0];
                        t._y = mv._position[1];
                        t._z = mv._position[2];
                        if (inf._weights.Count > 1)
                        {
                            inf = model._influences.FindOrCreate(inf, true);
                            inf.CalcMatrix();
                            v = new Vertex3(t, inf);
                        }
                        else
                        {
                            MDL0BoneNode bone = inf._weights[0].Bone;
                            v = new Vertex3(t * bone._inverseBindMatrix, bone);
                        }

                        p._manager._vertices.Add(v);
                        vertexIndices.Add(usedVertices.Count);
                        usedVertices.Add(i);
                        j = (ushort)(usedVertices.Count - 1);
                    }
                    else
                        j = (ushort)vertexIndices[usedVertices.IndexOf(i)];

                    *Indices++ = j;
                    pTriarr[pTri++] = (uint)l;
                    *Vertices++ = p._manager._vertices[j]._position;
                    *Normals++ = mv._normal;
                    *UVs++ = mv._texCoord;
                }
                model._objList.Add(p);
                offset += (int)m._faceVertCount;
            }

            //Check each polygon to see if it can be rigged to a single influence
            if (model._objList != null && model._objList.Count != 0)
                foreach (MDL0ObjectNode p in model._objList)
                {
                    IMatrixNode node = null;
                    bool singlebind = true;

                    foreach (Vertex3 v in p._manager._vertices)
                        if (v._matrixNode != null)
                        {
                            if (node == null)
                                node = v._matrixNode;

                            if (v._matrixNode != node)
                            {
                                singlebind = false;
                                break;
                            }
                        }

                    if (singlebind && p._matrixNode == null)
                    {
                        //Increase reference count ahead of time for rebuild
                        if (p._manager._vertices[0]._matrixNode != null)
                            p._manager._vertices[0]._matrixNode.ReferenceCount++;

                        foreach (Vertex3 v in p._manager._vertices)
                            if (v._matrixNode != null)
                                v._matrixNode.ReferenceCount--;

                        p._nodeId = -2; //Continued on polygon rebuild
                    }
                }

            //foreach (MDL0ObjectNode p in model._objList)
            //    foreach (MDL0MaterialNode m in model._matList)
            //    {
            //        MDL0MaterialNode m2 = p.OpaMaterialNode;

            //        if (m2 == null || m2.ShaderNode != m.ShaderNode || m2.Children.Count != m.Children.Count)
            //            continue;

            //        for (int i = 0; i < m.Children.Count; i++)
            //            if (m2.Children[i].Name != m.Children[i].Name)
            //                continue;

            //        p.OpaMaterialNode = m;
            //        break;
            //    }
            //for (int i = 0; i < model._matList.Count; i++)
            //    if (((MDL0MaterialNode)model._matList[i])._objects.Count == 0)
            //        model._matList.RemoveAt(i--);

            model.CleanGroups();
            model.BuildFromScratch(null);
        }
Ejemplo n.º 2
0
        public void CheckMetals()
        {
            if (_autoMetal)
            {
                if (MessageBox.Show(null, "Are you sure you want to turn this on?\nAny existing metal materials will be modified.", "", MessageBoxButtons.YesNo) == DialogResult.Yes)
                {
                    if (_children == null) Populate();
                    for (int x = 0; x < _matList.Count; x++)
                    {
                        MDL0MaterialNode n = (MDL0MaterialNode)_matList[x];
                        if (!n.isMetal)
                        {
                            if (n.MetalMaterial == null)
                            {
                                MDL0MaterialNode node = new MDL0MaterialNode();
                                _matGroup.AddChild(node);
                                node._updating = true;
                                node.Name = n.Name + "_ExtMtl";
                                node._ssc = 4;
                                node.New = true;

                                for (int i = 0; i <= n.Children.Count; i++)
                                {
                                    MDL0MaterialRefNode mr = new MDL0MaterialRefNode();
                                    node.AddChild(mr);
                                    mr.Texture = "metal00";
                                    mr._index1 = mr._index2 = i;
                                    mr.SignalPropertyChange();
                                    if (i == n.Children.Count || ((MDL0MaterialRefNode)n.Children[i]).HasTextureMatrix)
                                    {
                                        mr._minFltr = 5;
                                        mr._magFltr = 1;
                                        mr._lodBias = -2;

                                        mr.HasTextureMatrix = true;
                                        node.Rebuild(true);

                                        mr._projection = (int)TexProjection.STQ;
                                        mr._inputForm = (int)TexInputForm.ABC1;
                                        mr._texGenType = (int)TexTexgenType.Regular;
                                        mr._sourceRow = (int)TexSourceRow.Normals;
                                        mr._embossSource = 4;
                                        mr._embossLight = 2;
                                        mr.Normalize = true;

                                        mr.MapMode = (MDL0MaterialRefNode.MappingMethod)1;

                                        mr.getTexMtxVal();

                                        break;
                                    }
                                }

                                node._chan1 = new LightChannel(63, new RGBAPixel(128, 128, 128, 255), new RGBAPixel(255, 255, 255, 255), 0, 0, node);
                                node.C1ColorEnabled = true;
                                node.C1ColorDiffuseFunction = GXDiffuseFn.Clamped;
                                node.C1ColorAttenuation = GXAttnFn.Spotlight;
                                node.C1AlphaEnabled = true;
                                node.C1AlphaDiffuseFunction = GXDiffuseFn.Clamped;
                                node.C1AlphaAttenuation = GXAttnFn.Spotlight;

                                node._chan2 = new LightChannel(63, new RGBAPixel(255, 255, 255, 255), new RGBAPixel(), 0, 0, node);
                                node.C2ColorEnabled = true;
                                node.C2ColorDiffuseFunction = GXDiffuseFn.Disabled;
                                node.C2ColorAttenuation = GXAttnFn.Specular;
                                node.C2AlphaDiffuseFunction = GXDiffuseFn.Disabled;
                                node.C2AlphaAttenuation = GXAttnFn.Specular;

                                node._lSet = n._lSet;
                                node._fSet = n._fSet;

                                node._cull = n._cull;
                                node._numLights = 2;
                                node.ZCompareLoc = false;
                                node._normMapRefLight1 =
                                node._normMapRefLight2 =
                                node._normMapRefLight3 =
                                node._normMapRefLight4 = -1;

                                node.SignalPropertyChange();
                            }
                        }
                    }
                    foreach (MDL0MaterialNode node in _matList)
                    {
                        if (!node.isMetal)
                            continue;

                        if (node.ShaderNode != null)
                        {
                            if (node.ShaderNode._autoMetal && node.ShaderNode.texCount == node.Children.Count)
                            {
                                node._updating = false;
                                continue;
                            }
                            else
                            {
                                if (node.ShaderNode._stages == 4)
                                {
                                    foreach (MDL0MaterialNode y in node.ShaderNode._materials)
                                        if (!y.isMetal || y.Children.Count != node.Children.Count)
                                            goto Next;
                                    node.ShaderNode.DefaultAsMetal(node.Children.Count);
                                    continue;
                                }
                            }
                        }
                    Next:
                        bool found = false;
                        foreach (MDL0ShaderNode s in _shadGroup.Children)
                        {
                            if (s._autoMetal && s.texCount == node.Children.Count)
                            {
                                node.ShaderNode = s;
                                found = true;
                            }
                            else
                            {
                                if (s._stages == 4)
                                {
                                    foreach (MDL0MaterialNode y in s._materials)
                                        if (!y.isMetal || y.Children.Count != node.Children.Count)
                                            goto NotFound;
                                    node.ShaderNode = s;
                                    found = true;
                                    goto End;
                                NotFound:
                                    continue;
                                }
                            }
                        }
                    End:
                        if (!found)
                        {
                            MDL0ShaderNode shader = new MDL0ShaderNode();
                            _shadGroup.AddChild(shader);
                            shader.DefaultAsMetal(node.Children.Count);
                            node.ShaderNode = shader;
                        }
                    }
                    foreach (MDL0MaterialNode m in _matList)
                        m._updating = false;
                }
                else
                    _autoMetal = false;
            }
        }
Ejemplo n.º 3
0
        public MDL0MaterialNode FindOrCreateXluMaterial(string name)
        {
            foreach (MDL0MaterialNode m in _matList)
                if (m.Name.Equals(name, StringComparison.OrdinalIgnoreCase) && m.XLUMaterial)
                    return m;

            MDL0MaterialNode node = new MDL0MaterialNode() { _name = _matGroup.FindName(name), XLUMaterial = true };
            _matGroup.AddChild(node, false);

            return node;
        }
 public LightChannel(uint flags, RGBAPixel mat, RGBAPixel amb, uint color, uint alpha, MDL0MaterialNode material)
     : this(flags, mat, amb, color, alpha)
 {
     _parent = material;
 }
Ejemplo n.º 5
0
        internal string Write(MDL0MaterialNode mat, MDL0ObjectNode obj)
        {
            MDL0ShaderNode shader = ((MDL0ShaderNode)Parent);

            string stage = "";

            //Get the texture coordinate to use
            int texcoord = (int)TextureCoord;

            //Do we need to use the coordinates?
            bool bHasTexCoord = texcoord < mat.Children.Count;

            //Is there an indirect stage? (CMD is not 0)
            //Is active ==
            //FB true
            //LB false
            //TW max
            //SW max
            //M max
            //0001 0111 1111 1110 0000 0000 = 0x17FE00
            bool bHasIndStage = IndirectActive && bt < mat.IndirectShaderStages;

            // HACK to handle cases where the tex gen is not enabled
            if (!bHasTexCoord)
                texcoord = 0;

            stage += String.Format("//TEV stage {0}\n\n", Index);

            //Add indirect support later

            if (bHasIndStage)
            {
                stage += String.Format("// indirect op\n");

                //Perform the indirect op on the incoming regular coordinates using indtex as the offset coords
                if (Alpha != IndTexAlphaSel.Off)
                    stage += String.Format("alphabump = indtex{0}.{1} {2};\n",
                            (int)TexStage,
                            (int)Alpha,
                            (int)TexFormat);

                //Format
                stage += String.Format("vec3 indtevcrd{0} = indtex{1} * {2};\n", Index, (int)TexStage, (int)TexFormat);

                //Bias
                if (Bias != IndTexBiasSel.None)
                    stage += String.Format("indtevcrd{0}.{1} += {2};\n", Index, MDL0MaterialNode.tevIndBiasField[(int)Bias], MDL0MaterialNode.tevIndBiasAdd[(int)TexFormat]);

                //Multiply by offset matrix and scale
                if (Matrix != 0)
                {
                    if ((int)Matrix <= 3)
                    {
                        int mtxidx = 2 * ((int)Matrix - 1);
                        stage += String.Format("vec2 indtevtrans{0} = vec2(dot(" + MDL0MaterialNode.I_INDTEXMTX + "[{1}].xyz, indtevcrd{2}), dot(" + MDL0MaterialNode.I_INDTEXMTX + "[{3}].xyz, indtevcrd{4}));\n",
                            Index, mtxidx, Index, mtxidx + 1, Index);
                    }
                    else if ((int)Matrix < 5 && (int)Matrix <= 7 && bHasTexCoord)
                    {
                        //S
                        int mtxidx = 2 * ((int)Matrix - 5);
                        stage += String.Format("vec2 indtevtrans{0} = " + MDL0MaterialNode.I_INDTEXMTX + "[{1}].ww * uv{2}.xy * indtevcrd{3}.xx;\n", Index, mtxidx, texcoord, Index);
                    }
                    else if ((int)Matrix < 9 && (int)Matrix <= 11 && bHasTexCoord)
                    {
                        //T
                        int mtxidx = 2 * ((int)Matrix - 9);
                        stage += String.Format("vec2 indtevtrans{0} = " + MDL0MaterialNode.I_INDTEXMTX + "[{1}].ww * uv{2}.xy * indtevcrd{3}.yy;\n", Index, mtxidx, texcoord, Index);
                    }
                    else
                        stage += String.Format("vec2 indtevtrans{0} = 0;\n", Index);
                }
                else
                    stage += String.Format("vec2 indtevtrans{0} = 0;\n", Index);

                #region Wrapping

                // wrap S
                if (S_Wrap == IndTexWrap.NoWrap)
                    stage += String.Format("wrappedcoord.x = uv{0}.x;\n", texcoord);
                else if (S_Wrap == IndTexWrap.Wrap0)
                    stage += String.Format("wrappedcoord.x = 0.0f;\n");
                else
                    stage += String.Format("wrappedcoord.x = fmod( uv{0}.x, {1} );\n", texcoord, MDL0MaterialNode.tevIndWrapStart[(int)S_Wrap]);

                // wrap T
                if (T_Wrap == IndTexWrap.NoWrap)
                    stage += String.Format("wrappedcoord.y = uv{0}.y;\n", texcoord);
                else if (T_Wrap == IndTexWrap.Wrap0)
                    stage += String.Format("wrappedcoord.y = 0.0f;\n");
                else
                    stage += String.Format("wrappedcoord.y = fmod( uv{0}.y, {1} );\n", texcoord, MDL0MaterialNode.tevIndWrapStart[(int)T_Wrap]);

                stage += String.Format("tevcoord.xy {0}= wrappedcoord + indtevtrans{1};\n", UsePrevStage ? "+" : "", Index);

                #endregion
            }

            //Check if we need to use Alpha
            if (ColorSelectionA == ColorArg.RasterAlpha || ColorSelectionA == ColorArg.RasterColor
             || ColorSelectionB == ColorArg.RasterAlpha || ColorSelectionB == ColorArg.RasterColor
             || ColorSelectionC == ColorArg.RasterAlpha || ColorSelectionC == ColorArg.RasterColor
             || ColorSelectionD == ColorArg.RasterAlpha || ColorSelectionD == ColorArg.RasterColor
             || AlphaSelectionA == AlphaArg.RasterAlpha || AlphaSelectionB == AlphaArg.RasterAlpha
             || AlphaSelectionC == AlphaArg.RasterAlpha || AlphaSelectionD == AlphaArg.RasterAlpha)
            {
                string rasswap = shader.swapModeTable[rswap];
                stage += String.Format("rastemp = {0}.{1};\n", MDL0MaterialNode.tevRasTable[(int)ColorChannel], rasswap);
                stage += String.Format("crastemp = fract(rastemp * (255.0f/256.0f)) * (256.0f/255.0f);\n");
            }

            if (TextureEnabled)
            {
                if(!bHasIndStage) //Calculate tevcoord
                    if(bHasTexCoord)
                        stage += String.Format("tevcoord.xy = uv{0}.xy;\n", texcoord);
                    else
                        stage += String.Format("tevcoord.xy = vec2(0.0f, 0.0f);\n");

                string texswap = shader.swapModeTable[tswap];
                int texmap = (int)TextureMapID;

                stage += String.Format("{0} = texture2D(samp{1}, {2}.xy"/* + " * " + MDL0MaterialNode.I_TEXDIMS + "[{3}].xy" */+ ").{4};\n", "textemp", texmap, "tevcoord", texmap, texswap);
            }
            else
                stage += String.Format("textemp = vec4(1.0f, 1.0f, 1.0f, 1.0f);\n");

            //Check if we need to use Konstant Colors
            if (ColorSelectionA == ColorArg.KonstantColorSelection ||
                ColorSelectionB == ColorArg.KonstantColorSelection ||
                ColorSelectionC == ColorArg.KonstantColorSelection ||
                ColorSelectionD == ColorArg.KonstantColorSelection ||
                AlphaSelectionA == AlphaArg.KonstantAlphaSelection ||
                AlphaSelectionB == AlphaArg.KonstantAlphaSelection ||
                AlphaSelectionC == AlphaArg.KonstantAlphaSelection ||
                AlphaSelectionD == AlphaArg.KonstantAlphaSelection)
            {
                int kc = (int)KonstantColorSelection;
                int ka = (int)KonstantAlphaSelection;

                stage += String.Format("konsttemp = vec4({0}, {1});\n", MDL0MaterialNode.tevKSelTableC[kc], MDL0MaterialNode.tevKSelTableA[ka]);

                if(kc > 7 || ka > 7)
                    stage += String.Format("ckonsttemp = fract(konsttemp * (255.0f/256.0f)) * (256.0f/255.0f);\n");
                else
                    stage += String.Format("ckonsttemp = konsttemp;\n");
            }

            if (ColorSelectionA == ColorArg.PreviousColor || ColorSelectionA == ColorArg.PreviousAlpha
             || ColorSelectionB == ColorArg.PreviousColor || ColorSelectionB == ColorArg.PreviousAlpha
             || ColorSelectionC == ColorArg.PreviousColor || ColorSelectionC == ColorArg.PreviousAlpha
             || AlphaSelectionA == AlphaArg.PreviousAlpha || AlphaSelectionB == AlphaArg.PreviousAlpha || AlphaSelectionC == AlphaArg.PreviousAlpha)
                stage += String.Format("cprev = fract(prev * (255.0f/256.0f)) * (256.0f/255.0f);\n");

            if (ColorSelectionA == ColorArg.Color0 || ColorSelectionA == ColorArg.Alpha0
             || ColorSelectionB == ColorArg.Color0 || ColorSelectionB == ColorArg.Alpha0
             || ColorSelectionC == ColorArg.Color0 || ColorSelectionC == ColorArg.Alpha0
             || AlphaSelectionA == AlphaArg.Alpha0 || AlphaSelectionB == AlphaArg.Alpha0 || AlphaSelectionC == AlphaArg.Alpha0)
                stage += String.Format("cc0 = fract(c0 * (255.0f/256.0f)) * (256.0f/255.0f);\n");

            if (ColorSelectionA == ColorArg.Color1 || ColorSelectionA == ColorArg.Alpha1
             || ColorSelectionB == ColorArg.Color1 || ColorSelectionB == ColorArg.Alpha1
             || ColorSelectionC == ColorArg.Color1 || ColorSelectionC == ColorArg.Alpha1
             || AlphaSelectionA == AlphaArg.Alpha1 || AlphaSelectionB == AlphaArg.Alpha1 || AlphaSelectionC == AlphaArg.Alpha1)
                stage += String.Format("cc1 = fract(c1 * (255.0f/256.0f)) * (256.0f/255.0f);\n");

            if (ColorSelectionA == ColorArg.Color2 || ColorSelectionA == ColorArg.Alpha2
             || ColorSelectionB == ColorArg.Color2 || ColorSelectionB == ColorArg.Alpha2
             || ColorSelectionC == ColorArg.Color2 || ColorSelectionC == ColorArg.Alpha2
             || AlphaSelectionA == AlphaArg.Alpha2 || AlphaSelectionB == AlphaArg.Alpha2 || AlphaSelectionC == AlphaArg.Alpha2)
                stage += String.Format("cc2 = fract(c2 * (255.0f/256.0f)) * (256.0f/255.0f);\n");

            #region Color Channel

            stage += String.Format("// color combine\n{0} = ", MDL0MaterialNode.tevCOutputTable[(int)ColorRegister]);

            if (ColorClamp)
                stage += "saturate(";

            if (ColorScale > TevScale.MultiplyBy1)
                stage += String.Format("{0} * (", MDL0MaterialNode.tevScaleTable[(int)ColorScale]);

            if (!(ColorSelectionD == ColorArg.Zero && ColorSubtract == false))
                stage += String.Format("{0} {1} ", MDL0MaterialNode.tevCInputTable[(int)ColorSelectionD], MDL0MaterialNode.tevOpTable[ColorSubtract ? 1 : 0]);

            if (ColorSelectionA == ColorSelectionB)
                stage += String.Format("{0}",
                    MDL0MaterialNode.tevCInputTable[(int)ColorSelectionA + 16]);
            else if (ColorSelectionC == ColorArg.Zero)
                stage += String.Format("{0}",
                    MDL0MaterialNode.tevCInputTable[(int)ColorSelectionA + 16]);
            else if (ColorSelectionC == ColorArg.One)
                stage += String.Format("{0}",
                    MDL0MaterialNode.tevCInputTable[(int)ColorSelectionB + 16]);
            else if (ColorSelectionA == ColorArg.Zero)
                stage += String.Format("{0} * {1}",
                    MDL0MaterialNode.tevCInputTable[(int)ColorSelectionB + 16],
                    MDL0MaterialNode.tevCInputTable[(int)ColorSelectionC + 16]);
            else if (ColorSelectionB == ColorArg.Zero)
                stage += String.Format("{0} * (vec3(1.0f, 1.0f, 1.0f) - {1})",
                    MDL0MaterialNode.tevCInputTable[(int)ColorSelectionA + 16],
                    MDL0MaterialNode.tevCInputTable[(int)ColorSelectionC + 16]);
            else
                stage += String.Format("lerp({0}, {1}, {2})",
                    MDL0MaterialNode.tevCInputTable[(int)ColorSelectionA + 16],
                    MDL0MaterialNode.tevCInputTable[(int)ColorSelectionB + 16],
                    MDL0MaterialNode.tevCInputTable[(int)ColorSelectionC + 16]);

            stage += MDL0MaterialNode.tevBiasTable[(int)ColorBias];

            if (ColorClamp) stage += ")";
            if (ColorScale > TevScale.MultiplyBy1) stage += ")";

            #endregion

            stage += ";\n";

            #region Alpha Channel

            stage += String.Format("// alpha combine\n{0} = ", MDL0MaterialNode.tevAOutputTable[(int)AlphaRegister]);

            if (AlphaClamp)
                stage += "saturate(";

            if (AlphaScale > TevScale.MultiplyBy1)
                stage += String.Format("{0} * (", MDL0MaterialNode.tevScaleTable[(int)AlphaScale]);

            if(!(AlphaSelectionD == AlphaArg.Zero && AlphaSubtract == false))
                stage += String.Format("{0}.a {1} ", MDL0MaterialNode.tevAInputTable[(int)AlphaSelectionD], MDL0MaterialNode.tevOpTable[AlphaSubtract ? 1 : 0]);

            if (AlphaSelectionA == AlphaSelectionB)
                stage += String.Format("{0}.a",
                    MDL0MaterialNode.tevAInputTable[(int)AlphaSelectionA + 8]);
            else if (AlphaSelectionC == AlphaArg.Zero)
                stage += String.Format("{0}.a",
                    MDL0MaterialNode.tevAInputTable[(int)AlphaSelectionA + 8]);
            else if (AlphaSelectionA == AlphaArg.Zero)
                stage += String.Format("{0}.a * {1}.a",
                    MDL0MaterialNode.tevAInputTable[(int)AlphaSelectionB + 8],
                    MDL0MaterialNode.tevAInputTable[(int)AlphaSelectionC + 8]);
            else if (AlphaSelectionB == AlphaArg.Zero)
                stage += String.Format("{0}.a * (1.0f - {1}.a)",
                    MDL0MaterialNode.tevAInputTable[(int)AlphaSelectionA + 8],
                    MDL0MaterialNode.tevAInputTable[(int)AlphaSelectionC + 8]);
            else
                stage += String.Format("lerp({0}.a, {1}.a, {2}.a)",
                    MDL0MaterialNode.tevAInputTable[(int)AlphaSelectionA + 8],
                    MDL0MaterialNode.tevAInputTable[(int)AlphaSelectionB + 8],
                    MDL0MaterialNode.tevAInputTable[(int)AlphaSelectionC + 8]);

            stage += MDL0MaterialNode.tevBiasTable[(int)AlphaBias];

            if (AlphaClamp) stage += ")";
            if (AlphaScale > TevScale.MultiplyBy1) stage += ")";

            #endregion

            stage += ";\n\n//TEV stage " + Index + " done\n\n";

            return stage;
        }
Ejemplo n.º 6
0
        internal string Write(MDL0MaterialNode mat, MDL0ObjectNode obj)
        {
            MDL0ShaderNode shader = ((MDL0ShaderNode)Parent);

            string stage = "";

            //Get the texture coordinate to use
            int texcoord = (int)TextureCoord;

            //Do we need to use the coordinates?
            bool bHasTexCoord = texcoord < mat.Children.Count;

            //Is there an indirect stage? (CMD is not 0)
            //Is active ==
            //FB true
            //LB false
            //TW max
            //SW max
            //M max
            //0001 0111 1111 1110 0000 0000 = 0x17FE00
            bool bHasIndStage = IndirectActive && bt < mat.IndirectShaderStages;

            // HACK to handle cases where the tex gen is not enabled
            if (!bHasTexCoord)
            {
                texcoord = 0;
            }

            stage += String.Format("//TEV stage {0}\n\n", Index);

            //Add indirect support later

            if (bHasIndStage)
            {
                stage += String.Format("// indirect op\n");

                //Perform the indirect op on the incoming regular coordinates using indtex as the offset coords
                if (Alpha != IndTexAlphaSel.Off)
                {
                    stage += String.Format("alphabump = indtex{0}.{1} {2};\n",
                                           (int)TexStage,
                                           (int)Alpha,
                                           (int)TexFormat);
                }

                //Format
                stage += String.Format("vec3 indtevcrd{0} = indtex{1} * {2};\n", Index, (int)TexStage, (int)TexFormat);

                //Bias
                if (Bias != IndTexBiasSel.None)
                {
                    stage += String.Format("indtevcrd{0}.{1} += {2};\n", Index, MDL0MaterialNode.tevIndBiasField[(int)Bias], MDL0MaterialNode.tevIndBiasAdd[(int)TexFormat]);
                }

                //Multiply by offset matrix and scale
                if (Matrix != 0)
                {
                    if ((int)Matrix <= 3)
                    {
                        int mtxidx = 2 * ((int)Matrix - 1);
                        stage += String.Format("vec2 indtevtrans{0} = vec2(dot(" + MDL0MaterialNode.I_INDTEXMTX + "[{1}].xyz, indtevcrd{2}), dot(" + MDL0MaterialNode.I_INDTEXMTX + "[{3}].xyz, indtevcrd{4}));\n",
                                               Index, mtxidx, Index, mtxidx + 1, Index);
                    }
                    else if ((int)Matrix < 5 && (int)Matrix <= 7 && bHasTexCoord)
                    {
                        //S
                        int mtxidx = 2 * ((int)Matrix - 5);
                        stage += String.Format("vec2 indtevtrans{0} = " + MDL0MaterialNode.I_INDTEXMTX + "[{1}].ww * uv{2}.xy * indtevcrd{3}.xx;\n", Index, mtxidx, texcoord, Index);
                    }
                    else if ((int)Matrix < 9 && (int)Matrix <= 11 && bHasTexCoord)
                    {
                        //T
                        int mtxidx = 2 * ((int)Matrix - 9);
                        stage += String.Format("vec2 indtevtrans{0} = " + MDL0MaterialNode.I_INDTEXMTX + "[{1}].ww * uv{2}.xy * indtevcrd{3}.yy;\n", Index, mtxidx, texcoord, Index);
                    }
                    else
                    {
                        stage += String.Format("vec2 indtevtrans{0} = 0;\n", Index);
                    }
                }
                else
                {
                    stage += String.Format("vec2 indtevtrans{0} = 0;\n", Index);
                }

                #region Wrapping

                // wrap S
                if (S_Wrap == IndTexWrap.NoWrap)
                {
                    stage += String.Format("wrappedcoord.x = uv{0}.x;\n", texcoord);
                }
                else if (S_Wrap == IndTexWrap.Wrap0)
                {
                    stage += String.Format("wrappedcoord.x = 0.0f;\n");
                }
                else
                {
                    stage += String.Format("wrappedcoord.x = fmod( uv{0}.x, {1} );\n", texcoord, MDL0MaterialNode.tevIndWrapStart[(int)S_Wrap]);
                }

                // wrap T
                if (T_Wrap == IndTexWrap.NoWrap)
                {
                    stage += String.Format("wrappedcoord.y = uv{0}.y;\n", texcoord);
                }
                else if (T_Wrap == IndTexWrap.Wrap0)
                {
                    stage += String.Format("wrappedcoord.y = 0.0f;\n");
                }
                else
                {
                    stage += String.Format("wrappedcoord.y = fmod( uv{0}.y, {1} );\n", texcoord, MDL0MaterialNode.tevIndWrapStart[(int)T_Wrap]);
                }

                stage += String.Format("tevcoord.xy {0}= wrappedcoord + indtevtrans{1};\n", UsePrevStage ? "+" : "", Index);

                #endregion
            }

            //Check if we need to use Alpha
            if (ColorSelectionA == ColorArg.RasterAlpha || ColorSelectionA == ColorArg.RasterColor ||
                ColorSelectionB == ColorArg.RasterAlpha || ColorSelectionB == ColorArg.RasterColor ||
                ColorSelectionC == ColorArg.RasterAlpha || ColorSelectionC == ColorArg.RasterColor ||
                ColorSelectionD == ColorArg.RasterAlpha || ColorSelectionD == ColorArg.RasterColor ||
                AlphaSelectionA == AlphaArg.RasterAlpha || AlphaSelectionB == AlphaArg.RasterAlpha ||
                AlphaSelectionC == AlphaArg.RasterAlpha || AlphaSelectionD == AlphaArg.RasterAlpha)
            {
                string rasswap = shader.swapModeTable[rswap];
                stage += String.Format("rastemp = {0}.{1};\n", MDL0MaterialNode.tevRasTable[(int)ColorChannel], rasswap);
                stage += String.Format("crastemp = fract(rastemp * (255.0f/256.0f)) * (256.0f/255.0f);\n");
            }

            if (TextureEnabled)
            {
                if (!bHasIndStage)        //Calculate tevcoord
                {
                    if (bHasTexCoord)
                    {
                        stage += String.Format("tevcoord.xy = uv{0}.xy;\n", texcoord);
                    }
                    else
                    {
                        stage += String.Format("tevcoord.xy = vec2(0.0f, 0.0f);\n");
                    }
                }

                string texswap = shader.swapModeTable[tswap];
                int    texmap  = (int)TextureMapID;

                stage += String.Format("{0} = texture2D(samp{1}, {2}.xy" /* + " * " + MDL0MaterialNode.I_TEXDIMS + "[{3}].xy" */ + ").{4};\n", "textemp", texmap, "tevcoord", texmap, texswap);
            }
            else
            {
                stage += String.Format("textemp = vec4(1.0f, 1.0f, 1.0f, 1.0f);\n");
            }

            //Check if we need to use Konstant Colors
            if (ColorSelectionA == ColorArg.KonstantColorSelection ||
                ColorSelectionB == ColorArg.KonstantColorSelection ||
                ColorSelectionC == ColorArg.KonstantColorSelection ||
                ColorSelectionD == ColorArg.KonstantColorSelection ||
                AlphaSelectionA == AlphaArg.KonstantAlphaSelection ||
                AlphaSelectionB == AlphaArg.KonstantAlphaSelection ||
                AlphaSelectionC == AlphaArg.KonstantAlphaSelection ||
                AlphaSelectionD == AlphaArg.KonstantAlphaSelection)
            {
                int kc = (int)KonstantColorSelection;
                int ka = (int)KonstantAlphaSelection;

                stage += String.Format("konsttemp = vec4({0}, {1});\n", MDL0MaterialNode.tevKSelTableC[kc], MDL0MaterialNode.tevKSelTableA[ka]);

                if (kc > 7 || ka > 7)
                {
                    stage += String.Format("ckonsttemp = fract(konsttemp * (255.0f/256.0f)) * (256.0f/255.0f);\n");
                }
                else
                {
                    stage += String.Format("ckonsttemp = konsttemp;\n");
                }
            }

            if (ColorSelectionA == ColorArg.PreviousColor || ColorSelectionA == ColorArg.PreviousAlpha ||
                ColorSelectionB == ColorArg.PreviousColor || ColorSelectionB == ColorArg.PreviousAlpha ||
                ColorSelectionC == ColorArg.PreviousColor || ColorSelectionC == ColorArg.PreviousAlpha ||
                AlphaSelectionA == AlphaArg.PreviousAlpha || AlphaSelectionB == AlphaArg.PreviousAlpha || AlphaSelectionC == AlphaArg.PreviousAlpha)
            {
                stage += String.Format("cprev = fract(prev * (255.0f/256.0f)) * (256.0f/255.0f);\n");
            }

            if (ColorSelectionA == ColorArg.Color0 || ColorSelectionA == ColorArg.Alpha0 ||
                ColorSelectionB == ColorArg.Color0 || ColorSelectionB == ColorArg.Alpha0 ||
                ColorSelectionC == ColorArg.Color0 || ColorSelectionC == ColorArg.Alpha0 ||
                AlphaSelectionA == AlphaArg.Alpha0 || AlphaSelectionB == AlphaArg.Alpha0 || AlphaSelectionC == AlphaArg.Alpha0)
            {
                stage += String.Format("cc0 = fract(c0 * (255.0f/256.0f)) * (256.0f/255.0f);\n");
            }

            if (ColorSelectionA == ColorArg.Color1 || ColorSelectionA == ColorArg.Alpha1 ||
                ColorSelectionB == ColorArg.Color1 || ColorSelectionB == ColorArg.Alpha1 ||
                ColorSelectionC == ColorArg.Color1 || ColorSelectionC == ColorArg.Alpha1 ||
                AlphaSelectionA == AlphaArg.Alpha1 || AlphaSelectionB == AlphaArg.Alpha1 || AlphaSelectionC == AlphaArg.Alpha1)
            {
                stage += String.Format("cc1 = fract(c1 * (255.0f/256.0f)) * (256.0f/255.0f);\n");
            }

            if (ColorSelectionA == ColorArg.Color2 || ColorSelectionA == ColorArg.Alpha2 ||
                ColorSelectionB == ColorArg.Color2 || ColorSelectionB == ColorArg.Alpha2 ||
                ColorSelectionC == ColorArg.Color2 || ColorSelectionC == ColorArg.Alpha2 ||
                AlphaSelectionA == AlphaArg.Alpha2 || AlphaSelectionB == AlphaArg.Alpha2 || AlphaSelectionC == AlphaArg.Alpha2)
            {
                stage += String.Format("cc2 = fract(c2 * (255.0f/256.0f)) * (256.0f/255.0f);\n");
            }

            #region Color Channel

            stage += String.Format("// color combine\n{0} = ", MDL0MaterialNode.tevCOutputTable[(int)ColorRegister]);

            if (ColorClamp)
            {
                stage += "saturate(";
            }

            if (ColorScale > TevScale.MultiplyBy1)
            {
                stage += String.Format("{0} * (", MDL0MaterialNode.tevScaleTable[(int)ColorScale]);
            }

            if (!(ColorSelectionD == ColorArg.Zero && ColorSubtract == false))
            {
                stage += String.Format("{0} {1} ", MDL0MaterialNode.tevCInputTable[(int)ColorSelectionD], MDL0MaterialNode.tevOpTable[ColorSubtract ? 1 : 0]);
            }

            if (ColorSelectionA == ColorSelectionB)
            {
                stage += String.Format("{0}",
                                       MDL0MaterialNode.tevCInputTable[(int)ColorSelectionA + 16]);
            }
            else if (ColorSelectionC == ColorArg.Zero)
            {
                stage += String.Format("{0}",
                                       MDL0MaterialNode.tevCInputTable[(int)ColorSelectionA + 16]);
            }
            else if (ColorSelectionC == ColorArg.One)
            {
                stage += String.Format("{0}",
                                       MDL0MaterialNode.tevCInputTable[(int)ColorSelectionB + 16]);
            }
            else if (ColorSelectionA == ColorArg.Zero)
            {
                stage += String.Format("{0} * {1}",
                                       MDL0MaterialNode.tevCInputTable[(int)ColorSelectionB + 16],
                                       MDL0MaterialNode.tevCInputTable[(int)ColorSelectionC + 16]);
            }
            else if (ColorSelectionB == ColorArg.Zero)
            {
                stage += String.Format("{0} * (vec3(1.0f, 1.0f, 1.0f) - {1})",
                                       MDL0MaterialNode.tevCInputTable[(int)ColorSelectionA + 16],
                                       MDL0MaterialNode.tevCInputTable[(int)ColorSelectionC + 16]);
            }
            else
            {
                stage += String.Format("lerp({0}, {1}, {2})",
                                       MDL0MaterialNode.tevCInputTable[(int)ColorSelectionA + 16],
                                       MDL0MaterialNode.tevCInputTable[(int)ColorSelectionB + 16],
                                       MDL0MaterialNode.tevCInputTable[(int)ColorSelectionC + 16]);
            }

            stage += MDL0MaterialNode.tevBiasTable[(int)ColorBias];

            if (ColorClamp)
            {
                stage += ")";
            }
            if (ColorScale > TevScale.MultiplyBy1)
            {
                stage += ")";
            }

            #endregion

            stage += ";\n";

            #region Alpha Channel

            stage += String.Format("// alpha combine\n{0} = ", MDL0MaterialNode.tevAOutputTable[(int)AlphaRegister]);

            if (AlphaClamp)
            {
                stage += "saturate(";
            }

            if (AlphaScale > TevScale.MultiplyBy1)
            {
                stage += String.Format("{0} * (", MDL0MaterialNode.tevScaleTable[(int)AlphaScale]);
            }

            if (!(AlphaSelectionD == AlphaArg.Zero && AlphaSubtract == false))
            {
                stage += String.Format("{0}.a {1} ", MDL0MaterialNode.tevAInputTable[(int)AlphaSelectionD], MDL0MaterialNode.tevOpTable[AlphaSubtract ? 1 : 0]);
            }

            if (AlphaSelectionA == AlphaSelectionB)
            {
                stage += String.Format("{0}.a",
                                       MDL0MaterialNode.tevAInputTable[(int)AlphaSelectionA + 8]);
            }
            else if (AlphaSelectionC == AlphaArg.Zero)
            {
                stage += String.Format("{0}.a",
                                       MDL0MaterialNode.tevAInputTable[(int)AlphaSelectionA + 8]);
            }
            else if (AlphaSelectionA == AlphaArg.Zero)
            {
                stage += String.Format("{0}.a * {1}.a",
                                       MDL0MaterialNode.tevAInputTable[(int)AlphaSelectionB + 8],
                                       MDL0MaterialNode.tevAInputTable[(int)AlphaSelectionC + 8]);
            }
            else if (AlphaSelectionB == AlphaArg.Zero)
            {
                stage += String.Format("{0}.a * (1.0f - {1}.a)",
                                       MDL0MaterialNode.tevAInputTable[(int)AlphaSelectionA + 8],
                                       MDL0MaterialNode.tevAInputTable[(int)AlphaSelectionC + 8]);
            }
            else
            {
                stage += String.Format("lerp({0}.a, {1}.a, {2}.a)",
                                       MDL0MaterialNode.tevAInputTable[(int)AlphaSelectionA + 8],
                                       MDL0MaterialNode.tevAInputTable[(int)AlphaSelectionB + 8],
                                       MDL0MaterialNode.tevAInputTable[(int)AlphaSelectionC + 8]);
            }

            stage += MDL0MaterialNode.tevBiasTable[(int)AlphaBias];

            if (AlphaClamp)
            {
                stage += ")";
            }
            if (AlphaScale > TevScale.MultiplyBy1)
            {
                stage += ")";
            }

            #endregion

            stage += ";\n\n//TEV stage " + Index + " done\n\n";

            return(stage);
        }
Ejemplo n.º 7
0
        //Write this stage to the shader code
        internal string Write(MDL0MaterialNode mat)
        {
            MDL0ShaderNode shader = ((MDL0ShaderNode)Parent);

            string stage = "";

            //Get the texture coordinate to use
            int texcoord = (int)TextureCoord;

            //Do we need to use the coordinates?
            bool bHasTexCoord = texcoord < mat.Children.Count;

            //Is there an indirect stage? (CMD is not 0)
            //Is active ==
            //FB true
            //LB false
            //TW max
            //SW max
            //M max
            //0001 0111 1111 1110 0000 0000 = 0x17FE00
            bool bHasIndStage = (rawCMD & 0x17FE00) != 0 && bt < mat.IndirectTextures;

            // HACK to handle cases where the tex gen is not enabled
            if (!bHasTexCoord)
            {
                texcoord = 0;
            }

            stage += String.Format("//TEV stage {0}\n", Index);

            //Add indirect support later

            //if (bHasIndStage)
            //{
            //    stage += String.Format("// indirect op\n");
            //    // perform the indirect op on the incoming regular coordinates using indtex%d as the offset coords
            //    if (bpmem.tevind[n].bs != ITBA_OFF)
            //    {
            //        stage += String.Format("alphabump = indtex%d.%s %s;\n",
            //                bpmem.tevind[n].bt,
            //                tevIndAlphaSel[bpmem.tevind[n].bs],
            //                tevIndAlphaScale[bpmem.tevind[n].fmt]);
            //    }
            //    // format
            //    stage += String.Format("float3 indtevcrd%d = indtex%d * %s;\n", n, bpmem.tevind[n].bt, tevIndFmtScale[bpmem.tevind[n].fmt]);

            //    // bias
            //    if (bpmem.tevind[n].bias != ITB_NONE )
            //        stage += String.Format("indtevcrd%d.%s += %s;\n", n, tevIndBiasField[bpmem.tevind[n].bias], tevIndBiasAdd[bpmem.tevind[n].fmt]);

            //    // multiply by offset matrix and scale
            //    if (bpmem.tevind[n].mid != 0)
            //    {
            //        if (bpmem.tevind[n].mid <= 3)
            //        {
            //            int mtxidx = 2*(bpmem.tevind[n].mid-1);
            //            stage += String.Format("float2 indtevtrans%d = float2(dot("I_INDTEXMTX"[%d].xyz, indtevcrd%d), dot("I_INDTEXMTX"[%d].xyz, indtevcrd%d));\n",
            //                n, mtxidx, n, mtxidx+1, n);
            //        }
            //        else if (bpmem.tevind[n].mid <= 7 && bHasTexCoord)
            //        { // s matrix
            //            if (bpmem.tevind[n].mid >= 5);
            //            int mtxidx = 2*(bpmem.tevind[n].mid-5);
            //            stage += String.Format("float2 indtevtrans%d = "I_INDTEXMTX"[%d].ww * uv%d.xy * indtevcrd%d.xx;\n", n, mtxidx, texcoord, n);
            //        }
            //        else if (bpmem.tevind[n].mid <= 11 && bHasTexCoord)
            //        { // t matrix
            //            if (bpmem.tevind[n].mid >= 9);
            //            int mtxidx = 2*(bpmem.tevind[n].mid-9);
            //            stage += String.Format("float2 indtevtrans%d = "I_INDTEXMTX"[%d].ww * uv%d.xy * indtevcrd%d.yy;\n", n, mtxidx, texcoord, n);
            //        }
            //        else
            //            stage += String.Format("float2 indtevtrans%d = 0;\n", n);
            //    }
            //    else
            //        stage += String.Format("float2 indtevtrans%d = 0;\n", n);

            //    // ---------
            //    // Wrapping
            //    // ---------

            //    // wrap S
            //    if (bpmem.tevind[n].sw == ITW_OFF)
            //        stage += String.Format("wrappedcoord.x = uv%d.x;\n", texcoord);
            //    else if (bpmem.tevind[n].sw == ITW_0)
            //        stage += String.Format("wrappedcoord.x = 0.0f;\n");
            //    else
            //        stage += String.Format("wrappedcoord.x = fmod( uv%d.x, %s );\n", texcoord, tevIndWrapStart[bpmem.tevind[n].sw]);

            //    // wrap T
            //    if (bpmem.tevind[n].tw == ITW_OFF)
            //        stage += String.Format("wrappedcoord.y = uv%d.y;\n", texcoord);
            //    else if (bpmem.tevind[n].tw == ITW_0)
            //        stage += String.Format("wrappedcoord.y = 0.0f;\n");
            //    else
            //        stage += String.Format("wrappedcoord.y = fmod( uv%d.y, %s );\n", texcoord, tevIndWrapStart[bpmem.tevind[n].tw]);

            //    if (bpmem.tevind[n].fb_addprev) // add previous tevcoord
            //        stage += String.Format("tevcoord.xy += wrappedcoord + indtevtrans%d;\n", n);
            //    else
            //        stage += String.Format("tevcoord.xy = wrappedcoord + indtevtrans%d;\n", n);
            //}

            //Check if we need to use Alpha
            if (ColorSelectionA == ColorArg.RasterAlpha || ColorSelectionA == ColorArg.RasterColor ||
                ColorSelectionB == ColorArg.RasterAlpha || ColorSelectionB == ColorArg.RasterColor ||
                ColorSelectionC == ColorArg.RasterAlpha || ColorSelectionC == ColorArg.RasterColor ||
                ColorSelectionD == ColorArg.RasterAlpha || ColorSelectionD == ColorArg.RasterColor ||
                AlphaSelectionA == AlphaArg.RasterAlpha || AlphaSelectionB == AlphaArg.RasterAlpha ||
                AlphaSelectionC == AlphaArg.RasterAlpha || AlphaSelectionD == AlphaArg.RasterAlpha)
            {
                string rasswap = shader.swapModeTable[rswap];
                stage += String.Format("rastemp = {0}.{1};\n", shader.tevRasTable[(int)ColorChannel], rasswap);
                stage += String.Format("crastemp = frac(rastemp * (255.0f/256.0f)) * (256.0f/255.0f);\n");
            }

            if (TextureEnabled)
            {
                if (!bHasIndStage)        //Calculate tevcoord
                {
                    if (bHasTexCoord)
                    {
                        stage += String.Format("tevcoord.xy = uv{0}.xy;\n", texcoord);
                    }
                    else
                    {
                        stage += String.Format("tevcoord.xy = float2(0.0f, 0.0f);\n");
                    }
                }

                string texswap = shader.swapModeTable[tswap];
                int    texmap  = (int)TextureMapID;
                //SampleTexture(p, "textemp", "tevcoord", texswap, texmap, ApiType);
                stage += String.Format("{0} = tex2D(samp{1},{2}.xy * " + shader.I_TEXDIMS + "[{3}].xy).{4};\n", "textemp", texmap, "tevcoord", texmap, texswap);
            }
            else
            {
                stage += String.Format("textemp = float4(1.0f, 1.0f, 1.0f, 1.0f);\n");
            }

            //Check if we need to use Konstant Colors
            if (ColorSelectionA == ColorArg.KonstantColorSelection ||
                ColorSelectionB == ColorArg.KonstantColorSelection ||
                ColorSelectionC == ColorArg.KonstantColorSelection ||
                ColorSelectionD == ColorArg.KonstantColorSelection ||
                AlphaSelectionA == AlphaArg.KonstantAlphaSelection ||
                AlphaSelectionB == AlphaArg.KonstantAlphaSelection ||
                AlphaSelectionC == AlphaArg.KonstantAlphaSelection ||
                AlphaSelectionD == AlphaArg.KonstantAlphaSelection)
            {
                int kc = (int)KonstantColorSelection;
                int ka = (int)KonstantAlphaSelection;
                stage += String.Format("konsttemp = float4({0}, {1});\n", shader.tevKSelTableC[kc], shader.tevKSelTableA[ka]);
                if (kc > 7 || ka > 7)
                {
                    stage += String.Format("ckonsttemp = frac(konsttemp * (255.0f/256.0f)) * (256.0f/255.0f);\n");
                }
                else
                {
                    stage += String.Format("ckonsttemp = konsttemp;\n");
                }
            }

            if (ColorSelectionA == ColorArg.PreviousColor || ColorSelectionA == ColorArg.PreviousAlpha ||
                ColorSelectionB == ColorArg.PreviousColor || ColorSelectionB == ColorArg.PreviousAlpha ||
                ColorSelectionC == ColorArg.PreviousColor || ColorSelectionC == ColorArg.PreviousAlpha ||
                AlphaSelectionA == AlphaArg.PreviousAlpha || AlphaSelectionB == AlphaArg.PreviousAlpha || AlphaSelectionC == AlphaArg.PreviousAlpha)
            {
                stage += String.Format("cprev = frac(prev * (255.0f/256.0f)) * (256.0f/255.0f);\n");
            }

            if (ColorSelectionA == ColorArg.Color0 || ColorSelectionA == ColorArg.Alpha0 ||
                ColorSelectionB == ColorArg.Color0 || ColorSelectionB == ColorArg.Alpha0 ||
                ColorSelectionC == ColorArg.Color0 || ColorSelectionC == ColorArg.Alpha0 ||
                AlphaSelectionA == AlphaArg.Alpha0 || AlphaSelectionB == AlphaArg.Alpha0 || AlphaSelectionC == AlphaArg.Alpha0)
            {
                stage += String.Format("cc0 = frac(c0 * (255.0f/256.0f)) * (256.0f/255.0f);\n");
            }

            if (ColorSelectionA == ColorArg.Color1 || ColorSelectionA == ColorArg.Alpha1 ||
                ColorSelectionB == ColorArg.Color1 || ColorSelectionB == ColorArg.Alpha1 ||
                ColorSelectionC == ColorArg.Color1 || ColorSelectionC == ColorArg.Alpha1 ||
                AlphaSelectionA == AlphaArg.Alpha1 || AlphaSelectionB == AlphaArg.Alpha1 || AlphaSelectionC == AlphaArg.Alpha1)
            {
                stage += String.Format("cc1 = frac(c1 * (255.0f/256.0f)) * (256.0f/255.0f);\n");
            }

            if (ColorSelectionA == ColorArg.Color2 || ColorSelectionA == ColorArg.Alpha2 ||
                ColorSelectionB == ColorArg.Color2 || ColorSelectionB == ColorArg.Alpha2 ||
                ColorSelectionC == ColorArg.Color2 || ColorSelectionC == ColorArg.Alpha2 ||
                AlphaSelectionA == AlphaArg.Alpha2 || AlphaSelectionB == AlphaArg.Alpha2 || AlphaSelectionC == AlphaArg.Alpha2)
            {
                stage += String.Format("cc2 = frac(c2 * (255.0f/256.0f)) * (256.0f/255.0f);\n");
            }

            stage += String.Format("// color combine\n");
            if (ColorClamp)
            {
                stage += String.Format("{0} = saturate(", shader.tevCOutputTable[(int)ColorRegister]);
            }
            else
            {
                stage += String.Format("{0} = ", shader.tevCOutputTable[(int)ColorRegister]);
            }

            //Combine the color channel

            //There is no compare enum...
            //if (ColorBias != TevBias_COMPARE) // if not compare
            //{
            //Normal color combiner goes here
            if (ColorScale > TevScale.MultiplyBy1)
            {
                stage += String.Format("{0}*(", shader.tevScaleTable[(int)ColorScale]);
            }

            if (!(ColorSelectionD == ColorArg.Zero && ColorSubtract == false))
            {
                stage += String.Format("{0}{1}", shader.tevCInputTable[(int)ColorSelectionD], shader.tevOpTable[ColorSubtract ? 1 : 0]);
            }

            if (ColorSelectionA == ColorSelectionB)
            {
                stage += String.Format("{0}",
                                       shader.tevCInputTable[(int)ColorSelectionA + 16]);
            }
            else if (ColorSelectionC == ColorArg.Zero)
            {
                stage += String.Format("{0}",
                                       shader.tevCInputTable[(int)ColorSelectionA + 16]);
            }
            else if (ColorSelectionC == ColorArg.One)
            {
                stage += String.Format("{0}",
                                       shader.tevCInputTable[(int)ColorSelectionB + 16]);
            }
            else if (ColorSelectionA == ColorArg.Zero)
            {
                stage += String.Format("{0}*{1}",
                                       shader.tevCInputTable[(int)ColorSelectionB + 16],
                                       shader.tevCInputTable[(int)ColorSelectionC + 16]);
            }
            else if (ColorSelectionB == ColorArg.Zero)
            {
                stage += String.Format("{0}*(float3(1.0f, 1.0f, 1.0f)-{1})",
                                       shader.tevCInputTable[(int)ColorSelectionA + 16],
                                       shader.tevCInputTable[(int)ColorSelectionC + 16]);
            }
            else
            {
                stage += String.Format("lerp({0}, {1}, {2})",
                                       shader.tevCInputTable[(int)ColorSelectionA + 16],
                                       shader.tevCInputTable[(int)ColorSelectionB + 16],
                                       shader.tevCInputTable[(int)ColorSelectionC + 16]);
            }

            stage += shader.tevBiasTable[(int)ColorBias];

            if (ColorScale > TevScale.MultiplyBy1)
            {
                stage += ")";
            }
            //}
            //else
            //{
            //    int cmp = (cc.shift<<1)|cc.op|8; // comparemode stored here
            //    stage += String.Format(TEVCMPColorOPTable[cmp],//lookup the function from the op table
            //	        tevCInputTable[ColorSelectionD],
            //	        tevCInputTable[ColorSelectionA + 16],
            //	        tevCInputTable[ColorSelectionB + 16],
            //	        tevCInputTable[ColorSelectionC + 16]);
            //}
            if (ColorClamp)
            {
                stage += ")";
            }

            stage += ";\n";

            stage += String.Format("// alpha combine\n");
            // combine the alpha channel
            if (AlphaClamp)
            {
                stage += String.Format("{0} = saturate(", shader.tevAOutputTable[(int)AlphaRegister]);
            }
            else
            {
                stage += String.Format("{0} = ", shader.tevAOutputTable[(int)AlphaRegister]);
            }

            //if (AlphaSelectionBias != TevBias_COMPARE) // if not compare
            //{
            //normal alpha combiner goes here
            if (AlphaScale > TevScale.MultiplyBy1)
            {
                stage += String.Format("{0}*(", shader.tevScaleTable[(int)AlphaScale]);
            }

            if (!(AlphaSelectionD == AlphaArg.Zero && AlphaSubtract == false))
            {
                stage += String.Format("{0}.a{1}", shader.tevAInputTable[(int)AlphaSelectionD], shader.tevOpTable[AlphaSubtract ? 1 : 0]);
            }

            if (AlphaSelectionA == AlphaSelectionB)
            {
                stage += String.Format("{0}.a",
                                       shader.tevAInputTable[(int)AlphaSelectionA + 8]);
            }
            else if (AlphaSelectionC == AlphaArg.Zero)
            {
                stage += String.Format("{0}.a",
                                       shader.tevAInputTable[(int)AlphaSelectionA + 8]);
            }
            else if (AlphaSelectionA == AlphaArg.Zero)
            {
                stage += String.Format("{0}.a*{1}.a",
                                       shader.tevAInputTable[(int)AlphaSelectionB + 8],
                                       shader.tevAInputTable[(int)AlphaSelectionC + 8]);
            }
            else if (AlphaSelectionB == AlphaArg.Zero)
            {
                stage += String.Format("{0}.a*(1.0f-{1}.a)",
                                       shader.tevAInputTable[(int)AlphaSelectionA + 8],
                                       shader.tevAInputTable[(int)AlphaSelectionC + 8]);
            }
            else
            {
                stage += String.Format("lerp({0}.a, {1}.a, {2}.a)",
                                       shader.tevAInputTable[(int)AlphaSelectionA + 8],
                                       shader.tevAInputTable[(int)AlphaSelectionB + 8],
                                       shader.tevAInputTable[(int)AlphaSelectionC + 8]);
            }

            stage += shader.tevBiasTable[(int)AlphaBias];

            if (AlphaScale > 0)
            {
                stage += ")";
            }

            //}
            //else
            //{
            //    //compare alpha combiner goes here
            //    int cmp = (ac.shift<<1)|ac.op|8; // comparemode stored here
            //    stage += String.Format(TEVCMPAlphaOPTable[cmp],
            //            tevAInputTable[AlphaSelectionD],
            //            tevAInputTable[AlphaSelectionA + 8],
            //            tevAInputTable[AlphaSelectionB + 8],
            //            tevAInputTable[AlphaSelectionC + 8]);
            //}
            if (AlphaClamp)
            {
                stage += ")";
            }

            stage += String.Format(";\n\n");
            stage += String.Format("//TEV stage done\n");

            return(stage);
        }
        public MDL0Node ImportModel(string filePath)
        {
            MDL0Node model = new MDL0Node() { _name = Path.GetFileNameWithoutExtension(filePath) };
            model.InitGroups();
            if (_importOptions._setOrigPath)
                model._originalPath = filePath;

            //Parse the collada file and use the data to create an MDL0
            using (DecoderShell shell = DecoderShell.Import(filePath))
            try
            {
                model._version = _importOptions._modelVersion;

                Error = "There was a problem reading the model.";

                //Extract images, removing duplicates
                foreach (ImageEntry img in shell._images)
                {
                    string name;
                    MDL0TextureNode tex;

                    if (img._path != null)
                        name = Path.GetFileNameWithoutExtension(img._path);
                    else
                        name = img._name != null ? img._name : img._id;

                    tex = model.FindOrCreateTexture(name);
                    img._node = tex;
                }

                //Extract materials and create shaders
                int tempNo = -1;
                foreach (MaterialEntry mat in shell._materials)
                {
                    tempNo += 1;
                    MDL0MaterialNode matNode = new MDL0MaterialNode();

                    matNode._parent = model._matGroup;
                    matNode._name = mat._name != null ? mat._name : mat._id;

                    if (tempNo == 0)
                    {
                        MDL0ShaderNode shadNode = new MDL0ShaderNode();
                        shadNode._parent = model._shadGroup;
                        shadNode._name = "Shader" + tempNo;
                        model._shadList.Add(shadNode);
                    }
                    matNode.Shader = "Shader0";
                    matNode.ShaderNode = (MDL0ShaderNode)model._shadGroup.Children[0];

                    mat._node = matNode;
                    matNode._cull = _importOptions._culling;

                    //Find effect
                    if (mat._effect != null)
                        foreach (EffectEntry eff in shell._effects)
                            if (eff._id == mat._effect) //Attach textures and effects to material
                                if (eff._shader != null)
                                    foreach (LightEffectEntry l in eff._shader._effects)
                                        if (l._type == LightEffectType.diffuse && l._texture != null)
                                        {
                                            string path = l._texture;
                                            foreach (EffectNewParam p in eff._newParams)
                                                if (p._sid == l._texture)
                                                {
                                                    path = p._sampler2D._url;
                                                    if (!String.IsNullOrEmpty(p._sampler2D._source))
                                                    {
                                                        foreach (EffectNewParam p2 in eff._newParams)
                                                            if (p2._sid == p._sampler2D._source)
                                                                path = p2._path;
                                                    }
                                                }

                                            foreach (ImageEntry img in shell._images)
                                                if (img._id == path)
                                                {
                                                    MDL0MaterialRefNode mr = new MDL0MaterialRefNode();
                                                    (mr._texture = img._node as MDL0TextureNode)._references.Add(mr);
                                                    mr._name = mr._texture.Name;
                                                    matNode._children.Add(mr);
                                                    mr._parent = matNode;
                                                    mr._minFltr = mr._magFltr = 1;
                                                    mr._index1 = mr._index2 = mr.Index;
                                                    mr._uWrap = mr._vWrap = (int)_importOptions._wrap;
                                                    break;
                                                }
                                        }

                    matNode._numTextures = (byte)matNode.Children.Count;
                    model._matList.Add(matNode);
                }

                Say("Extracting scenes...");

                //Extract scenes
                foreach (SceneEntry scene in shell._scenes)
                {
                    //Parse joints first
                    NodeEntry[] joints = scene._nodes.Where(x => x._type == NodeType.JOINT).ToArray();
                    NodeEntry[] nodes = scene._nodes.Where(x => x._type != NodeType.JOINT).ToArray();
                    foreach (NodeEntry node in joints)
                        EnumNode(node, model._boneGroup, scene, model, shell);
                    foreach (NodeEntry node in nodes)
                        EnumNode(node, model._boneGroup, scene, model, shell);
                }

                //If there are no bones, rig all objects to a single bind.
                if (model._boneGroup._children.Count == 0)
                {
                    for (int i = 0; i < 2; i++)
                    {
                        MDL0BoneNode bone = new MDL0BoneNode();
                        bone.Scale = new Vector3(1);

                        bone._bindMatrix =
                        bone._inverseBindMatrix =
                        Matrix.Identity;

                        switch (i)
                        {
                            case 0:
                                bone._name = "TopN";
                                model._boneGroup._children.Add(bone);
                                bone._parent = model._boneGroup;
                                break;
                            case 1:
                                bone._name = "TransN";
                                model._boneGroup._children[0]._children.Add(bone);
                                bone._parent = model._boneGroup._children[0];
                                bone.ReferenceCount = model._objList.Count;
                                break;
                        }
                    }
                    if (model._objList != null && model._objList.Count != 0)
                        foreach (MDL0ObjectNode poly in model._objList)
                        {
                            poly._nodeId = 0;
                            poly.MatrixNode = (MDL0BoneNode)model._boneGroup._children[0]._children[0];
                        }
                }
                else
                {
                    //Check each polygon to see if it can be rigged to a single influence
                    if (model._objList != null && model._objList.Count != 0)
                        foreach (MDL0ObjectNode p in model._objList)
                        {
                            IMatrixNode node = null;
                            bool singlebind = true;

                            foreach (Vertex3 v in p._manager._vertices)
                                if (v._matrixNode != null)
                                {
                                    if (node == null)
                                        node = v._matrixNode;

                                    if (v._matrixNode != node)
                                    {
                                        singlebind = false;
                                        break;
                                    }
                                }

                            if (singlebind && p._matrixNode == null)
                            {
                                //Increase reference count ahead of time for rebuild
                                if (p._manager._vertices[0]._matrixNode != null)
                                    p._manager._vertices[0]._matrixNode.ReferenceCount++;

                                foreach (Vertex3 v in p._manager._vertices)
                                    if (v._matrixNode != null)
                                        v._matrixNode.ReferenceCount--;

                                p._nodeId = -2; //Continued on polygon rebuild
                            }
                        }
                }

                //Remove original color buffers if option set
                if (_importOptions._ignoreColors)
                {
                    if (model._objList != null && model._objList.Count != 0)
                        foreach (MDL0ObjectNode p in model._objList)
                            for (int x = 2; x < 4; x++)
                                if (p._manager._faceData[x] != null)
                                {
                                    p._manager._faceData[x].Dispose();
                                    p._manager._faceData[x] = null;
                                }
                }

                //Add color buffers if option set
                if (_importOptions._addClrs)
                {
                    RGBAPixel pixel = _importOptions._dfltClr;

                    //Add a color buffer to objects that don't have one
                    if (model._objList != null && model._objList.Count != 0)
                        foreach (MDL0ObjectNode p in model._objList)
                            if (p._manager._faceData[2] == null)
                            {
                                RGBAPixel* pIn = (RGBAPixel*)(p._manager._faceData[2] = new UnsafeBuffer(4 * p._manager._pointCount)).Address;
                                for (int i = 0; i < p._manager._pointCount; i++)
                                    *pIn++ = pixel;
                            }
                }

                //Apply defaults to materials
                if (model._matList != null)
                    foreach (MDL0MaterialNode p in model._matList)
                    {
                        if (_importOptions._mdlType == 0)
                        {
                            p._lSet = 20;
                            p._fSet = 4;
                            p._ssc = 3;

                            p.C1ColorEnabled = true;
                            p.C1AlphaMaterialSource = GXColorSrc.Vertex;
                            p.C1ColorMaterialSource = GXColorSrc.Vertex;
                            p.C1ColorDiffuseFunction = GXDiffuseFn.Clamped;
                            p.C1ColorAttenuation = GXAttnFn.Spotlight;
                            p.C1AlphaEnabled = true;
                            p.C1AlphaDiffuseFunction = GXDiffuseFn.Clamped;
                            p.C1AlphaAttenuation = GXAttnFn.Spotlight;

                            p.C2ColorDiffuseFunction = GXDiffuseFn.Disabled;
                            p.C2ColorAttenuation = GXAttnFn.None;
                            p.C2AlphaDiffuseFunction = GXDiffuseFn.Disabled;
                            p.C2AlphaAttenuation = GXAttnFn.None;
                        }
                        else
                        {
                            p._lSet = 0;
                            p._fSet = 0;
                            p._ssc = 1;

                            p._chan1.Color = new LightChannelControl(1795);
                            p._chan1.Alpha = new LightChannelControl(1795);
                            p._chan2.Color = new LightChannelControl(1795);
                            p._chan2.Alpha = new LightChannelControl(1795);
                        }
                    }

                //Set materials to use register color if option set
                if (_importOptions._useReg && model._objList != null)
                    foreach (MDL0ObjectNode p in model._objList)
                    {
                        MDL0MaterialNode m = p.OpaMaterialNode;
                        if (m != null && p._manager._faceData[2] == null && p._manager._faceData[3] == null)
                        {
                            m.C1MaterialColor = _importOptions._dfltClr;
                            m.C1ColorMaterialSource = GXColorSrc.Register;
                            m.C1AlphaMaterialSource = GXColorSrc.Register;
                        }
                    }

                //Remap materials if option set
                if (_importOptions._rmpMats && model._matList != null && model._objList != null)
                {
                    foreach (MDL0ObjectNode p in model._objList)
                        foreach (MDL0MaterialNode m in model._matList)
                            if (m.Children.Count > 0 &&
                                m.Children[0] != null &&
                                p.OpaMaterialNode != null &&
                                p.OpaMaterialNode.Children.Count > 0 &&
                                p.OpaMaterialNode.Children[0] != null &&
                                m.Children[0].Name == p.OpaMaterialNode.Children[0].Name &&
                                m.C1ColorMaterialSource == p.OpaMaterialNode.C1ColorMaterialSource)
                            {
                                p.OpaMaterialNode = m;
                                break;
                            }

                    //Remove unused materials
                    for (int i = 0; i < model._matList.Count; i++)
                        if (((MDL0MaterialNode)model._matList[i])._objects.Count == 0)
                            model._matList.RemoveAt(i--);
                }

                Error = "There was a problem writing the model.";

                //Clean the model and then build it!
                if (model != null)
                {
                    model.CleanGroups();
                    model.BuildFromScratch(this);
                }
            }
            catch (Exception x)
            {
                MessageBox.Show("Cannot continue importing this model.\n" + Error + "\n\nException:\n" + x.ToString());
                model = null;
                Close();
            }
            finally
            {
                //Clean up the mess we've made
                GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);
            }
            return model;
        }
Ejemplo n.º 9
0
        public void Render(GLContext ctx, MDL0MaterialNode node)
        {
            ctx.glEnable(GLEnableCap.FRAGMENT_PROGRAM_ARB);
            uint id;

            ctx.glGenProgramsARB(1, &id);
            if ((programHandle = id) == 0)
            {
                ctx.CheckErrors();
            }
            _context = ctx;
            int version = (int)(new string((sbyte *)ctx.glGetString(0x1F02)))[0];

            if (version < 2)
            {
                MessageBox.Show("You need at least OpenGL 2.0 to render shaders.",
                                "GLSL not supported", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
            }
            _renderChange = true;
            if (_renderChange)
            {
                //Test shader
                shader = @"uniform sampler2D samp0, samp1, samp2;
                void main(void) 
                { 
                    gl_FragColor = vec4 (1.0, 0.0, 0.0, 1.0);
                }
                ";
                vs     = @"
                void main(void)
                {
                  gl_Position = ftransform(); // gl_ModelViewProjectionMatrix * gl_Vertex;
                }
                ";
                //CreateGLSLShader(node);
            }

            if (!written)
            {
                Console.WriteLine(shader);
                written = true;
            }

            //Create shader
            fragmentHandle = (uint)_context.glCreateShader(ShaderType.FragmentShader);
            vertexHandle   = (uint)_context.glCreateShader(ShaderType.VertexShader);

            //Create program
            //shaderProgramHandle = _context.glCreateProgram();

            //Set the shader code
            _context.ShaderSource((int)fragmentHandle, shader);
            _context.ShaderSource((int)vertexHandle, vs);
            //_context.glProgramStringARB(AssemblyProgramTargetArb.FragmentProgram, OpenGL.etc.ArbVertexProgram.ProgramFormatAsciiArb, shader.Length, shader);

            //Compile the shader
            _context.glCompileShader(fragmentHandle);
            _context.glCompileShader(vertexHandle);
            //_context.glBindProgramARB(AssemblyProgramTargetArb.FragmentProgram, (int)shaderProgramHandle);

            //Attach the shader to the program
            //_context.glAttachObjectARB(shaderProgramHandle, fragmentShaderHandle);

            //Check to see if the shader compiled correctly
            //_context.GetShaderInfoLog(fragmentObject, out info);
            //_context.GetShader(fragmentObject, ShaderParameter.CompileStatus, out status_code);

            //if (status_code != 1)
            //    throw new ApplicationException(info);

            _context.glAttachShader(programHandle, fragmentHandle);
            _context.glAttachShader(programHandle, vertexHandle);
            _context.glLinkProgram(programHandle);
            _context.glUseProgram(programHandle);
            //_context.glUseProgramObjectARB(shaderProgramHandle);

            ctx.glDisable((uint)GLEnableCap.FRAGMENT_PROGRAM_ARB);
            ctx.glDisable((uint)GLEnableCap.VERTEX_PROGRAM_ARB);

            rendered = true;
        }
Ejemplo n.º 10
0
        private void CreateGLSLShader(MDL0MaterialNode m)
        {
            //Read stages and create GLSL C++ code string
            //Color and Alpha are generated seperately

            BuildSwapModeTable();
            int numStages  = Children.Count;
            int numTexgens = m.Children.Count;

            shader = "//Shader" + Index + "\n";

            shader += "uniform sampler2D";

            bool first = true;

            for (int i = 0; i < m.Children.Count; i++)
            {
                shader += String.Format("{0} samp{1}", first ? "" : ",", i);
                first   = false;
            }
            shader += ";\n";

            shader += String.Format("\n");

            shader += String.Format("uniform float4 " + I_COLORS + "[4] : register(c{0});\n", C_COLORS);
            shader += String.Format("uniform float4 " + I_KCOLORS + "[4] : register(c{0});\n", C_KCOLORS);
            shader += String.Format("uniform float4 " + I_ALPHA + "[1] : register(c{0});\n", C_ALPHA);
            shader += String.Format("uniform float4 " + I_TEXDIMS + "[8] : register(c{0});\n", C_TEXDIMS);
            shader += String.Format("uniform float4 " + I_ZBIAS + "[2] : register(c{0});\n", C_ZBIAS);
            shader += String.Format("uniform float4 " + I_INDTEXSCALE + "[2] : register(c{0});\n", C_INDTEXSCALE);
            shader += String.Format("uniform float4 " + I_INDTEXMTX + "[6] : register(c{0});\n", C_INDTEXMTX);
            shader += String.Format("uniform float4 " + I_FOG + "[3] : register(c{0});\n", C_FOG);

            shader += "\n";

            //No lighting for now

            //// shader variables
            //string I_POSNORMALMATRIX      = "cpnmtx";
            //string I_PROJECTION           = "cproj";
            //string I_MATERIALS            = "cmtrl";
            //string I_LIGHTS               = "clights";
            //string I_TEXMATRICES          = "ctexmtx";
            //string I_TRANSFORMMATRICES    = "ctrmtx";
            //string I_NORMALMATRICES       = "cnmtx";
            //string I_POSTTRANSFORMMATRICES= "cpostmtx";
            //string I_DEPTHPARAMS          = "cDepth";

            //int C_POSNORMALMATRIX         =  0;
            //int C_PROJECTION              = (C_POSNORMALMATRIX + 6);
            //int C_MATERIALS               = (C_PROJECTION + 4);
            //int C_LIGHTS                  = (C_MATERIALS + 4);
            //int C_TEXMATRICES             = (C_LIGHTS + 40);
            //int C_TRANSFORMMATRICES       = (C_TEXMATRICES + 24);
            //int C_NORMALMATRICES          = (C_TRANSFORMMATRICES + 64);
            //int C_POSTTRANSFORMMATRICES   = (C_NORMALMATRICES + 32);
            //int C_DEPTHPARAMS             = (C_POSTTRANSFORMMATRICES + 64);
            //int C_VENVCONST_END		      = (C_DEPTHPARAMS + 4);

            shader += String.Format(
                "float4 c0 = " + I_COLORS + "[1],\n" +
                "  c1 = " + I_COLORS + "[2],\n" +
                "  c2 = " + I_COLORS + "[3],\n" +
                "  prev = float4(0.0f, 0.0f, 0.0f, 0.0f),\n" +
                "  textemp = float4(0.0f, 0.0f, 0.0f, 0.0f),\n" +
                "  rastemp = float4(0.0f, 0.0f, 0.0f, 0.0f),\n" +
                "  konsttemp = float4(0.0f, 0.0f, 0.0f, 0.0f);\n" +
                "float3 comp16 = float3(1.0f, 255.0f, 0.0f),\n" +
                "  comp24 = float3(1.0f, 255.0f, 255.0f*255.0f);\n" +
                "float4 alphabump=float4(0.0f,0.0f,0.0f,0.0f);\n" +
                "float3 tevcoord=float3(0.0f, 0.0f, 0.0f);\n" +
                "float2 wrappedcoord=float2(0.0f,0.0f),\n" +
                "  tempcoord=float2(0.0f,0.0f);\n" +
                "float4 cc0=float4(0.0f,0.0f,0.0f,0.0f),\n" +
                "  cc1=float4(0.0f,0.0f,0.0f,0.0f);\n" +
                "float4 cc2=float4(0.0f,0.0f,0.0f,0.0f),\n" +
                "  cprev=float4(0.0f,0.0f,0.0f,0.0f);\n" +
                "float4 crastemp=float4(0.0f,0.0f,0.0f,0.0f),\n" +
                "  ckonsttemp=float4(0.0f,0.0f,0.0f,0.0f);\n\n");

            shader += String.Format("void main(\n");
            shader += "void";
            //shader += String.Format("  out float4 ocol0 : COLOR0,\n  in float4 rawpos : WPOS,\n");

            //    // compute window position if needed because binding semantic WPOS is not widely supported
            //if (m.Children.Count < 7)
            //{
            //    for (int i = 0; i < m.Children.Count; ++i)
            //        shader += String.Format(",\n  in float3 uv{0} : TEXCOORD{0}", i);
            //    shader += String.Format(",\n  in float4 clipPos : TEXCOORD{0}", m.Children.Count);
            //    //if(g_ActiveConfig.bEnablePixelLighting && g_ActiveConfig.backend_info.bSupportsPixelLighting)
            //        shader += String.Format(",\n  in float4 Normal : TEXCOORD{0}", m.Children.Count + 1);
            //}
            //else
            //{
            //    // wpos is in w of first 4 texcoords
            //    //if(g_ActiveConfig.bEnablePixelLighting && g_ActiveConfig.backend_info.bSupportsPixelLighting)
            //    //{
            //        for (int i = 0; i < 8; ++i)
            //            shader += String.Format(",\n  in float4 uv{0} : TEXCOORD{0}", i);
            //    //}
            //    //else
            //    //{
            //    //    for (unsigned int i = 0; i < xfregs.numTexGen.numTexGens; ++i)
            //    //        shader += String.Format(",\n  in float%d uv%d : TEXCOORD%d", i < 4 ? 4 : 3 , i, i);
            //    //}
            //}
            shader += ") {\n";

            //Get how many stages should we apply
            int active = m.ActiveShaderStages > stages ? stages : m.ActiveShaderStages;

            //Write stages to shader code
            foreach (TEVStage s in Children)
            {
                if (s.Index < active)
                {
                    shader += s.Write(m);
                }
            }

            shader += String.Format("prev.rgb = {0};\n", tevCOutputTable[(int)((TEVStage)Children[active - 1]).ColorRegister]);
            shader += String.Format("prev.a = {0};\n", tevAOutputTable[(int)((TEVStage)Children[active - 1]).AlphaRegister]);

            //Is this really necessary?
            //shader += String.Format("prev = frac(4.0f + prev * (255.0f/256.0f)) * (256.0f/255.0f);\n");

            shader += "gl_FragColor = prev;";

            //if (dstAlphaMode == DSTALPHA_ALPHA_PASS)
            //    shader += String.Format("  ocol0 = float4(prev.rgb, "I_ALPHA"[0].a);\n");
            //else
            //{
            //    WriteFog(p);
            //shader += "  ocol0 = prev;\n";
            //}

            // On D3D11, use dual-source color blending to perform dst alpha in a
            // single pass
            //if (dstAlphaMode == DSTALPHA_DUAL_SOURCE_BLEND)
            //{
            //    // Colors will be blended against the alpha from ocol1...
            //    shader += String.Format("  ocol1 = ocol0;\n");
            //    // ...and the alpha from ocol0 will be written to the framebuffer.
            //shader += "  ocol0.a = "+I_ALPHA+"[0].a;\n";
            //}

            shader += "}\n";

            _renderChange = false;
        }
Ejemplo n.º 11
0
 private static void WriteMaterial(StreamWriter writer, MDL0MaterialNode mat)
 {
     writer.WriteLine(String.Format("usemtl {0}", mat.Name));
 }
Ejemplo n.º 12
0
        public void NewMaterial()
        {
            if (_modelViewerOpen)
                return;

            MDL0Node model = ((MDL0Node)_resource);

            if (model._matGroup == null)
            {
                MDL0GroupNode g = model._matGroup;
                if (g == null)
                {
                    model.AddChild(g = new MDL0GroupNode(MDLResourceType.Materials), true);
                    model._matGroup = g; model._matList = g.Children;
                }
            }

            MDL0MaterialNode mat = new MDL0MaterialNode();
            model._matGroup.AddChild(mat);
            mat.Name = "Material" + mat.Index;
            mat.New = true;
            if (model._shadGroup == null)
            {
                MDL0GroupNode g = model._shadGroup;
                if (g == null)
                {
                    model.AddChild(g = new MDL0GroupNode(MDLResourceType.Shaders), true);
                    model._shadGroup = g; model._shadList = g.Children;
                }
            }
            if (model._shadList.Count == 0)
                NewShader();

            mat.ShaderNode = (MDL0ShaderNode)model._shadList[0];
            mat.AddChild(new MDL0MaterialRefNode() { Name = "MatRef0" });
            mat.Rebuild(true);

            BaseWrapper b = FindResource(mat, true);
            if (b != null)
                b.EnsureVisible();
        }