Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can I combine OpenGL 3D drawing with SkiaSharp? #614

Closed
ReactorScram opened this issue Aug 10, 2018 · 5 comments
Closed

Can I combine OpenGL 3D drawing with SkiaSharp? #614

ReactorScram opened this issue Aug 10, 2018 · 5 comments
Projects

Comments

@ReactorScram
Copy link

Description

I'm using SkiaSharp with OpenTK on a Window desktop, but if I try to draw into the OpenGL context directly, both the OpenGL and SkiaSharp drawing is corrupted. I am guessing that they are trampling each other's GL states.

Code

Can't share any code right now, there isn't anything in the documentation showing whether this is even allowed.

Expected Behavior

Expected that I can draw something in 3D, call GrContext.ResetContext or similar function, then draw in 2D with SkiaSharp. (Or vice versa, 2D than 3D. Either is fine.)

Actual Behavior

When I add our existing 3D code to the prototype SkiaSharp project, the 3D scene is not drawn, and the SkiaSharp 2D drawing is 'corrupted', i.e., text is not drawn, some objects are missing, a square appears where a square shouldn't be.

I can't call GrContext.ResetContext, because SKGlControl.grContext is private.

Basic Information

  • Version with issue: v1.60.2 of SkiaSharp and SkiaSharp.Views, from NuGet.
  • Last known good version: This is the first time I have tried SkiaSharp.
  • IDE: Visual Studio
  • Platform Target Frameworks: .NET Framework 4.5.2
    • Android: N/A
    • iOS: N/A
    • Linux: Not yet
    • macOS: N/A
    • Tizen: N/A
    • tvOS: N/A
    • UWP: N/A
    • watchOS: N/A
    • Windows Classic: Windows 10
  • Target Devices:
    • Acer laptop

Screenshots

image

This is the title bar for our app. If I just have OpenGL clear the viewport to purple, then have Skia render, it's okay. (Top) If I have OpenGL actually draw things, then the Home button and title text disappears and I get that grey box. (Bottom)

I could try to manually guess what OpenGL state needs to be corrected, but that sounds fragile.

Reproduction Link

I can make up a reproduction case if the issue isn't clear, but this is more of a question of "Can I even do this?" and not "Is this broken?"

@Ollhax
Copy link

Ollhax commented Aug 11, 2018

I'm rendering OpenGL and using SkiaSharp for creating UI, and the best way I've found to deal with this is to reset the OpenGL state manually after Skia is done. There are occasional issues when I hit some new setting I forgot to reset, but using Renderdoc or just guesswork to debug those problems is not overly difficult.

Note that this isn't really a SkiaSharp error, it's just how Skia works. See here: https://groups.google.com/forum/#!searchin/skia-discuss/gpu$20state%7Csort:relevance/skia-discuss/pj8lF9aHJ3Y/X7oHGhpkE8gJ - the author also posted a list of states he found were changed by Skia, which I found very useful when getting this to work myself. You probably also want to reset the texture unit, e.g. GL.ActiveTexture(TextureUnit.Texture0);

You do need to be able to call GrContext.ResetContext before rendering Skia surfaces, though. If you cannot access the GrContext, I recommend filing a separate report for that, and perhaps for now just use some reflection magic to access it.

@Ollhax
Copy link

Ollhax commented Aug 11, 2018

In case it's useful, this is what I use right now:

// Prepare
grContext.ResetContext(GRGlBackendState.All);

// (Draw canvas)

// Reset (using OpenTK's GL bindings)
GL.Disable(EnableCap.Blend);
GL.Disable(EnableCap.VertexProgramPointSize);
GL.BindVertexArray(vertexArrayObject); // Restore default VAO 
GL.FrontFace(FrontFaceDirection.Cw);
GL.Enable(EnableCap.FramebufferSrgb);
GL.ActiveTexture(TextureUnit.Texture0);
GL.PixelStore(PixelStoreParameter.UnpackAlignment, 4);
GL.BindFramebuffer(FramebufferTarget.ReadFramebuffer, 0);
GL.BindFramebuffer(FramebufferTarget.DrawFramebuffer, 0);
GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0);
GL.BindFramebuffer(FramebufferTarget.FramebufferExt, 0);
GL.UseProgram(0);
GL.BindBuffer(BufferTarget.ElementArrayBuffer, 0);
GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
GL.DrawBuffer(DrawBufferMode.Back);
GL.Enable(EnableCap.Dither);
GL.DepthMask(true);
GL.Enable(EnableCap.Multisample);
GL.Disable(EnableCap.ScissorTest);

@ReactorScram
Copy link
Author

Thanks, Ollhax, it was the "DisableVertexAttribArray" from your Google Groups link that I was missing.

The 3D code I have is legacy - It uses a mix of GL 1 and 2 rendering, so OpenGL must have been trying to send the generic vertex attributes when my code was only sending the fixed vertex and texcoord attributes.

I couldn't get Renderdoc to work for some reason. The last time I had this issue, I was on Linux so I just used apitrace there. I know this is a common issue anywhere 2 different codebases have to share an OpenGL state, imgui has a similar reset () function and a list of GL state that the user must reset themselves.

I'll close it since we all agree it's not technically a bug. Hopefully the next person with this problem finds this thread useful.

@mattleibow mattleibow added this to Complete / Invalid in Triage Aug 15, 2018
@KnIfER
Copy link

KnIfER commented Sep 7, 2021

how to combine OpenGL 3D with Skia in C++?

@KnIfER
Copy link

KnIfER commented Sep 7, 2021

some problem...

20210907_194031_CodecNo.0_CodecNo.1.mp4

https://groups.google.com/g/skia-discuss/c/3bl1U3D9a_Q

@ghost ghost locked as resolved and limited conversation to collaborators Aug 19, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
No open projects
Triage
  
Done
Development

No branches or pull requests

3 participants