Exemplo n.º 1
0
        private void ApplyStateCore(GraphicsContext ctx, ShaderProgram program, BlendState currentState)
        {
            if (Enabled)
            {
                // Enable blending
                if (currentState.Enabled == false)
                {
                    Gl.Enable(EnableCap.Blend);
                }

                // Set blending equation
                if (ctx.Extensions.BlendMinmax_EXT)
                {
                    if (EquationSeparated)
                    {
                        if (currentState.RgbEquation != RgbEquation || currentState.AlphaEquation != AlphaEquation)
                        {
                            Gl.BlendEquationSeparate(RgbEquation, AlphaEquation);
                        }
                    }
                    else
                    {
                        if (currentState.RgbEquation != RgbEquation)
                        {
                            Gl.BlendEquation(RgbEquation);
                        }
                    }
                }

                // Set blending function
                if (FunctionSeparated)
                {
                    if (currentState._RgbSrcFactor != _RgbSrcFactor || currentState._RgbDstFactor != _RgbDstFactor || currentState._AlphaSrcFactor != _AlphaSrcFactor || currentState._AlphaDstFactor != _AlphaDstFactor)
                    {
                        Gl.BlendFuncSeparate(_RgbSrcFactor, _RgbDstFactor, _AlphaSrcFactor, _AlphaDstFactor);
                    }
                }
                else
                {
                    if (currentState._RgbSrcFactor != _RgbSrcFactor || currentState._RgbDstFactor != _RgbDstFactor)
                    {
                        Gl.BlendFunc(_RgbSrcFactor, _RgbDstFactor);
                    }
                }

                // Set blend color, if required
                if (RequiresConstColor(_RgbSrcFactor) || RequiresConstColor(_AlphaSrcFactor) || RequiresConstColor(_RgbDstFactor) || RequiresConstColor(_AlphaDstFactor))
                {
                    Gl.BlendColor(_BlendColor.r, _BlendColor.g, _BlendColor.b, _BlendColor.a);
                }
            }
            else
            {
                // Disable blending
                if (currentState.Enabled == true)
                {
                    Gl.Disable(EnableCap.Blend);
                }
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Set ShaderProgram state.
        /// </summary>
        /// <param name="ctx">
        /// A <see cref="GraphicsContext"/> which has defined the shader program <paramref name="sProgram"/>.
        /// </param>
        /// <param name="sProgram">
        /// The <see cref="ShaderProgram"/> which has the state set.
        /// </param>
        public override void ApplyState(GraphicsContext ctx, ShaderProgram sProgram)
        {
            if (ctx == null)
            {
                throw new ArgumentNullException("ctx");
            }

            BlendState currentState = null;             // (BlendState)ctx.CurrentState[StateId];

            if (Enabled)
            {
                // Enable blending
                if (currentState == null || !currentState.Enabled)
                {
                    Gl.Enable(EnableCap.Blend);
                }

                // Set blending equation
                if (ctx.Caps.GlExtensions.BlendMinmax_EXT)
                {
                    if (EquationSeparated)
                    {
                        Gl.BlendEquationSeparate(RgbEquation, AlphaEquation);
                    }
                    else
                    {
                        Gl.BlendEquation((int)RgbEquation);
                    }
                }

                // Set blending function
                if (FunctionSeparated)
                {
                    Gl.BlendFuncSeparate((int)mRgbSrcFactor, (int)mRgbDstFactor, (int)mAlphaSrcFactor, (int)mAlphaDstFactor);
                }
                else
                {
                    Gl.BlendFunc(mRgbSrcFactor, mRgbDstFactor);
                }

                // Set blend color, if required
                if (RequiresConstColor(mRgbSrcFactor) || RequiresConstColor(mAlphaSrcFactor) || RequiresConstColor(mRgbDstFactor) || RequiresConstColor(mAlphaDstFactor))
                {
                    Gl.BlendColor(mBlendColor.Red, mBlendColor.Green, mBlendColor.Blue, mBlendColor.Alpha);
                }
            }
            else
            {
                // Disable blending
                if (currentState == null || currentState.Enabled)
                {
                    Gl.Disable(EnableCap.Blend);
                }
            }
        }
Exemplo n.º 3
0
        static void SetupState()
        {
            Gl.Enable(EnableCap.DepthTest);
            Gl.DepthMask(true);

            Gl.Enable(EnableCap.CullFace);
            Gl.CullFace(CullFaceMode.Back);

            Gl.Enable(EnableCap.Blend);
            Gl.BlendEquationSeparate(BlendEquationMode.FuncAdd, BlendEquationMode.FuncAdd);
            Gl.BlendFuncSeparate(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha, BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha);
        }
Exemplo n.º 4
0
        private void ApplyStateCore(GraphicsContext ctx, ShaderProgram program)
        {
            if (Enabled)
            {
                // Enable blending
                Gl.Enable(EnableCap.Blend);

                // Set blending equation
                if (ctx.Extensions.BlendMinmax_EXT)
                {
                    if (EquationSeparated)
                    {
                        Gl.BlendEquationSeparate(RgbEquation, AlphaEquation);
                    }
                    else
                    {
                        Gl.BlendEquation((int)RgbEquation);
                    }
                }

                // Set blending function
                if (FunctionSeparated)
                {
                    Gl.BlendFuncSeparate((int)_RgbSrcFactor, (int)_RgbDstFactor, (int)_AlphaSrcFactor, (int)_AlphaDstFactor);
                }
                else
                {
                    Gl.BlendFunc(_RgbSrcFactor, _RgbDstFactor);
                }

                // Set blend color, if required
                if (RequiresConstColor(_RgbSrcFactor) || RequiresConstColor(_AlphaSrcFactor) || RequiresConstColor(_RgbDstFactor) || RequiresConstColor(_AlphaDstFactor))
                {
                    Gl.BlendColor(_BlendColor.Red, _BlendColor.Green, _BlendColor.Blue, _BlendColor.Alpha);
                }
            }
            else
            {
                // Disable blending
                Gl.Disable(EnableCap.Blend);
            }
        }
Exemplo n.º 5
0
        static void CreateContext(/*params string[] RequiredExtensions*/)
        {
            GConsole.WriteLine("Initializing OpenGL");

#if DEBUG
            Khronos.KhronosApi.Log += (S, E) => {
                if (E.Name == "glGetError")
                {
                    return;
                }

                Console.ForegroundColor = ConsoleColor.Yellow;
                Console.WriteLine("OpenGL> {0}", string.Format("{0}({1}) = {2}", E.Name, string.Join(", ", E.Args), E.ReturnValue ?? "null"));
                Console.ResetColor();
            };
            Khronos.KhronosApi.LogEnabled = false;            //*/
#endif

            GConsole.WriteLine("Initializing GLFW");
            Glfw.ConfigureNativesDirectory("native/glfw3_64");
            if (!Glfw.Init())
            {
                FatalError("Could not initialize GLFW");
            }

            Glfw.SetErrorCallback((Err, Msg) => {
                FatalError("GLFW({0}) {1}", Err, Msg);
            });

            Width  = CVar.GetInt("width", 800);
            Height = CVar.GetInt("height", 600);

            Glfw.WindowHint(Glfw.Hint.Resizable, CVar.GetBool("resizable"));

            //Glfw.WindowHint(Glfw.Hint.ClientApi, Glfw.ClientApi.None);
            Glfw.WindowHint(Glfw.Hint.ClientApi, Glfw.ClientApi.OpenGL);
            Glfw.WindowHint(Glfw.Hint.ContextCreationApi, Glfw.ContextApi.Native);
            Glfw.WindowHint(Glfw.Hint.Doublebuffer, CVar.GetBool("gl_doublebuffer"));
            Glfw.WindowHint(Glfw.Hint.ContextVersionMajor, CVar.GetInt("gl_major"));
            Glfw.WindowHint(Glfw.Hint.ContextVersionMinor, CVar.GetInt("gl_minor"));

            Glfw.WindowHint(Glfw.Hint.Samples, CVar.GetInt("gl_samples"));
            Glfw.WindowHint(Glfw.Hint.OpenglForwardCompat, CVar.GetBool("gl_forwardcompat"));
            Glfw.WindowHint(Glfw.Hint.OpenglProfile, Glfw.OpenGLProfile.Core);
#if DEBUG
            Glfw.WindowHint(Glfw.Hint.OpenglDebugContext, true);
#endif

            GConsole.WriteLine("Creating window");
            Window = Glfw.CreateWindow(Width, Height, "libTech");
            if (!Window)
            {
                FatalError("Could not create window({0}x{1})", Width, Height);
            }

            Gl.Initialize();
            Glfw.MakeContextCurrent(Window);

            /*bool AllSupported = true;
             *
             * for (int i = 0; i < RequiredExtensions.Length; i++) {
             *      if (!Glfw.ExtensionSupported(RequiredExtensions[i])) {
             *              GConsole.WriteLine("{0} not supported", RequiredExtensions[i]);
             *              AllSupported = false;
             *      }
             * }
             *
             * if (!AllSupported)
             *      while (true)
             *              Thread.Sleep(10);*/

#if DEBUG
            Gl.DebugMessageCallback((Src, DbgType, ID, Severity, Len, Buffer, UserPtr) => {
                if (Severity == Gl.DebugSeverity.Notification)
                {
                    return;
                }

                GConsole.WriteLine("OpenGL {0} {1} {2}, {3}", Src, DbgType, ID, Severity);
                GConsole.WriteLine(Encoding.ASCII.GetString((byte *)Buffer, Len));

                if ((/*Severity == Gl.DebugSeverity.Medium ||*/ Severity == Gl.DebugSeverity.High) && Debugger.IsAttached)
                {
                    Debugger.Break();
                }
            }, IntPtr.Zero);

            Gl.Enable((EnableCap)Gl.DEBUG_OUTPUT);
            Gl.Enable((EnableCap)Gl.DEBUG_OUTPUT_SYNCHRONOUS);
#endif

            GConsole.WriteLine("{0}, {1}", Gl.GetString(StringName.Vendor), Gl.GetString(StringName.Renderer));
            GConsole.WriteLine("OpenGL {0}", Gl.GetString(StringName.Version));
            GConsole.WriteLine("GLSL {0}", Gl.GetString(StringName.ShadingLanguageVersion));

            Gl.ClearColor(69 / 255.0f, 112 / 255.0f, 56 / 255.0f, 1.0f);

            // F**k the police
            Gl.Enable((EnableCap)Gl.DEPTH_CLAMP);
            Gl.Enable(EnableCap.Blend);
            //Gl.VERTEX_PROGRAM_POINT_SIZE;
            Gl.Enable((EnableCap)Gl.VERTEX_PROGRAM_POINT_SIZE);
            //Gl.Enable((EnableCap)Gl.SAMPLE_SHADING);
            //Gl.Enable(EnableCap.FramebufferSrgb);

            Gl.BlendEquationSeparate(BlendEquationMode.FuncAdd, BlendEquationMode.FuncAdd);
            Gl.BlendFuncSeparate(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha, BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha);

            //Gl.BlendEquation(BlendEquationMode.FuncAdd);
            //Gl.BlendFunc(BlendingFactor.One, BlendingFactor.One);

            ShaderProgram.LoadDefaultShaders();
        }
Exemplo n.º 6
0
        public void RenderDrawData(ImDrawDataPtr drawData)
        {
            // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates)
            var fbWidth  = drawData.DisplaySize.X * drawData.FramebufferScale.X;
            var fbHeight = drawData.DisplaySize.Y * drawData.FramebufferScale.Y;

            if (fbWidth < 0 || fbHeight < 0)
            {
                return;
            }

            if (!drawData.Valid || drawData.CmdListsCount == 0)
            {
                return;
            }

            // Backup GL state
            // The vast majority of this probably is not necessary, and ideally should be handled by the main render application
            // with a state cache if actually required.
            // At the very least, however, it appears that SDL does not maintain/reset its own state perfectly when using opengl
            // and the scissor rect will break things.  Since I'm not sure if anything else would also break, and since this backup
            // is not nearly as terrible as the DX11 version was, I am leaving this in place for now.
            Gl.GetInteger(GetPName.ActiveTexture, out int lastActiveTexture);
            Gl.GetInteger(GetPName.CurrentProgram, out int lastProgram);
            Gl.GetInteger(GetPName.TextureBinding2d, out int lastTexture);
            Gl.GetInteger(GetPName.ArrayBufferBinding, out int lastArrayBuffer);
            Gl.GetInteger(GetPName.VertexArrayBinding, out int lastVertexArrayObject);
            Gl.GetInteger(GetPName.PolygonMode, out int lastPolygonMode);
            var lastViewport = new int[4];

            Gl.Get(GetPName.Viewport, lastViewport);
            var lastScissorBox = new int[4];

            Gl.Get(GetPName.ScissorBox, lastScissorBox);
            Gl.GetInteger(GetPName.BlendSrcRgb, out int lastBlendSrcRgb);
            Gl.GetInteger(GetPName.BlendDstRgb, out int lastBlendDstRgb);
            Gl.GetInteger(GetPName.BlendSrcAlpha, out int lastBlendSrcAlpha);
            Gl.GetInteger(GetPName.BlendDstAlpha, out int lastBlendDstAlpha);
            Gl.GetInteger(GetPName.BlendEquationRgb, out int lastBlendEquationRgb);
            Gl.GetInteger(GetPName.BlendEquationAlpha, out int lastBlendEquationAlpha);
            var lastEnableBlend       = Gl.IsEnabled(EnableCap.Blend);
            var lastEnableCullFace    = Gl.IsEnabled(EnableCap.CullFace);
            var lastEnableDepthTest   = Gl.IsEnabled(EnableCap.DepthTest);
            var lastEnableScissorTest = Gl.IsEnabled(EnableCap.ScissorTest);

            // Setup desired GL state
            Gl.ActiveTexture(TextureUnit.Texture0);
            // Recreate the VAO every time (this is to easily allow multiple GL contexts to be rendered to. VAO are not shared among GL contexts)
            // The renderer would actually work without any VAO bound, but then our VertexAttrib calls would overwrite the default one currently bound.
            _vertexArrayObject = Gl.GenVertexArray();
            SetupRenderState(drawData);

            // Will project scissor/clipping rectangles into framebuffer space
            var clipOff   = drawData.DisplayPos;            // (0,0) unless using multi-viewports
            var clipScale = drawData.FramebufferScale;      // (1,1) unless using retina display which are often (2,2)

            // Render command lists
            for (var n = 0; n < drawData.CmdListsCount; n++)
            {
                var cmdList = drawData.CmdListsRange[n];

                // Upload vertex/index buffers
                // TODO: this is *awful*
                Gl.BufferData(BufferTarget.ArrayBuffer, (uint)(cmdList.VtxBuffer.Size * Unsafe.SizeOf <ImDrawVert>()), cmdList.VtxBuffer.Data, BufferUsage.StreamDraw);
                Gl.BufferData(BufferTarget.ElementArrayBuffer, (uint)(cmdList.IdxBuffer.Size * sizeof(ushort)), cmdList.IdxBuffer.Data, BufferUsage.StreamDraw);

                for (var i = 0; i < cmdList.CmdBuffer.Size; i++)
                {
                    var pcmd = cmdList.CmdBuffer[i];
                    if (pcmd.UserCallback != IntPtr.Zero)
                    {
                        // TODO
                        throw new NotImplementedException();
                    }
                    else
                    {
                        // Project scissor/clipping rectangles into framebuffer space
                        var clipRect = new Vector4
                        {
                            X = (pcmd.ClipRect.X - clipOff.X) * clipScale.X,
                            Y = (pcmd.ClipRect.Y - clipOff.Y) * clipScale.Y,
                            Z = (pcmd.ClipRect.Z - clipOff.X) * clipScale.X,
                            W = (pcmd.ClipRect.W - clipOff.Y) * clipScale.Y,
                        };

                        if (clipRect.X < fbWidth && clipRect.Y < fbHeight && clipRect.Z >= 0 && clipRect.W >= 0)
                        {
                            // Apply scissor/clipping rectangle
                            Gl.Scissor((int)clipRect.X, (int)(fbHeight - clipRect.W), (int)(clipRect.Z - clipRect.X), (int)(clipRect.W - clipRect.Y));

                            // Bind texture, Draw
                            Gl.BindTexture(TextureTarget.Texture2d, (uint)pcmd.TextureId);
                            Gl.DrawElementsBaseVertex(PrimitiveType.Triangles, (int)pcmd.ElemCount, DrawElementsType.UnsignedShort, (IntPtr)(pcmd.IdxOffset * sizeof(short)), (int)pcmd.VtxOffset);
                        }
                    }
                }
            }

            // Destroy the temporary VAO
            Gl.DeleteVertexArrays(_vertexArrayObject);

            // Restore modified GL state
            Gl.UseProgram((uint)lastProgram);
            Gl.BindTexture(TextureTarget.Texture2d, (uint)lastTexture);
            Gl.ActiveTexture((TextureUnit)lastActiveTexture);
            Gl.BindVertexArray((uint)lastVertexArrayObject);
            Gl.BindBuffer(BufferTarget.ArrayBuffer, (uint)lastArrayBuffer);
            Gl.BlendEquationSeparate((BlendEquationMode)lastBlendEquationRgb, (BlendEquationMode)lastBlendEquationAlpha);
            Gl.BlendFuncSeparate((BlendingFactor)lastBlendSrcRgb, (BlendingFactor)lastBlendDstRgb, (BlendingFactor)lastBlendSrcAlpha, (BlendingFactor)lastBlendDstAlpha);
            if (lastEnableBlend)
            {
                Gl.Enable(EnableCap.Blend);
            }
            else
            {
                Gl.Disable(EnableCap.Blend);
            }
            if (lastEnableCullFace)
            {
                Gl.Enable(EnableCap.CullFace);
            }
            else
            {
                Gl.Disable(EnableCap.CullFace);
            }
            if (lastEnableDepthTest)
            {
                Gl.Enable(EnableCap.DepthTest);
            }
            else
            {
                Gl.Disable(EnableCap.DepthTest);
            }
            if (lastEnableScissorTest)
            {
                Gl.Enable(EnableCap.ScissorTest);
            }
            else
            {
                Gl.Disable(EnableCap.ScissorTest);
            }
            Gl.PolygonMode(MaterialFace.FrontAndBack, (PolygonMode)lastPolygonMode);
            Gl.Viewport(lastViewport[0], lastViewport[1], lastViewport[2], lastViewport[3]);
            Gl.Scissor(lastScissorBox[0], lastScissorBox[1], lastScissorBox[2], lastScissorBox[3]);
        }