private SBTreeNode CreateMOBJNode(HSD_MOBJ mobj) { SBTreeNode child = new SBTreeNode("MOBJ"); child.Tag = mobj; if (mobj.Material != null) { SBTreeNode mc = new SBTreeNode("Material Color"); mc.Tag = mobj.Material; child.Nodes.Add(mc); } if (mobj.PEDesc != null) { SBTreeNode mc = new SBTreeNode("Pixel Processing"); mc.Tag = mobj.PEDesc; child.Nodes.Add(mc); } if (mobj.Textures != null) { foreach (var tex in mobj.Textures.List) { SBTreeNode mc = new SBTreeNode(tex.Flags.ToString()); mc.Tag = tex; child.Nodes.Add(mc); } } return(child); }
public SBHsdMaterial(HSD_DOBJ dobj) { _mobj = dobj.Mobj; /*if (_mobj.Textures != null) * foreach (var tex in _mobj.Textures.List) * Console.WriteLine(tex.Flags.ToString());*/ }
private void FixMOBJTexIDs(HSD_MOBJ mobj) { int index = 0; if (mobj.Textures != null) { foreach (var t in mobj.Textures.List) { t.GXTexGenSrc = 4 + index; t.TexMapID = GXTexMapID.GX_TEXMAP0 + index; index++; } } }
public void SetMOBJ(HSD_MOBJ mobj) { _mobj = mobj; // load textures if (mobj.Textures != null) { var tex = mobj.Textures.List; int index = 0; foreach (var t in tex) { var bmp = Tools.BitmapTools.RgbaToImage(t.GetDecodedImageData(), t.ImageData.Width, t.ImageData.Height); TextureList.Images.Add(bmp); listTexture.Items.Add(new TextureContainer(t) { ImageIndex = index++, }); } listTexture.AutoResizeColumn(0, ColumnHeaderAutoResizeStyle.HeaderSize); } // load material color var mc = mobj.Material; buttonAmbient.BackColor = mc.AmbientColor; buttonDiffuse.BackColor = mc.DiffuseColor; buttonSpecular.BackColor = mc.SpecularColor; tbShine.Text = mc.Shininess.ToString(); tbAlpha.Text = mc.Alpha.ToString(); // load pixel processing if (mobj.PEDesc != null) { cbEnablePP.Checked = true; } }
/// <summary> /// /// </summary> /// <param name="mobj"></param> /// <returns></returns> public HSD_Material GetMaterialState(HSD_MOBJ mobj) { HSD_Material mat = HSDAccessor.DeepClone <HSD_Material>(mobj.Material); if (Nodes.Count > JOBJIndex && Nodes[JOBJIndex].Nodes.Count > DOBJIndex) { var node = Nodes[JOBJIndex].Nodes[DOBJIndex]; foreach (var t in node.Tracks) { switch ((MatTrackType)t.TrackType) { case MatTrackType.HSD_A_M_ALPHA: mat.Alpha = t.GetValue(node.Frame); break; case MatTrackType.HSD_A_M_AMBIENT_R: mat.AMB_R = (byte)(t.GetValue(node.Frame) * 0xFF); break; case MatTrackType.HSD_A_M_AMBIENT_G: mat.AMB_G = (byte)(t.GetValue(node.Frame) * 0xFF); break; case MatTrackType.HSD_A_M_AMBIENT_B: mat.AMB_B = (byte)(t.GetValue(node.Frame) * 0xFF); break; case MatTrackType.HSD_A_M_DIFFUSE_R: mat.DIF_R = (byte)(t.GetValue(node.Frame) * 0xFF); break; case MatTrackType.HSD_A_M_DIFFUSE_G: mat.DIF_G = (byte)(t.GetValue(node.Frame) * 0xFF); break; case MatTrackType.HSD_A_M_DIFFUSE_B: mat.DIF_B = (byte)(t.GetValue(node.Frame) * 0xFF); break; case MatTrackType.HSD_A_M_SPECULAR_R: mat.SPC_R = (byte)(t.GetValue(node.Frame) * 0xFF); break; case MatTrackType.HSD_A_M_SPECULAR_G: mat.SPC_G = (byte)(t.GetValue(node.Frame) * 0xFF); break; case MatTrackType.HSD_A_M_SPECULAR_B: mat.SPC_B = (byte)(t.GetValue(node.Frame) * 0xFF); break; } } } return(mat); }
/// <summary> /// /// </summary> /// <param name="mobj"></param> /// <returns></returns> public void GetMaterialState(HSD_MOBJ mobj, ref MatAnimMaterialState state) { if (Nodes.Count > JOBJIndex && Nodes[JOBJIndex].Nodes.Count > DOBJIndex) { var node = Nodes[JOBJIndex].Nodes[DOBJIndex]; foreach (var t in node.Tracks) { switch ((MatTrackType)t.TrackType) { case MatTrackType.HSD_A_M_PE_REF0: state.Ref0 = t.GetValue(node.Frame); break; case MatTrackType.HSD_A_M_PE_REF1: state.Ref1 = t.GetValue(node.Frame); break; case MatTrackType.HSD_A_M_ALPHA: state.Alpha = t.GetValue(node.Frame); break; case MatTrackType.HSD_A_M_AMBIENT_R: state.Ambient.X = t.GetValue(node.Frame); break; case MatTrackType.HSD_A_M_AMBIENT_G: state.Ambient.Y = t.GetValue(node.Frame); break; case MatTrackType.HSD_A_M_AMBIENT_B: state.Ambient.Z = t.GetValue(node.Frame); break; case MatTrackType.HSD_A_M_DIFFUSE_R: state.Diffuse.X = t.GetValue(node.Frame); break; case MatTrackType.HSD_A_M_DIFFUSE_G: state.Diffuse.Y = t.GetValue(node.Frame); break; case MatTrackType.HSD_A_M_DIFFUSE_B: state.Diffuse.Z = t.GetValue(node.Frame); break; case MatTrackType.HSD_A_M_SPECULAR_R: state.Specular.X = t.GetValue(node.Frame); break; case MatTrackType.HSD_A_M_SPECULAR_G: state.Specular.Y = t.GetValue(node.Frame); break; case MatTrackType.HSD_A_M_SPECULAR_B: state.Specular.Z = t.GetValue(node.Frame); break; } } } }
/// <summary> /// /// </summary> /// <param name="mobj"></param> private void BindMOBJ(Shader shader, HSD_MOBJ mobj, out float wscale, out float hscale, out bool mirrorX, out bool mirrorY) { GL.Enable(EnableCap.Texture2D); GL.Enable(EnableCap.Blend); GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha); GL.Enable(EnableCap.AlphaTest); GL.AlphaFunc(AlphaFunction.Greater, 0f); wscale = 1; hscale = 1; mirrorX = false; mirrorY = false; if (mobj == null) return; var pp = mobj.PEDesc; if (pp != null) { GL.BlendFunc(GXTranslator.toBlendingFactor(pp.SrcFactor), GXTranslator.toBlendingFactor(pp.DstFactor)); GL.DepthFunc(GXTranslator.toDepthFunction(pp.DepthFunction)); GL.AlphaFunc(GXTranslator.toAlphaFunction(pp.AlphaComp0), pp.AlphaRef0 / 255f); //GL.AlphaFunc(GXTranslator.toAlphaFunction(pp.AlphaComp1), pp.AlphaRef1 / 255f); } var color = mobj.Material; if (color != null) { shader.SetVector4("ambientColor", color.AMB_R / 255f, color.AMB_G / 255f, color.AMB_B / 255f, color.AMB_A / 255f); shader.SetVector4("diffuseColor", color.DIF_R / 255f, color.DIF_G / 255f, color.DIF_B / 255f, color.DIF_A / 255f); shader.SetVector4("specularColor", color.SPC_R / 255f, color.SPC_G / 255f, color.SPC_B / 255f, color.SPC_A / 255f); shader.SetFloat("shinniness", color.Shininess); shader.SetFloat("alpha", color.Alpha); } shader.SetBoolToInt("enableTEX0", mobj.RenderFlags.HasFlag(RENDER_MODE.TEX0)); shader.SetBoolToInt("enableSpecular", mobj.RenderFlags.HasFlag(RENDER_MODE.SPECULAR)); shader.SetBoolToInt("enableDiffuse", mobj.RenderFlags.HasFlag(RENDER_MODE.DIFFUSE)); shader.SetBoolToInt("enableMaterial", mobj.RenderFlags.HasFlag(RENDER_MODE.DIFFSE_MAT)); shader.SetBoolToInt("useVertexColor", mobj.RenderFlags.HasFlag(RENDER_MODE.DIFFSE_VTX)); shader.SetInt("enableTexDiffuse", 0); shader.SetInt("texDiffuse", 0); shader.SetInt("difColorType", 0); shader.SetInt("difAlphaType", 0); shader.SetInt("diffuseCoordType", 0); shader.SetVector2("diffuseUVScale", 1, 1); // Bind Textures if (mobj.Textures != null) { foreach (var tex in mobj.Textures.List) { if (tex.ImageData == null) continue; if (!imageBufferTextureIndex.ContainsKey(tex.ImageData.ImageData)) { imageBufferTextureIndex.Add(tex.ImageData.ImageData, TextureManager.TextureCount); TextureManager.Add(tex.GetDecodedImageData(), tex.ImageData.Width, tex.ImageData.Height); } var texid = TextureManager.Get(imageBufferTextureIndex[tex.ImageData.ImageData]); GL.ActiveTexture(TextureUnit.Texture0); GL.BindTexture(TextureTarget.Texture2D, texid); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)GXTranslator.toWrapMode(tex.WrapS)); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)GXTranslator.toWrapMode(tex.WrapT)); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)GXTranslator.toMagFilter(tex.MagFilter)); wscale = tex.WScale; hscale = tex.HScale; mirrorX = tex.WrapS == GXWrapMode.MIRROR; mirrorY = tex.WrapT == GXWrapMode.MIRROR; int coordType = 0; if (tex.Flags.HasFlag(TOBJ_FLAGS.COORD_REFLECTION)) coordType = 1; shader.SetInt("enableTexDiffuse", 1); shader.SetInt("diffuseTex", 0); shader.SetInt("difColorType", 0); shader.SetInt("difAlphaType", 0); shader.SetInt("diffuseCoordType", coordType); shader.SetVector2("diffuseUVScale", wscale, hscale); break; } } }
public SBDobjAttachment() { Text = "DOBJ List"; Dock = DockStyle.Fill; //this.s ApplicationSettings.SkinControl(this); dobjList = new SBTreeView(); dobjList.Dock = DockStyle.Top; dobjList.Size = new Size(200, 200); dobjList.CheckBoxes = true; dobjList.HideSelection = false; dobjList.AfterCheck += (sender, args) => { if (args.Node != null && args.Node.Tag is SBHsdMesh mesh) { mesh.Visible = args.Node.Checked; } }; dobjList.AfterSelect += (sender, args) => { foreach (TreeNode v in dobjList.Nodes) { if (v.Tag is SBHsdMesh mesh) { mesh.Selected = false; } } propertyGrid.SelectedObject = null; if (dobjList.SelectedNode != null) { if (dobjList.SelectedNode.Tag is SBHsdMesh mesh) { mesh.Selected = true; } propertyGrid.SelectedObject = dobjList.SelectedNode.Tag; } }; propertyGrid = new PropertyGrid(); propertyGrid.Dock = DockStyle.Fill; propertyGrid.Size = new Size(200, 400); propertyGrid.SelectedObjectsChanged += (sender, args) => { removeTexture.Visible = propertyGrid.SelectedObject is HSD_TOBJ; exportTexture.Visible = propertyGrid.SelectedObject is HSD_TOBJ; importTexture.Visible = propertyGrid.SelectedObject != null; }; clearTextures = new SBButton("Clear Textures"); clearTextures.Dock = DockStyle.Top; clearTextures.Click += (sender, args) => { if (scene != null) { if (scene.HasMaterialAnimations) { MessageBox.Show("Eror: DATs with material animations must keep their textures intact"); } else { if (MessageBox.Show("Are you sure? This cannot be undone", "Clear Textures", MessageBoxButtons.OKCancel) != DialogResult.OK) { return; } //TODO: //scene.ClearMaterialAnimations(); //return; foreach (SBHsdMesh m in scene.GetMeshObjects()) { m.ClearTextures(); } RefreshList(); } } }; optionPanel = new GroupBox(); optionPanel.Text = "Options"; ApplicationSettings.SkinControl(optionPanel); optionPanel.Dock = DockStyle.Top; //AutoScroll = true; exportTexture = new SBButton("Export Texture"); exportTexture.Dock = DockStyle.Top; exportTexture.Visible = false; optionPanel.Controls.Add(exportTexture); exportTexture.Click += (sender, args) => { string filePath; if (propertyGrid.SelectedObject is HSD_TOBJ tobj) { var filter = "PNG (*.png)|*.png;"; //if (tobj.ImageData != null && tobj.ImageData.Format == GXTexFmt.CMP) // filter = "DDS (*.dds)|*.dds;"; if (FileTools.TrySaveFile(out filePath, filter)) { //TODO: dds export / import /*if (tobj.ImageData != null && tobj.ImageData.Format == GXTexFmt.CMP) * { * SBSurface s = new SBSurface(); * s.Width = tobj.ImageData.Width; * s.Height = tobj.ImageData.Height; * s.InternalFormat = OpenTK.Graphics.OpenGL.InternalFormat.CompressedRgbaS3tcDxt1Ext; * s.Arrays.Add(new MipArray() { Mipmaps = new List<byte[]>() { HSDRaw.Tools.TPLConv.ToCMP(tobj.ImageData.ImageData, tobj.ImageData.Width, tobj.ImageData.Height) } }); * * IO_DDS.Export(filePath, s); * } * else*/ { FileTools.WriteBitmapFile(filePath, tobj.ImageData.Width, tobj.ImageData.Height, tobj.GetDecodedImageData()); } } } }; removeTexture = new SBButton("Remove Texture"); removeTexture.Dock = DockStyle.Top; removeTexture.Visible = false; optionPanel.Controls.Add(removeTexture); removeTexture.Click += (sender, args) => { if (dobjList.SelectedNode.Tag is HSD_TOBJ tobj) { // remove tobj from list var mobj = (HSD_MOBJ)dobjList.SelectedNode.Parent.Tag; HSD_TOBJ prevTexture = null; if (mobj.Textures != null) { foreach (var tex in mobj.Textures.List) { if (tex._s == tobj._s) { if (prevTexture == null) { mobj.Textures = tex.Next; } else { prevTexture.Next = tex.Next; } // update texture and flag stuff break; } prevTexture = tex; } } FixMOBJTexIDs(mobj); var root = dobjList.SelectedNode.Parent.Parent; root.Nodes.Clear(); root.Nodes.Add(CreateMOBJNode(mobj)); scene.RefreshRendering(); } }; importTexture = new SBButton("Import Texture"); importTexture.Dock = DockStyle.Top; importTexture.Visible = false; optionPanel.Controls.Add(importTexture); importTexture.Click += (sender, args) => { // select texture HSD_MOBJ mobj = null; SBTreeNode root = null; if (dobjList.SelectedNode.Tag is SBHsdMesh mesh) { if (mesh.DOBJ.Mobj != null) { mobj = mesh.DOBJ.Mobj; root = (SBTreeNode)dobjList.SelectedNode; } } if (dobjList.SelectedNode.Tag is HSD_MOBJ m) { mobj = m; root = (SBTreeNode)dobjList.SelectedNode.Parent; } if (dobjList.SelectedNode.Tag is HSD_TOBJ) { if (dobjList.SelectedNode.Parent.Tag is HSD_MOBJ mo) { mobj = mo; root = (SBTreeNode)dobjList.SelectedNode.Parent.Parent; } } if (mobj == null) { return; } string filePath; if (FileTools.TryOpenFile(out filePath, "Supported Formats (*.png*.dds)|*.png;*.dds")) { var settings = new TOBJImportSettings(); // select textue import options using (SBCustomDialog d = new SBCustomDialog(settings)) { if (d.ShowDialog() == DialogResult.OK) { // create tobj and attach to selected mobj HSD_TOBJ tobj = new HSD_TOBJ(); tobj.MagFilter = GXTexFilter.GX_LINEAR; tobj.HScale = 1; tobj.WScale = 1; tobj.WrapS = GXWrapMode.REPEAT; tobj.WrapT = GXWrapMode.REPEAT; tobj.SX = 1; tobj.SY = 1; tobj.SZ = 1; if (System.IO.Path.GetExtension(filePath.ToLower()) == ".dds") { var dxtsurface = IO_DDS.Import(filePath); if (dxtsurface.InternalFormat != OpenTK.Graphics.OpenGL.InternalFormat.CompressedRgbaS3tcDxt1Ext) { throw new NotSupportedException("DDS format " + dxtsurface.InternalFormat.ToString() + " not supported"); } tobj.EncodeImageData(dxtsurface.Arrays[0].Mipmaps[0], dxtsurface.Width, dxtsurface.Height, GXTexFmt.CMP, GXTlutFmt.IA8); } else { var bmp = new Bitmap(filePath); var bitmapData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); var length = bitmapData.Stride * bitmapData.Height; byte[] bytes = new byte[length]; Marshal.Copy(bitmapData.Scan0, bytes, 0, length); bmp.UnlockBits(bitmapData); tobj.EncodeImageData(bytes, bmp.Width, bmp.Height, settings.ImageFormat, settings.PaletteFormat); bmp.Dispose(); } if (settings.UseBlending && mobj.PEDesc == null) { mobj.PEDesc = new HSD_PEDesc(); } //TODO: set flags for texture types if (settings.TextureType == TOBJTextureType.Diffuse) { mobj.RenderFlags |= RENDER_MODE.DIFFUSE; tobj.Flags |= TOBJ_FLAGS.LIGHTMAP_DIFFUSE; } if (settings.TextureType == TOBJTextureType.Specular) { mobj.RenderFlags |= RENDER_MODE.SPECULAR; tobj.Flags |= TOBJ_FLAGS.LIGHTMAP_SPECULAR; } if (settings.TextureType == TOBJTextureType.Bump) { tobj.Flags |= TOBJ_FLAGS.BUMP; } switch (settings.UVType) { case TOBJUVType.Sphere: tobj.Flags |= TOBJ_FLAGS.COORD_REFLECTION; break; case TOBJUVType.TextureCoord: tobj.Flags |= TOBJ_FLAGS.COORD_UV; break; } if (mobj.Textures == null) { mobj.Textures = tobj; tobj.Flags |= TOBJ_FLAGS.COLORMAP_REPLACE; } else { tobj.Flags |= TOBJ_FLAGS.COLORMAP_BLEND; } propertyGrid.SelectedObject = tobj; FixMOBJTexIDs(mobj); root.Nodes.Clear(); root.Nodes.Add(CreateMOBJNode(mobj)); scene.RefreshRendering(); } } } }; propertyPanel = new GroupBox(); propertyPanel.Text = "Properties"; propertyPanel.Dock = DockStyle.Top; propertyPanel.Controls.Add(propertyGrid); propertyPanel.Height = 300; ApplicationSettings.SkinControl(propertyPanel); Controls.Add(propertyPanel); Controls.Add(new Splitter() { Dock = DockStyle.Top, Height = 10, BackColor = ApplicationSettings.BGColor2 }); Controls.Add(optionPanel); Controls.Add(new Splitter() { Dock = DockStyle.Top, Height = 10, BackColor = ApplicationSettings.BGColor2 }); Controls.Add(dobjList); Controls.Add(clearTextures); }
/// <summary> /// /// </summary> /// <param name="settings"></param> /// <param name="material"></param> /// <returns></returns> private HSD_MOBJ GenerateMaterial(IOMaterial material) { // create blank mobj var Mobj = new HSD_MOBJ(); Mobj.Material = new HSD_Material() { AMB_A = 0xFF, AMB_R = 0x7F, AMB_G = 0x7F, AMB_B = 0x7F, DiffuseColor = System.Drawing.Color.White, SpecularColor = System.Drawing.Color.White, Shininess = 50, Alpha = 1 }; // detect and set flags if (Settings.ImportVertexColor) { Mobj.RenderFlags |= RENDER_MODE.VERTEX; } if (Settings.EnableDiffuse) { Mobj.RenderFlags |= RENDER_MODE.DIFFUSE; } if (Settings.EnableConstant) { Mobj.RenderFlags |= RENDER_MODE.CONSTANT; } // Properties if (material != null && Settings.ImportMaterialInfo) { Mobj.Material.Shininess = material.Shininess; Mobj.Material.Alpha = material.Alpha; Mobj.Material.AMB_R = (byte)(material.AmbientColor.X * 255); Mobj.Material.AMB_G = (byte)(material.AmbientColor.Y * 255); Mobj.Material.AMB_B = (byte)(material.AmbientColor.Z * 255); Mobj.Material.AMB_A = (byte)(material.AmbientColor.W * 255); Mobj.Material.DIF_R = (byte)(material.DiffuseColor.X * 255); Mobj.Material.DIF_G = (byte)(material.DiffuseColor.Y * 255); Mobj.Material.DIF_B = (byte)(material.DiffuseColor.Z * 255); Mobj.Material.DIF_A = (byte)(material.DiffuseColor.W * 255); Mobj.Material.SPC_R = (byte)(material.SpecularColor.X * 255); Mobj.Material.SPC_G = (byte)(material.SpecularColor.Y * 255); Mobj.Material.SPC_B = (byte)(material.SpecularColor.Z * 255); Mobj.Material.SPC_A = (byte)(material.SpecularColor.W * 255); } // Textures if (material != null && Settings.ImportTexture) { if (material.DiffuseMap != null && !string.IsNullOrEmpty(material.DiffuseMap.FilePath)) { var texturePath = material.DiffuseMap.FilePath; if (texturePath.Contains("file://")) { texturePath = texturePath.Replace("file://", ""); } if (File.Exists(Path.Combine(_cache.FolderPath, texturePath))) { texturePath = Path.Combine(_cache.FolderPath, texturePath); } if (File.Exists(material.DiffuseMap.FilePath)) { texturePath = material.DiffuseMap.FilePath; } if (File.Exists(texturePath + ".png")) { texturePath = texturePath + ".png"; } var mobjPath = Path.Combine(Path.GetDirectoryName(texturePath), Path.GetFileNameWithoutExtension(texturePath)) + ".mobj"; if (Settings.ImportMOBJ && File.Exists(mobjPath)) { var dat = new HSDRaw.HSDRawFile(mobjPath); Mobj._s = dat.Roots[0].Data._s; return(Mobj); } else /// special mobj loading if (Path.GetExtension(texturePath).ToLower() == ".mobj") { var dat = new HSDRaw.HSDRawFile(texturePath); Mobj._s = dat.Roots[0].Data._s; return(Mobj); } else if (File.Exists(texturePath) && (texturePath.ToLower().EndsWith(".png") || texturePath.ToLower().EndsWith(".bmp"))) { Mobj.RenderFlags |= RENDER_MODE.TEX0; var tobj = TOBJConverter.ImportTOBJFromFile(texturePath, Settings.TextureFormat, Settings.PaletteFormat); tobj.Flags = TOBJ_FLAGS.LIGHTMAP_DIFFUSE | TOBJ_FLAGS.COORD_UV | TOBJ_FLAGS.COLORMAP_MODULATE; tobj.GXTexGenSrc = 4; tobj.TexMapID = GXTexMapID.GX_TEXMAP0; tobj.WrapS = ToGXWrapMode(material.DiffuseMap.WrapS); tobj.WrapT = ToGXWrapMode(material.DiffuseMap.WrapT); if (TOBJConverter.IsTransparent(tobj)) { _cache.HasXLU = true; Mobj.RenderFlags |= RENDER_MODE.XLU; tobj.Flags |= TOBJ_FLAGS.ALPHAMAP_MODULATE; } Mobj.Textures = tobj; } } } return(Mobj); }
/// <summary> /// /// </summary> /// <param name="mobj"></param> public void BindMOBJ(Shader shader, HSD_MOBJ mobj, HSD_JOBJ parentJOBJ, MatAnimManager animation) { if (mobj == null) { return; } GL.Enable(EnableCap.Texture2D); GL.Enable(EnableCap.Blend); GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha); GL.Enable(EnableCap.AlphaTest); GL.AlphaFunc(AlphaFunction.Greater, 0f); GL.DepthMask(!mobj.RenderFlags.HasFlag(RENDER_MODE.NO_ZUPDATE)); // Pixel Processing shader.SetInt("alphaOp", -1); // none shader.SetInt("alphaComp0", 7); // always shader.SetInt("alphaComp1", 7); // Materials var color = mobj.Material; if (color != null) { MaterialState.Ambient.X = color.AMB_R / 255f; MaterialState.Ambient.Y = color.AMB_G / 255f; MaterialState.Ambient.Z = color.AMB_B / 255f; MaterialState.Ambient.W = color.AMB_A / 255f; MaterialState.Diffuse.X = color.DIF_R / 255f; MaterialState.Diffuse.Y = color.DIF_G / 255f; MaterialState.Diffuse.Z = color.DIF_B / 255f; MaterialState.Diffuse.W = color.DIF_A / 255f; MaterialState.Specular.X = color.SPC_R / 255f; MaterialState.Specular.Y = color.SPC_G / 255f; MaterialState.Specular.Z = color.SPC_B / 255f; MaterialState.Specular.W = color.SPC_A / 255f; MaterialState.Shininess = color.Shininess; MaterialState.Alpha = color.Alpha; if (animation != null) { animation.GetMaterialState(mobj, ref MaterialState); } shader.SetVector4("ambientColor", MaterialState.Ambient); shader.SetVector4("diffuseColor", MaterialState.Diffuse); shader.SetVector4("specularColor", MaterialState.Specular); shader.SetFloat("shinniness", MaterialState.Shininess); shader.SetFloat("alpha", MaterialState.Alpha); } var pp = mobj.PEDesc; if (pp != null) { MaterialState.Ref0 = pp.AlphaRef0 / 255f; MaterialState.Ref1 = pp.AlphaRef1 / 255f; if (animation != null) { animation.GetMaterialState(mobj, ref MaterialState); } GL.BlendFunc(GXTranslator.toBlendingFactor(pp.SrcFactor), GXTranslator.toBlendingFactor(pp.DstFactor)); GL.DepthFunc(GXTranslator.toDepthFunction(pp.DepthFunction)); shader.SetInt("alphaOp", (int)pp.AlphaOp); shader.SetInt("alphaComp0", (int)pp.AlphaComp0); shader.SetInt("alphaComp1", (int)pp.AlphaComp1); shader.SetFloat("alphaRef0", MaterialState.Ref0); shader.SetFloat("alphaRef1", MaterialState.Ref1); } var enableAll = mobj.RenderFlags.HasFlag(RENDER_MODE.DF_ALL); shader.SetBoolToInt("no_zupdate", mobj.RenderFlags.HasFlag(RENDER_MODE.NO_ZUPDATE)); shader.SetBoolToInt("enableSpecular", parentJOBJ.Flags.HasFlag(JOBJ_FLAG.SPECULAR) && mobj.RenderFlags.HasFlag(RENDER_MODE.SPECULAR)); shader.SetBoolToInt("enableDiffuse", parentJOBJ.Flags.HasFlag(JOBJ_FLAG.LIGHTING) && mobj.RenderFlags.HasFlag(RENDER_MODE.DIFFUSE)); shader.SetBoolToInt("useConstant", mobj.RenderFlags.HasFlag(RENDER_MODE.CONSTANT)); shader.SetBoolToInt("useVertexColor", mobj.RenderFlags.HasFlag(RENDER_MODE.VERTEX)); shader.SetBoolToInt("useToonShading", mobj.RenderFlags.HasFlag(RENDER_MODE.TOON)); // Textures for (int i = 0; i < MAX_TEX; i++) { shader.SetBoolToInt($"hasTEX[{i}]", mobj.RenderFlags.HasFlag(RENDER_MODE.TEX0 + (i << 4)) || enableAll); } shader.SetInt("BumpTexture", -1); //LoadTextureConstants(shader); // Bind Textures if (mobj.Textures != null) { var textures = mobj.Textures.List; for (int i = 0; i < textures.Count; i++) { if (i > MAX_TEX) { break; } var tex = textures[i]; var displayTex = tex; if (tex.ImageData == null) { continue; } var blending = tex.Blending; var transform = Matrix4.CreateScale(tex.SX, tex.SY, tex.SZ) * Matrix4.CreateFromQuaternion(Math3D.FromEulerAngles(tex.RZ, tex.RY, tex.RX)) * Matrix4.CreateTranslation(tex.TX, tex.TY, tex.TZ); if (tex.SY != 0 && tex.SX != 0 && tex.SZ != 0) { transform.Invert(); } if (animation != null) { var state = animation.GetTextureAnimState(tex); if (state != null) { displayTex = state.TOBJ; blending = state.Blending; transform = state.Transform; } } // make sure texture is loaded PreLoadTexture(displayTex); // grab texture id var texid = TextureManager.Get(imageBufferTextureIndex[displayTex.ImageData.ImageData]); // set texture GL.ActiveTexture(TextureUnit.Texture0 + i); GL.BindTexture(TextureTarget.Texture2D, texid); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)GXTranslator.toWrapMode(tex.WrapS)); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)GXTranslator.toWrapMode(tex.WrapT)); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)GXTranslator.toMagFilter(tex.MagFilter)); var wscale = tex.WScale; var hscale = tex.HScale; var mirrorX = tex.WrapS == GXWrapMode.MIRROR; var mirrorY = tex.WrapT == GXWrapMode.MIRROR; var flags = tex.Flags; int coordType = (int)flags & 0xF; int colorOP = ((int)flags >> 16) & 0xF; int alphaOP = ((int)flags >> 20) & 0xF; if (flags.HasFlag(TOBJ_FLAGS.BUMP)) { colorOP = 4; } shader.SetInt($"sampler{i}", i); shader.SetInt($"TEX[{i}].gensrc", (int)tex.GXTexGenSrc); shader.SetBoolToInt($"TEX[{i}].is_ambient", flags.HasFlag(TOBJ_FLAGS.LIGHTMAP_AMBIENT)); shader.SetBoolToInt($"TEX[{i}].is_diffuse", flags.HasFlag(TOBJ_FLAGS.LIGHTMAP_DIFFUSE)); shader.SetBoolToInt($"TEX[{i}].is_specular", flags.HasFlag(TOBJ_FLAGS.LIGHTMAP_SPECULAR)); shader.SetBoolToInt($"TEX[{i}].is_ext", flags.HasFlag(TOBJ_FLAGS.LIGHTMAP_EXT)); shader.SetBoolToInt($"TEX[{i}].is_bump", flags.HasFlag(TOBJ_FLAGS.BUMP)); shader.SetInt($"TEX[{i}].color_operation", colorOP); shader.SetInt($"TEX[{i}].alpha_operation", alphaOP); shader.SetInt($"TEX[{i}].coord_type", coordType); shader.SetFloat($"TEX[{i}].blend", blending); shader.SetBoolToInt($"TEX[{i}].mirror_fix", mirrorY); shader.SetVector2($"TEX[{i}].uv_scale", wscale, hscale); shader.SetMatrix4x4($"TEX[{i}].transform", ref transform); var tev = tex.TEV; bool useTev = tev != null && tev.active.HasFlag(TOBJ_TEVREG_ACTIVE.COLOR_TEV); shader.SetBoolToInt($"hasTev[{i}]", useTev); if (useTev) { shader.SetInt($"Tev[{i}].color_op", (int)tev.color_op); shader.SetInt($"Tev[{i}].color_bias", (int)tev.color_bias); shader.SetInt($"Tev[{i}].color_scale", (int)tev.color_scale); shader.SetBoolToInt($"Tev[{i}].color_clamp", tev.color_clamp); shader.SetInt($"Tev[{i}].color_a", (int)tev.color_a_in); shader.SetInt($"Tev[{i}].color_b", (int)tev.color_b_in); shader.SetInt($"Tev[{i}].color_c", (int)tev.color_c_in); shader.SetInt($"Tev[{i}].color_d", (int)tev.color_d_in); shader.SetInt($"Tev[{i}].alpha_op", (int)tev.alpha_op); shader.SetInt($"Tev[{i}].alpha_bias", (int)tev.alpha_bias); shader.SetInt($"Tev[{i}].alpha_scale", (int)tev.alpha_scale); shader.SetBoolToInt($"Tev[{i}].alpha_clamp", tev.alpha_clamp); shader.SetInt($"Tev[{i}].alpha_a", (int)tev.alpha_a_in); shader.SetInt($"Tev[{i}].alpha_b", (int)tev.alpha_b_in); shader.SetInt($"Tev[{i}].alpha_c", (int)tev.alpha_c_in); shader.SetInt($"Tev[{i}].alpha_d", (int)tev.alpha_d_in); shader.SetColor($"Tev[{i}].konst", tev.constant, tev.constantAlpha); shader.SetColor($"Tev[{i}].tev0", tev.tev0, tev.tev0Alpha); shader.SetColor($"Tev[{i}].tev1", tev.tev1, tev.tev1Alpha); } } } }
/// <summary> /// /// </summary> /// <param name="settings"></param> /// <param name="material"></param> /// <returns></returns> private static HSD_MOBJ GenerateMaterial(ProcessingCache cache, ModelImportSettings settings, Material material) { var Mobj = new HSD_MOBJ(); Mobj.Material = new HSD_Material(); Mobj.Material.AmbientColorRGBA = 0x7F7F7FFF; Mobj.Material.DiffuseColorRGBA = 0xFFFFFFFF; Mobj.Material.SpecularColorRGBA = 0xFFFFFFFF; Mobj.Material.Shininess = 1; Mobj.Material.Alpha = 1; Mobj.RenderFlags = RENDER_MODE.ALPHA_COMPAT | RENDER_MODE.DIFFSE_VTX; // Properties if (settings.ImportMaterialInfo) { if (material.HasShininess) { Mobj.Material.Shininess = material.Shininess; } if (material.HasColorAmbient) { Mobj.Material.AMB_A = ColorFloatToByte(material.ColorAmbient.A); Mobj.Material.AMB_R = ColorFloatToByte(material.ColorAmbient.R); Mobj.Material.AMB_G = ColorFloatToByte(material.ColorAmbient.G); Mobj.Material.AMB_B = ColorFloatToByte(material.ColorAmbient.B); } if (material.HasColorDiffuse) { Mobj.Material.DIF_A = ColorFloatToByte(material.ColorDiffuse.A); Mobj.Material.DIF_R = ColorFloatToByte(material.ColorDiffuse.R); Mobj.Material.DIF_G = ColorFloatToByte(material.ColorDiffuse.G); Mobj.Material.DIF_B = ColorFloatToByte(material.ColorDiffuse.B); } if (material.HasColorSpecular) { Mobj.Material.SPC_A = ColorFloatToByte(material.ColorSpecular.A); Mobj.Material.SPC_R = ColorFloatToByte(material.ColorSpecular.R); Mobj.Material.SPC_G = ColorFloatToByte(material.ColorSpecular.G); Mobj.Material.SPC_B = ColorFloatToByte(material.ColorSpecular.B); } } // Textures if (settings.ImportTexture) { if (material.HasTextureDiffuse) { var texturePath = Path.Combine(cache.FolderPath, material.TextureDiffuse.FilePath); if (File.Exists(material.TextureDiffuse.FilePath)) { texturePath = material.TextureDiffuse.FilePath; } /// special mobj loading if (Path.GetExtension(texturePath).ToLower() == ".mobj") { var dat = new HSDRaw.HSDRawFile(texturePath); Mobj._s = dat.Roots[0].Data._s; return(Mobj); } else if (File.Exists(texturePath)) { Mobj.RenderFlags |= RENDER_MODE.TEX0; var tobj = TOBJConverter.ImportTOBJFromFile(texturePath, settings.TextureFormat, settings.PaletteFormat); tobj.Flags = TOBJ_FLAGS.LIGHTMAP_DIFFUSE | TOBJ_FLAGS.COORD_UV; if (settings.ShadingType == ShadingType.VertexColor || settings.ShadingType == ShadingType.Material) { tobj.Flags |= TOBJ_FLAGS.COLORMAP_MODULATE; } else { tobj.Flags |= TOBJ_FLAGS.COLORMAP_REPLACE; } tobj.GXTexGenSrc = 4; tobj.TexMapID = GXTexMapID.GX_TEXMAP0; tobj.WrapS = ToGXWrapMode(material.TextureDiffuse.WrapModeU); tobj.WrapT = ToGXWrapMode(material.TextureDiffuse.WrapModeV); Mobj.Textures = tobj; } } } return(Mobj); }