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"); }
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"); }
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"); }
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); }
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(); }
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"); }
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); }
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"); }
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); }
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"); }
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(); }