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

How to use offscreen render in GLWpfControl to export a image #119

Open
Spring-grow opened this issue Nov 25, 2023 · 0 comments
Open

How to use offscreen render in GLWpfControl to export a image #119

Spring-grow opened this issue Nov 25, 2023 · 0 comments
Labels
question Further information is requested

Comments

@Spring-grow
Copy link

Spring-grow commented Nov 25, 2023

I wrote a piece of code in a GLWpfControl ,Like below, but it doesn't work:

     private int FBO=0,CBO=0,DBO = 0,TBO=0;
       private static int rendercount = 0;
       public unsafe  void OffScreenRender()
       {
           Loger.LogInfo("start");
           int defautFrame = 0;
           
           defautFrame= GL.GetInteger(GetPName.FramebufferBinding);
           Loger.LogInfo($"default framebuffer {defautFrame}");
           if(FBO==0)
           {
               FBO = GL.GenFramebuffer();
               Loger.LogInfo($"Create FBO {FBO}");
           }
           GL.BindFramebuffer(FramebufferTarget.Framebuffer, FBO);

           if(CBO==0)
           {
               CBO = GL.GenRenderbuffer();

               Loger.LogInfo($"Create CBO {CBO}");
           }
               GL.BindRenderbuffer(RenderbufferTarget.Renderbuffer, CBO);
               GL.RenderbufferStorage(RenderbufferTarget.Renderbuffer, RenderbufferStorage.Rgba8, 800, 600);
               GL.FramebufferRenderbuffer(FramebufferTarget.Framebuffer, FramebufferAttachment.ColorAttachment0, RenderbufferTarget.Renderbuffer, CBO);

           if(DBO==0)
           {
               DBO = GL.GenRenderbuffer();
               Loger.LogInfo($"Create DBO {DBO}");
           }
               GL.BindRenderbuffer(RenderbufferTarget.Renderbuffer, DBO);
               GL.RenderbufferStorage(RenderbufferTarget.Renderbuffer, RenderbufferStorage.DepthComponent, 800, 600);
               GL.FramebufferRenderbuffer(FramebufferTarget.Framebuffer, FramebufferAttachment.DepthAttachment, RenderbufferTarget.Renderbuffer, DBO);

           if (TBO == 0)
           {
               TBO = GL.GenTexture();
               Loger.LogInfo($"Create TBO {TBO}");
           }
               GL.BindTexture(TextureTarget.Texture2D, TBO);
               GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, 800, 600, 0, PixelFormat.Rgba, PixelType.UnsignedInt, IntPtr.Zero);
               GL.FramebufferTexture2D(FramebufferTarget.Framebuffer, FramebufferAttachment.ColorAttachment0, TextureTarget.Texture2D, TBO, 0);
           if (GL.CheckFramebufferStatus(FramebufferTarget.Framebuffer) != FramebufferErrorCode.FramebufferComplete)
           {
               Loger.LogError($"OffScreenRender Framebuffer status is not complete");
           }


           **if (!initialed) InitGL();
           ShaderProgram.ActiveProgram(_program);
           UpdateGL();

           GL.BindFramebuffer(FramebufferTarget.Framebuffer, FBO);
           GL.Viewport(0, 0, 800, 600);
           //GL.Enable(EnableCap.DepthTest); 
           //GL.ClearColor(0.2f, 0.5f, 0.6f, 0.5f);
           GL.BindVertexArray(VAO);

           var g =MyData.Graphics;

           if (MDataType == MyType.Points)
           {
               GL.DrawElements(BeginMode.Points, g.PointsSize, DrawElementsType.UnsignedInt, 0);
           }
           else if (MDataType == MType.Face)
           {

               GL.DrawElements(BeginMode.Triangles, g.TranglesSize, DrawElementsType.UnsignedInt, g.PointsSize * sizeof(uint));
           }
           else
           {
               GL.DrawElements(BeginMode.Lines, g.GridsSize, DrawElementsType.UnsignedInt, (g.PointsSize + g.TranglesSize) * sizeof(uint));
           }
           GL.BindVertexArray(0);**

           byte[] pixels=new byte[4*800*600];
           GL.ReadBuffer(ReadBufferMode.ColorAttachment0);
           fixed(byte* buff=pixels){
               GL.ReadPixels(0, 0, 800, 600, PixelFormat.Rgba, PixelType.UnsignedInt,new IntPtr(buff));
           }
           //Bitmap bmp = new Bitmap(800, 600);

           //{mapType.ToString()}_{DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss-ffff")}
           GL.BindFramebuffer(FramebufferTarget.Framebuffer,defautFrame);
           ShaderProgram.DeactiveProgram();

           using (var fs = new FileStream($"D:\\GLCapture\\{DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss-ffff")}.pixels", FileMode.OpenOrCreate))
           {
               fs.Write(pixels, 0, pixels.Length);
               fs.Flush();
               fs.Close();
           }
           Loger.LogInfo("end");

       }

In this code, the InitGL and UpdateGL used to initialize program and VAO data, as well as the DrawElements section, are the same as what I wrote in GLWpfControl's OnRender(). Here, I want to achieve off screen rendering by binding my own framebuffer to OffScreenRender(), but this framebuffer does not work, when I read by ReadPixels from this buffer, all data in pixels is 0. I want to save the content rendered in GLWpfControl to an image through off screen rendering. What should I do?

@NogginBops NogginBops added the question Further information is requested label Nov 25, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants