You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I would like to create Actors from raw pixel data which I dynamically generate, instead of passing an image file that is stored on disk.
What I've tried so far:
using GameZero
using PNGFiles
using SimpleDirectMediaLayer
using SimpleDirectMediaLayer.LibSDL2
functionMyActor(image; kv...)
height, width =size(image)
raw_pixeldata = UInt8[]
for pixel in255*vec(image')
push!(raw_pixeldata, red(pixel))
push!(raw_pixeldata, green(pixel))
push!(raw_pixeldata, blue(pixel))
push!(raw_pixeldata, alpha(pixel))
end# sf = SimpleDirectMediaLayer.LibSDL2.SDL_CreateRGBSurface(0, width, height, 32, 0, 0, 0, 0)# sf.pixels = Ref{Vector{UInt8}}(raw_pixeldata) # doesn't work: type Ptr has no field pixels
sf = SimpleDirectMediaLayer.LibSDL2.SDL_CreateRGBSurfaceWithFormatFrom(raw_pixeldata, width, height, 8, 4, SimpleDirectMediaLayer.LibSDL2.SDL_PIXELFORMAT_RGBA8888)
w, h =size(sf)
a = GameZero.Actor("", sf, Rect(0, 0, Int(w), Int(h)), [1.0, 1.0], 0, 255, Dict{Symbol,Any}())
for (k, v) in kv
setproperty!(a, k, v)
endreturn a
end
image = PNGFiles.load("image.png") # this is just a simple example, in practice I want to generate it dynamically in the code
actor =MyActor(image) # doesn't work
I tried to use functions like SDL_CreateRGBSurface or SDL_CreateRGBSurfaceWithFormatFrom, but unfortunately I can't get it to work. The problem is that I don't know how to pass the pixel data to these functions. The SDL C API seems to expect a pointer void *pixels, but I'm not very familiar with C and I have no clue how to do that in Julia. I've also tried various combinations like Ref{Vector{UInt8}}(raw_pixeldata), Ref{Cvoid}(raw_pixeldata), etc., but nothing of it worked (and basically I don't really know what I'm doing here).
Please submit a bug report with steps to reproduce this fault, and any error messages that follow (in their entirety). Thanks.
Exception: EXCEPTION_ACCESS_VIOLATION at 0x1feebdc5840 -- unsafe_load at .\pointer.jl:119 [inlined]
unsafe_load at .\pointer.jl:119 [inlined]
...
Does anybody know how to use one of the linked SDL functions and could help me; or would you consider to create a constructor for Actor which allows to pass the image data directly (e.g. a Matrix{RGBA} from the Images.jl/ImageIO.jl packages)?
The text was updated successfully, but these errors were encountered:
There were a few pitfalls that I had to figure out:
the SDL function expects the pixel data as an array of UInt32 numbers, so the 8-bit color values for each channel first need to be combined into a single UInt32 for each pixel
(I think that) the pixel array which is passed as an argument needs to be stored in a permanent variable, so that the garbage collector won't free the corresponding memory which is referenced from the SDL function
depth is the combined bit-depth of all channels, i.e. here it should be set to 32
Pitch is the offset in bytes from one row of pixels to the next, e.g. width*4 for SDL_PIXELFORMAT_RGBA8888.
So with this my code example looks as follows:
using SimpleDirectMediaLayer
images = Vector{UInt32}[]
functionMyImageActor(image; kv...)
height, width =size(image)
depth =32# 8 bit per channel
pitch =4* width
format = SimpleDirectMediaLayer.LibSDL2.SDL_PIXELFORMAT_RGBA8888
pixels = UInt32[]
sizehint!(pixels, height * width)
for pixel in255* image'push!(pixels, UInt32(red(pixel)) <<24|UInt32(green(pixel)) <<16|UInt32(blue(pixel)) <<8|UInt32(alpha(pixel)))
endpush!(images, pixels) # prevent memory of the pixel array being freed by garbage collector
sf = SimpleDirectMediaLayer.LibSDL2.SDL_CreateRGBSurfaceWithFormatFrom(pixels, width, height, depth, pitch, format)
sf ==C_NULL&&error("surface is NULL")
a = GameZero.Actor("", sf, Rect(0, 0, width, height), [1.0, 1.0], 0, 255, Dict{Symbol,Any}())
for (k, v) in kv
setproperty!(a, k, v)
endreturn a
end
Probably there is potential for improvements in the code, but it seems to work so far. I still think it would be useful to have something like this built-in and managed directly by GameZero, so perhaps this issue can stay open as a feature request.
Hello and thanks for creating this package!
I would like to create
Actor
s from raw pixel data which I dynamically generate, instead of passing an image file that is stored on disk.What I've tried so far:
I tried to use functions like SDL_CreateRGBSurface or SDL_CreateRGBSurfaceWithFormatFrom, but unfortunately I can't get it to work. The problem is that I don't know how to pass the pixel data to these functions. The SDL C API seems to expect a pointer
void *pixels
, but I'm not very familiar with C and I have no clue how to do that in Julia. I've also tried various combinations likeRef{Vector{UInt8}}(raw_pixeldata)
,Ref{Cvoid}(raw_pixeldata)
, etc., but nothing of it worked (and basically I don't really know what I'm doing here).The Julia wrapper for the SDL function looks like
but this doesn't help me much either.
https://github.com/JuliaMultimedia/SimpleDirectMediaLayer.jl/blob/82c79b94289b65d2ad15f89363a632041c0d7c06/src/LibSDL2.jl#L1773-L1787
The code above crashes with a long error message
Does anybody know how to use one of the linked SDL functions and could help me; or would you consider to create a constructor for
Actor
which allows to pass the image data directly (e.g. aMatrix{RGBA}
from the Images.jl/ImageIO.jl packages)?The text was updated successfully, but these errors were encountered: