-
Notifications
You must be signed in to change notification settings - Fork 174
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鈥檒l occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add Image.draw(options) and tests (and remove draw_rot) #443
base: master
Are you sure you want to change the base?
Conversation
@@ -37,14 +37,17 @@ struct Gosu::RenderState | |||
} | |||
} | |||
|
|||
void apply_alpha_mode() const | |||
void apply_blend_mode() const |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
alpha_blend_mode confused me a bit the first time I looked through the files because you actually change not only the Alpha-Channel, so I renamed it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point. I guess the whole enum should be named Gosu::BlendMode
with BM_ADD
etc. as its members... :/
test/test_image.rb
Outdated
# should 4--3 | ||
# be: / \ | ||
# 1------2 | ||
@image.draw_as_quad(0, w, c, w, h, c, w-15, h/2, c, 15, h/2, c, 0, :default) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure about this one - But the one vertex is always off? I tried:
1-2 | 3-4 | 1-2
4-3 | 1-2 | 3-4
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Update - might be an Linux thingy. Because thats the only green system on CI - every other platform failed this test (with my wrong image)....
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't the first parameters be 0, h, c
?
I added Also a small bugfix discovered by simplecov (the gl_tex_info test was never called)... |
Gosu/GraphicsBase.hpp
Outdated
@@ -26,7 +26,9 @@ namespace Gosu | |||
//! to the old color's channels. | |||
AM_ADD, | |||
//! The color's channels will be multiplied with each other. | |||
AM_MULTIPLY | |||
AM_MULTIPLY, | |||
//! The color will completly replace the current one. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
*completely
What is this mode good for? I've thought about extending the AlphaMode enum to cover all of Adobe's blend modes because I'm familiar with them from Photoshop, but I'm not sure what AM_REPLACE
could be used for.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(I can think of use cases when drawing into an RGBA buffer; Gosu::Bitmap::insert
is basically AM_REPLACE
. But when you are drawing to the screen, you can't replace the destination pixels with translucent pixels.)
ext/gosu/gosu.i
Outdated
static Gosu::Image* from_blob(const std::string& blob, int width, int height) | ||
{ | ||
Gosu::Bitmap bitmap(width, height); | ||
memcpy(bitmap.data(), &blob[0], width * height * 4); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since we know how long blob
is, we can perform a range check here instead of reading from possibly invalid memory.
lib/gosu/compat.rb
Outdated
color = args[2] || opts.fetch(:color, 0xff_ffffff) | ||
mode = args[3] || opts.fetch(:mode, :default) | ||
|
||
# Make draw_rot obsolete as the params are bascially the same besides the rotation-specific values |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
*basically
rdoc/gosu.rb
Outdated
# Returns an image from a binary string of packed RGBA values. (e.g. from (Image#to_blob)) | ||
# | ||
# @param blob [String] a string of any length (preferably width * height * 4) | ||
# @param width [Ingeger] the width of the resulting image |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
*Integer
rdoc/gosu.rb
Outdated
## | ||
# Returns an image from a binary string of packed RGBA values. (e.g. from (Image#to_blob)) | ||
# | ||
# @param blob [String] a string of any length (preferably width * height * 4) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not just preferably! :)
test/test_helper.rb
Outdated
include TestHelper | ||
|
||
def self.draw(w, h) | ||
win = new(w,h) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+space between operators
test/test_helper.rb
Outdated
skip if runs_on_ci? | ||
end | ||
|
||
def runs_on_ci? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ruby doesn't usually have an s
at the end of verbs (e.g. equal?
). run_on_ci?
, on_ci?
, simply ci?
? Not sure
Re tl;dr my plan was to build However, Ruby supports named arguments now, and I don't think it's a good idea to fight the language design. So let's do it! As for the details: I'm not sure if What do you think about having |
Re: So 馃憤 for an explicit |
Re: AM_REPLACE, I'm not convinced :) But I do agree with every bit of renaming from AlphaMode to BlendMode. |
Ok so many response....Hope I don't miss anything 馃槃
Didn't knew that. Definitely a considerable approach - a bit like the ActiveRecord-Relation chaining. This might be possible to add besides the parameter Hash which internally just converts it for the final draw.
You're right. Drawing an image with the given (x,y) as the center rather than the upper-left-corner should be a thing and then the center-shortcut makes sense. We could even add a bit of abstraction by providing keywords instead of float numers like center: :middle (or :upperleft, :lowerright, etc.).
Absolutely.
I'll fix these. I guess I should look to some spell-checking addon for my editor 馃槃
I'm not totally sure how this exactly works as well but Ashton used this quite a lot when combining shaders (and had a hint that it has to be done "manually" because Gosu doesn't support it out-of-the-box). But I guess I just remove it for now until I figure out how all the bits are connected and then re-add it later if needed.
You're right - I'll change them too.
Yes and no. Thats what I tried first (in irb while trying to convert by AppVeyor dump to a real image) because I thought the conversion from RMagick to Gosu would use some kind of blob. But something like: Foo = Struct.new :to_blob, :columns, :rows
Image.new(Foo.new(Filebinread('dump'), 100, 100)).save('realimage.png') didn't work 馃槃
I'll look into this. |
1049a13
to
67b09da
Compare
ext/gosu/gosu.i
Outdated
@@ -658,6 +658,32 @@ namespace Gosu | |||
std::unique_ptr<Gosu::ImageData> image_data = $self->data().subimage(x, y, w, h); | |||
return image_data.get() ? new Gosu::Image(std::move(image_data)) : nullptr; | |||
} | |||
|
|||
%newobject from_blob; | |||
static Gosu::Image* from_blob(const std::string& blob, int width, int height) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If Gosu::Image
works (because it's default constructible now?), we should always just return images directly instead of working with pointers and %newobject
.
lib/gosu/compat.rb
Outdated
|
||
alias _draw_rot draw_rot | ||
def draw_rot(*args) | ||
Gosu.deprecation_message("Image#draw_rot is deprecated in Gosu x.y, use draw with an options hash instead, see https://www.libgosu.org/rdoc/Gosu/Image.html.") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
x.y = 0.14 :)
lib/gosu/compat.rb
Outdated
|
||
# Shorthand for scale_x: scale_y: | ||
scale = opts.delete(:scale) | ||
scale_x, scale_y = scale, scale if scale |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
scale_x
should override scale
, not the other way around
lib/gosu/compat.rb
Outdated
if DRAW_ALIGNMENTS.has_key?(center) | ||
DRAW_ALIGNMENTS[center] | ||
else | ||
raise ArgumentError, "Unknown drawing alignmengt: #{center} should be a float or one of: #{DRAW_ALIGNMENTS.keys.join(', ')}" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
*alignment
angle = opts.delete(:angle) | ||
|
||
raise ArgumentError, "Unknown options: #{opts.keys} should be either of [angle, center, center_x, center_y, color, mode, scale, scale_x, scale_y]" unless opts.empty? | ||
if angle or center_x or center_y |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think it's intuitive that passing center_x: 0.5
also sets center_y: 0.5
, but leaving out center_x
uses center_y: 0
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I still think changing the default value of center_x
/center_y
based on the presence of angle
is more intuitive, if only slightly :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right. Was a bit confused as I need to call draw_rot if any of the 3 is set because draw doesn't support center so I had to set angle to a default as well but I guess now I got it ;-) but not sure how you came to
out center_x uses center_y: 0
all defaulted to 0.5
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It only defaults to 0.5 when angle
or either center_...
parameter is given. So:
image.draw x, y, z, center_x: 0.5 # => center_y = 0.5 (surprising)
image.draw x, y, z # => center_y = 0.0 (OK)
:bottom => [0, 1], | ||
:bottom_right => [1, 1], | ||
} | ||
def draw(x, y, z, *args) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if executing relatively much Ruby code in every Image#draw
call slows down existing Gosu games. I guess we should release a 0.14.0-pre1 gem this time and rewrite Image#draw
in C++ if this is really an issue
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok my girls are sleeping againg.....So - you're right. Performance might really be an issue here as drawing is done for possibly thousands of things. I use Ruby for over 10 years now and it was always fast enough with pure Ruby code or existing gems but I tend to forget that this is not my game but the layer below which should be fast. I'll see if I can imitate what you already did with the other methods supporting options.
rdoc/gosu.rb
Outdated
# @return [Gosu::Image] | ||
# | ||
# @see Image#to_blob | ||
def self.from_text(blob, width, height); end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
*from_blob :)
rdoc/gosu.rb
Outdated
## | ||
# Returns an image from a binary string of packed RGBA values. (e.g. from (Image#to_blob)) | ||
# | ||
# @param blob [String] a binary string with 1 byte per channel and pixel (RGBA) (width * height * 4) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I might have added that already - but the old image constructor also supported 4 byte per channel for floating point values, from_blob
should als officially support it as it doesn't cost us much
rdoc/gosu.rb
Outdated
@@ -1038,7 +1050,7 @@ def clip_to(x, y, w, h); end | |||
# | |||
# @note Because the returned object is not a true image---it's implemented using vertex buffers and is not backed by a texture---there are restrictions on how it can be used. | |||
# | |||
# @note The width and height of the returned object will be the same values you passed to {record}, regardless of the area you draw on. It is important to pass accurate values if you plan on using {Gosu::Image#draw_as_quad} or {Gosu::Image#draw_rot} with the result later. | |||
# @note The width and height of the returned object will be the same values you passed to {record}, regardless of the area you draw on. It is important to pass accurate values if you plan on using {Gosu::Image#draw_as_quad} or {Gosu::Image#draw with an angle set) with the result later. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The {braces}
are broken now
src/RenderState.hpp
Outdated
|
||
RenderState() | ||
: transform(0), mode(AM_DEFAULT) | ||
: transform(0), mode(BM_DEFAULT) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you please update this to transform(nullptr)
while you're touching this line? Or even better, you can initialize the members inline using =
A big PR but definitely the right direction 馃憤 Time for me to finally fix my own PR :) |
67b09da
to
f4c536f
Compare
Regarding my previous comments on
I take that back :) First, in some cases we need to work with pointers because methods can return tl;dr |
@Kjarrigan Not at all! :) |
Ok. I can live with a not working windows, because some tests are better than none. I'll rework/rebase it later today and report back! |
Random idea: C++20 will support (a restricted form of) C99 struct initializers. I think all major C++ compilers already support this syntax as an extension. Why not use named arguments in C++ as well: class Gosu::Font
{
...
public:
struct DrawArgs
{
const std::string& text;
double x, y, z = 0;
double rel_x = 0, rel_y = 0;
double scale_x = 1, scale_y = 1;
Color color = Color::WHITE;
AlphaMode mode = AM_DEFAULT;
};
void draw_text(DrawArgs args);
... Then we should get named arguments as in Ruby: my_font.draw({ .text = "Hello World", .x = 5, .y = 7, .color = Gosu::Color::RED }); If this works on all CI compilers, we should totally do that, at least for all |
05ac06d
to
46cd8fd
Compare
Hi @jlnr ,
sorry for another PR but while looking through ashton and working on my little gosu game I stumbled across some things with the images.... Especially the long argument list bothered me quite a while and now that I know the internals a bit better I just changed it 馃槃
Here one general question remains for me - was there a specific reason you coded the other options (e.g. from_text) in the SWIG-File instead of Ruby? The latter is much more compact and keeping the SWIG stuff smaller is a good idea I think. When we drop Ruby < 2.x support we can make this even shorter with the builtin named parameters (which do all kinds of checks like raising if you have a typo in your param name).
Some of the changes in test_helper are stolen from #433 so I'll rebase if either one is merge first (did you have a change looking at the open questions over there?)
The replace-blend mode was something which looked important for ashton and wasn't hard to add (and more blend modes are already requested #413) so I thought I just add it.
Finally I added tests for all the things (at least I hope I didn't miss anything - I just looked through libgosu.org/rdoc from top to bottom). To keep the repo small I tried to reuse as many images as possible but maybe I should look for a better image for the retro/tileable-scaling tests.