Byjlnr (dev)
Date 2009-02-10 03:17
Edited 2009-02-10 03:24
As originally posted on the Wiki by jrmair, Aug 26, 2008:
> if anyone is interested in trying out or bugtesting TexPlay (a c extension for gosu for manipulating images) go here: http://banisterfiend.wordpress.com/ > > it currently supports get_pixel and the ability to manipulate gosu images at runtime (the drawing of circles, lines boxes etc). > > Perfect for fast pixel-perfect collision detection in games, and fast image manipulation.
I really like TexPlay, but I have a problem... the performance of the refresh_cache call you add to the instantiation of images (i.e. Gosu::Image.new(args)) is very, very bad for me. It adds anywhere from 0.5 seconds to nearly 0.9 seconds per image instantiation, and since I load more than a hundred images in my game, all at once, I've had to comment out the call to refresh_cache.
Interestingly, commenting out that call hasn't had any negative effect, so I've not been able to figure out exactly what it was supposed to do in the first place...
hehe yes. 90% of the time you will be able to use TexPlay just fine without the automatic caching in the Gosu::Image::new method...however in certain rare situations (see below) TexPlay will not do what you want unless auto-caching is enabled.
The rare situation is when two or more Gosu images are stored internally on the same quad yet you invoke the TexPlay#paint method on one of those images BEFORE you've finished loading the other images.. In this situation all TexPlay manipulations will work fine for the images loaded prior to the first TexPlay#paint call (TexPlay lazily caches the quad on #paint if the quad is not already cached) but will produce weird results for all image manipulation on the images loaded AFTER (since they missed out on being cached.)
(sorry that was convoluted, it's 3am here :/)
You've convinced me that since this case is so rare I will remove auto-caching from the next version of TexPlay and come up with another way of resolving the weird edge-case .
I fixed the issue with refresh_cache in the new (0.1.4) release of TexPlay. I also added some useful error messages for when you encounter the quirk with gl_tex_info (fixed in Gosu 0.7.13.4 ?)
also added a few more methods and constants: * TexPlay#quad_cached? - returns true if the quad the texture is located on has already been cached * TexPlay::TP_MAX_QUAD_SIZE - returns the sidelength of the largest quad that can be allocated. (taken directly from max_texture_size() method in Gosu's Texture.cpp)
I haven't written it up fully yet, but here is an explanation of an earlier iteration: dup_eval. And a very useful helper library (also now signficantly updated): object2module.
You can check out the BETA release of TexPlay 0.1.6 that utilizes gen_eval and let me know what you think. I personally haven't noticed any real reduction in speed; my benchmarks seem to indicate gen_eval runs more or less the same speed as instance_eval but YMMV.
A new version of TexPlay is scheduled for release within the next week or so.
It features: * bezier curves * floodfill and texturefill (non recursive for speed and efficiency) * bresenham line and circle * polylines and polygons * turtle graphics * enhanced composite (splice) * an each iterator for the Gosu::Image class * more control over syncing to opengl * almost a complete rewrite of the C source with an emphasis on efficiency and simplicity (no more pseudo OOP in C) * ...many other features designed to enhance extensibility
Im currently not so interested in affine transformations as most of these are covered very well by Gosu itself but if people are interested it may be fun to implement these (esp. since SSE instructions can be used to do it very efficiently)
A beta of the new TexPlay can be downloaded here: Download
It's pretty much complete but has a few areas that need to be sorted out before I bump it up to 0.2.0.
In particular it has the following problems/omissions: * thick lines are a hack and very slow (just drawing a filled circle at every pixel). This will be corrected very soon as im working on a polygon filling routine * polylines and beziers and floodfill just sync the whole image whereas they should keep track of their exact rectangle of activity for more efficient syncing * didn't get around to writing the Gosu::Image#each iterator * turtle graphics is written in Ruby so is very slow, i'll rewrite in C soon * removed bitmasking and leftshift/rightshift, haven't added them back in yet * bezier curves are currently limited to 13 points (this will be easy to bump up) * floodfill sometimes acts temperamentally when the image doesn't have a border, this should be easy to fix. (this is why all the example progs have borders)
if you find any other problems let me know.
NB: the example that shows texture filling under a bezier curve is called example_fill.rb
EDIT: the reason im releasing this now and not when the problems are corrected is because i have exams now and i wont be able to work on it again for a couple of weeks. :( and i just wanted to get something out there
EDIT: this release breaks backwards compatibility in a number of ways, so relying on the old manual may be confusing. I'll write up the new functionality soon as i get a chance
semi-cross platform gem for TexPlay 0.2 available, should work fine for linux and macosx systems:
go: gem install texplay
For Windows: The Windows build is still not quite working, I'll follow the method that Gosu uses to deal with multiple .so versions. Should be available soon, but i'll need someone to compile a 1.9.1 compatible windows .so for me at some point :)
Windows users should use the googlecode link given above (in the previous post) in the meantime until a gem is available :)
Though, in the rakefile, it says it will copy texplay.so to /home/john/projects/selene.. .. .. I'm guessing you just forgot to delete that part? (Haven't tried compiling yet)
hey, can you send me the image and the the get_pixel command that causes the prob? (note that get_pixel will return nil if you request a pixel outside of the image bounds, i.e < 0 or > image.width - 1)
but tbh it sounds like you're sending nil as a parameter to get_pixel??
I've got a nice little bug for you: Texplay fails to splice images with (a) side(s) greater than 1023px
> -:31:in splice': Error: gl_tex_info returns nil for #<Gosu::Image:0x9574780> (1023 x 1023). Could be caused by very large image or Gosu bug. Try > updating Gosu or use a smaller image. Note: TexPlay should be able to work with 1024 x 1024 images. (Exception) > from -:31:in initialize' > from -:38:in new' > from -:38:in <main>'
(ofcourse the "(1023 x 1023)" part changes with every image)
These are the results I got:
And this is the code I used:
require 'gosu' require 'texplay'
class Window < Gosu::Window def initialize super(1026, 1026, false) self.caption = "Gosu Ruby Project" @img = Gosu::Image.new(self,"1023.png",false) @img2 = Gosu::Image.new(self,"40.png", false) @img.splice(@img2,0,0) end def draw @img.draw(0,0,0) end end
Yeah, I know.. I only used #{dimensions}.png for testing this former 'bug'. I've simply gone around using such high dimensions (I originally wanted panels of 1024x1024), and opted for 512x512, using #create_blank_image() On this I then #splice my tiles, etc.
* interoperability with Devil library * adds a screenshot method to Gosu::Window, enabling you to take screenshots of gameplay and save to a file. * adds a Gosu::Image#save method (and so enabling you to save images you manipulate with TexPlay, needs Devil gem installed: http://banisterfiend.wordpress.com/2009/10/14/the-devil-image-library-for-ruby/)
chroma_key only works with exact color values with :alpha corresponding to [0,0,0,0]. I'm assuming that some of the 'alpha' values that you're splicing in are not full alpha ([0,0,0,0]) and so they are included in the splice (rather than skipped).
You can use a color_control proc in combination with splice to do a more flexible splice and choose exactly what colors you want included or skipped during the splice.
If you give me a copy of both images i can design a color_control proc that will get you the result you want.
Well, i recommend ensuring the parts of the image you want excluded from the splice to be FULL ALPHA ([0,0,0,0]). Using splice with :chroma_key is MUCH faster than using a color control proc
ok, try the new gem :) This is my first binary gem built entirely on windows (both the windows and linux/macosx versions) using RubyInstaller and the devkit. Let me know of any problems...
fixed in this version is alpha blending, i also tried to fix the segfault issue on some linux distros but that will have to wait until Gosu gets a MAX_TEXTURE_SIZE constant for ruby 1.8
As far as I can tell the :trace works very well. I'm already using it in 2 core places in the game I'm working on.
I've traced in both vertical directions (up and down, not left/right though).. and used both :until_color and :while_color. It works perfectly so far, thanks for great release!
I am trying to create a Tilemap class. The layers with trees, flowers and such stuff are drawn as seperate Images but the ground layer with (for example) grass or stone should be one single image.
TopicGosu / Extending Gosu / TexPlay, drawing and hit-testing for Gosu::Image [from wiki]