Yes. You can fake being an RMagick image. When you do not pass a String as the filename argument to Image.new, Gosu will send #cols and #rows to the object, and then #to_blob to get a String of cols*rows*4 bytes of data. This can actually be used to build all kinds of simple generators.
# EmptyImageStub is based on an idea Julian Raschke suggested in #gosu # on IRC. It provides empty RMagic::Image-like objects which, when # passed to Gosu::Image's constructor, have their to_blob method called, # to provide RGBA data. This allows the easy creation of new Gosu::Image # objects without accessing the filesystem, which can then be drawn into # with TexPlay. class EmptyImageStub def initialize(w,h) @w, @h = w, h; end
Hmm, I think you will have to try around a bit to find out which format this is in, but you should be able to get the right format out of glGetTexImage(). Then someone should test if it also works on a big-endian PowerPC machine :)
What I do is:
unsigned rgba = *rgbaIter; /* next four bytes */ result.setPixel(x, y, Gosu::Color(rgba).abgr()); // swap R and B
I've been using the technique discussed in the awright thread to generate new images, however this method is very slow. Is it possible to add a new method to Gosu to _quickly_ generate new Gosu Images of a given width and height ? or do you know of a faster method using the current setup?
im creating the strings using memset so it should be very fast: int size = width * height * 4; char buf[size]; memset(buf, 0, size); return rb_str_new(buf, size);
So im assuming the RMagick functions that take the string and convert to an image are what's causing the delay.
I want to be able to make the creation of blank images of arbitrary size and then manipulating them with texplay in _real_time_ a feasible possibilty. I was experimenting with a damage system for a game im writing where on collision chunks of the image are separated from the main craft and sent flying across the screen. I was doing this by creating a blank texture of a certain size and then splicing pieces from the source image into it. However it was just too slow, and identified the bottleneck was in the creation of the blank Image. :( Would it be too hard to add a very fast Gosu::Image::create_blank_image(window, width, height) function ? :)) Or do you know another way of doing it?
Hmmm, no idea. Using the C++ API would be faster of course, but I guess you are trying stay on the Ruby side of things (Gosu::Bitmap bmp; bmp.resize(w, h); then create an Image from that). I don't think I'm doing anything completely wasteful in the progress, but updating textures, creating new textures, etc., is all something that can cause weird lags due to particular gfx drivers. (For example, changing a texture on the iPhone is almost a no-go, as far as I can see.) Does the RMagick game work smoothly for you?
yep the RMagick example is fine. If I use Gosu::Image::new() and load just an empty image file (a blank .png) it is very fast, of course, and I may just resort to this (though it seems a bit weird to carry around a blank .png file just for splicing things into, but not really a big deal). I guess I was hoping that creating a blank image using the to_blob() trick would be just as fast as loading a blank .png from a file.
If I was to use the c++ API i'd have to dynamically link to the gosu.so file, which seems a bit weird to me...unless I've got that wrong?
To be honest, I have no idea how the C++ thing would work :(
And this is really weird. Does it get better if you cache the string? Because loading from a PNG should be WAY slower than creating an image the way you did. Is this with 1.9? Does it maybe do fancy multibyte stuff?
you were right, i did some benchmarking, loading from a string is alot faster than loading from a file. there was just something screwy with my code :)