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 take a screenshot? #96

Open
pascalr opened this issue Jan 7, 2021 · 4 comments
Open

How to take a screenshot? #96

pascalr opened this issue Jan 7, 2021 · 4 comments
Assignees
Labels
Milestone

Comments

@pascalr
Copy link

pascalr commented Jan 7, 2021

Hello I was wondering how I can get the pixel values that are rendered to the screen. I got this so far:

module RendererPatch
  def take_screenshot(x,y,width,height)
    pixels = []
    glReadPixels(x,y,width,height,GL_RGB,GL_FLOAT,pixels)
  end
end
Mittsu::OpenGLRenderer.include RendererPatch

But I don't understand what kind of variable pixels is supposed to be. It's complaining:

/var/lib/gems/2.7.0/gems/opengl-bindings-1.6.10/lib/opengl_command.rb:246:in []: can't convert Array into Integer (TypeError)

This is the method source code from opengl-bindings:

GL_FUNCTIONS_ARGS_MAP[:glReadPixels] = [Fiddle::TYPE_INT, Fiddle::TYPE_INT, Fiddle::TYPE_INT, Fiddle::TYPE_INT,
                                        -Fiddle::TYPE_INT, -Fiddle::TYPE_INT, Fiddle::TYPE_VOIDP]
GL_FUNCTIONS_RETVAL_MAP[:glReadPixels] = Fiddle::TYPE_VOID
def glReadPixels(_x_, _y_, _width_, _height_, _format_, _type_, _pixels_)
  f = OpenGL::get_command(:glReadPixels)
  f.call(_x_, _y_, _width_, _height_, _format_, _type_, _pixels_)
end

PS: Thanks for the great library!

@danini-the-panini
Copy link
Owner

danini-the-panini commented Jan 8, 2021

I think pixels should be a string of length width*height*4 (I think float size is 4 bytes), and then to turn it into an array of floats you would call pixels.unpack('F*')

I should really just add a function to do this and output a ChunkyPNG object or something.

Possibly related to #75

@pascalr
Copy link
Author

pascalr commented Jan 8, 2021

That would be great if you manage to add a function that outputs a png!

I tried with the string, but I didn't get very far, somehow it made my application crash without any error messages.

I believe the length of the string should be width*height*4*3 in my case since I wanted RGB, but probably mutliplied by 4 for GL_RGBA for a png.

@danini-the-panini
Copy link
Owner

Oh right, I forgot about the number of channels 🤦‍♀️

@pascalr
Copy link
Author

pascalr commented Jan 14, 2021

I was finally able to do it with this:

module RendererPatch
  def take_screenshot(x,y,width,height)
    type_nb_bytes = 1 # for GL_UNSIGNED_BYTE (0 to 255)
    nb_channels = 3 # for GL_RGB
    pixels = ' '*width*height*type_nb_bytes*nb_channels
    glReadPixels(x,y,width,height,GL_RGB,GL_UNSIGNED_BYTE,pixels)
    png = ChunkyPNG::Image.from_rgb_stream(width, height, pixels)
    png.flip_horizontally!
    png.save('screenshot.png', :interlace => true)
  end
end
Mittsu::OpenGLRenderer.include RendererPatch

@danini-the-panini danini-the-panini added this to the 0.4.0 milestone Jan 20, 2021
@danini-the-panini danini-the-panini modified the milestones: 0.4.0, 0.5.0 Jul 13, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants