public void Init(IntPtr windowHandle, Size size) { if (!CreateEGLContext()) { Debug.WriteLine("Failed to create EGL context."); return; } var nativeWindow = windowHandle; if (!CreateEGLSurface(nativeWindow)) { Debug.WriteLine("Failed to create EGL surface."); return; } OpenGLMaterial.InitCommonMaterials(); // Other state GL.Disable(GL.GL_CULL_FACE); GL.Disable(GL.GL_DEPTH_TEST); GL.DepthFunc(GL.GL_NEVER); GL.Enable(GL.GL_SCISSOR_TEST); Utility.CheckGLESError(); }
public void Init(IntPtr windowHandle, Size size) { CreateOpenGLContext(windowHandle); OpenGLMaterial.InitCommonMaterials(); ImGui.Development.SpecialMesh.Init(); // Other state GL.Enable(GL.GL_MULTISAMPLE); GL.Disable(GL.GL_CULL_FACE); GL.Disable(GL.GL_DEPTH_TEST); GL.DepthFunc(GL.GL_NEVER); GL.Enable(GL.GL_SCISSOR_TEST); //set-up framebuffer GL.GenFramebuffers(1, framebuffers); GL.GenTextures(1, textures); framebuffer = framebuffers[0]; framebufferColorTexture = textures[0]; GL.BindFramebuffer(GL.GL_FRAMEBUFFER_EXT, framebuffer); //attach color texture to the framebuffer GL.BindTexture(GL.GL_TEXTURE_2D, framebufferColorTexture); GL.TexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_RGBA, (int)size.Width, (int)size.Height, 0, GL.GL_RGB, GL.GL_UNSIGNED_BYTE, IntPtr.Zero); GL.FramebufferTexture2D(GL.GL_FRAMEBUFFER_EXT, GL.GL_COLOR_ATTACHMENT0_EXT, GL.GL_TEXTURE_2D, framebufferColorTexture, 0); GL.TexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_NEAREST); GL.TexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_NEAREST); GL.TexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_S, (int)GL.GL_CLAMP); GL.TexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_T, (int)GL.GL_CLAMP); GL.GetFramebufferAttachmentParameteriv(GL.GL_FRAMEBUFFER_EXT, GL.GL_COLOR_ATTACHMENT0_EXT, GL.GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE, IntBuffer); Utility.CheckGLError(); var alphaBits = IntBuffer[0]; if(alphaBits != 8) { throw new Exception("Framebuffer format is not R8G8B8A8."); } //check if framebuffer is complete if (GL.CheckFramebufferStatus(GL.GL_FRAMEBUFFER_EXT) != GL.GL_FRAMEBUFFER_COMPLETE_EXT) { throw new Exception("Framebuffer is not complete."); } GL.BindFramebuffer(GL.GL_FRAMEBUFFER_EXT, 0); quadMesh = new QuadMesh(size.Width, size.Height); Utility.CheckGLError(); }
public void Init(IntPtr windowHandle, Size size) { CreateOpenGLContext(windowHandle); OpenGLMaterial.InitCommonMaterials(); ImGui.Development.SpecialMesh.Init(); // Other state GL.Enable(GL.GL_MULTISAMPLE); GL.Disable(GL.GL_CULL_FACE); GL.Disable(GL.GL_DEPTH_TEST); GL.DepthFunc(GL.GL_NEVER); GL.Enable(GL.GL_SCISSOR_TEST); InitializeTextRenderResources(size); }
public byte[] DrawMeshToImage( int width, int height, Mesh mesh, OpenGLMaterial material) { List<DrawCommand> commandBuffer = mesh.CommandBuffer; if (commandBuffer.Count == 0 || commandBuffer[0].ElemCount == 0) { return null; } VertexBuffer vertexBuffer = mesh.VertexBuffer; IndexBuffer indexBuffer = mesh.IndexBuffer; // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled GL.Enable(GL.GL_BLEND); GL.BlendEquation(GL.GL_FUNC_ADD_EXT); GL.BlendFunc(GL.GL_ONE, GL.GL_ONE); GL.Disable(GL.GL_CULL_FACE); GL.Disable(GL.GL_DEPTH_TEST); GL.DepthFunc(GL.GL_NEVER); GL.Enable(GL.GL_SCISSOR_TEST); // Setup viewport, orthographic projection matrix GL.Viewport(0, 0, width, height); float L = 0; float R = width; float T = 0; float B = height; float N = -0.1f; float F = 100.0f; float[] ortho_projection = new float[16] { 2.0f/(R-L), 0.0f, 0.0f, 0.0f, 0.0f, 2.0f/(T-B), 0.0f, 0.0f, 0.0f, 0.0f, 2.0f/(N-F), 0.0f, (R+L)/(L-R), (T+B)/(B-T), (F+N)/(N-F), 1.0f, }; // Setup view transformation var viewMatrix = GetViewMatrix(width, height); material.program.Bind(); material.program.SetUniformMatrix4("ViewMtx", viewMatrix); material.program.SetUniformMatrix4("ProjMtx", ortho_projection); // Send vertex and index data GL.BindVertexArray(material.VaoHandle); GL.BindBuffer(GL.GL_ARRAY_BUFFER, material.VboHandle); GL.BufferData(GL.GL_ARRAY_BUFFER, vertexBuffer.Count * Marshal.SizeOf<DrawVertex>(), vertexBuffer.Pointer, GL.GL_STREAM_DRAW); GL.BindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, material.EboHandle); GL.BufferData(GL.GL_ELEMENT_ARRAY_BUFFER, indexBuffer.Count * Marshal.SizeOf<DrawIndex>(), indexBuffer.Pointer, GL.GL_STREAM_DRAW); Utility.CheckGLError(); // Draw var indexBufferOffset = IntPtr.Zero; foreach (var drawCmd in commandBuffer) { var clipRect = drawCmd.ClipRect; if (drawCmd.TextureData != null) { GL.ActiveTexture(GL.GL_TEXTURE0); GL.BindTexture(GL.GL_TEXTURE_2D, (uint) drawCmd.TextureData.GetNativeTextureId()); } GL.Scissor((int) clipRect.X, (int) (height - clipRect.Height - clipRect.Y), (int) clipRect.Width, (int) clipRect.Height); GL.DrawElements(GL.GL_TRIANGLES, drawCmd.ElemCount, GL.GL_UNSIGNED_INT, indexBufferOffset); indexBufferOffset = IntPtr.Add(indexBufferOffset, drawCmd.ElemCount * Marshal.SizeOf<DrawIndex>()); Utility.CheckGLError(); } //TODO dispose OpenGL resources var pixels = new byte[width * height * 4]; GL.ReadPixels(0, 0, width, height, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, pixels); return pixels; }
/// <summary> /// Draw text mesh /// </summary> internal static void DrawTextMesh(OpenGLMaterial glyphMaterial, TextMesh textMesh, int width, int height) { // Backup GL state GL.GetIntegerv(GL.GL_CURRENT_PROGRAM, IntBuffer); int last_program = IntBuffer[0]; GL.GetIntegerv(GL.GL_TEXTURE_BINDING_2D, IntBuffer); int last_texture = IntBuffer[0]; GL.GetIntegerv(GL.GL_ACTIVE_TEXTURE, IntBuffer); int last_active_texture = IntBuffer[0]; GL.GetIntegerv(GL.GL_ARRAY_BUFFER_BINDING, IntBuffer); int last_array_buffer = IntBuffer[0]; GL.GetIntegerv(GL.GL_ELEMENT_ARRAY_BUFFER_BINDING, IntBuffer); int last_element_array_buffer = IntBuffer[0]; GL.GetIntegerv(GL.GL_VERTEX_ARRAY_BINDING, IntBuffer); int last_vertex_array = IntBuffer[0]; GL.GetIntegerv(GL.GL_BLEND_SRC, IntBuffer); int last_blend_src = IntBuffer[0]; GL.GetIntegerv(GL.GL_BLEND_DST, IntBuffer); int last_blend_dst = IntBuffer[0]; GL.GetIntegerv(GL.GL_BLEND_EQUATION_RGB, IntBuffer); int last_blend_equation_rgb = IntBuffer[0]; GL.GetIntegerv(GL.GL_BLEND_EQUATION_ALPHA, IntBuffer); int last_blend_equation_alpha = IntBuffer[0]; GL.GetFloatv(GL.GL_COLOR_CLEAR_VALUE, FloatBuffer); float last_clear_color_r = FloatBuffer[0]; float last_clear_color_g = FloatBuffer[1]; float last_clear_color_b = FloatBuffer[2]; float last_clear_color_a = FloatBuffer[3]; GL.GetIntegerv(GL.GL_VIEWPORT, IntBuffer); Rect last_viewport = new Rect(IntBuffer[0], IntBuffer[1], IntBuffer[2], IntBuffer[3]); uint last_enable_blend = GL.IsEnabled(GL.GL_BLEND); uint last_enable_cull_face = GL.IsEnabled(GL.GL_CULL_FACE); uint last_enable_depth_test = GL.IsEnabled(GL.GL_DEPTH_TEST); uint last_enable_scissor_test = GL.IsEnabled(GL.GL_SCISSOR_TEST); GL.GetIntegerv(GL.GL_SCISSOR_BOX, IntBuffer); int last_sessor_rect_x = IntBuffer[0]; int last_sessor_rect_y = IntBuffer[1]; int last_sessor_rect_width = IntBuffer[2]; int last_sessor_rect_height = IntBuffer[3]; GLM.mat4 ortho_projection = GLM.glm.ortho(0.0f, width, height, 0.0f, -5.0f, 5.0f); GL.Viewport(0, 0, width, height); var material = glyphMaterial; var vertexBuffer = textMesh.VertexBuffer; var indexBuffer = textMesh.IndexBuffer; material.program.Bind(); material.program.SetUniformMatrix4("ProjMtx", ortho_projection.to_array());//FIXME make GLM.mat4.to_array() not create a new array // Send vertex data GL.BindVertexArray(material.VaoHandle); GL.BindBuffer(GL.GL_ARRAY_BUFFER, material.VboHandle); GL.BufferData(GL.GL_ARRAY_BUFFER, vertexBuffer.Count * Marshal.SizeOf <DrawVertex>(), vertexBuffer.Pointer, GL.GL_STREAM_DRAW); GL.BindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, material.EboHandle); GL.BufferData(GL.GL_ELEMENT_ARRAY_BUFFER, indexBuffer.Count * Marshal.SizeOf <DrawIndex>(), indexBuffer.Pointer, GL.GL_STREAM_DRAW); Utility.CheckGLError(); GL.Enable(GL.GL_STENCIL_TEST); var indexBufferOffset = IntPtr.Zero; foreach (var drawCmd in textMesh.Commands) { var clipRect = drawCmd.ClipRect; { // Draw text mesh to stencil buffer GL.StencilOp(GL.GL_KEEP, GL.GL_KEEP, GL.GL_INVERT); GL.StencilFunc(GL.GL_ALWAYS, 1, 1); GL.ColorMask(false, false, false, false); //only draw to stencil buffer GL.Clear(GL.GL_STENCIL_BUFFER_BIT); //clear stencil buffer to 0 GL.Scissor((int)clipRect.X, (int)(height - clipRect.Height - clipRect.Y), (int)clipRect.Width, (int)clipRect.Height); GL.DrawElements(GL.GL_TRIANGLES, drawCmd.ElemCount, GL.GL_UNSIGNED_INT, indexBufferOffset); Utility.CheckGLError(); // Draw text mesh againest stencil buffer GL.StencilFunc(GL.GL_EQUAL, 1, 1); GL.StencilOp(GL.GL_KEEP, GL.GL_KEEP, GL.GL_KEEP); GL.ColorMask(true, true, true, true); GL.DrawElements(GL.GL_TRIANGLES, drawCmd.ElemCount, GL.GL_UNSIGNED_INT, indexBufferOffset); } indexBufferOffset = IntPtr.Add(indexBufferOffset, drawCmd.ElemCount * Marshal.SizeOf <DrawIndex>()); } GL.Disable(GL.GL_STENCIL_TEST); // Restore modified GL state GL.UseProgram((uint)last_program); GL.ActiveTexture((uint)last_active_texture); GL.BindTexture(GL.GL_TEXTURE_2D, (uint)last_texture); GL.BindVertexArray((uint)last_vertex_array); GL.BindBuffer(GL.GL_ARRAY_BUFFER, (uint)last_array_buffer); GL.BindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, (uint)last_element_array_buffer); GL.BlendEquationSeparate((uint)last_blend_equation_rgb, (uint)last_blend_equation_alpha); GL.BlendFunc((uint)last_blend_src, (uint)last_blend_dst); if (last_enable_blend == GL.GL_TRUE) { GL.Enable(GL.GL_BLEND); } else { GL.Disable(GL.GL_BLEND); } if (last_enable_cull_face == GL.GL_TRUE) { GL.Enable(GL.GL_CULL_FACE); } else { GL.Disable(GL.GL_CULL_FACE); } if (last_enable_depth_test == GL.GL_TRUE) { GL.Enable(GL.GL_DEPTH_TEST); } else { GL.Disable(GL.GL_DEPTH_TEST); } if (last_enable_scissor_test == GL.GL_TRUE) { GL.Enable(GL.GL_SCISSOR_TEST); } else { GL.Disable(GL.GL_SCISSOR_TEST); } GL.ClearColor(last_clear_color_r, last_clear_color_g, last_clear_color_b, last_clear_color_a); GL.Viewport((int)last_viewport.X, (int)last_viewport.Y, (int)last_viewport.Width, (int)last_viewport.Height); GL.Scissor(last_sessor_rect_x, last_sessor_rect_y, last_sessor_rect_width, last_sessor_rect_height); }
public static void DrawMesh(OpenGLMaterial material, Mesh mesh, int width, int height) { List <DrawCommand> commandBuffer = mesh.CommandBuffer; VertexBuffer vertexBuffer = mesh.VertexBuffer; IndexBuffer indexBuffer = mesh.IndexBuffer; // Backup GL state GL.GetIntegerv(GL.GL_CURRENT_PROGRAM, IntBuffer); int last_program = IntBuffer[0]; GL.GetIntegerv(GL.GL_TEXTURE_BINDING_2D, IntBuffer); int last_texture = IntBuffer[0]; GL.GetIntegerv(GL.GL_ACTIVE_TEXTURE, IntBuffer); int last_active_texture = IntBuffer[0]; GL.GetIntegerv(GL.GL_ARRAY_BUFFER_BINDING, IntBuffer); int last_array_buffer = IntBuffer[0]; GL.GetIntegerv(GL.GL_ELEMENT_ARRAY_BUFFER_BINDING, IntBuffer); int last_element_array_buffer = IntBuffer[0]; GL.GetIntegerv(GL.GL_VERTEX_ARRAY_BINDING, IntBuffer); int last_vertex_array = IntBuffer[0]; GL.GetIntegerv(GL.GL_BLEND_SRC, IntBuffer); int last_blend_src = IntBuffer[0]; GL.GetIntegerv(GL.GL_BLEND_DST, IntBuffer); int last_blend_dst = IntBuffer[0]; GL.GetIntegerv(GL.GL_BLEND_EQUATION_RGB, IntBuffer); int last_blend_equation_rgb = IntBuffer[0]; GL.GetIntegerv(GL.GL_BLEND_EQUATION_ALPHA, IntBuffer); int last_blend_equation_alpha = IntBuffer[0]; GL.GetIntegerv(GL.GL_VIEWPORT, IntBuffer); Rect last_viewport = new Rect(IntBuffer[0], IntBuffer[1], IntBuffer[2], IntBuffer[3]); uint last_enable_blend = GL.IsEnabled(GL.GL_BLEND); uint last_enable_cull_face = GL.IsEnabled(GL.GL_CULL_FACE); uint last_enable_depth_test = GL.IsEnabled(GL.GL_DEPTH_TEST); uint last_enable_scissor_test = GL.IsEnabled(GL.GL_SCISSOR_TEST); GL.GetIntegerv(GL.GL_SCISSOR_BOX, IntBuffer); int last_sessor_rect_x = IntBuffer[0]; int last_sessor_rect_y = IntBuffer[1]; int last_sessor_rect_width = IntBuffer[2]; int last_sessor_rect_height = IntBuffer[3]; // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled GL.Enable(GL.GL_BLEND); GL.BlendEquation(GL.GL_FUNC_ADD_EXT); GL.BlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA); GL.Disable(GL.GL_CULL_FACE); GL.Disable(GL.GL_DEPTH_TEST); GL.DepthFunc(GL.GL_NEVER); GL.Enable(GL.GL_SCISSOR_TEST); // Setup viewport, orthographic projection matrix GL.Viewport(0, 0, width, height); GLM.mat4 ortho_projection = GLM.glm.ortho(0.0f, width, height, 0.0f, -5.0f, 5.0f); material.program.Bind(); material.program.SetUniformMatrix4("ProjMtx", ortho_projection.to_array());//FIXME make GLM.mat4.to_array() not create a new array // Send vertex and index data GL.BindVertexArray(material.VaoHandle); GL.BindBuffer(GL.GL_ARRAY_BUFFER, material.VboHandle); GL.BufferData(GL.GL_ARRAY_BUFFER, vertexBuffer.Count * Marshal.SizeOf <DrawVertex>(), vertexBuffer.Pointer, GL.GL_STREAM_DRAW); GL.BindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, material.EboHandle); GL.BufferData(GL.GL_ELEMENT_ARRAY_BUFFER, indexBuffer.Count * Marshal.SizeOf <DrawIndex>(), indexBuffer.Pointer, GL.GL_STREAM_DRAW); Utility.CheckGLError(); // Draw var indexBufferOffset = IntPtr.Zero; foreach (var drawCmd in commandBuffer) { var clipRect = drawCmd.ClipRect; if (drawCmd.TextureData != null) { GL.ActiveTexture(GL.GL_TEXTURE0); GL.BindTexture(GL.GL_TEXTURE_2D, (uint)drawCmd.TextureData.GetNativeTextureId()); } GL.Scissor((int)clipRect.X, (int)(height - clipRect.Height - clipRect.Y), (int)clipRect.Width, (int)clipRect.Height); GL.DrawElements(GL.GL_TRIANGLES, drawCmd.ElemCount, GL.GL_UNSIGNED_INT, indexBufferOffset); indexBufferOffset = IntPtr.Add(indexBufferOffset, drawCmd.ElemCount * Marshal.SizeOf <DrawIndex>()); Utility.CheckGLError(); } // Restore modified GL state GL.UseProgram((uint)last_program); GL.ActiveTexture((uint)last_active_texture); GL.BindTexture(GL.GL_TEXTURE_2D, (uint)last_texture); GL.BindVertexArray((uint)last_vertex_array); GL.BindBuffer(GL.GL_ARRAY_BUFFER, (uint)last_array_buffer); GL.BindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, (uint)last_element_array_buffer); GL.BlendEquationSeparate((uint)last_blend_equation_rgb, (uint)last_blend_equation_alpha); GL.BlendFunc((uint)last_blend_src, (uint)last_blend_dst); if (last_enable_blend == GL.GL_TRUE) { GL.Enable(GL.GL_BLEND); } else { GL.Disable(GL.GL_BLEND); } if (last_enable_cull_face == GL.GL_TRUE) { GL.Enable(GL.GL_CULL_FACE); } else { GL.Disable(GL.GL_CULL_FACE); } if (last_enable_depth_test == GL.GL_TRUE) { GL.Enable(GL.GL_DEPTH_TEST); } else { GL.Disable(GL.GL_DEPTH_TEST); } if (last_enable_scissor_test == GL.GL_TRUE) { GL.Enable(GL.GL_SCISSOR_TEST); } else { GL.Disable(GL.GL_SCISSOR_TEST); } GL.Viewport((int)last_viewport.X, (int)last_viewport.Y, (int)last_viewport.Width, (int)last_viewport.Height); GL.Scissor(last_sessor_rect_x, last_sessor_rect_y, last_sessor_rect_width, last_sessor_rect_height); }