/// <summary>SkyHost constructor. Note: constructor only runs for clients, not server as it only uses static methods in SkyHost.</summary> internal SkyHost() { SkyTopCurrentColor = SkyTopBrightestColor; SkyBottomCurrentColor = SkyBottomBrightestColor; var fa = SkyBottomCurrentColor.ToFloatArray(); GL.ClearColor(fa[0], fa[1], fa[2], 1); }
public void Update(FrameEventArgs e) { var brightnessPercent = UpdateSun(e); if (brightnessPercent > 1) { brightnessPercent = 1; //cant multiply by any more than 100%, sky is at 100% or greater for a large portion of the daytime where the sky gradient colors remain the same } //need to update following values on every update in case the sun position has been altered either by an admin or server sync SkyTopCurrentColor = SkyTopBrightestColor * brightnessPercent; SkyBottomCurrentColor = SkyBottomBrightestColor * brightnessPercent; var fa = SkyBottomCurrentColor.ToFloatArray(); //need a float array to pass to ClearColor and Fog GL.ClearColor(fa[0], fa[1], fa[2], 1); GL.Fog(FogParameter.FogColor, Game.Player.EyesUnderWater ? (WorldHost.FogColorUnderWater * brightnessPercent).ToFloatArray() : fa); }
/// <summary> /// Push the modelview matrix, load the identity and load a new matrix at the origin and looking the same way as the player. /// After rendering the skybox, enable blending and render the sun and moon. /// </summary> /// <remarks> /// A future optimization would be to draw all opaque world objects first and then render the skybox followed by transparent world objects. /// This prevents the pixel shader from drawing many of the same pixels twice. However is more complicated for a small benefit. /// </remarks> public void Render(FrameEventArgs e) { GL.PushMatrix(); GL.LoadIdentity(); var sky = Matrix4d.LookAt(0, 0, 0, (float)Math.Cos(Game.Player.Coords.Direction) * (float)Math.Cos(Game.Player.Coords.Pitch), (float)Math.Sin(Game.Player.Coords.Pitch), (float)Math.Sin(Game.Player.Coords.Direction) * (float)Math.Cos(Game.Player.Coords.Pitch), 0, 1, 0); GL.LoadMatrix(ref sky); GL.PushAttrib(AttribMask.EnableBit); GL.Disable(EnableCap.DepthTest); GL.Disable(EnableCap.Texture2D); const float TOP = 0.3f; const float BOTTOM = 0.04f; //make bottom color at the horizon so we can always set the fog color to the same and have nice blending const float SIDE = 0.5f; const float SIDE_OUT = SIDE + SIDE / 2; //where the sides stick out to create 8 faces //draw skybox as a triangle fan with a center top point and 8 bottom points, cuts down on the noticeable gradient corners //drawn clockwise because we are "inside" the skybox, not in a display list because the colors change on every render (could make a dynamic vbo) GL.Begin(BeginMode.TriangleFan); GL.Color3(SkyTopCurrentColor.ToFloatArray()); GL.Vertex3(0, TOP, 0); //center top point GL.Color3(SkyBottomCurrentColor.ToFloatArray()); GL.Vertex3(SIDE, BOTTOM, SIDE); GL.Vertex3(0, BOTTOM, SIDE_OUT); GL.Vertex3(-SIDE, BOTTOM, SIDE); GL.Vertex3(-SIDE_OUT, BOTTOM, 0); GL.Vertex3(-SIDE, BOTTOM, -SIDE); GL.Vertex3(0, BOTTOM, -SIDE_OUT); GL.Vertex3(SIDE, BOTTOM, -SIDE); GL.Vertex3(SIDE_OUT, BOTTOM, 0); GL.Vertex3(SIDE, BOTTOM, SIDE); GL.End(); GlHelper.ResetColor(); //render sun/moon GL.Enable(EnableCap.Texture2D); GL.Enable(EnableCap.Blend); DisplayList.RenderDisplayList(DisplayList.SunId, SunPosition.X, SunPosition.Y, 0, Textures.EnvironmentTextureType.Sun); DisplayList.RenderDisplayList(DisplayList.MoonId, -SunPosition.X, -SunPosition.Y, 0, Textures.EnvironmentTextureType.Moon); GL.PopAttrib(); GL.PopMatrix(); }