Not logged inGosu Forums
Forum back to Help Search Register Login
Up Topic Gosu / Gosu News / Gosu 0.7.39 released
- - By jlnr (dev) Date 2011-11-19 00:15 Edited 2011-11-19 11:18
This is a bit more of an experimental release, I have cleaned up the backend a lot, which conveniently made the long-undocumented record function work.

Let me know if performance has suffered in any way. If anything, Gosu should be faster now, but it doesn't feel faster in CptnRuby for me. (Might be my system.)

• All: Added Window#record(width, height).
• All: Removed an overcautious assert() from OGG file reading
• All: Fixed OGG files' destructor stopping unrelated songs
• Linux: Fullscreen only covers one screen now (thanks JayThirtySeven!)
• Ruby: Switched from rdoc to YARD

Note to GL hackers: Custom GL code now inherits Gosu's MODEL_VIEW matrix (applied transforms) as well as current clipping rect. If your code does not want this, you have to unset it manually. Also, if the current clipping area is empty while you call enqueueGL, the GL block is not run. I am open to debate this, it's a weird case. :)

record is a super-powerful, awesome feature, and there are countless ways to use and abuse it. In two sentences, you can just do @map_image = record(@map.width_in_pixels, @map.height_in_pixels) { @map.draw } once and then draw @map_image every frame. @map_image will behave like a single Image, but contain a vertex array of all your map tiles. One method call - @map_image.draw - will draw your whole map. This is a good optimization in C++ and a HUGE one in Ruby. Putting 120,000 calls to Image#draw inside a macro, I could still draw it at 60 Hz, and that would be one gigantic map. Try that with nested Ruby loops!

I wish it wasn't so hard to explain, I really need to adjust the CptnRuby script. :)
Parent - By Spooner Date 2011-11-19 00:33
I'm using a fair bit of recording in Smash and Grab and it makes a massive difference to frame-rate (only about 3000 draws in 4 recordings though). Without it, I'd have to render everything to multiple images and mess around with a lot of code to manage that instead, because it would be unusable otherwise. Thanks for finally fixing it up properly - saved a lot of code over what I had to use for the undocumented version though it is likely to break other games that use it because it now works properly :D
Parent - By jlnr (dev) Date 2011-11-19 00:57
Oh, and a note. If you call record within any transform, the outer transform will be applied to what is in the block. This makes sense in its own way, but will change, so don't rely on it :)
Parent - - By Jwosty Date 2011-11-19 04:18
Ooooh! That record thing sounds pretty nifty. So it's basically like getting a region from the screen and then being able to draw it?
Parent - By jlnr (dev) Date 2011-11-19 11:13
It is a bit like rendering to a texture, but not really. It just groups a lot of drawing operations together. This is why you cannot draw_rot the resulting image yet, or tint it with colors (but this will be fixed). You can also not use Texplay on it.

Also, unlike rendering to a texture, it does not restrict you to drawing in the region between (0, 0) and (width, height). You need to use clipping for that.
Parent - By erisdiscord Date 2011-11-19 05:34
Goodness. Record is working? I'm gonna have to dig out some of my old code one of these days and try it out. :D
Parent - - By danikaze Date 2011-11-21 19:01
As erisdiscord said, is record working?
I'm on C++ and 0.7.40 and still getting error C2039: 'record' : is not a member of MyWindow (class MyWindow : public Gosu::Window)
Parent - - By jlnr (dev) Date 2011-11-21 19:34 Edited 2011-11-21 19:54
In C++, it is beginRecording() to start recording, then Gosu::Image(endRecording(width, height)) to construct an image from the result of the recording process. Both are member functions of Gosu::Graphics. (corrected)
Parent - - By danikaze Date 2011-11-21 19:44
uhm, I'm sorry, but as it's not documented I didn't know how to use it.
Anyways, I can't see it as usable...
Parent - - By jlnr (dev) Date 2011-11-21 19:54
Sorry, I was confused. They are both members of Gosu::Graphics and documented there:
Parent - - By danikaze Date 2011-11-21 20:23

So this should work, right? (but it doesn't :P)


// do some drawing ops.

auto_ptr<Gosu::ImageData> ptr =  graphics().endRecording(1280,720);
Gosu::saveImageFile(ptr->toBitmap(), resourcePrefix() + L"screenshot.png");
Parent - - By jlnr (dev) Date 2011-11-21 20:24
Right, because recording is not the same as rendering to a texture. toBitmap() will throw an exception telling you that Macros cannot be converted into Bitmaps.

Rendering to textures has not been implemented yet. But if it was, you wouldn't need record anyway. :) There would be an equivalent pair of beginRenderingToTexture/endRenderingToTexture.
Parent - - By danikaze Date 2011-11-21 20:32 Edited 2011-11-21 20:46
so right now you can't "take screenshots" using this, can you?
Parent - - By jlnr (dev) Date 2011-11-21 20:55
No, you can use raw GL for that though. You just have to call Graphics::flush() and then use any of the GL functions for copying the screen to memory (or was it textures? - not Gosu specific anyway).
Parent - By danikaze Date 2011-11-21 21:57
well, I'll do my research with GL then :)
Parent - - By Maverick Date 2011-11-22 00:35
I still feel like this whole record() business is misleading and very very strict in terms of what it can and cannot do.
I know this is a really useful feature, but I feel like this could be a stand-out feature for Gosu if we could (*ahem* you could...) figure out how to make the recorded data mutable like a texture.
Parent - - By Spooner Date 2011-11-22 02:50 Edited 2011-11-22 03:01
Although it acts like an Image in Gosu, all that happens in record is that it stores a series of GL commands you are calling and can replicate exactly that at a later date (why jlnr calls it a "macro"). This is a small speed improvement in C++ but a massive, massive one in Ruby (since then you just have "many" operations in pure C++, not "many" Image#draws calling those same operations in Ruby). Brilliant for drawing large backgrounds from tiles, for example, which don't often change and need to be re-recorded.
Parent - By Maverick Date 2011-11-22 03:44
As I said, I'm not denying it's awesome, but if we can see it move onto actually being mutable as an image, that would be the real big step I think for Gosu. (One of the key features that really stands out both performance-wise AND graphics-wise)
Parent - - By jlnr (dev) Date 2011-11-22 11:33 Edited 2011-11-22 11:44
I really want to add render-to-texture too, but I think it would be even more misleading to make it related to macro recording - I think it should be a separate function. Some advantage of record-to-macro that couldn't be had with a proper texture:

• recording macros is super fast, independent of graphics drivers, unlike textures
• macros can be much smaller than textures in memory. If you want to e.g. record a large tile map, each tile is 144 bytes in the macro because it only references the existing tile Image. On a texture, you could only represent 6x6px in that space.
• macros scale up and rotate nicely like vector graphics do, textures become pixelated and blurry.

Maybe "like vector graphics" is really the right way to imagine them? idk :)

For my use cases (tile maps, skeletal animation) this makes them much better than textures. But now that they're there, the next cool feature will indeed be render-to-texture. Maybe that'd make the whole GLSL post-processing thing nicer too?
Parent - - By danikaze Date 2011-11-22 14:36
For this purpose, maybe enabling a backbuffer would be even more useful.
Do you plan to enable it sometime?
Parent - - By jlnr (dev) Date 2011-11-22 14:47
Isn't that the same as render-to-texture? I have no clue (yet) ;)

Anyway, I'll be focusing on the interface for a while now. Contributions on GitHub are welcome if there is a use case for them. (Unused code breaks within months, in my experience)
Parent - By danikaze Date 2011-11-22 18:15
I'm not sure. Never implemented it, just used ;)
Parent - - By bestguigui Date 2011-11-28 18:20
This is an amazing feature ! I was starting to use render to texture, but it seems that native Gosu will now do the trick ! Thanks again !
Parent - - By RavensKrag Date 2011-11-29 05:18
So, how does this work exactly? There's a height and a width, but no x and y? What if I record images being draw at 2000,2000 or something like that? Is it somehow intelligent enough to cut out the 2000x2000 block of dead space?

Suddenly interested in this technique for the game I'm working on, but I have a larger bottleneck I need to get through first.
Parent - - By jlnr (dev) Date 2011-11-29 10:17
That's what it used to do, and you didn't even have to pass width/height then. But the resulting values were hard to rely on so I made it manual. (e.g. what if you want to record a map, but this one block happens to an empty first row/column)

It always starts from (0, 0). You should draw what you want to draw all between (0, 0) and (width, height), but you can easily use translate() to do so.
Parent - - By RavensKrag Date 2011-11-29 15:05
Yeah, I figured translate() was the solution there.  Thanks a lot.
Parent - - By jlnr (dev) Date 2011-11-29 15:34
Also note that this only works in 0.7.40, so we are definitely in the wrong thread now. ;)
Parent - - By bestguigui Date 2011-12-01 20:27
Too bad it currently doesn't take Custom OpenGL Code :(
I hope it'll be possible in a coming version ;)
Parent - - By jlnr (dev) Date 2011-12-01 20:51
translate does actually work with custom GL now. Just be sure to use gl(z) { code } instead of the old gl { code }.

Macros are also implemented using gl(z), and they respect transforms correctly.
Parent - - By bestguigui Date 2011-12-02 18:24
I was referring to Window#record ;)
Parent - - By jlnr (dev) Date 2011-12-02 18:31
Oh...yeah well, that is impossible sadly :) It may work with a future render_to_texture function.
Parent - By bestguigui Date 2011-12-02 18:46
That would be great ! But take the time needed, your work is still awesome
Parent - By Spooner Date 2011-11-29 13:52
I got the impression that the only effect that the recorded size had was to affect how #draw_rot managed rotation and center_x/center_y. Other than that, the size is not relevant (And I tell Gosu that all my recordings are 1x1 because I don't need to rotate or center them and everything is fine :D).
Up Topic Gosu / Gosu News / Gosu 0.7.39 released

Powered by mwForum 2.29.7 © 1999-2015 Markus Wichitill