public MasterRenderer(int screenWidth, int screenHeight, GraphicsOptions options = null)
        {
            Instance    = this;
            GFXSettings = options ?? new GraphicsOptions();

            ScreenWidth  = screenWidth;
            ScreenHeight = screenHeight;

            if (GLVersion == 0)
            {
                int major = GL.GetInteger(GetPName.MajorVersion);
                int minor = GL.GetInteger(GetPName.MinorVersion);
                GLVersion = major + minor * 0.1f;

                //if (major < 4)
                //    throw new Exception(string.Format("OpenGL 4.0 or later is required to run this game. This machine is running: {0}", GLVersion));
                if (major < 4)
                {
                    DashCMD.WriteWarning("[OpenGL] OpenGL 4.0 or later is required to run this game properly!. This machine is running: {0}", GLVersion);
                }
                else
                {
                    DashCMD.WriteLine("[OpenGL] Version: {0}", ConsoleColor.DarkGray, GLVersion);
                }
            }

            GLError.Begin();

            Camera camera = new Camera(this);

            camera.MakeActive();

            Lights = new LightList();

            Texture.Blank = GLoader.LoadBlankTexture(Color.White);

            Renderer3Ds = new Dictionary <Type, Renderer3D>();
            Renderer2Ds = new Dictionary <Type, Renderer2D>();

            Gui     = new GuiRenderer(this);
            Sprites = new SpriteRenderer(this);
            Sky     = new SkyboxRenderer(this);

            AddRenderer(Gui);
            AddRenderer(Sprites);

            activePipeline = new ForwardPipeline(this);

            StateManager.Enable(EnableCap.CullFace);
            StateManager.Enable(EnableCap.DepthTest);

            GL.CullFace(CullFaceMode.Back);

            ErrorCode mInitError = GLError.End();

            if (mInitError != ErrorCode.NoError)
            {
                throw new Exception(string.Format("Uncaught master renderer init opengl error: {0}", mInitError));
            }
        }
 public void EndRender(Shader shader)
 {
     // Reset blend and depth settigns
     StateManager.Enable(EnableCap.DepthTest);
     StateManager.Disable(EnableCap.Blend);
     // Disable shader
     shader.DisableAttributes();
     // Unbind the quad
     GL.BindVertexArray(0);
     // Stop the shader
     shader.Stop();
 }
        void RenderShadowMap()
        {
            if (Renderer.Sun != null)
            {
                shadowCamera.Position = Renderer.Sun.Position * 1500; // Extrapolate the normalized sun position a bit
                shadowCamera.Update();
            }

            // Enable global wireframe if needed
            if (Renderer.GlobalWireframe)
            {
                StateManager.EnableWireframe();
            }

            // Ensure back-face culling is enabled
            StateManager.Disable(EnableCap.CullFace);
            StateManager.Enable(EnableCap.DepthTest);

            shadowShader.Start();
            shadowShader.LoadMatrix4("lightSpaceMatrix", shadowCamera.LightSpaceMatrix);

            if (GFXSettings.ShadowResolution != shadowMap.Width)
            {
                shadowMap.Resize(GFXSettings.ShadowResolution, GFXSettings.ShadowResolution);
            }

            GL.Viewport(0, 0, shadowMap.Width, shadowMap.Height);
            shadowMap.Bind();

            GL.Clear(ClearBufferMask.DepthBufferBit);

            foreach (Renderer3D renderer in Renderer.Renderer3Ds.Values)
            {
                renderer.Render(shadowShader, RenderPass.Shadow, false);
            }
            GL.DepthFunc(DepthFunction.Always);
            foreach (Renderer3D renderer in Renderer.Renderer3Ds.Values)
            {
                renderer.Render(shadowShader, RenderPass.Shadow, true);
            }
            GL.DepthFunc(DepthFunction.Less);

            shadowMap.Unbind();
            shadowShader.Stop();

            StateManager.DisableWireframe(true);

            GL.Viewport(0, 0,
                        Renderer.ScreenWidth % 2 == 0 ? Renderer.ScreenWidth : Renderer.ScreenWidth - 1,
                        Renderer.ScreenHeight % 2 == 0 ? Renderer.ScreenHeight : Renderer.ScreenHeight + 1);
        }
 public void PrepareRender(Shader shader, bool keepDepthTest = false)
 {
     // Start shader
     shader.Start();
     // Bind the quad
     Quad.Bind();
     // Enable the shader
     shader.EnableAttributes();
     // Setup blending and depth properties
     StateManager.Enable(EnableCap.Blend);
     GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha);
     if (!keepDepthTest)
     {
         StateManager.Disable(EnableCap.DepthTest);
     }
 }
示例#5
0
        public override void Render()
        {
            StateManager.Disable(EnableCap.CullFace);
            StateManager.Disable(EnableCap.DepthTest);
            StateManager.Enable(EnableCap.Blend);
            GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha);

            shader.Start();
            shader.LoadMatrix4("projectionMatrix", Matrix4.CreateOrthographic(Master.ScreenWidth, Master.ScreenHeight, 1, -1));
            shader.LoadMatrix4("viewMatrix", Matrix4.Identity);
            shader.LoadMatrix4("transformationMatrix", Matrix4.Identity);

            SpriteBatch.Render(shader);

            GL.BindTexture(TextureTarget.Texture2D, 0);
            shader.Stop();

            StateManager.Enable(EnableCap.CullFace);
        }
        void RenderObjects()
        {
            // Enable global wireframe if needed
            if (Renderer.GlobalWireframe)
            {
                StateManager.EnableWireframe();
            }

            // Ensure back-face culling is enabled
            StateManager.Enable(EnableCap.CullFace);
            StateManager.Enable(EnableCap.DepthTest);
            StateManager.Enable(EnableCap.Blend);
            GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha);

            forwardShader.Start();
            forwardShader.LoadColor4("colorOverlay", Color.White);
            forwardShader.LoadFloat("entityLighting", 1f);

            // Load global shader variables
            Camera camera = Camera.Active;

            forwardShader.LoadBool("fogEnabled", Renderer.FogEnabled);
            if (Renderer.FogEnabled)
            {
                forwardShader.LoadInt("fogQuality", (int)GFXSettings.FogQuality);
                forwardShader.LoadFloat("fogDensity", Renderer.FogDensity);
                forwardShader.LoadFloat("fogGradient", Renderer.FogGradient);
                forwardShader.LoadFloat("fogMin", Renderer.FogMin);
                forwardShader.LoadFloat("fogMax", Renderer.FogMax);

                GL.ActiveTexture(TextureUnit.Texture1);
                if (GFXSettings.FogQuality == FogQuality.High)
                {
                    skyRenderTarg.Texture.Bind();
                }
                else if (GFXSettings.FogQuality == FogQuality.Medium)
                {
                    Renderer.Sky.skyMap.Bind();
                    forwardShader.LoadFloat("skyMapOffset", Renderer.Sky.skyMapOffset);
                }
                else
                {
                    forwardShader.LoadColor3("fogColor", Renderer.FogColor);
                }
            }
            forwardShader.LoadLights(Renderer.Lights);
            forwardShader.LoadMatrix4("projectionMatrix", camera.ProjectionMatrix);
            forwardShader.LoadMatrix4("viewMatrix", camera.ViewMatrix);
            forwardShader.LoadVector3("cameraPosition", camera.Position);
            forwardShader.LoadFloat("ambientIntensity", Renderer.AmbientIntensity);
            forwardShader.LoadBool("renderShadows", GFXSettings.RenderShadows);
            forwardShader.LoadFloat("lightFalloff", Renderer.LightFalloff);

            if (GFXSettings.RenderShadows)
            {
                forwardShader.LoadMatrix4("lightSpaceMatrix", shadowCamera.LightSpaceMatrix);
                forwardShader.LoadInt("pcfSamples", GFXSettings.ShadowPCFSamples);
                forwardShader.LoadFloat("shadowTexelMultiplier", shadow_texelMultiplier);
                forwardShader.LoadFloat("shadowBias", Renderer.ShadowBias);
                forwardShader.LoadFloat("shadowVisibility", Renderer.ShadowVisibility);

                GL.ActiveTexture(TextureUnit.Texture0);
                shadowMap.BindTex();
            }

            // Render normal geometry
            foreach (Renderer3D renderer in Renderer.Renderer3Ds.Values)
            {
                renderer.Prepare();
                renderer.Render(forwardShader, RenderPass.Normal, false);
            }

            shadowMap.UnbindTex();

            // Render front geometry
            if (GFXSettings.RenderShadows)
            {
                GL.ActiveTexture(TextureUnit.Texture0);
                shadowMap.BindTex();
            }

            GL.Clear(ClearBufferMask.DepthBufferBit);
            foreach (Renderer3D renderer in Renderer.Renderer3Ds.Values)
            {
                renderer.Prepare();
                renderer.Render(forwardShader, RenderPass.Normal, true);
            }

            forwardShader.Stop();
            shadowMap.UnbindTex();

            // Reset wireframe
            StateManager.DisableWireframe(true);
        }
        public override void Render(float deltaTime)
        {
            TryBindScreenshotTarg();
            GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);

            if (IsRenderingEnabled(RendererFlags.Objects))
            {
                if (GFXSettings.RenderShadows)
                {
                    RenderShadowMap();
                    TryBindScreenshotTarg();
                }

                if (IsRenderingEnabled(RendererFlags.Sky))
                {
                    // Render the skybox
                    if (Renderer.FogEnabled && GFXSettings.FogQuality == FogQuality.High)
                    {
                        skyRenderTarg.Bind();

                        GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
                        Renderer.Sky.Render(deltaTime, false);

                        skyRenderTarg.Unbind();
                    }
                }

                if (GFXSettings.EnablePostProcessing)
                {
                    ppBuffer.Bind();
                    GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
                }

                if (IsRenderingEnabled(RendererFlags.Sky))
                {
                    Renderer.Sky.Render(deltaTime, true);
                }

                RenderObjects();

                if (GFXSettings.EnablePostProcessing)
                {
                    ppBuffer.Unbind();
                    TryBindScreenshotTarg();
                }

                // Tell the renderers to clear their batches
                foreach (Renderer3D renderer in Renderer.Renderer3Ds.Values)
                {
                    renderer.ClearBatch();
                }

                if (GFXSettings.EnablePostProcessing)
                {
                    Renderer.Gui.PrepareRender(ppShader);

                    GL.ActiveTexture(TextureUnit.Texture0);
                    ppBuffer.ColorTexture.Bind();

                    ppShader.LoadVector2("resolution", new Vector2(ScreenWidth, ScreenHeight));
                    ppShader.LoadMatrix4("transformationMatrix", Matrix4.Identity);
                    ppShader.LoadBool("apply_fxaa", GFXSettings.ApplyFXAA);

                    // Draw Post Process
                    GL.DrawArrays(BeginMode.TriangleStrip, 0, 4);

                    ppBuffer.ColorTexture.Unbind();
                    Renderer.Gui.EndRender(ppShader);
                }
            }

            if (IsRenderingEnabled(RendererFlags.Gui2D))
            {
                StateManager.Enable(EnableCap.Blend);
                GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha);

                if (Renderer.DebugRenderShadowMap)
                {
                    Renderer.Gui.DebugRenderShadowMap(shadowMap);
                }

                StateManager.Disable(EnableCap.DepthTest);

                // Draw 2D UI
                foreach (Renderer2D renderer in Renderer.Renderer2Ds.Values)
                {
                    renderer.Prepare();
                    renderer.Render();
                }
            }

            if (screenshotRequest != null)
            {
                SaveCurrentBufferAsScreenshot();
                screenshotRenderTarg.Unbind();
                screenshotRequest = null;
            }
        }
        public void Render(float deltaTime, bool drawSun)
        {
            if (Master.Sun != null)
            {
                sun            = Master.Sun;
                sun.LightPower = 1;
            }

            StateManager.Disable(EnableCap.DepthTest);

            shader.Start();
            shader.LoadMatrix4("projectionMatrix", Camera.Active.ProjectionMatrix);
            shader.LoadMatrix4("viewMatrix", Camera.Active.ViewMatrix.ClearTranslation());
            shader.LoadVector3("sunPosition", Master.Sun != null ? Master.Sun.Position : Vector3.Zero);
            //shader.LoadColor3("fogColor", master.FogColor);

            //currentHour += (deltaTime);
            if (currentHour > 24)
            {
                currentHour -= 24;
            }
            else if (currentHour < 0)
            {
                currentHour += 24;
            }

            // http://i.imgur.com/Uj45YN2.png
            float timeP = currentHour / 24;

            /*
             *              timeP     timeT
             * midnight:       0       | 0.75
             * noon:           0.5     | 0.25
             * mid-sun-set:    0.75    | 0.5
             * mid-sun-rise:   0.25    | 0
             */

            float timeT = timeP - 0.25f;

            if (timeT < 0)
            {
                timeT += 1;
            }
            else if (timeT > 1)
            {
                timeT -= 1;
            }

            timeT = timeT * MathHelper.TwoPi;

            float sunY = (float)Math.Sin(timeT);

            Master.LightFalloff     = Interpolation.CubicBezier(0, 1, 1, 1, MathHelper.Clamp(sunY + 0.2f, 0, 1f));
            Master.ShadowVisibility = sunY > 0 ? 1f : 0f;// MathHelper.Clamp(sunY, 0, 1f);

            float shadowMinBias   = 0.0005f;
            float shadowMaxBias   = 0.0015f;
            float shadowBiasRange = shadowMaxBias - shadowMinBias;

            Master.ShadowBias = MathHelper.Clamp(
                (((1.4f - sunY) * shadowMaxBias) - shadowMinBias),
                shadowMinBias, shadowMaxBias);

            if (Master.Sun != null)
            {
                sun.Position = new Vector3((float)Math.Cos(timeT), sunY, 0);
            }

            // 12 - 12 = 0      / 12 = 0
            // 0 - 12 = -12     / 12 = -1
            // 24 - 12 = 12     / 12 = 1

            //float n = Math.Abs((currentHour - 12) / 12) * 1.5f;

            //float mapOff = MathHelper.Clamp(n * n, 0, 1);

            //Diagnostics.DashCMD.WriteLine("Hour: {0:N2}, Off: {1:N2}, Fade: {2:N2}", currentHour, mapOff, mapFade);

            //skyMapOffset = mapOff;
            shader.LoadFloat("skyMapOffset", 1f - Master.LightFalloff);
            shader.LoadFloat("skyMapFade", 1f);
            shader.LoadBool("renderSun", drawSun);

            GL.ActiveTexture(TextureUnit.Texture0);
            skyMap.Bind();

            cube.Bind();
            shader.EnableAttributes();

            if (Master.GlobalWireframe)
            {
                StateManager.EnableWireframe();
            }

            GL.DrawArrays(BeginMode.Triangles, 0, cube.VertexCount);

            StateManager.DisableWireframe();

            shader.DisableAttributes();
            GL.BindVertexArray(0);
            shader.Stop();

            StateManager.Enable(EnableCap.DepthTest);
        }