Beispiel #1
0
        internal Shader(string vertRelative, string fragRelative, bool build = false)
        {
            if (!build)
            {
                RelativeVertexShader   = vertRelative;
                RelativeFragmentShader = fragRelative;
                return;
            }

            int vertShader = CompileShader(ShaderType.VertexShader, vertRelative);

            GLException.CheckError("Compile vertex shader");

            int fragShader = CompileShader(ShaderType.FragmentShader, fragRelative);

            GLException.CheckError("Compile fragment shader");

            Program = GL.CreateProgram();
            GLException.CheckError("Create shader program");

            GL.AttachShader(Program, vertShader);
            GL.AttachShader(Program, fragShader);
            GL.LinkProgram(Program);
            GL.GetProgram(Program, GetProgramParameterName.LinkStatus, out int Success);
            if (Success == 0)
            {
                throw new GLException(ErrorCode.InvalidOperation, "GL.LinkProgram had info log: " + GL.GetProgramInfoLog(Program));
            }

            GL.DeleteShader(vertShader);
            GL.DeleteShader(fragShader);
            GLException.CheckError("Shader");
        }
Beispiel #2
0
        internal void Load(string basePath)
        {
            string vertexSource = File.ReadAllText(Path.Combine(basePath, RelativeVertexShader));
            int    vertShader   = CompileShader(ShaderType.VertexShader, vertexSource);

            GLException.CheckError("Compile vertex shader");

            string fragmentSource = File.ReadAllText(Path.Combine(basePath, RelativeFragmentShader));
            int    fragShader     = CompileShader(ShaderType.FragmentShader, fragmentSource);

            GLException.CheckError("Compile fragment shader");

            Program = GL.CreateProgram();
            GLException.CheckError("Create shader program");

            GL.AttachShader(Program, vertShader);
            GL.AttachShader(Program, fragShader);
            GL.LinkProgram(Program);
            GL.GetProgram(Program, GetProgramParameterName.LinkStatus, out int Success);
            if (Success == 0)
            {
                throw new GLException(ErrorCode.InvalidOperation, "GL.LinkProgram had info log: " + GL.GetProgramInfoLog(Program));
            }

            GL.DeleteShader(vertShader);
            GL.DeleteShader(fragShader);
            GLException.CheckError("Shader");
        }
Beispiel #3
0
        public void Draw(Camera camera)
        {
            bool blendState = GL.IsEnabled(EnableCap.Blend);

            GL.Enable(EnableCap.Blend);
            GL.BlendEquation(BlendEquationMode.FuncAdd);
            GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha);


            DefaultShader.UseShader();
            OpenTK.Mathematics.Matrix4 modelMatrix = OpenTK.Mathematics.Matrix4.Identity * OpenTK.Mathematics.Matrix4.CreateTranslation(0, 0.0f, 0);
            DefaultShader.SetMatrix("model", ref modelMatrix);

            OpenTK.Mathematics.Matrix4 viewMatrix = camera.GetViewMatrix();
            DefaultShader.SetMatrix("view", ref viewMatrix);

            OpenTK.Mathematics.Matrix4 projectionMatrix = camera.ProjectionMatrix;
            DefaultShader.SetMatrix("projection", ref projectionMatrix);

            DefaultShader.SetVector3("lineColor", ref GridColor);
            DefaultShader.SetVector3("cam_pos", ref camera.transform.Position);


            GLException.CheckError("LineGridRenderer Shader");
            VAO.Draw();

            if (!blendState)
            {
                GL.Disable(EnableCap.Blend);
            }

            GLException.CheckError("LineGridRenderer VAO");
        }
Beispiel #4
0
        public CubeMap(Bitmap[] textures, TextureUnit slot, bool srgb = false)
        {
            TextureSlot    = slot;
            InternalFormat = srgb ? Srgb8Alpha8 : SizedInternalFormat.Rgba8;

            // There is only one level
            MipmapLevels = 1;

            GLException.CheckError("Clear");

            GL.CreateTextures(TextureTarget.TextureCubeMap, 1, out GLTexture);
            GLException.CheckError("CreateTexture");

            BindTexture();
            for (int i = 0; i < textures.Length; i++)
            {
                Bitmap     bmp  = textures[i];
                BitmapData data = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, global::System.Drawing.Imaging.PixelFormat.Format32bppArgb);

                GL.TexImage2D(TextureTarget.TextureCubeMapPositiveX + i, 0, PixelInternalFormat.Rgba8, bmp.Width, bmp.Height, 0, PixelFormat.Rgba, PixelType.UnsignedByte, data.Scan0);
                GLException.CheckError("SubImage");

                bmp.UnlockBits(data);
                bmp.Dispose();
            }
            UnbindTexture();

            SetMagFilter(TextureMagFilter.Linear);
            SetMinFilter(TextureMinFilter.Linear);
            SetWrap(TextureCoordinate.S, TextureWrapMode.ClampToEdge);
            SetWrap(TextureCoordinate.T, TextureWrapMode.ClampToEdge);
            SetWrap(TextureCoordinate.R, TextureWrapMode.ClampToEdge);

            GL.TextureParameter(GLTexture, TextureParameterName.TextureMaxLevel, MipmapLevels - 1);
        }
Beispiel #5
0
        public Texture2D(Bitmap image, bool generateMipmaps, TextureUnit slot, bool srgb)
        {
            Width          = image.Width;
            Height         = image.Height;
            TextureSlot    = slot;
            InternalFormat = srgb ? Srgb8Alpha8 : SizedInternalFormat.Rgba8;

            if (generateMipmaps)
            {
                // Calculate how many levels to generate for this texture
                MipmapLevels = (int)Math.Floor(Math.Log(Math.Max(Width, Height), 2));
            }
            else
            {
                // There is only one level
                MipmapLevels = 1;
            }

            GLException.CheckError("Clear");

            GL.CreateTextures(TextureTarget.Texture2D, 1, out GLTexture);
            GL.TextureStorage2D(GLTexture, MipmapLevels, InternalFormat, Width, Height);
            GLException.CheckError("Storage2d");

            BitmapData data = image.LockBits(new Rectangle(0, 0, Width, Height), ImageLockMode.ReadOnly, global::System.Drawing.Imaging.PixelFormat.Format32bppArgb);

            GL.TextureSubImage2D(GLTexture, 0, 0, 0, Width, Height, PixelFormat.Bgra, PixelType.UnsignedByte, data.Scan0);
            GLException.CheckError("SubImage");

            image.UnlockBits(data);

            if (generateMipmaps)
            {
                GL.GenerateTextureMipmap(GLTexture);
            }

            GL.TextureParameter(GLTexture, TextureParameterName.TextureWrapS, (int)TextureWrapMode.Repeat);
            GLException.CheckError("WrapS");
            GL.TextureParameter(GLTexture, TextureParameterName.TextureWrapT, (int)TextureWrapMode.Repeat);
            GLException.CheckError("WrapT");

            GL.TextureParameter(GLTexture, TextureParameterName.TextureMinFilter, (int)(generateMipmaps ? TextureMinFilter.Linear : TextureMinFilter.LinearMipmapLinear));
            GL.TextureParameter(GLTexture, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
            GLException.CheckError("Filtering");

            GL.TextureParameter(GLTexture, TextureParameterName.TextureMaxLevel, MipmapLevels - 1);

            // This is a bit weird to do here
            image.Dispose();
        }
Beispiel #6
0
        public void Draw(Camera camera)
        {
            if (Target == null)
            {
                return;
            }

            bool depthState = GL.IsEnabled(EnableCap.DepthTest);

            GL.Disable(EnableCap.DepthTest);

            DefaultShader.UseShader();
            float   distance    = Vector3.Distance(camera.transform.Position, Target.Position);
            Matrix4 modelMatrix = Matrix4.Identity * Matrix4.CreateScale(Scale.X * (distance / 32.0f), Scale.Y * (distance / 32.0f), Scale.Z * (distance / 32.0f)) * Matrix4.CreateTranslation(Target.Position.X, Target.Position.Y, Target.Position.Z);

            DefaultShader.SetMatrix("model", ref modelMatrix);

            Matrix4 viewMatrix = camera.GetViewMatrix();

            DefaultShader.SetMatrix("view", ref viewMatrix);

            Matrix4 projectionMatrix = camera.ProjectionMatrix;

            DefaultShader.SetMatrix("projection", ref projectionMatrix);


            // Draw X Axis
            DefaultShader.SetVector3("lineColor", ref xAxisColor);
            GLException.CheckError("AxisRenderer Shader");
            VAO.Draw(PrimitiveType.LineStrip, 0, vert_offset);

            // Draw Y Axis
            DefaultShader.SetVector3("lineColor", ref yAxisColor);
            GLException.CheckError("AxisRenderer Shader");
            VAO.Draw(PrimitiveType.LineStrip, vert_offset, vert_offset * 2);

            // Draw Z Axis
            DefaultShader.SetVector3("lineColor", ref zAxisColor);
            GLException.CheckError("AxisRenderer Shader");
            VAO.Draw(PrimitiveType.LineStrip, vert_offset * 2, vert_offset * 3);

            if (depthState)
            {
                GL.Enable(EnableCap.DepthTest);
            }

            GLException.CheckError("AxisRenderer VAO");
        }
Beispiel #7
0
        private int CompileShader(ShaderType type, string source)
        {
            GLException.CheckError("Before CreateShader(" + type + ")");
            int Shader = GL.CreateShader(type);

            GL.ShaderSource(Shader, 1, new string[] { source }, new int[] { source.Length });
            GL.CompileShader(Shader);
            GL.GetShader(Shader, ShaderParameter.CompileStatus, out int success);
            if (success != 1)
            {
                GL.GetShaderInfoLog(Shader, out string infoLog);
                throw new GLException(ErrorCode.InvalidOperation, $"GL.CompileShader for shader [{type}] had info log: {infoLog}");
            }

            return(Shader);
        }
Beispiel #8
0
        public void Draw(Camera camera, GameObject gameObject)
        {
            bool blendState = GL.IsEnabled(EnableCap.Blend);

            GL.Disable(EnableCap.Blend);
            //GL.BlendEquation(BlendEquationMode.FuncAdd);
            //GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha);


            DefaultShader.UseShader();

            // compute custom model matrix based on the physics stuff
            OpenTK.Mathematics.Matrix4 min = OpenTK.Mathematics.Matrix4.CreateTranslation(gameObject.BodyReference.BoundingBox.Min.X, gameObject.BodyReference.BoundingBox.Min.Y, gameObject.BodyReference.BoundingBox.Min.Z);
            //OpenTK.Mathematics.Matrix4 max = OpenTK.Mathematics.Matrix4.CreateTranslation(gameObject.BodyReference.BoundingBox.Max.X, gameObject.BodyReference.BoundingBox.Max.Y, gameObject.BodyReference.BoundingBox.Max.Z);



            OpenTK.Mathematics.Matrix4 modelMatrix = gameObject.transform.GetModelMatrix();
            DefaultShader.SetMatrix("model", ref modelMatrix);

            OpenTK.Mathematics.Matrix4 viewMatrix = camera.GetViewMatrix();
            DefaultShader.SetMatrix("view", ref viewMatrix);

            OpenTK.Mathematics.Matrix4 projectionMatrix = camera.ProjectionMatrix;
            DefaultShader.SetMatrix("projection", ref projectionMatrix);

            DefaultShader.SetVector3("lineColor", ref Color);


            GLException.CheckError("LineShapeRenderer Shader");
            VAO.Draw();

            if (blendState)
            {
                GL.Enable(EnableCap.Blend);
            }

            GLException.CheckError("LineShapeRenderer VAO");
        }
Beispiel #9
0
        internal void Load(string basePath)
        {
            using (Bitmap image = (Bitmap)Image.FromFile(Path.Combine(basePath, RelativeAssetPath)))
            {
                Width  = image.Width;
                Height = image.Height;

                GLException.CheckError("Clear");

                GL.CreateTextures(TextureTarget.Texture2D, 1, out GLTexture);
                GL.TextureStorage2D(GLTexture, MipmapLevels, InternalFormat, Width, Height);
                GLException.CheckError("Storage2d");

                BitmapData data = image.LockBits(new Rectangle(0, 0, Width, Height), ImageLockMode.ReadOnly, global::System.Drawing.Imaging.PixelFormat.Format32bppArgb);

                GL.TextureSubImage2D(GLTexture, 0, 0, 0, Width, Height, PixelFormat.Bgra, PixelType.UnsignedByte, data.Scan0);
                GLException.CheckError("SubImage");

                image.UnlockBits(data);
            }

            if (MipmapLevels > 1)
            {
                GL.GenerateTextureMipmap(GLTexture);
            }

            GL.TextureParameter(GLTexture, TextureParameterName.TextureWrapS, (int)TextureWrapMode.Repeat);
            GLException.CheckError("WrapS");
            GL.TextureParameter(GLTexture, TextureParameterName.TextureWrapT, (int)TextureWrapMode.Repeat);
            GLException.CheckError("WrapT");

            GL.TextureParameter(GLTexture, TextureParameterName.TextureMinFilter, (int)(MipmapLevels > 1 ? TextureMinFilter.Linear : TextureMinFilter.LinearMipmapLinear));
            GL.TextureParameter(GLTexture, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
            GLException.CheckError("Filtering");

            GL.TextureParameter(GLTexture, TextureParameterName.TextureMaxLevel, MipmapLevels - 1);
        }
Beispiel #10
0
        public void CreateDeviceResources()
        {
            GL.CreateVertexArrays(1, out _vertexArray);

            _vertexBufferSize = 10000;
            _indexBufferSize  = 2000;

            GL.CreateBuffers(1, out _vertexBuffer);
            GL.CreateBuffers(1, out _indexBuffer);
            GL.NamedBufferData(_vertexBuffer, _vertexBufferSize, IntPtr.Zero, BufferUsageHint.DynamicDraw);
            GL.NamedBufferData(_indexBuffer, _indexBufferSize, IntPtr.Zero, BufferUsageHint.DynamicDraw);

            RecreateFontDeviceTexture();

            _shader = new Shader(Resources.imgui_vert_shader, Resources.imgui_frag_shader, true);

            GL.VertexArrayVertexBuffer(_vertexArray, 0, _vertexBuffer, IntPtr.Zero, Unsafe.SizeOf <ImDrawVert>());
            GL.VertexArrayElementBuffer(_vertexArray, _indexBuffer);

            GL.EnableVertexArrayAttrib(_vertexArray, 0);
            GL.VertexArrayAttribBinding(_vertexArray, 0, 0);
            GL.VertexArrayAttribFormat(_vertexArray, 0, 2, VertexAttribType.Float, false, 0);

            GL.EnableVertexArrayAttrib(_vertexArray, 1);
            GL.VertexArrayAttribBinding(_vertexArray, 1, 0);
            GL.VertexArrayAttribFormat(_vertexArray, 1, 2, VertexAttribType.Float, false, 8);

            GL.EnableVertexArrayAttrib(_vertexArray, 2);
            GL.VertexArrayAttribBinding(_vertexArray, 2, 0);
            GL.VertexArrayAttribFormat(_vertexArray, 2, 4, VertexAttribType.UnsignedByte, true, 16);



            IconAtlas = new Texture2D(Resources.editor_icon_atlas, false, TextureUnit.Texture0, false);

            GLException.CheckError("ImGui Setup");
        }
Beispiel #11
0
        private void RenderImDrawData(ImDrawDataPtr draw_data)
        {
            if (draw_data.CmdListsCount == 0)
            {
                return;
            }

            for (int i = 0; i < draw_data.CmdListsCount; i++)
            {
                ImDrawListPtr cmd_list = draw_data.CmdListsRange[i];

                int vertexSize = cmd_list.VtxBuffer.Size * Unsafe.SizeOf <ImDrawVert>();
                if (vertexSize > _vertexBufferSize)
                {
                    int newSize = (int)Math.Max(_vertexBufferSize * 1.5f, vertexSize);
                    GL.NamedBufferData(_vertexBuffer, newSize, IntPtr.Zero, BufferUsageHint.DynamicDraw);
                    _vertexBufferSize = newSize;

                    //Console.WriteLine($"Resized dear imgui vertex buffer to new size {_vertexBufferSize}");
                }

                int indexSize = cmd_list.IdxBuffer.Size * sizeof(ushort);
                if (indexSize > _indexBufferSize)
                {
                    int newSize = (int)Math.Max(_indexBufferSize * 1.5f, indexSize);
                    GL.NamedBufferData(_indexBuffer, newSize, IntPtr.Zero, BufferUsageHint.DynamicDraw);
                    _indexBufferSize = newSize;

                    //Console.WriteLine($"Resized dear imgui index buffer to new size {_indexBufferSize}");
                }
            }

            // Setup orthographic projection matrix into our constant buffer
            ImGuiIOPtr io  = ImGui.GetIO();
            Matrix4    mvp = Matrix4.CreateOrthographicOffCenter(0.0f, io.DisplaySize.X, io.DisplaySize.Y, 0.0f, -1.0f, 1.0f);

            _shader.UseShader();
            _shader.SetMatrix("projection_matrix", ref mvp);
            _shader.SetInt("in_fontTexture", 0);
            GLException.CheckError("ImGui Projection");

            GL.BindVertexArray(_vertexArray);
            GLException.CheckError("ImGui VAO");
            draw_data.ScaleClipRects(io.DisplayFramebufferScale);

            SetRenderSettings(io);

            // Render command lists
            for (int n = 0; n < draw_data.CmdListsCount; n++)
            {
                ImDrawListPtr cmd_list = draw_data.CmdListsRange[n];

                GL.NamedBufferSubData(_vertexBuffer, IntPtr.Zero, cmd_list.VtxBuffer.Size * Unsafe.SizeOf <ImDrawVert>(), cmd_list.VtxBuffer.Data);
                GLException.CheckError($"ImGui Data Vert {n}");

                GL.NamedBufferSubData(_indexBuffer, IntPtr.Zero, cmd_list.IdxBuffer.Size * sizeof(ushort), cmd_list.IdxBuffer.Data);
                GLException.CheckError($"ImGui Data Idx {n}");

                int vtx_offset = 0;
                int idx_offset = 0;

                for (int cmd_i = 0; cmd_i < cmd_list.CmdBuffer.Size; cmd_i++)
                {
                    ImDrawCmdPtr pcmd = cmd_list.CmdBuffer[cmd_i];
                    if (pcmd.UserCallback != IntPtr.Zero)
                    {
                        int callback     = (int)pcmd.UserCallback;
                        int callbackData = (int)pcmd.UserCallbackData;
                        if (ImGuiDelegates[callback - 1](ImGuiDelegateArgs[callbackData - 1]))
                        {
                            _shader.UseShader();
                            _shader.SetMatrix("projection_matrix", ref mvp);
                            _shader.SetInt("in_fontTexture", 0);
                            GLException.CheckError("ImGui Projection");

                            GL.BindVertexArray(_vertexArray);
                            GLException.CheckError("ImGui VAO");
                            draw_data.ScaleClipRects(io.DisplayFramebufferScale);

                            // Reset ImGui values
                            SetRenderSettings(io);
                        }
                    }
                    else
                    {
                        GL.ActiveTexture(TextureUnit.Texture0);
                        GL.BindTexture(TextureTarget.Texture2D, (int)pcmd.TextureId);
                        GLException.CheckError("ImGui Texture");

                        // We do _windowHeight - (int)clip.W instead of (int)clip.Y because gl has flipped Y when it comes to these coordinates
                        var clip = pcmd.ClipRect;
                        GL.Scissor((int)clip.X, _windowHeight - (int)clip.W, (int)(clip.Z - clip.X), (int)(clip.W - clip.Y));
                        GLException.CheckError("ImGui Scissor");

                        if ((io.BackendFlags & ImGuiBackendFlags.RendererHasVtxOffset) != 0)
                        {
                            GL.DrawElementsBaseVertex(PrimitiveType.Triangles, (int)pcmd.ElemCount, DrawElementsType.UnsignedShort, (IntPtr)(idx_offset * sizeof(ushort)), vtx_offset);
                        }
                        else
                        {
                            GL.DrawElements(BeginMode.Triangles, (int)pcmd.ElemCount, DrawElementsType.UnsignedShort, (int)pcmd.IdxOffset * sizeof(ushort));
                        }
                    }

                    GLException.CheckError("ImGui Draw");
                    idx_offset += (int)pcmd.ElemCount;
                }

                vtx_offset += cmd_list.VtxBuffer.Size;
            }

            UnsetRenderSettings();
        }