Beispiel #1
0
        private ImageTexture[] loadMaterialTextures(ai.Material material, ai.TextureType type, TextureType textureType)
        {
            ImageTexture[] textures = new ImageTexture[material.GetMaterialTextureCount(type)];

            for (int i = 0; i < textures.Length; i++)
            {
                ai.TextureSlot slot;
                material.GetMaterialTexture(type, i, out slot);

                string path = directory + slot.FilePath;

                ImageTexture texture;

                ImageTexture loaded = loadedTextures.Find(x => x.path == path);

                if (loaded != null)
                {
                    texture = loaded;
                }
                else
                {
                    texture = new ImageTexture(gl, path, textureType);
                    loadedTextures.Add(texture);
                    Console.WriteLine($"Texture file path: {path}");
                }

                textures[i] = texture;
            }

            return(textures);
        }
Beispiel #2
0
        List <Texture> loadMaterialTextures(Assimp.Material mat, Assimp.TextureType type, string typeName)
        {
            List <Texture> textures = new List <Texture>();

            for (int i = 0; i < mat.GetMaterialTextureCount(type); i++)
            {
                bool        skip = false;
                TextureSlot textureSlot;
                mat.GetMaterialTexture(type, i, out textureSlot);
                for (int j = 0; j < texturesLoaded.Count; j++)
                {
                    if (texturesLoaded[j].path.CompareTo(textureSlot.FilePath) == 0)
                    {
                        skip = true;
                        textures.Add(texturesLoaded[j]);
                        break;
                    }
                }

                if (!skip)
                {
                    Texture texture = new Texture();
                    texture.id   = TextureFromFile(textureSlot.FilePath, directory);
                    texture.type = typeName;
                    texture.path = textureSlot.FilePath;
                    textures.Add(texture);
                    texturesLoaded.Add(texture);
                }
            }
            return(textures);
        }
Beispiel #3
0
        private static Material ConvertMaterialFromAiMaterial(Ai.Material aiMaterial, string texturesDirectory,
                                                              TextureSet textureSet)
        {
            Material material = new Material();

            material.Shader  = "BLINN";
            material.Field02 = 2688;
            material.Name    = aiMaterial.Name;
            material.Field25 = 1;

            if (aiMaterial.HasColorDiffuse)
            {
                material.DiffuseColor = aiMaterial.ColorDiffuse.ToMML();
            }
            else
            {
                material.DiffuseColor = new Color(1, 1, 1, 1);
            }

            if (aiMaterial.HasColorAmbient)
            {
                material.AmbientColor = aiMaterial.ColorAmbient.ToMML();
            }
            else
            {
                material.AmbientColor = new Color(1, 1, 1, 1);
            }

            if (aiMaterial.HasColorSpecular)
            {
                material.SpecularColor = aiMaterial.ColorSpecular.ToMML();
            }
            else
            {
                material.SpecularColor = new Color(0.5f, 0.5f, 0.5f, 1);
            }

            if (aiMaterial.HasColorEmissive)
            {
                material.EmissionColor = aiMaterial.ColorEmissive.ToMML();
            }
            else
            {
                material.EmissionColor = new Color(0, 0, 0, 1);
            }

            if (aiMaterial.HasShininess && aiMaterial.ShadingMode == Ai.ShadingMode.Phong)
            {
                material.Shininess = aiMaterial.Shininess;
            }
            else
            {
                material.Shininess = 50f;
            }

            Texture texture;

            if (aiMaterial.HasTextureDiffuse &&
                (texture = ConvertTexture(aiMaterial.TextureDiffuse.FilePath, texturesDirectory, textureSet)) !=
                null)
            {
                material.Field00          |= 1;
                material.Diffuse.TextureId = texture.Id;
                material.Diffuse.Field02   = 241;
            }

            if (aiMaterial.HasTextureAmbient &&
                (texture = ConvertTexture(aiMaterial.TextureAmbient.FilePath, texturesDirectory, textureSet)) !=
                null)
            {
                material.Ambient.TextureId = texture.Id;
                material.Ambient.Field02   = 241;
            }

            if (aiMaterial.HasTextureNormal &&
                (texture = ConvertTexture(aiMaterial.TextureNormal.FilePath, texturesDirectory, textureSet)) !=
                null)
            {
                material.Field00         |= 256;
                material.Normal.TextureId = texture.Id;
                material.Normal.Field02   = 242;
            }

            if (aiMaterial.HasTextureSpecular &&
                (texture = ConvertTexture(aiMaterial.TextureSpecular.FilePath, texturesDirectory, textureSet)) !=
                null)
            {
                material.Field00           |= 128;
                material.Specular.TextureId = texture.Id;
                material.Specular.Field02   = 243;
            }

            if (aiMaterial.HasTextureReflection &&
                (texture = ConvertTexture(aiMaterial.TextureReflection.FilePath, texturesDirectory, textureSet)) !=
                null)
            {
                material.Field00 |= 33832;
                material.Reflection.TextureId = texture.Id;
                material.Reflection.Field02   = 1017;
            }

            if (aiMaterial.GetMaterialTexture(Ai.TextureType.Shininess, 0, out Ai.TextureSlot shininess) &&
                (texture = ConvertTexture(shininess.FilePath, texturesDirectory, textureSet)) != null)
            {
                material.Field00          |= 8192;
                material.Tangent.TextureId = texture.Id;
                material.Tangent.Field02   = 246;
            }

            foreach (var materialTexture in material.MaterialTextures)
            {
                if (materialTexture == material.Diffuse)
                {
                    materialTexture.Field00 = materialTexture.IsActive ? 82288 : 48;
                }

                materialTexture.Field05 = 1;

                if (materialTexture.IsActive)
                {
                    materialTexture.Field01 = 0x2418C3;
                    materialTexture.Field06 = 1;
                    materialTexture.Field11 = 1;
                    materialTexture.Field16 = 1;
                    materialTexture.Field21 = 1;
                }
            }

            return(material);
        }
Beispiel #4
0
        /// <summary>
        /// Helper method, used to transfer information from Material to ClientMaterial
        /// </summary>
        /// <param name="mat"> the source Material </param>
        /// <param name="myMat"> the destination ClientMaterial </param>
        protected void ApplyMaterial(Material mat, ClientMaterial myMat)
        {
            if (mat.GetMaterialTextureCount(TextureType.Diffuse) > 0)
            {
                TextureSlot tex;
                if (mat.GetMaterialTexture(TextureType.Diffuse, 0, out tex))
                {
                    ShaderResourceView temp;
                    myMat.setDiffuseTexture(temp = CreateTexture(Path.Combine(Path.GetDirectoryName(sourceFileName), Path.GetFileName(tex.FilePath))));
                    myMat.setTexCount(temp == null ? 0 : 1);
                }
                else
                {
                    myMat.setDiffuseTexture(null);
                    myMat.setTexCount(1);
                }
            }

            // copies over all the material properties to the struct
            // sets the diffuse color
            Color4 color = new Color4(.4f, .4f, .4f, 1.0f); // default is light grey

            if (mat.HasColorDiffuse)
            {
                myMat.setDiffuse(mat.ColorDiffuse.R, mat.ColorDiffuse.G, mat.ColorDiffuse.B, mat.ColorDiffuse.A);
            }
            else
            {
                myMat.setDiffuse(color.Red, color.Green, color.Blue, color.Alpha);
            }

            // sets the specular color
            color = new Color4(0.1f, 0.1f, 0.1f, 1.0f);  // default is non-specular
            if (mat.HasColorSpecular)
            {
                myMat.setSpecular(mat.ColorDiffuse.R, mat.ColorDiffuse.G, mat.ColorDiffuse.B, mat.ColorDiffuse.A);
            }
            else
            {
                myMat.setSpecular(color.Red, color.Green, color.Blue, color.Alpha);
            }

            // sets the ambient color
            color = new Color4(.3f, .3f, .3f, 1.0f);    // default is dark grey
            if (mat.HasColorAmbient)
            {
                myMat.setAmbient(mat.ColorDiffuse.R, mat.ColorDiffuse.G, mat.ColorDiffuse.B, mat.ColorDiffuse.A);
            }
            else
            {
                myMat.setAmbient(color.Red, color.Green, color.Blue, color.Alpha);
            }

            // sets the emissive color
            color = new Color4(0, 0, 0, 1.0f);  // default is black
            if (mat.HasColorEmissive)
            {
                myMat.setEmissive(mat.ColorDiffuse.R, mat.ColorDiffuse.G, mat.ColorDiffuse.B, mat.ColorDiffuse.A);
            }
            else
            {
                myMat.setEmissive(color.Red, color.Green, color.Blue, color.Alpha);
            }

            // sets the shininess
            float shininess = 1;    // default is 1

            if (mat.HasShininess)
            {
                myMat.setShininess(mat.Shininess);
            }
            else
            {
                myMat.setShininess(shininess);
            }

            // sets the opacity
            float opacity = 1;      // default is 1

            if (mat.HasOpacity)
            {
                myMat.setOpacity(mat.Opacity);
            }
            else
            {
                myMat.setOpacity(mat.Opacity);
            }
        }
Beispiel #5
0
        void ProcessMaterials(Scene scene, string directoryName, VertexMode mode)
        {
            for (int i = 0; i < scene.MaterialCount; i++)
            {
                Material        mat      = new Material();
                Assimp.Material material = scene.Materials[i];

                var diffuse = material.ColorDiffuse;
                mat.diffuse = new Vec3(diffuse.R, diffuse.G, diffuse.B);

                var specular = material.ColorSpecular;
                mat.specular = new Vec3(specular.R, specular.G, specular.B);

                var emissive = material.ColorEmissive;
                mat.emissive = new Vec3(emissive.R, emissive.G, emissive.B);

                float shininess = material.Shininess;
                mat.shininess = shininess;

                float shininessStrength = material.ShininessStrength;

                mat.specular.x *= shininessStrength;
                mat.specular.y *= shininessStrength;
                mat.specular.z *= shininessStrength;

                int numDiffuseMaps = material.GetMaterialTextureCount(TextureType.Diffuse);
                int numNormalMaps  = material.GetMaterialTextureCount(TextureType.Normals);

                if (numDiffuseMaps > 0)
                {
                    material.GetMaterialTexture(TextureType.Diffuse, 0, out var diffuseMapName);
                    Console.WriteLine(diffuseMapName.FilePath);

                    if (!File.Exists(diffuseMapName.FilePath) && (mode == VertexMode.TextureAndNormal || mode == VertexMode.TextureOnly))
                    {
                        var a = new ModelWorkerEventArgs()
                        {
                            Args = diffuseMapName.FilePath, EventType = ModelWorkerEventArgs.EventArgsType.TextureNotExists, Context = directoryName
                        };
                        this.OnActionCallback?.Invoke(this, a);
                        diffuseMapName.FilePath = a.Args.Replace(directoryName, "");
                    }

                    mat.diffuseMapName = diffuseMapName.FilePath;
                }

                if (numNormalMaps > 0)
                {
                    material.GetMaterialTexture(TextureType.Normals, 0, out var normalMapName);
                    Console.WriteLine(normalMapName.FilePath);

                    if (!File.Exists(normalMapName.FilePath) && mode == VertexMode.TextureAndNormal)
                    {
                        var a = new ModelWorkerEventArgs()
                        {
                            Args = normalMapName.FilePath, EventType = ModelWorkerEventArgs.EventArgsType.TextureNotExists, Context = directoryName
                        };
                        this.OnActionCallback?.Invoke(this, a);
                        normalMapName.FilePath = a.Args.Replace(directoryName, "");
                        ;
                    }

                    mat.normalMapName = normalMapName.FilePath;
                }

                this._materials.Add(mat);
            }
        }
        private void ApplyFixedFunctionMaterial(Mesh mesh, Material mat, bool textured, bool shaded)
        {
            shaded = shaded && (mesh == null || mesh.HasNormals);
            if (shaded)
            {
                GL.Enable(EnableCap.Lighting);
            }
            else
            {
                GL.Disable(EnableCap.Lighting);
            }

            var hasColors = mesh != null && mesh.HasVertexColors(0);
            if (hasColors)
            {
                GL.Enable(EnableCap.ColorMaterial);
                GL.ColorMaterial(MaterialFace.FrontAndBack, ColorMaterialParameter.AmbientAndDiffuse);
            }
            else
            {
                GL.Disable(EnableCap.ColorMaterial);
            }

            // note: keep semantics of hasAlpha consistent with IsAlphaMaterial()
            var hasAlpha = false;
            var hasTexture = false;

            // note: keep this up-to-date with the code in UploadTextures()
            if (textured && mat.GetMaterialTextureCount(TextureType.Diffuse) > 0)
            {
                hasTexture = true;

                TextureSlot tex;
                mat.GetMaterialTexture(TextureType.Diffuse, 0, out tex);
                var gtex = _scene.TextureSet.GetOriginalOrReplacement(tex.FilePath);

                hasAlpha = hasAlpha || gtex.HasAlpha == Texture.AlphaState.HasAlpha;

                if(gtex.State == Texture.TextureState.GlTextureCreated)
                {
                    GL.ActiveTexture(TextureUnit.Texture0);
                    gtex.BindGlTexture();

                    GL.Enable(EnableCap.Texture2D);
                }
                else
                {
                    GL.Disable(EnableCap.Texture2D);
                }
            }
            else
            {
                GL.Disable(EnableCap.Texture2D);
            }

            GL.Enable(EnableCap.Normalize);

            var alpha = 1.0f;
            if (mat.HasOpacity)
            {
                alpha = mat.Opacity;
                if (alpha < AlphaSuppressionThreshold) // suppress zero opacity, this is likely wrong input data
                {
                    alpha = 1.0f;
                }
            }

            var color = new Color4(.8f, .8f, .8f, 1.0f);
            if (mat.HasColorDiffuse)
            {
                color = AssimpToOpenTk.FromColor(mat.ColorDiffuse);
                if (color.A < AlphaSuppressionThreshold) // s.a.
                {
                    color.A = 1.0f;
                }
            }
            color.A *= alpha;
            hasAlpha = hasAlpha || color.A < 1.0f;

            if (shaded)
            {
                // if the material has a texture but the diffuse color texture is all black,
                // then heuristically assume that this is an import/export flaw and substitute
                // white.
                if (hasTexture && color.R < 1e-3f && color.G < 1e-3f && color.B < 1e-3f)
                {
                    GL.Material(MaterialFace.FrontAndBack, MaterialParameter.Diffuse, Color4.White);
                }
                else
                {
                    GL.Material(MaterialFace.FrontAndBack, MaterialParameter.Diffuse, color);
                }

                color = new Color4(0, 0, 0, 1.0f);
                if (mat.HasColorSpecular)
                {
                    color = AssimpToOpenTk.FromColor(mat.ColorSpecular);
                }
                GL.Material(MaterialFace.FrontAndBack, MaterialParameter.Specular, color);

                color = new Color4(.2f, .2f, .2f, 1.0f);
                if (mat.HasColorAmbient)
                {
                    color = AssimpToOpenTk.FromColor(mat.ColorAmbient);
                }
                GL.Material(MaterialFace.FrontAndBack, MaterialParameter.Ambient, color);

                color = new Color4(0, 0, 0, 1.0f);
                if (mat.HasColorEmissive)
                {
                    color = AssimpToOpenTk.FromColor(mat.ColorEmissive);
                }
                GL.Material(MaterialFace.FrontAndBack, MaterialParameter.Emission, color);

                float shininess = 1;
                float strength = 1;
                if (mat.HasShininess)
                {
                    shininess = mat.Shininess;

                }
                // todo: I don't even remember how shininess strength was supposed to be handled in assimp
                if (mat.HasShininessStrength)
                {
                    strength = mat.ShininessStrength;
                }

                var exp = shininess*strength;
                if (exp >= 128.0f) // 128 is the maximum exponent as per the Gl spec
                {
                    exp = 128.0f;
                }

                GL.Material(MaterialFace.FrontAndBack, MaterialParameter.Shininess, exp);
            }
            else if (!hasColors)
            {
                GL.Color3(color.R, color.G, color.B);
            }

            if (hasAlpha)
            {
                GL.Enable(EnableCap.Blend);
                GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha);
                GL.DepthMask(false);
            }
            else
            {
                GL.Disable(EnableCap.Blend);
                GL.DepthMask(true);
            }
        }
Beispiel #7
0
        /// <summary>
        /// Check if a given assimp material requires alpha-blending for rendering
        /// </summary>
        /// <param name="material"></param>
        /// <returns></returns>
        public bool IsAlphaMaterial(Material material)
        {
            if (material.HasOpacity && IsTransparent(material.Opacity))
            {
                return true;
            }

            // Also treat material as (potentially) semi-transparent if the alpha
            // components of any of the diffuse, specular, ambient and emissive
            // colors are non-1. It is not very well-defined how assimp handles
            // these values so better count them into transparency as well.
            //
            // Ignore color values with alpha=0, however. These are most likely
            // not intended to be fully transparent.
            if (material.HasColorDiffuse && IsTransparent(material.ColorDiffuse.A))
            {
                return true;
            }

            if (material.HasColorSpecular && IsTransparent(material.ColorSpecular.A))
            {
                return true;
            }

            if (material.HasColorAmbient && IsTransparent(material.ColorAmbient.A))
            {
                return true;
            }

            if (material.HasColorEmissive && IsTransparent(material.ColorEmissive.A))
            {
                return true;
            }


            if (material.GetMaterialTextureCount(TextureType.Diffuse) > 0)
            {
                TextureSlot tex;
                material.GetMaterialTexture(TextureType.Diffuse, 0, out tex);
                var gtex = _scene.TextureSet.GetOriginalOrReplacement(tex.FilePath);

                if(gtex.HasAlpha == Texture.AlphaState.HasAlpha)
                {
                    return true;
                }
            }

            return false;
        }
Beispiel #8
0
        /// <summary>
        /// Uploads all the textures required for a given material to VRAM (i.e.
        /// create the corresponding Gl objects). Textures that have been 
        /// uploaded before are not attempted again.
        /// </summary>
        /// <param name="material"></param>
        /// <returns>Whether there were any new texture uploads</returns>
        public bool UploadTextures(Material material)
        {
            Debug.Assert(material != null);
            var any = false;

            // note: keep this up to date with the code in ApplyFixedFunctionMaterial
            if (material.GetMaterialTextureCount(TextureType.Diffuse) > 0)
            {
                TextureSlot tex;
                material.GetMaterialTexture(TextureType.Diffuse, 0, out tex);

                var gtex = _scene.TextureSet.GetOriginalOrReplacement(tex.FilePath);

                if (gtex.State == Texture.TextureState.WinFormsImageCreated)
                {
                    gtex.Upload();
                    any = true;
                }
                else if (gtex.ReconfigureUploadedTextureRequested)
                {
                    gtex.ReconfigureUploadedTexture();
                }
            }
            return any;
        }
Beispiel #9
0
		void WriteTextureStack (Material mat, TextureType type, BinaryWriter writer, Dictionary<string,string> textures) {
			var count = mat.GetMaterialTextureCount(type);
			writer.Write(count);
			for (var i = 0; i < count; i++) {
				TextureSlot slot;
				mat.GetMaterialTexture(type, i, out slot);
				if (slot.Mapping != TextureMapping.FromUV)
					throw new ContentException("Unsupported texture mapping type, textures must be UV-mapped.");
				if (!textures.ContainsKey(slot.FilePath)) {
					textures.Add(slot.FilePath, Path.GetFileNameWithoutExtension(slot.FilePath));
				}
				writer.Write(textures[slot.FilePath]);
				writer.Write(slot.UVIndex);
				writer.Write(slot.BlendFactor);
				writer.Write((int)slot.Operation);
				writer.Write(slot.WrapModeU == TextureWrapMode.Wrap);
				writer.Write(slot.WrapModeV == TextureWrapMode.Wrap);
			}
		}