Exemple #1
0
 /// <summary>Creates glow attenuation data from a half distance and a mode. The resulting value can be later passed to SplitGlowAttenuationData in order to reconstruct the parameters.</summary>
 /// <param name="HalfDistance">The distance at which the glow is at 50% of its full intensity. The value is clamped to the integer range from 1 to 4096. Values less than or equal to 0 disable glow attenuation.</param>
 /// <param name="Mode">The glow attenuation mode.</param>
 /// <returns>A System.UInt16 packed with the information about the half distance and glow attenuation mode.</returns>
 public static ushort GetAttenuationData(double HalfDistance, GlowAttenuationMode Mode)
 {
     if (HalfDistance <= 0.0 | Mode == GlowAttenuationMode.None)
     {
         return(0);
     }
     if (HalfDistance < 1.0)
     {
         HalfDistance = 1.0;
     }
     else if (HalfDistance > 4095.0)
     {
         HalfDistance = 4095.0;
     }
     return((ushort)((int)System.Math.Round(HalfDistance) | ((int)Mode << 12)));
 }
Exemple #2
0
        /// <summary>Gets the current intensity glow intensity, using the glow attenuation factor</summary>
        /// <param name="ModelMatrix">The model transformation matrix to apply</param>
        /// <param name="Vertices">The verticies to which the glow is to be applied</param>
        /// <param name="Face">The face which these vertices make up</param>
        /// <param name="GlowAttenuationData">The current glow attenuation</param>
        /// <param name="mode">The returned glow attenuation mode</param>
        /// <returns></returns>
        public static double GetDistanceFactor(Matrix4D ModelMatrix, VertexTemplate[] Vertices, ref MeshFace Face, ushort GlowAttenuationData, out GlowAttenuationMode mode)
        {
            mode = GlowAttenuationMode.None;
            if (Face.Vertices.Length == 0)
            {
                return(1.0);
            }

            double halfdistance;

            Glow.SplitAttenuationData(GlowAttenuationData, out mode, out halfdistance);
            int     i = (int)Face.Vertices[0].Index;
            Vector3 d = new Vector3(Vertices[i].Coordinates.X, Vertices[i].Coordinates.Y, -Vertices[i].Coordinates.Z);

            d.Transform(ModelMatrix);
            switch (mode)
            {
            case GlowAttenuationMode.DivisionExponent2:
            {
                double t = d.NormSquared();
                return(t / (t + halfdistance * halfdistance));
            }

            case GlowAttenuationMode.DivisionExponent4:
            {
                double t = d.NormSquared();
                t            *= t;
                halfdistance *= halfdistance;
                return(t / (t + halfdistance * halfdistance));
            }

            default:
                return(1.0);
            }
        }
Exemple #3
0
 /// <summary>Recreates the half distance and the glow attenuation mode from a packed System.UInt16 that was created by GetGlowAttenuationData.</summary>
 /// <param name="Data">The data returned by GetGlowAttenuationData.</param>
 /// <param name="Mode">The mode of glow attenuation.</param>
 /// <param name="HalfDistance">The half distance of glow attenuation.</param>
 public static void SplitAttenuationData(ushort Data, out GlowAttenuationMode Mode, out double HalfDistance)
 {
     Mode         = (GlowAttenuationMode)(Data >> 12);
     HalfDistance = (double)(Data & 4095);
 }
Exemple #4
0
		/// <summary>Recreates the half distance and the glow attenuation mode from a packed System.UInt16 that was created by GetGlowAttenuationData.</summary>
		/// <param name="Data">The data returned by GetGlowAttenuationData.</param>
		/// <param name="Mode">The mode of glow attenuation.</param>
		/// <param name="HalfDistance">The half distance of glow attenuation.</param>
		internal static void SplitGlowAttenuationData(ushort Data, out GlowAttenuationMode Mode, out double HalfDistance) {
			Mode = (GlowAttenuationMode)(Data >> 12);
			HalfDistance = (double)(Data & 4095);
		}
Exemple #5
0
		/// <summary>Creates glow attenuation data from a half distance and a mode. The resulting value can be later passed to SplitGlowAttenuationData in order to reconstruct the parameters.</summary>
		/// <param name="HalfDistance">The distance at which the glow is at 50% of its full intensity. The value is clamped to the integer range from 1 to 4096. Values less than or equal to 0 disable glow attenuation.</param>
		/// <param name="Mode">The glow attenuation mode.</param>
		/// <returns>A System.UInt16 packed with the information about the half distance and glow attenuation mode.</returns>
		internal static ushort GetGlowAttenuationData(double HalfDistance, GlowAttenuationMode Mode) {
			if (HalfDistance <= 0.0 | Mode == GlowAttenuationMode.None) return 0;
			if (HalfDistance < 1.0) {
				HalfDistance = 1.0;
			} else if (HalfDistance > 4095.0) {
				HalfDistance = 4095.0;
			}
			return (ushort)((int)Math.Round(HalfDistance) | ((int)Mode << 12));
		}
Exemple #6
0
        public void RenderFace(Shader Shader, ObjectState State, MeshFace Face, Matrix4D modelMatrix, Matrix4D modelViewMatrix, bool IsDebugTouchMode = false)
        {
            if (State.Prototype.Mesh.Vertices.Length < 1)
            {
                return;
            }

            MeshMaterial      material = State.Prototype.Mesh.Materials[Face.Material];
            VertexArrayObject VAO      = (VertexArrayObject)State.Prototype.Mesh.VAO;

            if (lastVAO != VAO.handle)
            {
                VAO.Bind();
                lastVAO = VAO.handle;
            }

            if (!OptionBackFaceCulling || (Face.Flags & MeshFace.Face2Mask) != 0)
            {
                GL.Disable(EnableCap.CullFace);
            }
            else if (OptionBackFaceCulling)
            {
                if ((Face.Flags & MeshFace.Face2Mask) == 0)
                {
                    GL.Enable(EnableCap.CullFace);
                }
            }

            // matrix

            Shader.SetCurrentModelViewMatrix(modelViewMatrix);
            Shader.SetCurrentTextureMatrix(State.TextureTranslation);

            if (OptionWireFrame || IsDebugTouchMode)
            {
                if (material.Color != lastColor)
                {
                    Shader.SetMaterialAmbient(material.Color);
                    lastColor = material.Color;
                }
                Shader.SetOpacity(1.0f);
                Shader.SetBrightness(1.0f);
                VAO.Draw(PrimitiveType.LineLoop, Face.IboStartIndex, Face.Vertices.Length);
                return;
            }

            // lighting
            if (OptionLighting)
            {
                if (material.Color != lastColor)
                {
                    Shader.SetMaterialAmbient(material.Color);
                    Shader.SetMaterialDiffuse(material.Color);
                    Shader.SetMaterialSpecular(material.Color);
                    //TODO: Ambient and specular colors are not set by any current parsers
                }

                if ((material.Flags & MeshMaterial.EmissiveColorMask) != 0)
                {
                    Shader.SetMaterialEmission(material.EmissiveColor);
                    Shader.SetMaterialEmissive(true);
                }
                else
                {
                    Shader.SetMaterialEmissive(false);
                }

                Shader.SetMaterialShininess(1.0f);
            }
            else
            {
                if (material.Color != lastColor)
                {
                    Shader.SetMaterialAmbient(material.Color);
                }
                //As lighting is disabled, the face cannot be emitting light....
                Shader.SetMaterialEmissive(false);
            }

            lastColor = material.Color;
            PrimitiveType DrawMode;

            switch (Face.Flags & MeshFace.FaceTypeMask)
            {
            case MeshFace.FaceTypeTriangles:
                DrawMode = PrimitiveType.Triangles;
                break;

            case MeshFace.FaceTypeTriangleStrip:
                DrawMode = PrimitiveType.TriangleStrip;
                break;

            case MeshFace.FaceTypeQuads:
                DrawMode = PrimitiveType.Quads;
                break;

            case MeshFace.FaceTypeQuadStrip:
                DrawMode = PrimitiveType.QuadStrip;
                break;

            default:
                DrawMode = PrimitiveType.Polygon;
                break;
            }

            // daytime polygon
            {
                // texture
                if (material.DaytimeTexture != null && currentHost.LoadTexture(material.DaytimeTexture, (OpenGlTextureWrapMode)material.WrapMode))
                {
                    Shader.SetIsTexture(true);
                    if (LastBoundTexture != material.DaytimeTexture.OpenGlTextures[(int)material.WrapMode])
                    {
                        GL.BindTexture(TextureTarget.Texture2D,
                                       material.DaytimeTexture.OpenGlTextures[(int)material.WrapMode].Name);
                        LastBoundTexture = material.DaytimeTexture.OpenGlTextures[(int)material.WrapMode];
                    }
                }
                else
                {
                    Shader.SetIsTexture(false);
                }

                // Calculate the brightness of the poly to render
                float factor;
                if (material.BlendMode == MeshMaterialBlendMode.Additive)
                {
                    //Additive blending- Full brightness
                    factor = 1.0f;
                    GL.Enable(EnableCap.Blend);
                    GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.One);
                    Shader.SetIsFog(false);
                }
                else if ((material.Flags & MeshMaterial.EmissiveColorMask) != 0)
                {
                    //As material is emitting light, it must be at full brightness
                    factor = 1.0f;
                }
                else if (material.NighttimeTexture == null || material.NighttimeTexture == material.DaytimeTexture)
                {
                    //No nighttime texture or both are identical- Darken the polygon to match the light conditions
                    float blend = inv255 * material.DaytimeNighttimeBlend + 1.0f - Lighting.OptionLightingResultingAmount;
                    if (blend > 1.0f)
                    {
                        blend = 1.0f;
                    }

                    factor = 1.0f - 0.7f * blend;
                }
                else
                {
                    //Valid nighttime texture- Blend the two textures by DNB at max brightness
                    factor = 1.0f;
                }
                Shader.SetBrightness(factor);

                float alphaFactor;
                GlowAttenuationMode mode = GlowAttenuationMode.None;
                if (material.GlowAttenuationData != 0)
                {
                    alphaFactor = (float)Glow.GetDistanceFactor(modelMatrix, State.Prototype.Mesh.Vertices, ref Face, material.GlowAttenuationData, out mode);
                }
                else
                {
                    alphaFactor = 1.0f;
                }

                if (material.BlendMode == MeshMaterialBlendMode.Additive)
                {
                    Shader.SetMaterialAdditive(1 + (int)mode);
                }
                else
                {
                    Shader.SetMaterialAdditive(0);
                }

                Shader.SetOpacity(inv255 * material.Color.A * alphaFactor);

                // render polygon
                VAO.Draw(DrawMode, Face.IboStartIndex, Face.Vertices.Length);
            }

            // nighttime polygon
            if (material.NighttimeTexture != null && material.NighttimeTexture != material.DaytimeTexture && currentHost.LoadTexture(material.NighttimeTexture, (OpenGlTextureWrapMode)material.WrapMode))
            {
                // texture
                Shader.SetIsTexture(true);
                if (LastBoundTexture != material.NighttimeTexture.OpenGlTextures[(int)material.WrapMode])
                {
                    GL.BindTexture(TextureTarget.Texture2D, material.NighttimeTexture.OpenGlTextures[(int)material.WrapMode].Name);
                    LastBoundTexture = material.NighttimeTexture.OpenGlTextures[(int)material.WrapMode];
                }


                GL.Enable(EnableCap.Blend);

                // alpha test
                GL.Enable(EnableCap.AlphaTest);
                GL.AlphaFunc(AlphaFunction.Greater, 0.0f);

                // blend mode
                float alphaFactor;
                if (material.GlowAttenuationData != 0)
                {
                    alphaFactor = (float)Glow.GetDistanceFactor(modelMatrix, State.Prototype.Mesh.Vertices, ref Face, material.GlowAttenuationData);
                    float blend = inv255 * material.DaytimeNighttimeBlend + 1.0f - Lighting.OptionLightingResultingAmount;
                    if (blend > 1.0f)
                    {
                        blend = 1.0f;
                    }

                    alphaFactor *= blend;
                }
                else
                {
                    alphaFactor = inv255 * material.DaytimeNighttimeBlend + 1.0f - Lighting.OptionLightingResultingAmount;
                    if (alphaFactor > 1.0f)
                    {
                        alphaFactor = 1.0f;
                    }
                }

                Shader.SetOpacity(inv255 * material.Color.A * alphaFactor);

                // render polygon
                VAO.Draw(DrawMode, Face.IboStartIndex, Face.Vertices.Length);
                RestoreBlendFunc();
                RestoreAlphaFunc();
            }


            // normals
            if (OptionNormals)
            {
                Shader.SetIsTexture(false);
                Shader.SetBrightness(1.0f);
                Shader.SetOpacity(1.0f);
                VertexArrayObject NormalsVAO = (VertexArrayObject)State.Prototype.Mesh.NormalsVAO;
                NormalsVAO.Bind();
                lastVAO = NormalsVAO.handle;
                NormalsVAO.Draw(PrimitiveType.Lines, Face.NormalsIboStartIndex, Face.Vertices.Length * 2);
            }

            // finalize
            if (material.BlendMode == MeshMaterialBlendMode.Additive)
            {
                RestoreBlendFunc();
                Shader.SetIsFog(OptionFog);
            }
        }