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); }
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; } }
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; }
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; }
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); }
//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; }
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; }
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; }
private static void WriteMaterial(StreamWriter writer, MDL0MaterialNode mat) { writer.WriteLine(String.Format("usemtl {0}", mat.Name)); }
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(); }