private Texture2D LoadTexture(glTFLoader.Schema.Texture texture)
    {
        string path = "Assets/cache_" + texture.Name + ".png";

        string sourceID = texture.Source;

        glTFLoader.Schema.Image image = m_model.Images[sourceID];
        Bitmap bitmap = image.Uri;

        bitmap.Save(path);

        byte[]    data = File.ReadAllBytes(path);
        Texture2D res  = new Texture2D(2, 2);

        res.LoadImage(data); // auto resize

        string          samplerID = texture.Sampler;
        Sampler         sampler   = m_model.Samplers[samplerID];
        TextureWrapMode wrapS     = s_wrapSMode[sampler.WrapS];
        TextureWrapMode wrapT     = s_wrapTMode[sampler.WrapT];

        if (wrapS == wrapT)
        {
            res.wrapMode = wrapS;
        }
        else
        {
            throw new System.NotImplementedException("Texture wrap mode not supported");
        }
        return(res);
    }
示例#2
0
		static byte[] loadDataUri (GL.Image img) {
			int idxComa = img.Uri.IndexOf (",", 5, StringComparison.Ordinal);
			return Convert.FromBase64String (img.Uri.Substring (idxComa + 1));
		}
示例#3
0
		///// <summary>
		///// build texture array
		///// </summary>
		///// <returns>The images.</returns>
		///// <param name="textureSize">Uniformized Texture size for all images</param>
		public void BuildTexArray (ref Image texArray, uint firstImg = 0) {
			int texDim = (int)texArray.CreateInfo.extent.width;

			PrimaryCommandBuffer cmd = cmdPool.AllocateAndStart (VkCommandBufferUsageFlags.OneTimeSubmit);
			texArray.SetLayout (cmd, VkImageAspectFlags.Color, VkImageLayout.Undefined, VkImageLayout.TransferDstOptimal, 
						VkPipelineStageFlags.BottomOfPipe, VkPipelineStageFlags.Transfer);
			transferQ.EndSubmitAndWait (cmd, true);
			
			VkImageBlit imageBlit = new VkImageBlit {
				srcSubresource = new VkImageSubresourceLayers (VkImageAspectFlags.Color, 1, 0),
				dstOffsets_1 = new VkOffset3D (texDim, texDim, 1)
			};

			for (int l = 0; l < gltf.Images.Length; l++) {
				GL.Image img = gltf.Images[l];
				Image vkimg = null;

				if (img.BufferView != null) {//load image from gltf buffer view
					GL.BufferView bv = gltf.BufferViews[(int)img.BufferView];
					ensureBufferIsLoaded (bv.Buffer);
					vkimg = Image.Load (dev, loadedBuffers[bv.Buffer].Slice (bv.ByteOffset), (ulong)bv.ByteLength, VkImageUsageFlags.TransferSrc);
				} else if (img.Uri.StartsWith ("data:", StringComparison.Ordinal)) {//load base64 encoded image
					Debug.WriteLine ("loading embedded image {0} : {1}", img.Name, img.MimeType);
					vkimg = Image.Load (dev, glTFLoader.loadDataUri (img), VkImageUsageFlags.TransferSrc);
				} else {
					Debug.WriteLine ("loading image {0} : {1} : {2}", img.Name, img.MimeType, img.Uri);//load image from file path in uri
					vkimg = Image.Load (dev, Path.Combine (baseDirectory, img.Uri), VkImageUsageFlags.TransferSrc);
				}

				imageBlit.srcOffsets_1 = new VkOffset3D ((int)vkimg.CreateInfo.extent.width, (int)vkimg.CreateInfo.extent.height, 1);
				imageBlit.dstSubresource = new VkImageSubresourceLayers (VkImageAspectFlags.Color, 1, 0, (uint)l + firstImg);

				cmd = cmdPool.AllocateAndStart (VkCommandBufferUsageFlags.OneTimeSubmit);

				vkimg.SetLayout (cmd, VkImageAspectFlags.Color,
						VkAccessFlags.HostWrite, VkAccessFlags.TransferRead,
						VkImageLayout.Undefined, VkImageLayout.TransferSrcOptimal,
						VkPipelineStageFlags.Host, VkPipelineStageFlags.Transfer);

				Vk.vkCmdBlitImage (cmd.Handle, vkimg.Handle, VkImageLayout.TransferSrcOptimal,
					texArray.Handle, VkImageLayout.TransferDstOptimal, 1, ref imageBlit, VkFilter.Linear);
				
				transferQ.EndSubmitAndWait (cmd, true);								

				vkimg.Dispose ();
			}

			cmd = cmdPool.AllocateAndStart (VkCommandBufferUsageFlags.OneTimeSubmit);

			uint imgCount = (uint)gltf.Images.Length;
			VkImageSubresourceRange mipSubRange = new VkImageSubresourceRange (VkImageAspectFlags.Color, 0, 1, firstImg, imgCount);

			for (int i = 1; i < texArray.CreateInfo.mipLevels; i++) {
				imageBlit = new VkImageBlit {
					srcSubresource = new VkImageSubresourceLayers (VkImageAspectFlags.Color, imgCount, (uint)i - 1, firstImg),
					srcOffsets_1 = new VkOffset3D ((int)texDim >> (i - 1), (int)texDim >> (i - 1), 1),
					dstSubresource = new VkImageSubresourceLayers (VkImageAspectFlags.Color, imgCount, (uint)i, firstImg),
					dstOffsets_1 = new VkOffset3D ((int)texDim >> i, (int)texDim >> i, 1)
				};

				texArray.SetLayout (cmd,
					VkAccessFlags.TransferWrite, VkAccessFlags.TransferRead,
					VkImageLayout.TransferDstOptimal, VkImageLayout.TransferSrcOptimal, mipSubRange,
					VkPipelineStageFlags.Transfer, VkPipelineStageFlags.Transfer);

				Vk.vkCmdBlitImage (cmd.Handle, texArray.Handle, VkImageLayout.TransferSrcOptimal,
					texArray.Handle, VkImageLayout.TransferDstOptimal, 1, ref imageBlit, VkFilter.Linear);
				texArray.SetLayout (cmd, VkImageLayout.TransferSrcOptimal, VkImageLayout.ShaderReadOnlyOptimal, mipSubRange,
					VkPipelineStageFlags.Transfer, VkPipelineStageFlags.FragmentShader);

				mipSubRange.baseMipLevel = (uint)i;
			}
			mipSubRange.baseMipLevel = texArray.CreateInfo.mipLevels - 1;
			texArray.SetLayout (cmd, VkImageLayout.TransferDstOptimal, VkImageLayout.ShaderReadOnlyOptimal, mipSubRange,
				VkPipelineStageFlags.Transfer, VkPipelineStageFlags.FragmentShader);

			cmd.End ();
			transferQ.Submit (cmd);
			transferQ.WaitIdle ();
			cmd.Free ();
		}
示例#4
0
        internal static Dictionary <string, int> AddMaterials(this Gltf gltf, IList <Material> materials, List <byte> buffer, List <BufferView> bufferViews)
        {
            var materialDict = new Dictionary <string, int>();
            var newMaterials = new List <glTFLoader.Schema.Material>();

            var textureDict = new Dictionary <string, int>(); // the name of the texture image, the id of the texture
            var textures    = new List <glTFLoader.Schema.Texture>();

            var images   = new List <glTFLoader.Schema.Image>();
            var samplers = new List <glTFLoader.Schema.Sampler>();

            var matId     = 0;
            var texId     = 0;
            var imageId   = 0;
            var samplerId = 0;

            foreach (var material in materials)
            {
                if (materialDict.ContainsKey(material.Name))
                {
                    continue;
                }

                var m = new glTFLoader.Schema.Material();
                newMaterials.Add(m);

                m.PbrMetallicRoughness = new MaterialPbrMetallicRoughness();
                m.PbrMetallicRoughness.BaseColorFactor = material.Color.ToArray();
                m.PbrMetallicRoughness.MetallicFactor  = 1.0f;
                m.DoubleSided = material.DoubleSided;
                m.Name        = material.Name;

                if (material.Unlit)
                {
                    m.Extensions = new Dictionary <string, object> {
                        { "KHR_materials_unlit", new Dictionary <string, object> {
                          } }
                    };
                }
                else
                {
                    m.Extensions = new Dictionary <string, object> {
                        { "KHR_materials_pbrSpecularGlossiness", new Dictionary <string, object> {
                              { "diffuseFactor", new[] { material.Color.Red, material.Color.Green, material.Color.Blue, material.Color.Alpha } },
                              { "specularFactor", new[] { material.SpecularFactor, material.SpecularFactor, material.SpecularFactor } },
                              { "glossinessFactor", material.GlossinessFactor }
                          } }
                    };
                }

                if (material.Texture != null && File.Exists(material.Texture))
                {
                    // Add the texture
                    var ti = new TextureInfo();
                    m.PbrMetallicRoughness.BaseColorTexture = ti;
                    ti.Index    = texId;
                    ti.TexCoord = 0;
                    ((Dictionary <string, object>)m.Extensions["KHR_materials_pbrSpecularGlossiness"])["diffuseTexture"] = ti;

                    if (textureDict.ContainsKey(material.Texture))
                    {
                        ti.Index = textureDict[material.Texture];
                    }
                    else
                    {
                        var tex = new Texture();
                        textures.Add(tex);

                        var image = new glTFLoader.Schema.Image();

                        using (var ms = new MemoryStream())
                        {
                            // Flip the texture image vertically
                            // to align with OpenGL convention.
                            // 0,1  1,1
                            // 0,0  1,0
                            using (var texImage = SixLabors.ImageSharp.Image.Load(material.Texture))
                            {
                                texImage.Mutate(x => x.Flip(FlipMode.Vertical));
                                texImage.Save(ms, new SixLabors.ImageSharp.Formats.Png.PngEncoder());
                            }
                            var imageData = ms.ToArray();
                            image.BufferView = AddBufferView(bufferViews, 0, buffer.Count, imageData.Length, null, null);
                            buffer.AddRange(imageData);
                        }

                        while (buffer.Count % 4 != 0)
                        {
                            // Console.WriteLine("Padding...");
                            buffer.Add(0);
                        }

                        image.MimeType = glTFLoader.Schema.Image.MimeTypeEnum.image_png;
                        tex.Source     = imageId;
                        images.Add(image);

                        var sampler = new Sampler();
                        sampler.MagFilter = Sampler.MagFilterEnum.LINEAR;
                        sampler.MinFilter = Sampler.MinFilterEnum.LINEAR;
                        sampler.WrapS     = Sampler.WrapSEnum.REPEAT;
                        sampler.WrapT     = Sampler.WrapTEnum.REPEAT;
                        tex.Sampler       = samplerId;
                        samplers.Add(sampler);

                        textureDict.Add(material.Texture, texId);

                        texId++;
                        imageId++;
                        samplerId++;
                    }
                }

                if (material.Color.Alpha < 1.0)
                {
                    m.AlphaMode = glTFLoader.Schema.Material.AlphaModeEnum.BLEND;
                }
                else
                {
                    m.AlphaMode = glTFLoader.Schema.Material.AlphaModeEnum.OPAQUE;
                }

                materialDict.Add(m.Name, matId);
                matId++;
            }

            if (materials.Count > 0)
            {
                gltf.Materials = newMaterials.ToArray();
            }
            if (textures.Count > 0)
            {
                gltf.Textures = textures.ToArray();
            }
            if (images.Count > 0)
            {
                gltf.Images = images.ToArray();
            }
            if (samplers.Count > 0)
            {
                gltf.Samplers = samplers.ToArray();
            }

            return(materialDict);
        }