コード例 #1
0
        private void ExportDds(string filename, NutTexture tex)
        {
            Dds dds = new Dds();

            dds.FromNutTexture(tex);
            dds.Save(filename);
        }
コード例 #2
0
 private void SetGeneralAndDimensionsText(NutTexture tex)
 {
     textureIdTB.Text = tex.ToString();
     formatLabel.Text = "Format: " + (tex.pixelInternalFormat == PixelInternalFormat.Rgba ? "" + tex.pixelFormat : "" + tex.pixelInternalFormat);
     widthLabel.Text  = "Width: " + tex.Width;
     heightLabel.Text = "Height:" + tex.Height;
 }
コード例 #3
0
        private void ExportPng(string filename, NutTexture tex)
        {
            if (tex.surfaces[0].mipmaps.Count > 1)
            {
                MessageBox.Show("Note: Textures exported as PNG do not preserve mipmaps.");
            }

            switch (tex.pixelFormat)
            {
            case OpenTK.Graphics.OpenGL.PixelFormat.Rgba:
                Pixel.fromRGBA(new FileData(tex.surfaces[0].mipmaps[0]), tex.Width, tex.Height).Save(filename);
                break;

            case OpenTK.Graphics.OpenGL.PixelFormat.AbgrExt:
                Pixel.fromABGR(new FileData(tex.surfaces[0].mipmaps[0]), tex.Width, tex.Height).Save(filename);
                break;

            case OpenTK.Graphics.OpenGL.PixelFormat.Bgra:
                Pixel.fromBGRA(new FileData(tex.surfaces[0].mipmaps[0]), tex.Width, tex.Height).Save(filename);
                break;

            default:
                RenderTextureToPng(tex, filename, true, true, true, true);
                break;
            }
        }
コード例 #4
0
        private void ImportBack(string filename)
        {
            if (dontModify)
            {
                return;
            }

            NutTexture tex = textureFromFile[filename];

            try
            {
                Dds        dds  = new Dds(new FileData(filename));
                NutTexture ntex = dds.ToNutTexture();

                tex.Height = ntex.Height;
                tex.Width  = ntex.Width;
                tex.pixelInternalFormat = ntex.pixelInternalFormat;
                tex.surfaces            = ntex.surfaces;
                tex.pixelFormat         = ntex.pixelFormat;

                //GL.DeleteTexture(NUT.glTexByHashId[tex.HASHID]);
                currentNut.glTexByHashId.Remove(tex.HashId);
                currentNut.glTexByHashId.Add(tex.HashId, NUT.CreateTexture2D(tex));

                FillForm();
                textureListBox.SelectedItem = tex;
                glControl1.Invalidate();
            }
            catch
            {
                Console.WriteLine("Could not be open for editing");
            }
        }
コード例 #5
0
        public static Texture2D CreateTexture2D(NutTexture nutTexture, int surfaceIndex = 0)
        {
            bool compressedFormatWithMipMaps = TextureFormatTools.IsCompressed(nutTexture.pixelInternalFormat);

            List <byte[]> mipmaps = nutTexture.surfaces[surfaceIndex].mipmaps;

            if (compressedFormatWithMipMaps)
            {
                // HACK: Skip loading mipmaps for non square textures for now.
                // The existing mipmaps don't display properly for some reason.
                if (nutTexture.surfaces[0].mipmaps.Count > 1 && nutTexture.isDds && (nutTexture.Width == nutTexture.Height))
                {
                    // Reading mipmaps past the first level is only supported for DDS currently.
                    Texture2D texture = new Texture2D();
                    texture.LoadImageData(nutTexture.Width, nutTexture.Height, nutTexture.surfaces[surfaceIndex].mipmaps,
                                          (InternalFormat)nutTexture.pixelInternalFormat);
                    return(texture);
                }
                else
                {
                    // Only load the first level and generate the rest.
                    Texture2D texture = new Texture2D();
                    texture.LoadImageData(nutTexture.Width, nutTexture.Height, mipmaps[0], (InternalFormat)nutTexture.pixelInternalFormat);
                    return(texture);
                }
            }
            else
            {
                // Uncompressed.
                Texture2D texture = new Texture2D();
                texture.LoadImageData(nutTexture.Width, nutTexture.Height, mipmaps[0],
                                      new TextureFormatUncompressed(nutTexture.pixelInternalFormat, nutTexture.pixelFormat, nutTexture.pixelType));
                return(texture);
            }
        }
コード例 #6
0
        public static void RegenerateMipmapsFromTexture2D(NutTexture tex)
        {
            if (!TextureFormatTools.IsCompressed(tex.pixelInternalFormat))
            {
                return;
            }

            Rendering.OpenTkSharedResources.dummyResourceWindow.MakeCurrent();

            // Create an OpenGL texture with generated mipmaps.
            Texture2D texture2D = new Texture2D();

            texture2D.LoadImageData(tex.Width, tex.Height, tex.surfaces[0].mipmaps[0], (InternalFormat)tex.pixelInternalFormat);

            texture2D.Bind();

            for (int i = 0; i < tex.surfaces[0].mipmaps.Count; i++)
            {
                // Get the image size for the current mip level of the bound texture.
                int imageSize;
                GL.GetTexLevelParameter(TextureTarget.Texture2D, i,
                                        GetTextureParameter.TextureCompressedImageSize, out imageSize);

                byte[] mipLevelData = new byte[imageSize];

                // Replace the Nut texture with the OpenGL texture's data.
                GL.GetCompressedTexImage(TextureTarget.Texture2D, i, mipLevelData);
                tex.surfaces[0].mipmaps[i] = mipLevelData;
            }
        }
コード例 #7
0
 private void SetCubeMapText(NutTexture tex)
 {
     // Display the current face instead of mip map information.
     mipmapGroupBox.Text = "Cube Map Faces";
     SetCurrentCubeMapFaceLabel(mipLevelTrackBar.Value);
     mipLevelTrackBar.Maximum = tex.surfaces.Count - 1;
     minMipLevelLabel.Text    = "";
     maxMipLevelLabel.Text    = "";
 }
コード例 #8
0
 private void RemoveToolStripMenuItem1_Click_1(object sender, EventArgs e)
 {
     if (textureListBox.SelectedIndex >= 0 && currentNut != null)
     {
         NutTexture tex = ((NutTexture)textureListBox.SelectedItem);
         currentNut.glTexByHashId.Remove(tex.HashId);
         currentNut.Nodes.Remove(tex);
         FillForm();
     }
 }
コード例 #9
0
        public bool getTextureByID(int hash, out NutTexture suc)
        {
            suc = null;
            foreach (NutTexture t in Nodes)
            {
                if (t.HashId == hash)
                {
                    suc = t;
                    return(true);
                }
            }

            return(false);
        }
コード例 #10
0
        private void SetMipMapText(NutTexture tex)
        {
            // Display the total mip maps.
            mipmapGroupBox.Text = "Mipmaps";
            mipLevelLabel.Text  = "Mip Level";

            mipLevelTrackBar.Maximum = tex.surfaces[0].mipmaps.Count - 1;
            int newMipLevel = Math.Min(currentMipLevel, mipLevelTrackBar.Maximum);

            mipLevelTrackBar.Value = newMipLevel;

            minMipLevelLabel.Text = "1";
            maxMipLevelLabel.Text = "Total:" + tex.surfaces[0].mipmaps.Count + "";
        }
コード例 #11
0
        private void replaceToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (currentNut == null || textureListBox.SelectedItem == null)
            {
                return;
            }
            using (var ofd = new OpenFileDialog())
            {
                NutTexture texture = (NutTexture)(textureListBox.SelectedItem);

                ofd.Filter = "Supported Formats|*.dds;*.png|" +
                             "DirectDraw Surface (.dds)|*.dds|" +
                             "Portable Network Graphics (.png)|*.png|" +
                             "All files(*.*)|*.*";

                if (ofd.ShowDialog() == DialogResult.OK)
                {
                    NutTexture newTexture = null;
                    string     extension  = Path.GetExtension(ofd.FileName).ToLowerInvariant();
                    if (extension == ".dds")
                    {
                        Dds dds = new Dds(new FileData(ofd.FileName));
                        newTexture = dds.ToNutTexture();
                    }
                    else if (extension == ".png")
                    {
                        newTexture = FromPng(ofd.FileName, 1);
                    }
                    else
                    {
                        return;
                    }

                    texture.Height = newTexture.Height;
                    texture.Width  = newTexture.Width;
                    texture.pixelInternalFormat = newTexture.pixelInternalFormat;
                    texture.surfaces            = newTexture.surfaces;
                    texture.pixelFormat         = newTexture.pixelFormat;

                    Edited = true;

                    //GL.DeleteTexture(NUT.glTexByHashId[texture.HASHID]);
                    currentNut.glTexByHashId.Remove(texture.HashId);
                    currentNut.glTexByHashId.Add(texture.HashId, NUT.CreateTexture2D(texture));

                    FillForm();
                }
            }
        }
コード例 #12
0
        private void RenderTextureToPng(NutTexture nutTexture, string outputPath, bool r = true, bool g = true, bool b = true, bool a = false)
        {
            if (OpenTkSharedResources.SetupStatus != OpenTkSharedResources.SharedResourceStatus.Initialized || glControl1 == null)
            {
                return;
            }

            // Load the OpenGL texture and export the image data.
            Texture2D texture = (Texture2D)currentNut.glTexByHashId[nutTexture.HashId];

            using (Bitmap image = Rendering.TextureToBitmap.RenderBitmap(texture, r, g, b, a))
            {
                image.Save(outputPath);
            }
        }
コード例 #13
0
        private void mipLevelTrackBar_Scroll(object sender, EventArgs e)
        {
            NutTexture tex = ((NutTexture)textureListBox.SelectedItem);

            if (tex.surfaces.Count == 6)
            {
                // Create a new texture for the selected surface at the first mip level.
                currentMipLevel = 0;
                SetCurrentCubeMapFaceLabel(mipLevelTrackBar.Value);
                textureToRender = NUT.CreateTexture2D(tex, mipLevelTrackBar.Value);
            }
            else
            {
                // Regular texture.
                currentMipLevel = mipLevelTrackBar.Value;
            }

            glControl1.Invalidate();
        }
コード例 #14
0
        private void exportTextureToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (currentNut == null || textureListBox.SelectedItem == null)
            {
                return;
            }

            using (var sfd = new SaveFileDialog())
            {
                NutTexture tex = (NutTexture)(textureListBox.SelectedItem);

                sfd.FileName = tex.ToString() + ".dds";

                // OpenGL is used for simplifying conversion to PNG.
                if (OpenTkSharedResources.SetupStatus == OpenTkSharedResources.SharedResourceStatus.Initialized)
                {
                    sfd.Filter = "Supported Formats|*.dds;*.png|" +
                                 "DirectDraw Surface (.dds)|*.dds|" +
                                 "Portable Network Graphics (.png)|*.png|" +
                                 "All files(*.*)|*.*";
                }
                else
                {
                    sfd.Filter = "DirectDraw Surface (.dds)|*.dds|" +
                                 "All files(*.*)|*.*";
                }

                if (sfd.ShowDialog() == DialogResult.OK)
                {
                    string extension = Path.GetExtension(sfd.FileName).ToLowerInvariant();

                    if (extension == ".dds")
                    {
                        ExportDds(sfd.FileName, tex);
                    }
                    else if (extension == ".png")
                    {
                        ExportPng(sfd.FileName, tex);
                    }
                }
            }
        }
コード例 #15
0
        public void ConvertToDdsNut(bool regenerateMipMaps = true)
        {
            for (int i = 0; i < Nodes.Count; i++)
            {
                NutTexture originalTexture = (NutTexture)Nodes[i];

                // Reading/writing mipmaps is only supported for DDS textures,
                // so we will need to convert all the textures.
                Dds        dds        = new Dds(originalTexture);
                NutTexture ddsTexture = dds.ToNutTexture();
                ddsTexture.HashId = originalTexture.HashId;

                if (regenerateMipMaps)
                {
                    RegenerateMipmapsFromTexture2D(ddsTexture);
                }

                Nodes[i] = ddsTexture;
            }
        }
コード例 #16
0
 public static TextureCubeMap CreateTextureCubeMap(NutTexture t)
 {
     if (TextureFormatTools.IsCompressed(t.pixelInternalFormat))
     {
         // Compressed cubemap with mipmaps.
         TextureCubeMap texture = new TextureCubeMap();
         texture.LoadImageData(t.Width, (InternalFormat)t.pixelInternalFormat,
                               t.surfaces[0].mipmaps, t.surfaces[1].mipmaps, t.surfaces[2].mipmaps,
                               t.surfaces[3].mipmaps, t.surfaces[4].mipmaps, t.surfaces[5].mipmaps);
         return(texture);
     }
     else
     {
         // Uncompressed cube map with no mipmaps.
         TextureCubeMap texture = new TextureCubeMap();
         texture.LoadImageData(t.Width, new TextureFormatUncompressed(t.pixelInternalFormat, t.pixelFormat, t.pixelType),
                               t.surfaces[0].mipmaps[0], t.surfaces[1].mipmaps[0], t.surfaces[2].mipmaps[0],
                               t.surfaces[3].mipmaps[0], t.surfaces[4].mipmaps[0], t.surfaces[5].mipmaps[0]);
         return(texture);
     }
 }
コード例 #17
0
        private void RegenerateMipMaps_Click(object sender, EventArgs e)
        {
            if (OpenTkSharedResources.SetupStatus != OpenTkSharedResources.SharedResourceStatus.Initialized)
            {
                return;
            }

            if (textureListBox.SelectedItem != null)
            {
                NutTexture tex = ((NutTexture)textureListBox.SelectedItem);
                NUT.RegenerateMipmapsFromTexture2D(tex);

                // Render the selected texture again.
                currentNut.RefreshGlTexturesByHashId();
                if (currentNut.glTexByHashId.ContainsKey(tex.HashId))
                {
                    textureToRender = currentNut.glTexByHashId[tex.HashId];
                }

                glControl1.Invalidate();
            }
        }
コード例 #18
0
        public static NutTexture FromPng(string fname, int mipcount)
        {
            Bitmap     bmp = new Bitmap(fname);
            NutTexture tex = new NutTexture();

            tex.surfaces.Add(new TextureSurface());
            tex.surfaces[0].mipmaps.Add(FromPng(bmp));
            for (int i = 1; i < mipcount; i++)
            {
                if (bmp.Width / (int)Math.Pow(2, i) < 4 || bmp.Height / (int)Math.Pow(2, i) < 4)
                {
                    break;
                }
                tex.surfaces[0].mipmaps.Add(FromPng(Pixel.ResizeImage(bmp, bmp.Width / (int)Math.Pow(2, i), bmp.Height / (int)Math.Pow(2, i))));
            }
            tex.Width  = bmp.Width;
            tex.Height = bmp.Height;
            tex.pixelInternalFormat = PixelInternalFormat.Rgba;
            tex.pixelFormat         = OpenTK.Graphics.OpenGL.PixelFormat.Rgba;

            return(tex);
        }
コード例 #19
0
        private void textureListBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (textureListBox.SelectedIndex >= 0)
            {
                NutTexture tex = ((NutTexture)textureListBox.SelectedItem);
                if (tex == null)
                {
                    return;
                }

                // Render the selected texture.
                if (currentNut.glTexByHashId.ContainsKey(tex.HashId))
                {
                    textureToRender = currentNut.glTexByHashId[tex.HashId];
                }

                SetGeneralAndDimensionsText(tex);

                if (tex.surfaces.Count == 6)
                {
                    SetCubeMapText(tex);
                    if (OpenTkSharedResources.SetupStatus == OpenTkSharedResources.SharedResourceStatus.Initialized)
                    {
                        RenderTools.dummyTextures[Filetypes.Models.Nuds.NudEnums.DummyTexture.StageMapHigh] = NUT.CreateTextureCubeMap(tex);
                    }
                }
                else
                {
                    SetMipMapText(tex);
                }
            }
            else
            {
                SetDefaultGeneralAndDimensionsText();
            }

            // Render on index changed rather than every frame.
            glControl1.Invalidate();
        }
コード例 #20
0
 private NUT ReplaceTexture(NutTexture tex, int width, int height, NUT nut)
 {
     if (tex.Width == width && tex.Height == height)
     {
         tex.HashId = 0x280052B7;
         if (nut != null && nut.Nodes.Count > 0)
         {
             tex.HashId = ((NutTexture)nut.Nodes[0]).HashId;
         }
         if (nut == null)
         {
             nut = new NUT();
         }
         nut.Nodes.Clear();
         nut.glTexByHashId.Clear();
         nut.Nodes.Add(tex);
         nut.glTexByHashId.Add(tex.HashId, NUT.CreateTexture2D(tex));
     }
     else
     {
         MessageBox.Show("Dimensions must be " + width + "x" + height);
     }
     return(nut);
 }
コード例 #21
0
        public void ReadNTP3(FileData d)
        {
            d.Seek(0x6);

            ushort count = d.ReadUShort();

            d.Skip(0x8);
            int headerPtr = 0x10;

            for (ushort i = 0; i < count; ++i)
            {
                d.Seek(headerPtr);

                NutTexture tex = new NutTexture();
                tex.isDds = true;
                tex.pixelInternalFormat = PixelInternalFormat.Rgba32ui;

                int totalSize = d.ReadInt();
                d.Skip(4);
                int dataSize   = d.ReadInt();
                int headerSize = d.ReadUShort();
                d.Skip(2);

                //It might seem that mipmapCount and pixelFormat would be shorts, but they're bytes because they stay in the same place regardless of endianness
                d.Skip(1);
                byte mipmapCount = d.ReadByte();
                d.Skip(1);
                tex.setPixelFormatFromNutFormat(d.ReadByte());
                tex.Width  = d.ReadUShort();
                tex.Height = d.ReadUShort();
                d.Skip(4); //0 in dds nuts (like NTP3) and 1 in gtx nuts; texture type?
                uint caps2 = d.ReadUInt();

                bool isCubemap    = false;
                byte surfaceCount = 1;
                if ((caps2 & (uint)Dds.Ddscaps2.Cubemap) == (uint)Dds.Ddscaps2.Cubemap)
                {
                    //Only supporting all six faces
                    if ((caps2 & (uint)Dds.Ddscaps2.CubemapAllfaces) == (uint)Dds.Ddscaps2.CubemapAllfaces)
                    {
                        isCubemap    = true;
                        surfaceCount = 6;
                    }
                    else
                    {
                        throw new NotImplementedException($"Unsupported cubemap face amount for texture {i} with hash 0x{tex.HashId:X}. Six faces are required.");
                    }
                }

                int dataOffset = 0;
                if (Version < 0x0200)
                {
                    dataOffset = headerPtr + headerSize;
                    d.ReadInt();
                }
                else if (Version >= 0x0200)
                {
                    dataOffset = d.ReadInt() + headerPtr;
                }
                d.ReadInt();
                d.ReadInt();
                d.ReadInt();

                //The size of a single cubemap face (discounting mipmaps). I don't know why it is repeated. If mipmaps are present, this is also specified in the mipSize section anyway.
                int cmapSize1 = 0;
                int cmapSize2 = 0;
                if (isCubemap)
                {
                    cmapSize1 = d.ReadInt();
                    cmapSize2 = d.ReadInt();
                    d.Skip(8);
                }

                int[] mipSizes = new int[mipmapCount];
                if (mipmapCount == 1)
                {
                    if (isCubemap)
                    {
                        mipSizes[0] = cmapSize1;
                    }
                    else
                    {
                        mipSizes[0] = dataSize;
                    }
                }
                else
                {
                    for (byte mipLevel = 0; mipLevel < mipmapCount; ++mipLevel)
                    {
                        mipSizes[mipLevel] = d.ReadInt();
                    }
                    d.Align(0x10);
                }

                d.Skip(0x10); //eXt data - always the same

                d.Skip(4);    //GIDX
                d.ReadInt();  //Always 0x10
                tex.HashId = d.ReadInt();
                d.Skip(4);    // padding align 8

                for (byte surfaceLevel = 0; surfaceLevel < surfaceCount; ++surfaceLevel)
                {
                    TextureSurface surface = new TextureSurface();
                    for (byte mipLevel = 0; mipLevel < mipmapCount; ++mipLevel)
                    {
                        byte[] texArray = d.GetSection(dataOffset, mipSizes[mipLevel]);
                        surface.mipmaps.Add(texArray);
                        dataOffset += mipSizes[mipLevel];
                    }
                    tex.surfaces.Add(surface);
                }

                if (tex.getNutFormat() == 14 || tex.getNutFormat() == 17)
                {
                    tex.SwapChannelOrderUp();
                }

                if (Version < 0x0200)
                {
                    headerPtr += totalSize;
                }
                else if (Version >= 0x0200)
                {
                    headerPtr += headerSize;
                }

                Nodes.Add(tex);
            }
        }
コード例 #22
0
        public void FromNutTexture(NutTexture tex)
        {
            header                   = new Header();
            header.flags             = (uint)(Ddsd.Caps | Ddsd.Height | Ddsd.Width | Ddsd.Pixelformat | Ddsd.Mipmapcount | Ddsd.Linearsize);
            header.width             = (uint)tex.Width;
            header.height            = (uint)tex.Height;
            header.pitchOrLinearSize = (uint)tex.ImageSize;
            header.mipmapCount       = (uint)tex.surfaces[0].mipmaps.Count;
            header.caps2             = tex.DdsCaps2;
            bool isCubemap = (header.caps2 & (uint)Ddscaps2.Cubemap) == (uint)Ddscaps2.Cubemap;

            header.caps = (uint)Ddscaps.Texture;
            if (header.mipmapCount > 1)
            {
                header.caps |= (uint)(Ddscaps.Complex | Ddscaps.Mipmap);
            }
            if (isCubemap)
            {
                header.caps |= (uint)Ddscaps.Complex;
            }

            switch (tex.pixelInternalFormat)
            {
            case PixelInternalFormat.CompressedRgbaS3tcDxt1Ext:
                header.ddspf.fourCc = 0x31545844;
                header.ddspf.flags  = (uint)Ddpf.Fourcc;
                break;

            case PixelInternalFormat.CompressedRgbaS3tcDxt3Ext:
                header.ddspf.fourCc = 0x33545844;
                header.ddspf.flags  = (uint)Ddpf.Fourcc;
                break;

            case PixelInternalFormat.CompressedRgbaS3tcDxt5Ext:
                header.ddspf.fourCc = 0x35545844;
                header.ddspf.flags  = (uint)Ddpf.Fourcc;
                break;

            case PixelInternalFormat.CompressedRedRgtc1:
                header.ddspf.fourCc = 0x31495441;
                header.ddspf.flags  = (uint)Ddpf.Fourcc;
                break;

            case PixelInternalFormat.CompressedRgRgtc2:
                header.ddspf.fourCc = 0x32495441;
                header.ddspf.flags  = (uint)Ddpf.Fourcc;
                break;

            case PixelInternalFormat.Rgba:
                header.ddspf.fourCc = 0x00000000;
                if (tex.pixelFormat == OpenTK.Graphics.OpenGL.PixelFormat.Rgba)
                {
                    header.ddspf.flags       = (uint)(Ddpf.Rgb | Ddpf.Alphapixels);
                    header.ddspf.rgbBitCount = 0x8 * 4;
                    header.ddspf.rBitMask    = 0x000000FF;
                    header.ddspf.gBitMask    = 0x0000FF00;
                    header.ddspf.bBitMask    = 0x00FF0000;
                    header.ddspf.aBitMask    = 0xFF000000;
                }
                break;

            default:
                throw new NotImplementedException($"Unknown pixel format 0x{tex.pixelInternalFormat:X}");
            }

            List <byte> d = new List <byte>();

            foreach (byte[] b in tex.GetAllMipmaps())
            {
                d.AddRange(b);
            }
            bdata = d.ToArray();
        }
コード例 #23
0
        private void LetsDance(object sender, EventArgs e)
        {
            Control c = MainForm.Instance.GetActiveModelViewport();

            if (!(c is ModelViewport))
            {
                return;
            }
            ModelViewport view = (ModelViewport)c;

            view.currentMode = ModelViewport.Mode.Normal;

            NUT n = null;

            if (((MenuItem)sender).GetContextMenu().SourceControl == stock_90_renderer)
            {
                n = stock90;
            }
            if (((MenuItem)sender).GetContextMenu().SourceControl == chr_00_renderer)
            {
                n = chr00;
            }
            if (((MenuItem)sender).GetContextMenu().SourceControl == chr_11_renderer)
            {
                n = chr11;
            }
            if (((MenuItem)sender).GetContextMenu().SourceControl == chr_13_renderer)
            {
                n = chr13;
            }
            if (n == null)
            {
                return;
            }

            byte[] data = RenderTools.DXT5ScreenShot(view.glViewport, view.shootX, view.shootY, view.shootWidth, view.shootHeight);
            int    id   = n.Nodes.Count > 0 ? ((NutTexture)n.Nodes[0]).HashId : 0x280052B7;

            n.Nodes.Clear();
            n.glTexByHashId.Clear();

            NutTexture tex = new NutTexture();

            tex.Width  = view.shootWidth;
            tex.Height = view.shootHeight;
            tex.surfaces.Add(new TextureSurface());
            tex.surfaces[0].mipmaps.Add(FlipDxt5(data, tex.Width, tex.Height));
            tex.pixelInternalFormat = PixelInternalFormat.CompressedRgbaS3tcDxt5Ext;
            tex.HashId = id;
            n.Nodes.Add(tex);
            n.glTexByHashId.Add(tex.HashId, NUT.CreateTexture2D(tex));
            ((MenuItem)sender).GetContextMenu().SourceControl.Invalidate();

            if (((MenuItem)sender).GetContextMenu().SourceControl == stock_90_renderer)
            {
                if (stock90Loc != null)
                {
                    stock90.Save(stock90Loc);
                }
            }
            if (((MenuItem)sender).GetContextMenu().SourceControl == chr_00_renderer)
            {
                if (chr00Loc != null)
                {
                    chr00.Save(chr00Loc);
                }
            }
            if (((MenuItem)sender).GetContextMenu().SourceControl == chr_11_renderer)
            {
                if (chr11Loc != null)
                {
                    chr11.Save(chr13Loc);
                }
            }
            if (((MenuItem)sender).GetContextMenu().SourceControl == chr_13_renderer)
            {
                if (chr13Loc != null)
                {
                    chr13.Save(chr13Loc);
                }
            }
        }
コード例 #24
0
        private void ImportNutFromFolder(object sender, EventArgs e)
        {
            using (FolderSelectDialog f = new FolderSelectDialog())
            {
                if (f.ShowDialog() == DialogResult.OK)
                {
                    Edited = true;
                    if (!Directory.Exists(f.SelectedPath))
                    {
                        Directory.CreateDirectory(f.SelectedPath);
                    }
                    NUT nut;
                    nut = currentNut;

                    foreach (var texPath in Directory.GetFiles(f.SelectedPath))
                    {
                        string extension = Path.GetExtension(texPath).ToLowerInvariant();
                        if (!(extension == ".dds" || extension == ".png"))
                        {
                            continue;
                        }
                        int  texId;
                        bool isTex = int.TryParse(Path.GetFileNameWithoutExtension(texPath), NumberStyles.HexNumber,
                                                  new CultureInfo("en-US"), out texId);

                        NutTexture texture = null;
                        if (isTex)
                        {
                            foreach (NutTexture tex in nut.Nodes)
                            {
                                if (tex.HashId == texId)
                                {
                                    texture = tex;
                                }
                            }
                        }

                        if (texture == null)
                        {
                            //new texture
                            NutTexture tex = null;
                            if (extension == ".dds")
                            {
                                Dds dds = new Dds(new FileData(texPath));
                                tex = dds.ToNutTexture();
                            }
                            else if (extension == ".png")
                            {
                                tex = FromPng(texPath, 1);
                            }

                            if (isTex)
                            {
                                tex.HashId = texId;
                            }
                            else
                            {
                                tex.HashId = nut.Nodes.Count;
                            }
                            nut.Nodes.Add(tex);
                            currentNut.glTexByHashId.Add(tex.HashId, NUT.CreateTexture2D(tex));
                            FillForm();
                        }
                        else
                        {
                            //existing texture
                            NutTexture tex = texture;

                            NutTexture ntex = null;
                            if (extension == ".dds")
                            {
                                Dds dds = new Dds(new FileData(texPath));
                                ntex = dds.ToNutTexture();
                            }
                            else if (extension == ".png")
                            {
                                ntex = FromPng(texPath, 1);
                            }

                            tex.Height = ntex.Height;
                            tex.Width  = ntex.Width;
                            tex.pixelInternalFormat = ntex.pixelInternalFormat;
                            tex.surfaces            = ntex.surfaces;
                            tex.pixelFormat         = ntex.pixelFormat;

                            //GL.DeleteTexture(NUT.glTexByHashId[tex.HASHID]);
                            currentNut.glTexByHashId.Remove(tex.HashId);
                            currentNut.glTexByHashId.Add(tex.HashId, NUT.CreateTexture2D(tex));
                            FillForm();
                        }
                    }
                    if (!Runtime.textureContainers.Contains(nut))
                    {
                        Runtime.textureContainers.Add(nut);
                    }
                }
            }
            FillForm();
        }
コード例 #25
0
        public void ReadNTWU(FileData d)
        {
            d.Seek(0x6);

            ushort count = d.ReadUShort();

            d.Skip(0x8);
            int headerPtr = 0x10;

            for (ushort i = 0; i < count; ++i)
            {
                d.Seek(headerPtr);

                NutTexture tex = new NutTexture();
                tex.pixelInternalFormat = PixelInternalFormat.Rgba32ui;

                int totalSize = d.ReadInt();
                d.Skip(4);
                int dataSize   = d.ReadInt();
                int headerSize = d.ReadUShort();
                d.Skip(2);

                d.Skip(1);
                byte mipmapCount = d.ReadByte();
                d.Skip(1);
                tex.setPixelFormatFromNutFormat(d.ReadByte());
                tex.Width  = d.ReadUShort();
                tex.Height = d.ReadUShort();
                d.ReadInt(); //Always 1?
                uint caps2 = d.ReadUInt();

                bool isCubemap    = false;
                byte surfaceCount = 1;
                if ((caps2 & (uint)Dds.Ddscaps2.Cubemap) == (uint)Dds.Ddscaps2.Cubemap)
                {
                    //Only supporting all six faces
                    if ((caps2 & (uint)Dds.Ddscaps2.CubemapAllfaces) == (uint)Dds.Ddscaps2.CubemapAllfaces)
                    {
                        isCubemap    = true;
                        surfaceCount = 6;
                    }
                    else
                    {
                        throw new NotImplementedException($"Unsupported cubemap face amount for texture {i} with hash 0x{tex.HashId:X}. Six faces are required.");
                    }
                }

                int dataOffset      = d.ReadInt() + headerPtr;
                int mipDataOffset   = d.ReadInt() + headerPtr;
                int gtxHeaderOffset = d.ReadInt() + headerPtr;
                d.ReadInt();

                int cmapSize1 = 0;
                int cmapSize2 = 0;
                if (isCubemap)
                {
                    cmapSize1 = d.ReadInt();
                    cmapSize2 = d.ReadInt();
                    d.Skip(8);
                }

                int imageSize = 0; //Total size of first mipmap of every surface
                int mipSize   = 0; //Total size of mipmaps other than the first of every surface
                if (mipmapCount == 1)
                {
                    if (isCubemap)
                    {
                        imageSize = cmapSize1;
                    }
                    else
                    {
                        imageSize = dataSize;
                    }
                }
                else
                {
                    imageSize = d.ReadInt();
                    mipSize   = d.ReadInt();
                    d.Skip((mipmapCount - 2) * 4);
                    d.Align(0x10);
                }

                d.Skip(0x10); //eXt data - always the same

                d.Skip(4);    //GIDX
                d.ReadInt();  //Always 0x10
                tex.HashId = d.ReadInt();
                d.Skip(4);    // padding align 8

                d.Seek(gtxHeaderOffset);
                Gtx.Gx2Surface gtxHeader = new Gtx.Gx2Surface();

                gtxHeader.dim       = d.ReadInt();
                gtxHeader.width     = d.ReadInt();
                gtxHeader.height    = d.ReadInt();
                gtxHeader.depth     = d.ReadInt();
                gtxHeader.numMips   = d.ReadInt();
                gtxHeader.format    = d.ReadInt();
                gtxHeader.aa        = d.ReadInt();
                gtxHeader.use       = d.ReadInt();
                gtxHeader.imageSize = d.ReadInt();
                gtxHeader.imagePtr  = d.ReadInt();
                gtxHeader.mipSize   = d.ReadInt();
                gtxHeader.mipPtr    = d.ReadInt();
                gtxHeader.tileMode  = d.ReadInt();
                gtxHeader.swizzle   = d.ReadInt();
                gtxHeader.alignment = d.ReadInt();
                gtxHeader.pitch     = d.ReadInt();

                //mipOffsets[0] is not in this list and is simply the start of the data (dataOffset)
                //mipOffsets[1] is relative to the start of the data (dataOffset + mipOffsets[1])
                //Other mipOffsets are relative to mipOffset[1] (dataOffset + mipOffsets[1] + mipOffsets[i])
                int[] mipOffsets = new int[mipmapCount];
                mipOffsets[0] = 0;
                for (byte mipLevel = 1; mipLevel < mipmapCount; ++mipLevel)
                {
                    mipOffsets[mipLevel] = 0;
                    mipOffsets[mipLevel] = mipOffsets[1] + d.ReadInt();
                }

                for (byte surfaceLevel = 0; surfaceLevel < surfaceCount; ++surfaceLevel)
                {
                    tex.surfaces.Add(new TextureSurface());
                }

                int w = tex.Width, h = tex.Height;
                for (byte mipLevel = 0; mipLevel < mipmapCount; ++mipLevel)
                {
                    int p = gtxHeader.pitch / (gtxHeader.width / w);

                    int size;
                    if (mipmapCount == 1)
                    {
                        size = imageSize;
                    }
                    else if (mipLevel + 1 == mipmapCount)
                    {
                        size = (mipSize + mipOffsets[1]) - mipOffsets[mipLevel];
                    }
                    else
                    {
                        size = mipOffsets[mipLevel + 1] - mipOffsets[mipLevel];
                    }

                    size /= surfaceCount;

                    for (byte surfaceLevel = 0; surfaceLevel < surfaceCount; ++surfaceLevel)
                    {
                        gtxHeader.data = d.GetSection(dataOffset + mipOffsets[mipLevel] + (size * surfaceLevel), size);

                        //Real size
                        //Leave the below line commented for now because it breaks RGBA textures
                        //size = ((w + 3) >> 2) * ((h + 3) >> 2) * (GTX.getBPP(gtxHeader.format) / 8);
                        if (size < (Gtx.GetBpp(gtxHeader.format) / 8))
                        {
                            size = (Gtx.GetBpp(gtxHeader.format) / 8);
                        }

                        byte[] deswiz = Gtx.SwizzleBc(
                            gtxHeader.data,
                            w,
                            h,
                            gtxHeader.format,
                            gtxHeader.tileMode,
                            p,
                            gtxHeader.swizzle
                            );
                        tex.surfaces[surfaceLevel].mipmaps.Add(new FileData(deswiz).GetSection(0, size));
                    }

                    w /= 2;
                    h /= 2;

                    if (w < 1)
                    {
                        w = 1;
                    }
                    if (h < 1)
                    {
                        h = 1;
                    }
                }

                headerPtr += headerSize;

                Nodes.Add(tex);
            }
        }
コード例 #26
0
        private void importToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (currentNut == null)
            {
                return;
            }
            using (var ofd = new OpenFileDialog())
            {
                ofd.Filter = "Supported Formats|*.dds;*.png|" +
                             "DirectDraw Surface (.dds)|*.dds|" +
                             "Portable Network Graphics (.png)|*.png|" +
                             "All files(*.*)|*.*";

                if (ofd.ShowDialog() == DialogResult.OK)
                {
                    int  texId;
                    bool isTex = int.TryParse(Path.GetFileNameWithoutExtension(ofd.FileName), NumberStyles.HexNumber,
                                              new CultureInfo("en-US"), out texId);

                    if (isTex)
                    {
                        foreach (NutTexture te in currentNut.Nodes)
                        {
                            if (texId == te.HashId)
                            {
                                isTex = false;
                            }
                        }
                    }

                    NutTexture tex       = null;
                    string     extension = Path.GetExtension(ofd.FileName).ToLowerInvariant();
                    if (extension == ".dds")
                    {
                        Dds dds = new Dds(new FileData(ofd.FileName));
                        tex = dds.ToNutTexture();
                    }
                    else if (extension == ".png")
                    {
                        tex = FromPng(ofd.FileName, 1);
                    }
                    else
                    {
                        return;
                    }

                    Edited = true;

                    if (isTex)
                    {
                        tex.HashId = texId;
                    }
                    else
                    {
                        tex.HashId = 0x40FFFF00 | (currentNut.Nodes.Count);
                    }

                    // Replace OpenGL texture.
                    if (currentNut.glTexByHashId.ContainsKey(tex.HashId))
                    {
                        currentNut.glTexByHashId.Remove(tex.HashId);
                    }

                    currentNut.glTexByHashId.Add(tex.HashId, NUT.CreateTexture2D(tex));

                    currentNut.Nodes.Add(tex);
                    FillForm();
                }
            }
        }
コード例 #27
0
 public Dds(NutTexture tex)
 {
     FromNutTexture(tex);
 }
コード例 #28
0
        private void RenderTexture(bool justRenderAlpha = false)
        {
            if (OpenTkSharedResources.SetupStatus != OpenTkSharedResources.SharedResourceStatus.Initialized)
            {
                return;
            }

            if (!tabControl1.SelectedTab.Text.Equals("Textures"))
            {
                return;
            }

            if (!OpenTkSharedResources.shaders["Texture"].LinkStatusIsOk)
            {
                return;
            }

            // Get the selected NUT texture.
            NutTexture nutTexture     = null;
            Texture    displayTexture = null;

            if (currentMaterialList[currentMatIndex].HasProperty("NU_materialHash") && texturesListView.SelectedIndices.Count > 0)
            {
                int hash = currentMaterialList[currentMatIndex].textures[texturesListView.SelectedIndices[0]].hash;

                // Display dummy textures from resources.
                if (Enum.IsDefined(typeof(NudEnums.DummyTexture), hash))
                {
                    displayTexture = RenderTools.dummyTextures[(NudEnums.DummyTexture)hash];
                }
                else
                {
                    foreach (NUT n in Runtime.textureContainers)
                    {
                        if (n.glTexByHashId.ContainsKey(hash))
                        {
                            n.getTextureByID(hash, out nutTexture);
                            displayTexture = n.glTexByHashId[hash];
                            break;
                        }
                    }
                }
            }

            // We can't share these vaos across both contexts.
            if (justRenderAlpha)
            {
                texAlphaGlControl.MakeCurrent();

                Mesh3D screenTriangle = ScreenDrawing.CreateScreenTriangle();

                GL.Viewport(texAlphaGlControl.ClientRectangle);
                if (displayTexture != null)
                {
                    ScreenDrawing.DrawTexturedQuad(displayTexture, 1, 1, screenTriangle, false, false, false, true);
                }
                texAlphaGlControl.SwapBuffers();
            }
            else
            {
                texRgbGlControl.MakeCurrent();

                Mesh3D screenTriangle = ScreenDrawing.CreateScreenTriangle();

                GL.Viewport(texRgbGlControl.ClientRectangle);
                if (displayTexture != null)
                {
                    ScreenDrawing.DrawTexturedQuad(displayTexture, 1, 1, screenTriangle);
                }
                texRgbGlControl.SwapBuffers();
            }
        }
コード例 #29
0
        public NutTexture ToNutTexture()
        {
            NutTexture tex = new NutTexture();

            tex.isDds  = true;
            tex.HashId = 0x48415348;
            tex.Height = (int)header.height;
            tex.Width  = (int)header.width;
            byte surfaceCount = 1;
            bool isCubemap    = (header.caps2 & (uint)Ddscaps2.Cubemap) == (uint)Ddscaps2.Cubemap;

            if (isCubemap)
            {
                if ((header.caps2 & (uint)Ddscaps2.CubemapAllfaces) == (uint)Ddscaps2.CubemapAllfaces)
                {
                    surfaceCount = 6;
                }
                else
                {
                    throw new NotImplementedException($"Unsupported cubemap face amount for texture. Six faces are required.");
                }
            }

            bool isBlock = true;

            switch (header.ddspf.fourCc)
            {
            case 0x00000000:     //RGBA
                isBlock = false;
                tex.pixelInternalFormat = PixelInternalFormat.Rgba;
                tex.pixelFormat         = OpenTK.Graphics.OpenGL.PixelFormat.Rgba;
                break;

            case 0x31545844:     //DXT1
                tex.pixelInternalFormat = PixelInternalFormat.CompressedRgbaS3tcDxt1Ext;
                break;

            case 0x33545844:     //DXT3
                tex.pixelInternalFormat = PixelInternalFormat.CompressedRgbaS3tcDxt3Ext;
                break;

            case 0x35545844:     //DXT5
                tex.pixelInternalFormat = PixelInternalFormat.CompressedRgbaS3tcDxt5Ext;
                break;

            case 0x31495441:     //ATI1
            case 0x55344342:     //BC4U
                tex.pixelInternalFormat = PixelInternalFormat.CompressedRedRgtc1;
                break;

            case 0x32495441:     //ATI2
            case 0x55354342:     //BC5U
                tex.pixelInternalFormat = PixelInternalFormat.CompressedRgRgtc2;
                break;

            default:
                MessageBox.Show("Unsupported DDS format - 0x" + header.ddspf.fourCc.ToString("x"));
                break;
            }

            uint formatSize = GetFormatSize(header.ddspf.fourCc);

            FileData d = new FileData(bdata);

            if (header.mipmapCount == 0)
            {
                header.mipmapCount = 1;
            }

            uint off = 0;

            for (byte i = 0; i < surfaceCount; ++i)
            {
                TextureSurface surface = new TextureSurface();
                uint           w = header.width, h = header.height;
                for (int j = 0; j < header.mipmapCount; ++j)
                {
                    //If texture is DXT5 and isn't square, limit the mipmaps to an amount such that width and height are each always >= 4
                    if (tex.pixelInternalFormat == PixelInternalFormat.CompressedRgbaS3tcDxt5Ext && tex.Width != tex.Height && (w < 4 || h < 4))
                    {
                        break;
                    }

                    uint s = (w * h); //Total pixels
                    if (isBlock)
                    {
                        s = (uint)(s * ((float)formatSize / 0x10)); //Bytes per 16 pixels
                        if (s < formatSize)                         //Make sure it's at least one block
                        {
                            s = formatSize;
                        }
                    }
                    else
                    {
                        s = (uint)(s * (formatSize)); //Bytes per pixel
                    }

                    w /= 2;
                    h /= 2;
                    surface.mipmaps.Add(d.GetSection((int)off, (int)s));
                    off += s;
                }
                tex.surfaces.Add(surface);
            }

            return(tex);
        }