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

When debugging, Surface.pixels is not set #29

Open
AresAndy opened this issue Jun 9, 2019 · 7 comments
Open

When debugging, Surface.pixels is not set #29

AresAndy opened this issue Jun 9, 2019 · 7 comments

Comments

@AresAndy
Copy link

AresAndy commented Jun 9, 2019

When debugging, Surface struct returned from window.surface.to_unsafe does not contain
pixels, but property is clearly defined (at sdl/src/lib_sdl/surface.cr), therefore pixel read access is impossible

@ysbaddaden
Copy link
Owner

Please add some details or better, reproducible code. I gave no idea what you're doing and expecting...

@AresAndy
Copy link
Author

Yes, sorry, I totally forgot to include any actual source code..

What I'm trying to do (surely in a unsafe, inefficient way, but I don't mind at the moment..) is to get the RGB values of a pixel at x,y coordinates. I looked around for quite a while, and stumbled on a piece of C code, that I roughly transliterated to crystal:

def get_pix_at(surf, x, y)
    # debugger
    LibSDL.lock_surface(surf)
    ll_surface = surf.surface
    bpp = ll_surface.format.value.bytesPerPixel
    pix = (ll_surface.pixels + y * ll_surface.pitch * bpp).as(UInt32*).value

    r  = 0_u8
    g  = 0_u8
    b  = 0_u8
    pr : UInt8* = pointerof(r)
    pg : UInt8* = pointerof(g) 
    pb : UInt8* = pointerof(b) 
    LibSDL.get_rgb(pix, ll_surface.format, pr, pg, pb)
    res = [pr.value, pg.value, pb.value]
    LibSDL.unlock_surface(surf)
    return res
end

This compiles with no warning whatsoever, does not crash when used, but the RGB array is constantly [0,0,0].. When debugging this function, ll_surface contains most of the property of its type, except for pixels. It's nice to see that rather than crashing for a bad pointer dereference it returns zero, but still.. If ll_surface is a LibSDL::Surface, one instance of it should contain pixels.. Right?

lib LibSDL
 # ...
  struct Surface
    flags : UInt32
    format : PixelFormat*
    w : Int
    h : Int
    pitch : Int
    pixels : Void*
    userdata : Void*
    locked : Int
    lock_data : Void*
    clip_rect : Rect
    map : Void* # BlitMap*
    refcount : Int
  end
# and so forth...

@ysbaddaden
Copy link
Owner

Have a look to http://lazyfoo.net/SDL_tutorials/lesson31/index.php

All samples are ports of Lazy Foo' tutorials, but I never went as far as reading a pixel color (lesson 31) and Surface#pixels is unavailable for the moment.

@AresAndy
Copy link
Author

AresAndy commented Jun 11, 2019

Oh, I see... Are there any plans/timelines to make Surface#pixels available? Or any workarounds?
I'm doing a fun weekend project, but it could be interesting for newcomers to show how Crystal can be used outside from web development and library bindings design, in a practical manner.

@ysbaddaden
Copy link
Owner

You can reopen SDL::Surface:

class SDL::Surface
  def pixels
    surface.pixels
  end
end

Then you have a direct access to the underlying void* buffer of the surface, whose actual format depends on the surface format. For example:

def get_pixel(surface, x, y)
  buffer = surface.pixels.as(UInt32*) # <= assumes 32-bit depth!
  pixel = buffer + x + y * surface.width
  LibSDL.get_rgb(pixel.value, out r, out g, out b)
  {r, g, b}
end

window = SDL::Window.new(640, 480)
window.surface.fill(255, 0, 0)

p get_pixel(window.surface, 120, 240)

@AresAndy
Copy link
Author

Hi, sorry to reply so lately, but I got stuck with other things..

I tried this piece of code, it has the problem that you're not passing a format parameter to LibSDL.get_rgb, but that can be fetched from the surface parameter. Anyhow, the final result of the function is alway {0,0,0}, no matter what kind of bit depth I use, no matter what the coordinates are.
I feel like there is something missing in the library at this point

@ysbaddaden
Copy link
Owner

No problem for me on Linux. Is the surface really 32-bit?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants